TypeScript: få syntaxträd


Jag hade läst "hela internet", men kan inte hitta några exempel på hur man får syntaxträd (precis som i Esprima) från TypeScript-kod. Jag menar hur man kan få ett objekt som detta (Esprima Parser-exempel)

{
    "type": "Program",
    "body": [
        {
            "type": "VariableDeclaration",
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "id": {
                        "type": "Identifier",
                        "name": "answer"
                    },
                    "init": {
                        "type": "BinaryExpression",
                        "operator": "*",
                        "left": {
                            "type": "Literal",
                            "value": 6,
                            "raw": "6"
                        },
                        "right": {
                            "type": "Literal",
                            "value": 7,
                            "raw": "7"
                        }
                    }
                }
            ],
            "kind": "var"
        }
    ]
}

från javascript-kod

var answer = 6 * 7;

bara för TypeScript-källtext?

P.S. Jag hoppas mycket på din hjälp, eftersom jag inte vill skriva din egen hemska cykel)

P.P.S. Jag tror att lib-filerna typescript.ts(.js) och typescriptServices.ts(.js) kan hjälpa mig, men jag vet inte hur :(

Löst

Stort tack till användaren Steve Fenton. Här är min kod, om någon är intresserad av:

// uses
var typeScriptLS =  new Harness.TypeScriptLS();
var ServicesFactory = new Services.TypeScriptServicesFactory();
var serviceShim = ServicesFactory.createLanguageServiceShim(typeScriptLS);

// add lib.d.ts
var _libText = window.document.getElementById('lib.d.ts').innerText;
typeScriptLS.addScript('lib.d.ts', _libText.replace(/\r\n?/g,"\n"), true);

// add greeter.ts
var _sourceText = window.document.getElementById('greeter.ts').innerText;
typeScriptLS.addScript('greeter.ts', _sourceText.replace(/\r\n?/g,"\n"), true);

// script name
var _scriptName = 'greeter.ts';
// get syntax tree
var _st = serviceShim.languageService.getSyntaxTree(_scriptName);
//console.log(_st);
console.log(JSON.stringify(_st, "", 2));

Svar #1

TypeScript-parsaren producerar inte direkt ett träd som det där, men du kan ändå använda dess objektmodell för att göra alla möjliga saker. Vi använder det i vissa verktyg för att göra syntaxomvandlingar för teständamål, till exempel. Här är ett utdrag som du kan använda för att skriva ut syntaksträdet:

import ts from "typescript";
 
const code = "enum { x = 1 }";
const sc = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest, true);

let indent = 0;
function print(node: ts.Node) {
    console.log(new Array(indent + 1).join(" ") + ts.SyntaxKind[node.kind]);
    indent++;
    ts.forEachChild(node, print);
    indent--;
}
 
print(sc);

Svar #2

Den här frågan kom upp tidigare i september.

Det finns för närvarande inget som kan göra detta åt dig - det finns ingen magisk getSyntaxTree-metod att kalla som gör detta.

TypeScript-kompilatorn är dock öppen källkod och skriven helt i TypeScript så att du kan granska den för att ta reda på om det finns något du kan använda/lägga till ett handtag för.

Fördelen med detta är att du har en stor möjlighet att släppa ditt arbete som ett open-source-projekt, eftersom det genom antalet upp-röster på de två frågorna finns en viss efterfrågan på detta.

Alternativt, hämta syntaxträdet från den kompilerade JavaScripten (som är koden som faktiskt kommer att köras vid körningstid) med hjälp av Esprima eller SpiderMonkey.

Relaterade artiklar