TypeScript: get syntax tree

Czytałem "cały internet" , ale nie mogę znaleźć żadnych przykładów na uzyskanie drzewa składni (tak jak w Esprimie) ze źródła TypeScrypt. Chodzi mi o to, jak Mogę uzyskać taki obiekt ( Esprima Parser przykład)

{
    "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"
        }
    ]
}

Z kodu javascript

var answer = 6 * 7;

Tylko dla tekstu źródłowego maszynopisu?

P. S. bardzo liczę na twoją pomoc, bo nie chcę pisać własnego strasznego roweru)

P. P. S. Myślę, że plik LIB jest maszynopisem.ts(.js) oraz maszynopisy.ts(.js) aby mi pomóc, ale nie wiem jak : (

Rozwiązane

Wielkie dzięki dla użytkownika Steve Fenton. Oto Mój kod, jeśli ktoś zainteresowany:

// 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));
Author: bukvaG, 2013-11-25

4 answers

To pytanie pojawiło się przed we wrześniu .

Obecnie nie ma czegoś, co zrobi to za Ciebie - nie ma magicznej getSyntaxTree metody, która by to zrobiła.

Kompilator maszynopisu jest jednak open-source-i jest napisany w całości w maszynopisie, więc możesz go zeskanować, aby dowiedzieć się, czy jest coś, czego możesz użyć / dodać uchwyt.

Po stronie tego jest to, że masz dużą szansę, aby opublikować swoją pracę jako projekt open-source jako ocenianie głosując w górę nad tymi dwoma pytaniami, istnieje pewien popyt na to.

Alternatywnie można pobrać drzewo składni ze skompilowanego JavaScript (który jest kodem, który będzie faktycznie wykonywany w czasie wykonywania) za pomocą Esprima lub SpiderMonkey.

 7
Author: user75525,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:34

Parser maszynopisu nie tworzy bezpośrednio takiego drzewa, ale nadal można używać jego modelu obiektowego do robienia różnego rodzaju rzeczy. Używamy go w niektórych narzędziach do wykonywania przekształceń składni w celach testowych, na przykład. Oto fragment, którego możesz użyć do wydrukowania drzewa składni:

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);
 12
Author: Ryan Cavanaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-12 14:46:59

Znalazłem przeredagowanie działa bardzo dobrze. Przykład:

var recast = require('recast');
var ast = recast.parse(`var answer = 6 * 7;`);
console.log(ast);

To wyświetli wszystkie potrzebne informacje i typ zdarzenia, więc ta lib jest naprawdę niesamowita:)

[
   {
      "type": "VariableDeclaration",
      "declarations": [
         {
            "type": "VariableDeclarator",
            "id": {
               "type": "Identifier",
               "name": "answer",
               "typeAnnotation": {
                  "type": "TypeAnnotation",
                  "typeAnnotation": {
                     "type": "NumberTypeAnnotation",
                     "loc": {
                        "start": {
                           "line": 1,
                           "column": 12
                        },
                        "end": {
                           "line": 1,
                           "column": 18
                        },
                        "lines": {},
                        "indent": 0
                     }
                  },
                  "loc": {
                     "start": {
                        "line": 1,
                        "column": 10
                     },
                     "end": {
                        "line": 1,
                        "column": 18
                     },
                     "lines": {},
                     "indent": 0
                  }
               },
               "loc": {
                  "start": {
                     "line": 1,
                     "column": 4
                  },
                  "end": {
                     "line": 1,
                     "column": 18
                  },
                  "lines": {},
                  "indent": 0
               }
            },
            "init": {
               "type": "BinaryExpression",
               "operator": "*",
               "left": {
                  "type": "Literal",
                  "value": 6,
                  "raw": "6",
                  "loc": {
                     "start": {
                        "line": 1,
                        "column": 21
                     },
                     "end": {
                        "line": 1,
                        "column": 22
                     },
                     "lines": {},
                     "indent": 0
                  }
               },
               "right": {
                  "type": "Literal",
                  "value": 7,
                  "raw": "7",
                  "loc": {
                     "start": {
                        "line": 1,
                        "column": 25
                     },
                     "end": {
                        "line": 1,
                        "column": 26
                     },
                     "lines": {},
                     "indent": 0
                  }
               },
               "loc": {
                  "start": {
                     "line": 1,
                     "column": 21
                  },
                  "end": {
                     "line": 1,
                     "column": 26
                  },
                  "lines": {},
                  "indent": 0
               }
            },
            "loc": {
               "start": {
                  "line": 1,
                  "column": 4
               },
               "end": {
                  "line": 1,
                  "column": 26
               },
               "lines": {},
               "indent": 0
            }
         }
      ],
      "kind": "var",
      "loc": {
         "start": {
            "line": 1,
            "column": 0
         },
         "end": {
            "line": 1,
            "column": 27
         },
         "lines": {},
         "indent": 0
      }
   }
]
 0
Author: Andzej Maciusovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 07:27:27

Korzystanie z przekształcenia i babylon @ next jest możliwe. Chociaż będziesz musiał zaufać składni zdefiniowanej przez te technologie do reprezentowania kodu TypeScript AST i że będą one na bieżąco - ponieważ TypeScript ma nowe funkcje językowe wydanie po wydaniu (krótki okres czasu) - nie jest jak w innych językach (JavaScript), gdzie masz dobrze zdefiniowane wersje i wydane w standardzie - więc jeśli użytkownicy zaczną używać nowych funkcji językowych te technologie (myślę, że Babilon) powinny nadążyć to date or the parsing will fail

// 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)}
`);
 0
Author: cancerbero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 20:03:34