ต้นไม้ไวยากรณ์นามธรรม - การแก้ไขสัญลักษณ์ TypeScript โดยใช้ API ของคอมไพเลอร์
ฉันกำลังพยายามใช้ TypeScript compiler 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));
ดีมาก แต่ตอนนี้ผมติดขัด เพราะสัญลักษณ์ดูเหมือนจะไม่สามารถเปลี่ยนแปลงได้ คุณควรจะทำการคัดลอกมันแล้วจากนั้นก็ให้ตารางค้นหาบางอย่างกับตัวปล่อย (emitter) หรือใช้ SymbolWriter แบบกำหนดเอง หรือ SymbolDisplayBuilder? ผมไม่เห็นจุดต่อขยายมากนักในคลาสเหล่านี้
คำตอบ #1
ตัวอย่างเช่น การเปลี่ยนชื่อของตัวแปรระดับโลกและการอ้างอิงทั้งหมดถึงมัน
สัญลักษณ์มีการประกาศเก็บไว้ภายในตัวมัน (เอกสารบางส่วน https://basarat.gitbook.io/typescript/overview/binder/binder-declarations)
คุณสามารถเข้าถึงสิ่งเหล่านี้ได้โดยใช้ let declarations=symbol.getDeclarations(); และในความเป็นจริง นั่นคือสิ่งที่ getRenameInfo ใน services.ts ทำ (ซอร์สโค้ด)