make defining __infer__ redundant

This commit is contained in:
Jos de Jong 2023-09-08 14:25:14 +02:00
parent 7fc9d2a2f3
commit 232d5d4a96
3 changed files with 34 additions and 34 deletions

View File

@ -1,7 +1,7 @@
export function $reflect<T>(types: string, arg: T) : T { export function $reflect<T>(arg: T, types?: string) : T {
// TODO: implement typed-function for real // TODO: implement typed-function for real
if (types === '__infer__') { if (!types) {
console.error('__infer__ should be replaced with runtime type information by the TypeScript plugin') console.error('types should be resolved with runtime type information by the TypeScript plugin')
} }
console.log(`INFER: Creating function with types ${types}`) console.log(`INFER: Creating function with types ${types}`)

View File

@ -1,6 +1,6 @@
import { $reflect } from '../core/$reflect.js' import { $reflect } from '../core/$reflect.js'
export const square = $reflect('__infer__', <T>(dep: { export const square = $reflect(<T>(dep: {
multiply: (a: T, b: T) => T, multiply: (a: T, b: T) => T,
unaryMinus: (x: T) => T, // just for the experiment unaryMinus: (x: T) => T, // just for the experiment
}): (a: T) => T => }): (a: T) => T =>

View File

@ -7,43 +7,43 @@ const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
return sourceFile => { return sourceFile => {
const visitor = (node: ts.Node): ts.Node => { const visitor = (node: ts.Node): ts.Node => {
// we're looking for a function call like $reflect(deps => ...)
// @ts-ignore // @ts-ignore
if (ts.isStringLiteral(node) && node.text === '__infer__') { if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === '$reflect') {
console.log('PLUGIN: FOUND AN OCCURRENCE OF __infer__') 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 => ...) // TODO: validate that argNode is an ArrowFunction
const parentNode = node.parent // @ts-ignore
if (ts.isCallExpression(parentNode) && ts.isIdentifier(parentNode.expression) && parentNode.expression.escapedText === '$reflect') { const argNode = node.arguments[0]
// console.log('PARENT') // @ts-ignore
// console.log(parentNode) 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
// @ts-ignore const paramNode = argNode.parameters[0]
const argNode = parentNode.arguments[1] const paramTypeSrc = paramNode.type.getText(sourceFile)
// @ts-ignore console.log('PLUGIN: PARAM TYPE SRC', paramTypeSrc)
const returnType = argNode.type.getText(sourceFile) // {
console.log('PLUGIN: RETURN TYPE') // multiply: (a: number, b: number) => number,
console.log(returnType) // unaryMinus: (x: number) => number, // just for the experiment
// (a: number) => number // }
// @ts-ignore const type = checker.getTypeAtLocation(paramNode)
const paramNode = argNode.parameters[0] const paramType = checker.typeToString(type, paramNode, ts.TypeFormatFlags.InTypeAlias)
const paramTypeSrc = paramNode.type.getText(sourceFile) console.log('PLUGIN: PARAM TYPE STRING', paramType)
console.log('PLUGIN: PARAM TYPE SRC', paramTypeSrc) // { multiply: (a: number, b: number) => number; unaryMinus: (x: number) => number; }
// {
// multiply: (a: number, b: number) => number,
// unaryMinus: (x: number) => number, // just for the experiment
// }
const type = checker.getTypeAtLocation(paramNode) const depsAndReturnType = `{ deps: ${paramType}; return: ${returnType} }`
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} }` // 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) return ts.visitEachChild(node, visitor, context)