gpt4 book ai didi

typescript - ts.setSyntheticLeadingComments 不会删除现有评论

转载 作者:行者123 更新时间:2023-12-02 03:19:39 28 4
gpt4 key购买 nike

描述

你好,

我正在尝试构建可以在函数之上添加注释的东西。不幸的是,似乎 ts.setSyntheticLeadingComments 不允许我替换现有评论。

我试过:

  • ts.setSyntheticLeadingComments(node, [])
  • ts.setSyntheticLeadingComments(node, undefined)
  • node = ts.setSyntheticLeadingComments(node, [])

但这些都不起作用。最终,我的目标是能够用新评论替换我本应生成的现有评论。

有什么想法吗?谢谢🙏

复制

const transformFactory = (context: ts.TransformationContext) => (
rootNode: ts.SourceFile
): ts.SourceFile => {
const visit = (node: ts.Node) => {
node = ts.visitEachChild(node, visit, context);

ts.setSyntheticLeadingComments(node, []);

return node;
};

return ts.visitNode(rootNode, visit);
};

const sourceFile = ts.createSourceFile(
path,
source,
ts.ScriptTarget.ESNext,
true,
ts.ScriptKind.TS
);
const result = ts.transform(sourceFile, [transformFactory]);
const resultPrinter = ts.createPrinter({ removeComments: false });

console.log(resultPrinter.printFile(result.transformed[0]));

尝试下面的转换器,看看如何完全不删除评论

使用 ts.createPrinter(..., { substituteNode(hint, node) { ... } }) 也无济于事

旁注

似乎 ts.getSyntheticLeadingComments() 也没有像我期望的那样工作。它总是返回 undefined,这导致我使用以下实用程序,尽管我不确定是否完全理解它的目的(借自 https://github.com/angular/tsickle/blob/6f5835a644f3c628a61e3dcd558bb9c59c73dc2f/src/transformer_util.ts#L257-L266)

/**
* A replacement for ts.getLeadingCommentRanges that returns the union of synthetic and
* non-synthetic comments on the given node, with their text included. The returned comments must
* not be mutated, as their content might or might not be reflected back into the AST.
*/
export function getAllLeadingComments(node: ts.Node):
ReadonlyArray<Readonly<ts.CommentRange&{text: string}>> {
const allRanges: Array<Readonly<ts.CommentRange&{text: string}>> = [];
const nodeText = node.getFullText();
const cr = ts.getLeadingCommentRanges(nodeText, 0);
if (cr) allRanges.push(...cr.map(c => ({...c, text: nodeText.substring(c.pos, c.end)})));
const synthetic = ts.getSyntheticLeadingComments(node);
if (synthetic) allRanges.push(...synthetic);
return allRanges;
}

最佳答案

问题是您希望 *SyntheticLeadingComments 函数影响源注释。他们不会。它们只会影响之前合成的注释(即您在代码中添加的注释)。

实际评论不会作为节点保存在 AST 中。您可以使用 getLeadingCommentRangesgetTrailingCommentRanges 获取实际的源注释。

一个节点有一个 start 和一个 end 位置,不包含任何注释。节点还有一个 fullStart,它是包含任何前导注释的位置。输出节点时,typescript 就是这样知道如何将注释复制到输出的。

如果我们使用 setTextRange 设置节点范围以排除这些现有评论,结果是我们有效地从输出中删除它们,我们可以使用 setSyntheticLeadingComments< 添加新评论:

import * as ts from 'typescript'

const transformFactory = (context: ts.TransformationContext) => (
rootNode: ts.SourceFile
): ts.SourceFile => {
const visit = (node: ts.Node) => {
node = ts.visitEachChild(node, visit, context);
if(ts.isFunctionDeclaration(node)) {
let sourceFileText = node.getSourceFile().text;
const existingComments = ts.getLeadingCommentRanges(sourceFileText, node.pos);
if (existingComments) {
// Log existing comments just for fun
for (const comment of existingComments) {
console.log(sourceFileText.substring(comment.pos, comment.end))
}
// Comment also attaches to the first child, we must remove it recursively.
let removeComments = (c: ts.Node) => {
if (c.getFullStart() === node.getFullStart()) {
ts.setTextRange(c, { pos: c.getStart(), end: c.getEnd() });
}
c = ts.visitEachChild(c, removeComments, context);
return c;
}
ts.visitEachChild(node, removeComments, context);
ts.setTextRange(node, { pos: node.getStart(), end: node.getEnd() })
ts.setSyntheticLeadingComments(node, [{
pos: -1,
end: -1,
hasTrailingNewLine: false,
text: "Improved comment",
kind: ts.SyntaxKind.SingleLineCommentTrivia
}]);

}
}
return node;
};

return ts.visitNode(rootNode, visit);
};

const sourceFile = ts.createSourceFile(
"path.ts",
`
// Original comment
function test () {

}
`,
ts.ScriptTarget.ESNext,
true,
ts.ScriptKind.TS
);
const result = ts.transform(sourceFile, [transformFactory]);
const resultPrinter = ts.createPrinter({ removeComments: false });

console.log("!");
console.log(resultPrinter.printFile(result.transformed[0]));

关于typescript - ts.setSyntheticLeadingComments 不会删除现有评论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55172827/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com