diff --git a/src/core/$reflect.ts b/src/core/$reflect.ts deleted file mode 100644 index ca4f920..0000000 --- a/src/core/$reflect.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function $reflect(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 -} diff --git a/src/core/typed.ts b/src/core/typed.ts new file mode 100644 index 0000000..3306776 --- /dev/null +++ b/src/core/typed.ts @@ -0,0 +1,11 @@ +export function typed(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 +} diff --git a/src/experiment/arithmeticInfer.ts b/src/experiment/arithmeticInfer.ts index 4a4a6e6..be544a3 100644 --- a/src/experiment/arithmeticInfer.ts +++ b/src/experiment/arithmeticInfer.ts @@ -1,6 +1,6 @@ -import { $reflect } from '../core/$reflect.js' +import { typed } from '../core/typed.js' -export const square = $reflect((dep: { +export const square = typed('square', '__infer__', (dep: { multiply: (a: T, b: T) => T, unaryMinus: (x: T) => T, // just for the experiment }): (a: T) => T => diff --git a/src/plugins/typeInferPlugin.ts b/src/plugins/typeInferPlugin.ts index 84c0dcf..4ca6c21 100644 --- a/src/plugins/typeInferPlugin.ts +++ b/src/plugins/typeInferPlugin.ts @@ -7,43 +7,43 @@ const transformer: ts.TransformerFactory = context => { return sourceFile => { const visitor = (node: ts.Node): ts.Node => { - // we're looking for a function call like $reflect(deps => ...) // @ts-ignore - 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) + if (ts.isStringLiteral(node) && node.text === '__infer__') { + console.log('PLUGIN: FOUND AN OCCURRENCE OF __infer__') - // 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 + // 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) - // @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 - // } + // 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 - 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; } + // @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 depsAndReturnType = `{ deps: ${paramType}; return: ${returnType} }` + 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; } - // 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)) + const depsAndReturnType = `{ deps: ${paramType}; return: ${returnType} }` - return node + return ts.factory.createStringLiteral(depsAndReturnType) + } } return ts.visitEachChild(node, visitor, context)