我正在尝试使用TypeScript编译器API(1.4)来重命名源文件中的符号,例如重命名全局变量和对它的所有引用。我从这里的说明开始,然后使用它来获取所有标识符
function getNodes(sf: ts.SourceFile): ts.Node[]
{
var nodes: ts.Node[] = [];
function allNodes(n: ts.Node)
{
ts.forEachChild(n, n => { if (n.kind == ts.SyntaxKind.Identifier) nodes.push(n); allNodes(n); return false; })
};
allNodes(sf);
return nodes;
}
一旦创建了类型检查器,就可以将节点(对标识符的每个引用都有一个单独的实例)解析为符号(对同一变量的引用都有相同的实例):
var checker = program.getTypeChecker(true);
var symbols = getNodes(sourceFile).map((n, i, array) => checker.getSymbolAtLocation(n));
太好了。但现在我被卡住了,因为这个符号似乎是不可变的。你应该克隆它,然后为发射器提供某种查找表吗?或者自定义SymbolWriter或SymbolDisplayBuilder?我在类中看不到太多扩展点。
例如,重命名全局变量及其所有引用。
符号内部存储有声明(有些文档https://basarat.gitbook.io/typescript/overview/binder/binder-declarations)
您可以使用let declarations = symbol.getDeclarations();
访问这些内容,事实上services.ts
中的getRenameInfo
正是这样做的(源代码)。