TypeScript:获取语法树

buk*_*vaG 41 abstract-syntax-tree typescript

我读过"整个互联网",但找不到任何关于从TypeScrypt源获取语法树(就像在Esprima中一样)的例子.我的意思是我怎样才能得到这样的对象(Esprima Parser示例)

{
    "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"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

来自javascript代码

var answer = 6 * 7;
Run Code Online (Sandbox Code Playgroud)

仅适用于TypeScript源文本?

PS我非常希望得到你的帮助,因为我不想写你自己糟糕的自行车)

PPS我认为lib文件typescript.ts(.js)和typescriptServices.ts(.js)帮助我,但我不知道如何:(

解决了

非常感谢用户Steve Fenton.这是我的代码,如果有人对此感兴趣:

// 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));
Run Code Online (Sandbox Code Playgroud)

Rya*_*ugh 18

TypeScript解析器不直接生成这样的树,但您仍然可以使用其对象模型来执行各种操作.例如,我们在某些工具中使用它来进行语法转换以进行测试.这是一个可用于打印语法树的片段:

import ts = require('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);
Run Code Online (Sandbox Code Playgroud)

  • 我在http://blog.ctaggart.com/2014/06/typescript-ast-from-nodejs.html上找到并发表了关于我的发现的博客 (2认同)

Fen*_*ton 7

这个问题早在九月之前出现过.

目前还没有什么能够为你做到这一点 - 没有神奇的getSyntaxTree方法可以做到这一点.

但是TypeScript编译器是开源的 - 并且完全用TypeScript编写,因此您可以扫描它以查明是否有可以使用/添加句柄的东西.

最重要的是,你有很大的机会将你的工作作为一个开源项目发布,从两个问题的最高投票来判断,对此有一些需求.

或者,使用EsprimaSpiderMonkey从编译的JavaScript(这是将在运行时实际执行的代码)中获取语法树.


can*_*ero 5

使用 recast 和 babylon@next 是可能的。尽管您必须相信这些技术定义的用于表示 TypeScript 代码的语法 AST 并且它们会保持最新状态 - 因为 TypeScript 具有按版本发布的新语言功能(短时间) - 不像其他语言(JavaScript ) 你有明确定义的版本并以标准发布 - 所以如果你的用户开始使用新的语言功能,这些技术(我猜巴比伦)应该保持最新,否则解析将失败

// npm install recast babylon@next
const source = `
interface I {
  color: string
}
class C implements I{
  color: string='blue'
}
`
const recast = require('recast')
const tsParser = require("recast/parsers/typescript")
const ast = recast.parse(source, {
  parser: tsParser
});
console.log(`
CODE: 

${source}

AST: 

${JSON.stringify(ast)}
`);
Run Code Online (Sandbox Code Playgroud)