Как сгенерировать код из анализатора AST typescript?

#typescript #abstract-syntax-tree

#typescript #абстрактное синтаксическое дерево

Вопрос:

После того, как я прочитал статью Using the Compiler API, я смог получить AST из string-code.

Но когда я пытаюсь сгенерировать код (с помощью escodegen) из AST (не переносить его) в code, я получаю сообщение об ошибке:

 Unknown node type: undefined
 

Есть ли способ сгенерировать 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 });
 

codesandbox.io

Ответ №1:

Вы можете сделать это createPrinter и перейти node к printNode .

Вот рабочий пример:

 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() { }
 

codesandbox

Ответ №2:

Я думаю, это может вам помочь:

 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);
 

ВЫХОДНОЙ СИГНАЛ:

 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:  
 

Обновить

 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;
 

Сгенерировать AST обратно в код

Пожалуйста, взгляните сюда, я знаю, это не полный ответ, но это может помочь другим людям ответить на этот вопрос.

К сожалению, у меня нет времени копать глубже(

P.S. Код взят отсюда

Комментарии:

1. На самом деле, мне нужен строковый код. в моем случае я ожидаю function foo() .... . итак, есть ли способ сгенерировать обратно из ast в string?

2. В вашем обновлении он переносится. Я хочу восстановить (не транспилировать, я сказал это в вопросе, пожалуйста)

3. @JonSud извините, просто не хватает времени, чтобы углубиться