如何从 AST 打字稿解析器生成代码?

Jon*_*Sud 6 abstract-syntax-tree typescript

在阅读了Using the Compiler API文章后,我可以从字符串代码中获取 AST。

但是,当我尝试从 AST生成代码(通过 escodegen)(而不是转译它)到代码时,我得到了一个错误:

Unknown node type: undefined
Run Code Online (Sandbox Code Playgroud)

有没有办法为代码生成 ast?

import * as fs from "fs";
import escodegen from "escodegen";
import * as ts from "typescript";

const code = `
 function foo() { }
`;

const node = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest);

console.log({ node });

const x = escodegen.generate(node);

console.log({ x });
Run Code Online (Sandbox Code Playgroud)

代码和盒子.io

Shl*_*evi 16

您可以通过createPrinter并传递nodeprintNode

这里的工作示例:

const code = `
 function foo() { }
`;

const node = ts.createSourceFile("x.ts", code, ts.ScriptTarget.Latest);
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });

const result = printer.printNode(ts.EmitHint.Unspecified, node, node);
console.log(result); // function foo() { }
Run Code Online (Sandbox Code Playgroud)

代码沙盒


cap*_*ian 7

我想这可能对你有帮助:

import * as ts from "typescript";

const filename = "test.ts";
const code = `const test: number = 1 + 2;`;

const sourceFile = ts.createSourceFile(
    filename, code, ts.ScriptTarget.Latest
);

function printRecursiveFrom(
  node: ts.Node, indentLevel: number, sourceFile: ts.SourceFile
) {
  const indentation = "-".repeat(indentLevel);
  const syntaxKind = ts.SyntaxKind[node.kind];
  const nodeText = node.getText(sourceFile);
  console.log(`${indentation}${syntaxKind}: ${nodeText}`);

  node.forEachChild(child =>
      printRecursiveFrom(child, indentLevel + 1, sourceFile)
  );
}

printRecursiveFrom(sourceFile, 0, sourceFile);
Run Code Online (Sandbox Code Playgroud)

输出:

SourceFile:  
-EndOfFileToken:  
SourceFile:  
-EndOfFileToken:  
SourceFile: const test: number = 1 + 2; 
-FirstStatement: const test: number = 1 + 2; 
--VariableDeclarationList: const test: number = 1 + 2 
---VariableDeclaration: test: number = 1 + 2 
----Identifier: test 
----NumberKeyword: number 
----BinaryExpression: 1 + 2 
-----FirstLiteralToken: 1 
-----PlusToken: + 
-----FirstLiteralToken: 2 
-EndOfFileToken:  
Run Code Online (Sandbox Code Playgroud)

更新

import * as ts from "typescript";

const code = `const test: number = 1 + 2;`;
const transpiledCode = ts.transpileModule(code, {}).outputText;
console.log(transpiledCode); // var test = 1 + 2;
Run Code Online (Sandbox Code Playgroud)

生成 AST 回代码

请看这里 我知道,这不是完整的答案,但它可能会帮助其他人回答这个问题。

不幸的是,我没有时间深入挖掘(

PS代码取自这里