I'm creating a transformer that needs to replace each Call Expression placeholder with the code __REPLACED__, so I wrote this code:
compiler.ts
import * as ts from "typescript"
const filePath = "source.ts"
const programOptions = {
rootNames: [filePath],
options: {
target: ts.ScriptTarget.ES2020,
outDir: "outdir"
}
}
const transformerFactory: ts.TransformerFactory<ts.SourceFile> = context => {
return node => {
const visitor: ts.Visitor = rootNode => {
const node = ts.visitEachChild(rootNode, visitor, context)
if (ts.isCallExpression(node)) {
if (node.expression.getText() !== "placeholder") {
return node
}
const subsNode = ts.factory.createIdentifier("__REPLACED__")
return subsNode
}
return node
}
return ts.visitNode(node, visitor)
}
}
const program = ts.createIncrementalProgram(programOptions)
const entrySourceFile = program.getSourceFile(filePath)
const customTransformers: ts.CustomTransformers = { before: [transformerFactory] }
const emitResults = program.emit(entrySourceFile, undefined, undefined, undefined, customTransformers)
It works well if the source.ts file doesn't have any placeholder inside a anonymous function call, the code below everything works right:
source.ts
placeholder("param")
void function() {
placeholder("param")
}
Using thats source.ts described above, TypeScript Compiler API emits what I expected:
outdir\source.js
__REPLACED__;
void async function () {
__REPLACED__;
};
But if I call this anonymous function right after creating it, I get an error if I use the following code as source.ts:
source.ts
placeholder("param")
void function() {
placeholder("param")
}() // <---- HERE'S THE PROBLEM
Here's the trace error:
(node:9204) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'text' of undefined
at NodeObject.getText (project_dir\node_modules\typescript\lib\typescript.js:156127:31)
at visitor (project_dir\typescriptCompiler.ts:22:41)
at visitNode (project_dir\node_modules\typescript\lib\typescript.js:85158:23)
at Object.visitEachChild (project_dir\node_modules\typescript\lib\typescript.js:85565:59)
at visitor (project_dir\typescriptCompiler.ts:20:33)
at visitNode (project_dir\node_modules\typescript\lib\typescript.js:85158:23)
at Object.visitEachChild (project_dir\node_modules\typescript\lib\typescript.js:85622:64)
at visitor (project_dir\typescriptCompiler.ts:20:33)
at visitNodes (project_dir\node_modules\typescript\lib\typescript.js:85211:48)
at visitLexicalEnvironment (project_dir\node_modules\typescript\lib\typescript.js:85251:22)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:9204) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:9204) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I suspect the problem is with recursion, i think somehow I'm removing the anonymous function node before accessing the placehorlders.
in advance thank you for your help.
Thanks.