Compare commits
2 Commits
26631febf9
...
232d5d4a96
Author | SHA1 | Date | |
---|---|---|---|
232d5d4a96 | |||
7fc9d2a2f3 |
11
src/core/$reflect.ts
Normal file
11
src/core/$reflect.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export function $reflect<T>(arg: T, types?: string) : T {
|
||||
// TODO: implement typed-function for real
|
||||
if (!types) {
|
||||
console.error('types should be resolved with runtime type information by the TypeScript plugin')
|
||||
}
|
||||
|
||||
console.log(`INFER: Creating function with types ${types}`)
|
||||
|
||||
// TODO: here we can now turn the inputs into a real typed-function with a signature
|
||||
return arg
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
export function typed<T>(name: string, types: string, arg: T) : T {
|
||||
// TODO: implement typed-function for real
|
||||
if (types === '__infer__') {
|
||||
console.error('__infer__ should be replaced with runtime type information by the TypeScript plugin')
|
||||
}
|
||||
|
||||
console.log(`TYPED-FUNCTION: Creating function "${name}" with types ${types}`)
|
||||
|
||||
// TODO: here we can now turn the inputs into a real typed-function with a signature
|
||||
return arg
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { typed } from '../core/typed.js'
|
||||
import { $reflect } from '../core/$reflect.js'
|
||||
|
||||
export const square = typed('square', '__infer__', <T>(dep: {
|
||||
export const square = $reflect(<T>(dep: {
|
||||
multiply: (a: T, b: T) => T,
|
||||
unaryMinus: (x: T) => T, // just for the experiment
|
||||
}): (a: T) => T =>
|
||||
|
@ -7,43 +7,43 @@ const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
|
||||
|
||||
return sourceFile => {
|
||||
const visitor = (node: ts.Node): ts.Node => {
|
||||
// we're looking for a function call like $reflect(deps => ...)
|
||||
// @ts-ignore
|
||||
if (ts.isStringLiteral(node) && node.text === '__infer__') {
|
||||
console.log('PLUGIN: FOUND AN OCCURRENCE OF __infer__')
|
||||
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === '$reflect') {
|
||||
console.log('PLUGIN: FOUND AN OCCURRENCE OF $reflect')
|
||||
// console.log('PARENT')
|
||||
// console.log(node)
|
||||
|
||||
// we're looking for a function call like typed('name', '__infer__', deps => ...)
|
||||
const parentNode = node.parent
|
||||
if (ts.isCallExpression(parentNode) && ts.isIdentifier(parentNode.expression) && parentNode.expression.escapedText === 'typed') {
|
||||
// console.log('PARENT')
|
||||
// console.log(parentNode)
|
||||
// TODO: validate that argNode is an ArrowFunction
|
||||
// @ts-ignore
|
||||
const argNode = node.arguments[0]
|
||||
// @ts-ignore
|
||||
const returnType = argNode.type.getText(sourceFile)
|
||||
console.log('PLUGIN: RETURN TYPE')
|
||||
console.log(returnType)
|
||||
// (a: number) => number
|
||||
|
||||
// TODO: validate that argNode is an ArrowFunction
|
||||
// @ts-ignore
|
||||
const argNode = parentNode.arguments[2]
|
||||
// @ts-ignore
|
||||
const returnType = argNode.type.getText(sourceFile)
|
||||
console.log('PLUGIN: RETURN TYPE')
|
||||
console.log(returnType)
|
||||
// (a: number) => number
|
||||
// @ts-ignore
|
||||
const paramNode = argNode.parameters[0]
|
||||
const paramTypeSrc = paramNode.type.getText(sourceFile)
|
||||
console.log('PLUGIN: PARAM TYPE SRC', paramTypeSrc)
|
||||
// {
|
||||
// multiply: (a: number, b: number) => number,
|
||||
// unaryMinus: (x: number) => number, // just for the experiment
|
||||
// }
|
||||
|
||||
// @ts-ignore
|
||||
const paramNode = argNode.parameters[0]
|
||||
const paramTypeSrc = paramNode.type.getText(sourceFile)
|
||||
console.log('PLUGIN: PARAM TYPE SRC', paramTypeSrc)
|
||||
// {
|
||||
// multiply: (a: number, b: number) => number,
|
||||
// unaryMinus: (x: number) => number, // just for the experiment
|
||||
// }
|
||||
const type = checker.getTypeAtLocation(paramNode)
|
||||
const paramType = checker.typeToString(type, paramNode, ts.TypeFormatFlags.InTypeAlias)
|
||||
console.log('PLUGIN: PARAM TYPE STRING', paramType)
|
||||
// { multiply: (a: number, b: number) => number; unaryMinus: (x: number) => number; }
|
||||
|
||||
const type = checker.getTypeAtLocation(paramNode)
|
||||
const paramType = checker.typeToString(type, paramNode, ts.TypeFormatFlags.InTypeAlias)
|
||||
console.log('PLUGIN: PARAM TYPE STRING', paramType)
|
||||
// { multiply: (a: number, b: number) => number; unaryMinus: (x: number) => number; }
|
||||
const depsAndReturnType = `{ deps: ${paramType}; return: ${returnType} }`
|
||||
|
||||
const depsAndReturnType = `{ deps: ${paramType}; return: ${returnType} }`
|
||||
// Now we insert a second argument to the $reflect function call: a string with the types
|
||||
// @ts-ignore
|
||||
node.arguments.push(ts.factory.createStringLiteral(depsAndReturnType))
|
||||
|
||||
return ts.factory.createStringLiteral(depsAndReturnType)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
return ts.visitEachChild(node, visitor, context)
|
||||
|
Loading…
Reference in New Issue
Block a user