2013-11-25 19 views
35

Tôi đã đọc "toàn bộ internet", nhưng không thể tìm thấy bất kỳ ví dụ nào về việc nhận cây cú pháp (giống như trong Esprima) từ nguồn TypeScrypt. Ý tôi là làm thế nào tôi có thể nhận được đối tượng như thế này (Esprima Parser dụ)TypeScript: lấy cây cú pháp

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

từ mã javascript

var answer = 6 * 7; 

chỉ cho văn bản nguồn nguyên cảo?

P.S. Tôi hy vọng rất nhiều vì sự giúp đỡ của bạn, bởi vì tôi không muốn viết chiếc xe đạp khủng khiếp của riêng bạn)

P.P.S. Tôi nghĩ rằng các tập tin typescript.ts lib (.js) và typescriptServices.ts (.js) để giúp tôi, nhưng tôi không biết làm thế nào :(

Giải Quyết

Cảm ơn rất nhiều cho người dùng Steve . Fenton Đây là mã của tôi, nếu có ai quan tâm đến:.

// 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)); 
+3

đâu là 'Harness' quy định tại các tập tin được triển khai? Tôi không thấy "Khai thác" ở bất kỳ đâu trong tsc.js, typescript.js hoặc typescriptServices.js. Hoặc rộng hơn, làm thế nào để bạn chạy mẫu mã đã giải quyết này? –

+0

Tôi xin lỗi nếu bạn đã chờ đợi./src/harness/ trên https://github.com/Microsoft/TypeScript. Nhưng bây giờ mã của tôi có thể trở thành không hợp lệ – bukvaG

+0

Có thể trùng lặp của [Làm thế nào chúng ta có thể nhận được cây cú pháp của TypeScript?] (Http://stackoverflow.com/questions/18714501/how-can-we-get-the-syntax-tree- of-typescript) – ColinE

Trả lời

7

câu hỏi này đã đưa ra trước back in September

không có hiện cái gì đó sẽ làm việc này cho bạn - những lại là không có ma thuật getSyntaxTree phương pháp để gọi đó sẽ làm điều này.

Trình biên dịch TypeScript là mã nguồn mở, mặc dù - và được viết hoàn toàn bằng TypeScript để bạn có thể quét nó để tìm hiểu xem có điều gì bạn có thể sử dụng/thêm một xử lý.

Điều quan trọng là bạn có cơ hội lớn để phát hành công việc của mình dưới dạng dự án nguồn mở như đánh giá bởi các phiếu bầu trên hai câu hỏi, có một số yêu cầu về điều này.

Hoặc, lấy cây cú pháp từ JavaScript được biên dịch (là mã thực sự sẽ thực thi khi chạy) bằng cách sử dụng Esprima hoặc SpiderMonkey.

+1

+1 như mong đợi.Tôi có câu hỏi khác đã được ưa thích :) – basarat

+0

Rất cám ơn lời khuyên của bạn, nó đã giúp tôi rất nhiều. – bukvaG

12

Trình phân tích cú pháp TypeScript không trực tiếp tạo ra một cây như thế, nhưng bạn vẫn có thể sử dụng mô hình đối tượng của nó để làm đủ mọi thứ. Chúng tôi sử dụng nó trong một số công cụ để thực hiện chuyển đổi cú pháp cho mục đích thử nghiệm, ví dụ. Dưới đây là một đoạn trích mà bạn có thể sử dụng để in cây cú pháp:

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

Làm cách nào để đưa tệp này vào tệp app.js ?: var TypeScript = require ('./ typescriptServices'); để nó chạy? –

+0

Tôi đã giải thích câu hỏi chi tiết hơn tại đây: http://stackoverflow.com/questions/23983998/how-do-i-require-the-typescriptservices-d-ts-in-a-node-js-app –

+2

Tôi đã tìm ra nó ra và viết về những phát hiện của tôi tại http://blog.ctaggart.com/2014/06/typescript-ast-from-nodejs.html –

0

Tôi đã tìm thấy recast để hoạt động rất tốt. Ví dụ:

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

chí đầu ra này tất cả các thông tin cần thiết và sự kiện TypeAnnotation, vì vậy lib này là thực sự tuyệt vời :)

[ 
    { 
     "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

Theo như tôi đã thử, recast sẽ không nhận ra cú pháp kiểu đầy đủ. – Jaime

Các vấn đề liên quan