【问题标题】:Add comment before function using TypeScript Compiler API使用 TypeScript Compiler API 在函数前添加注释
【发布时间】:2018-10-05 03:04:15
【问题描述】:

我有一个想要转换为 JavaScript 的 TypeScript 文件。作为翻译的一部分,我想在每个函数之前添加注释,我希望使用 TypeScript Compiler API 来做到这一点。

我尝试了两种不同的方法。其中之一是抓取SourceFile 并更改其statements,如下所示:

const program = ts.createProgram([args.input], {});
const srcFile = find(program.getSourceFiles(), (sourceFile) => !sourceFile.isDeclarationFile);
srcFile.statements = ts.createNodeArray(srcFile.statements.map((statement) => {
    if (!ts.isFunctionDeclaration(statement)) {
        return statement;
    }
    return ts.addSyntheticLeadingComment(
        statement,
        ts.SyntaxKind.MultiLineCommentTrivia,
        "My long desired comment",
        true,
    );
}));

这给了我以下错误:

TypeError: Cannot read property 'emitNode' of undefined
at getOrCreateEmitNode (/Users/.../node_modules/typescript/lib/typescript.js:52792:19)
at getOrCreateEmitNode (/Users/.../node_modules/typescript/lib/typescript.js:52801:17)
at setSyntheticLeadingComments (/Users/.../node_modules/typescript/lib/typescript.js:52918:9)
at Object.addSyntheticLeadingComment (/Users/.../node_modules/typescript/lib/typescript.js:52923:16)
at /Users/.../dist/index.js:26:15
at Array.map (<anonymous>)
at Object.<anonymous> (/Users/.../dist/index.js:21:60)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)

我尝试在ts.addSyntheticLeadingComment 之前打印statement,而statementFunctionDeclaration,正如预期的那样,尽管缺少emitNode 字段,我希望该字段由getOrCreateEmitNode 创建函数。

我尝试的第二种方法类似,但遇到了同样的问题;而不是覆盖原来的srcFile.statement,我正在使用打印机,如下所示:

const printer = ts.createPrinter(undefined, {
    substituteNode: (hint, node) => {
        if (ts.isFunctionDeclaration(node)) {
            return ts.addSyntheticLeadingComment(
                node,
                ts.SyntaxKind.MultiLineCommentTrivia,
                "My long desired comment",
                true,
           );
        }
    },
});

console.log(printer.printFile(srcFile));

这给出了与前面的代码相同的错误。

我要更改的 TypeScript 文件非常简单:

function myFunc(a: number, b: number): number {
    return a + b;
}

【问题讨论】:

    标签: typescript typescript-compiler-api


    【解决方案1】:

    不需要替换节点。请记住,cmets 不是 AST 的一部分,因此不要将它们添加到语句数组中以代替现有函数声明。相反,只需在节点上调用addSyntheticLeadingComment 而不使用返回值。

    例如,以下代码可以正常工作:

    import * as ts from "typescript";
    
    const file = ts.createSourceFile("test.ts", `function myFunc(a: number, b: number): number {
        return a + b;
    }`, ts.ScriptTarget.Latest, true);
    const functionDec = file.statements.find(ts.isFunctionDeclaration)!;
    
    ts.addSyntheticLeadingComment(functionDec, ts.SyntaxKind.MultiLineCommentTrivia,
        "My long desired comment", true);
    
    const printer = ts.createPrinter({ removeComments: false });
    console.log(printer.printFile(file));
    

    输出:

    /*My long desired comment*/
    function myFunc(a: number, b: number): number {
        return a + b;
    }
    

    【讨论】:

      【解决方案2】:

      David Sherret's 的答案是正确的,但是无论我尝试什么,我都一直遇到Cannot read property 'emitNode' of undefined at getOrCreateEmitNode 错误。

      事实证明我错过了ts.createSourceFile 中名为setParentNodes 的第四个参数。通过将此参数设置为 true,我可以使用addSyntheticLeadingComment

      基本上这个参数(setParentNodes)设置每个Nodeparent属性。

      getOrCreateEmitNode 需要向上遍历树,如果没有父引用,则无法这样做。有关setParentNodes 的更多详细信息,请查看this Github issue

      【讨论】:

        猜你喜欢
        • 2022-08-15
        • 1970-01-01
        • 1970-01-01
        • 2021-05-12
        • 1970-01-01
        • 2013-08-13
        • 1970-01-01
        • 2017-12-30
        • 2021-03-12
        相关资源
        最近更新 更多