feat: Return type annotations #53
@ -2,7 +2,7 @@
|
|||||||
import typed from 'typed-function'
|
import typed from 'typed-function'
|
||||||
import {makeChain} from './Chain.mjs'
|
import {makeChain} from './Chain.mjs'
|
||||||
import {dependencyExtractor, generateTypeExtractor} from './extractors.mjs'
|
import {dependencyExtractor, generateTypeExtractor} from './extractors.mjs'
|
||||||
import {R_, isReturnAnnotated} from './returns.mjs'
|
import R_ from './returns.mjs'
|
||||||
import {typeListOfSignature, typesOfSignature, subsetOfKeys} from './utils.mjs'
|
import {typeListOfSignature, typesOfSignature, subsetOfKeys} from './utils.mjs'
|
||||||
|
|
||||||
const anySpec = {} // fixed dummy specification of 'any' type
|
const anySpec = {} // fixed dummy specification of 'any' type
|
||||||
@ -693,7 +693,7 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
/* Now build the catchall implementation */
|
/* Now build the catchall implementation */
|
||||||
const self = this
|
const self = this
|
||||||
/* For return-type annotation, we will have to fix this to
|
/* For return type annotation, we may have to fix this to
|
||||||
propagate the return type. At the moment we are just bagging
|
propagate the return type. At the moment we are just bagging
|
||||||
*/
|
*/
|
||||||
const patch = (refs) => (...args) => {
|
const patch = (refs) => (...args) => {
|
||||||
@ -815,12 +815,9 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Finally ready to make the call.
|
// Finally ready to make the call.
|
||||||
let returnSpec = behavior.does(innerRefs)
|
const implementation = behavior.does(innerRefs)
|
||||||
if (isReturnAnnotated(returnSpec)) {
|
// Could do something with return type information here
|
||||||
// for now just drop return type information
|
return implementation(...args)
|
||||||
returnSpec = returnSpec.via
|
|
||||||
}
|
|
||||||
return returnSpec(...args)
|
|
||||||
}
|
}
|
||||||
// The actual uses value needs to be a set:
|
// The actual uses value needs to be a set:
|
||||||
const outerUses = new Set(Object.values(simplifiedUses))
|
const outerUses = new Set(Object.values(simplifiedUses))
|
||||||
@ -862,12 +859,9 @@ export default class PocomathInstance {
|
|||||||
_addTFimplementation(imps, signature, behavior) {
|
_addTFimplementation(imps, signature, behavior) {
|
||||||
const {uses, does} = behavior
|
const {uses, does} = behavior
|
||||||
if (uses.length === 0) {
|
if (uses.length === 0) {
|
||||||
let returnSpec = does()
|
const implementation = does()
|
||||||
if (isReturnAnnotated(returnSpec)) {
|
// could do something with return type information here
|
||||||
// for now just dump the return information
|
imps[signature] = implementation
|
||||||
returnSpec = returnSpec.via
|
|
||||||
}
|
|
||||||
imps[signature] = returnSpec
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const refs = {}
|
const refs = {}
|
||||||
@ -927,13 +921,9 @@ export default class PocomathInstance {
|
|||||||
if (full_self_referential) {
|
if (full_self_referential) {
|
||||||
imps[signature] = this._typed.referToSelf(self => {
|
imps[signature] = this._typed.referToSelf(self => {
|
||||||
refs.self = self
|
refs.self = self
|
||||||
let returnSpec = does(refs)
|
const implementation = does(refs)
|
||||||
if (isReturnAnnotated(returnSpec)) {
|
|
||||||
// What are we going to do with the return type info in here?
|
// What are we going to do with the return type info in here?
|
||||||
// Anyhow, drop it for now
|
return implementation
|
||||||
returnSpec = returnSpec.via
|
|
||||||
}
|
|
||||||
return returnSpec
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -953,12 +943,9 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let returnSpec = does(refs)
|
const implementation = does(refs)
|
||||||
if (isReturnAnnotated(returnSpec)) {
|
// could do something with return type information here
|
||||||
// drop return type for now
|
imps[signature] = implementation
|
||||||
returnSpec = returnSpec.via
|
|
||||||
}
|
|
||||||
imps[signature] = returnSpec
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_correctPartialSelfRefs(name, imps) {
|
_correctPartialSelfRefs(name, imps) {
|
||||||
@ -993,13 +980,9 @@ export default class PocomathInstance {
|
|||||||
for (let i = 0; i < part_self_references.length; ++i) {
|
for (let i = 0; i < part_self_references.length; ++i) {
|
||||||
refs[`self(${part_self_references[i]})`] = impls[i]
|
refs[`self(${part_self_references[i]})`] = impls[i]
|
||||||
}
|
}
|
||||||
let returnSpec = does(refs)
|
const implementation = does(refs)
|
||||||
if (isReturnAnnotated(returnSpec)) {
|
|
||||||
// What will we do with the return type info in here?
|
// What will we do with the return type info in here?
|
||||||
// anyhow, drop it for now
|
return implementation
|
||||||
returnSpec = returnSpec.via
|
|
||||||
}
|
|
||||||
return returnSpec
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,28 @@
|
|||||||
/* Annotate a function with its return type */
|
/* Annotate a function with its return type */
|
||||||
export function R_(type, fn) {
|
|
||||||
return {returns: type, via: fn}
|
/* Unfortunately JavaScript is missing a way to cleanly clone a function
|
||||||
|
* object, see https://stackoverflow.com/questions/1833588
|
||||||
|
*/
|
||||||
|
|
||||||
|
const clonedFrom = Symbol('the original function this one was cloned from')
|
||||||
|
function cloneFunction(fn) {
|
||||||
|
const behavior = fn[clonedFrom] || fn // don't nest clones
|
||||||
|
const theClone = function () { return behavior.apply(this, arguments) }
|
||||||
|
Object.assign(theClone, fn)
|
||||||
|
theClone[clonedFrom] = body
|
||||||
|
Object.defineProperty(
|
||||||
|
theClone, 'name', {value: fn.name, configurable: true })
|
||||||
|
return theClone
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isReturnAnnotated(x) {
|
export function R_(type, fn) {
|
||||||
return x && typeof x === 'object' && 'returns' in x && 'via' in x
|
if ('returns' in fn) fn = cloneFunction(fn)
|
||||||
|
fn.returns = type
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
|
||||||
|
export function returnTypeOf(fn) {
|
||||||
|
return fn.returns || 'any'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default R_
|
export default R_
|
||||||
|
Loading…
Reference in New Issue
Block a user