Проблема в том, что функции *SyntheticLeadingComments
влияют на исходные комментарии. Они не будут. Они будут влиять только на комментарии, которые были ранее синтезированы (т.е. добавлены вами в коде).
Фактические комментарии не сохраняются как узлы в AST. Вы можете получить реальные исходные комментарии, используя getLeadingCommentRanges
и getTrailingCommentRanges
.
Узел имеет позицию start
и end
, которые не содержат никаких комментариев. Существует также полный старт для узла, который является позицией, включая любые ведущие комментарии. Когда выводится узел, именно так машинопись знает, как копировать комментарии в вывод.
Если мы используем 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]));