From aa1c276301d7cd989f5697c47763b9bbf91880d0 Mon Sep 17 00:00:00 2001 From: Reyad Attiyat Date: Sun, 19 Feb 2017 15:42:22 -0600 Subject: [PATCH] Fix: Label Functions and Methods declartions as Ambient (fixes #162) Ambient functions do not have a body and will cuase rules to throw an excpetion. We use the types TSAmbientFunctionExpression and TSAmbientMethoDeclaration. --- lib/ast-converter.js | 16 +- .../typescript/basics/declare-class.result.js | 374 +++++++++++++ .../typescript/basics/declare-class.src.ts | 4 + .../basics/declare-function.result.js | 4 +- ...eclare-module-with-ambient-class.result.js | 519 ++++++++++++++++++ .../declare-module-with-ambient-class.src.ts | 6 + ...are-namespace-with-ambient-class.result.js | 519 ++++++++++++++++++ ...eclare-namespace-with-ambient-class.src.ts | 6 + 8 files changed, 1444 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/typescript/basics/declare-class.result.js create mode 100644 tests/fixtures/typescript/basics/declare-class.src.ts create mode 100644 tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.result.js create mode 100644 tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.src.ts create mode 100644 tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.result.js create mode 100644 tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.src.ts diff --git a/lib/ast-converter.js b/lib/ast-converter.js index b978b90..36d84f7 100644 --- a/lib/ast-converter.js +++ b/lib/ast-converter.js @@ -875,7 +875,7 @@ module.exports = function(ast, extra) { return modifier.kind === ts.SyntaxKind.DeclareKeyword; }); if (isDeclareFunction) { - functionDeclarationType = "DeclareFunction"; + functionDeclarationType = "TSAmbientFunctionDeclaration"; } } @@ -1074,6 +1074,7 @@ module.exports = function(ast, extra) { // TODO: double-check that these positions are correct var methodLoc = ast.getLineAndCharacterOfPosition(node.name.end + 1), nodeIsMethod = (node.kind === SyntaxKind.MethodDeclaration), + isAmbient = ts.isInAmbientContext(node), method = { type: "FunctionExpression", id: null, @@ -1136,6 +1137,10 @@ module.exports = function(ast, extra) { methodDefinitionType = "TSAbstractMethodDefinition"; } } + if (isAmbient) { + methodDefinitionType = "TSAmbientMethodDefinition"; + method.type = "TSAmbientFunctionExpression"; + } assign(result, { type: methodDefinitionType, @@ -1167,6 +1172,7 @@ module.exports = function(ast, extra) { var constructorIsStatic = Boolean(node.flags & ts.NodeFlags.Static), firstConstructorToken = constructorIsStatic ? ts.findNextToken(node.getFirstToken(), ast) : node.getFirstToken(), constructorLoc = ast.getLineAndCharacterOfPosition(node.parameters.pos - 1), + constructorIsAmbient = ts.isInAmbientContext(node), constructor = { type: "FunctionExpression", id: null, @@ -1230,8 +1236,14 @@ module.exports = function(ast, extra) { }; } + var constructorMethodDefinitionType = "MethodDefinition"; + if (constructorIsAmbient) { + constructorMethodDefinitionType = "TSAmbientMethodDefinition"; + constructor.type = "TSAmbientFunctionExpression"; + } + assign(result, { - type: "MethodDefinition", + type: constructorMethodDefinitionType, key: constructorKey, value: constructor, computed: constructorIsComputed, diff --git a/tests/fixtures/typescript/basics/declare-class.result.js b/tests/fixtures/typescript/basics/declare-class.result.js new file mode 100644 index 0000000..b5343ef --- /dev/null +++ b/tests/fixtures/typescript/basics/declare-class.result.js @@ -0,0 +1,374 @@ +module.exports = { + "type": "Program", + "range": [ + 1, + 38 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "range": [ + 1, + 38 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "range": [ + 15, + 18 + ], + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 17 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [ + { + "type": "TSAmbientMethodDefinition", + "range": [ + 25, + 36 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 15 + } + }, + "key": { + "type": "Identifier", + "range": [ + 25, + 28 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + } + }, + "name": "bar" + }, + "value": { + "type": "TSAmbientFunctionExpression", + "id": null, + "generator": false, + "expression": false, + "async": false, + "body": null, + "range": [ + 28, + 36 + ], + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 15 + } + }, + "returnType": { + "type": "TypeAnnotation", + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 14 + } + }, + "range": [ + 32, + 35 + ], + "typeAnnotation": { + "type": "TSAnyKeyword", + "range": [ + 32, + 35 + ], + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 14 + } + } + } + }, + "params": [] + }, + "computed": false, + "static": false, + "kind": "method", + "accessibility": null, + "decorators": [] + } + ], + "range": [ + 19, + 38 + ], + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 4, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "decorators": [] + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Identifier", + "value": "declare", + "range": [ + 1, + 8 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 7 + } + } + }, + { + "type": "Keyword", + "value": "class", + "range": [ + 9, + 14 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 13 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 15, + 18 + ], + "loc": { + "start": { + "line": 2, + "column": 14 + }, + "end": { + "line": 2, + "column": 17 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 19, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 2, + "column": 19 + } + } + }, + { + "type": "Identifier", + "value": "bar", + "range": [ + 25, + 28 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 7 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 28, + 29 + ], + "loc": { + "start": { + "line": 3, + "column": 7 + }, + "end": { + "line": 3, + "column": 8 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 29, + 30 + ], + "loc": { + "start": { + "line": 3, + "column": 8 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + { + "type": "Punctuator", + "value": ":", + "range": [ + 30, + 31 + ], + "loc": { + "start": { + "line": 3, + "column": 9 + }, + "end": { + "line": 3, + "column": 10 + } + } + }, + { + "type": "Identifier", + "value": "any", + "range": [ + 32, + 35 + ], + "loc": { + "start": { + "line": 3, + "column": 11 + }, + "end": { + "line": 3, + "column": 14 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 35, + 36 + ], + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 15 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 37, + 38 + ], + "loc": { + "start": { + "line": 4, + "column": 0 + }, + "end": { + "line": 4, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/basics/declare-class.src.ts b/tests/fixtures/typescript/basics/declare-class.src.ts new file mode 100644 index 0000000..2df2a34 --- /dev/null +++ b/tests/fixtures/typescript/basics/declare-class.src.ts @@ -0,0 +1,4 @@ + +declare class Foo { + bar(): any; +} diff --git a/tests/fixtures/typescript/basics/declare-function.result.js b/tests/fixtures/typescript/basics/declare-function.result.js index efe5741..8ab0b25 100644 --- a/tests/fixtures/typescript/basics/declare-function.result.js +++ b/tests/fixtures/typescript/basics/declare-function.result.js @@ -16,7 +16,7 @@ module.exports = { }, "body": [ { - "type": "DeclareFunction", + "type": "TSAmbientFunctionDeclaration", "range": [ 0, 42 @@ -344,4 +344,4 @@ module.exports = { } } ] -}; \ No newline at end of file +}; diff --git a/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.result.js b/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.result.js new file mode 100644 index 0000000..5b5e29b --- /dev/null +++ b/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.result.js @@ -0,0 +1,519 @@ +module.exports = { + "type": "Program", + "range": [ + 1, + 66 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "body": [ + { + "type": "TSModuleDeclaration", + "range": [ + 1, + 66 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "modifiers": [ + { + "type": "TSDeclareKeyword", + "range": [ + 1, + 8 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 7 + } + } + } + ], + "name": { + "type": "Identifier", + "range": [ + 16, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 19 + } + }, + "name": "Test" + }, + "body": { + "type": "TSModuleBlock", + "range": [ + 21, + 66 + ], + "loc": { + "start": { + "line": 2, + "column": 20 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "statements": [ + { + "type": "ClassDeclaration", + "range": [ + 27, + 64 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + } + }, + "id": { + "type": "Identifier", + "range": [ + 33, + 36 + ], + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [ + { + "type": "TSAmbientMethodDefinition", + "range": [ + 47, + 58 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "key": { + "type": "Identifier", + "range": [ + 47, + 50 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 11 + } + }, + "name": "bar" + }, + "value": { + "type": "TSAmbientFunctionExpression", + "id": null, + "generator": false, + "expression": false, + "async": false, + "body": null, + "range": [ + 50, + 58 + ], + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "returnType": { + "type": "TypeAnnotation", + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + }, + "range": [ + 54, + 57 + ], + "typeAnnotation": { + "type": "TSAnyKeyword", + "range": [ + 54, + 57 + ], + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + } + } + }, + "params": [] + }, + "computed": false, + "static": false, + "kind": "method", + "accessibility": null, + "decorators": [] + } + ], + "range": [ + 37, + 64 + ], + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 5, + "column": 5 + } + } + }, + "superClass": null, + "implements": [], + "decorators": [] + } + ] + } + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Identifier", + "value": "declare", + "range": [ + 1, + 8 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 7 + } + } + }, + { + "type": "Identifier", + "value": "module", + "range": [ + 9, + 15 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 14 + } + } + }, + { + "type": "Identifier", + "value": "Test", + "range": [ + 16, + 20 + ], + "loc": { + "start": { + "line": 2, + "column": 15 + }, + "end": { + "line": 2, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 21, + 22 + ], + "loc": { + "start": { + "line": 2, + "column": 20 + }, + "end": { + "line": 2, + "column": 21 + } + } + }, + { + "type": "Keyword", + "value": "class", + "range": [ + 27, + 32 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 33, + 36 + ], + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 13 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 37, + 38 + ], + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 15 + } + } + }, + { + "type": "Identifier", + "value": "bar", + "range": [ + 47, + 50 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 11 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 50, + 51 + ], + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 12 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 51, + 52 + ], + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 13 + } + } + }, + { + "type": "Punctuator", + "value": ":", + "range": [ + 52, + 53 + ], + "loc": { + "start": { + "line": 4, + "column": 13 + }, + "end": { + "line": 4, + "column": 14 + } + } + }, + { + "type": "Identifier", + "value": "any", + "range": [ + 54, + 57 + ], + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 57, + 58 + ], + "loc": { + "start": { + "line": 4, + "column": 18 + }, + "end": { + "line": 4, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 63, + 64 + ], + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 65, + 66 + ], + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.src.ts b/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.src.ts new file mode 100644 index 0000000..58b0925 --- /dev/null +++ b/tests/fixtures/typescript/namespaces-and-modules/declare-module-with-ambient-class.src.ts @@ -0,0 +1,6 @@ + +declare module Test { + class Foo { + bar(): any; + } +} diff --git a/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.result.js b/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.result.js new file mode 100644 index 0000000..42cf396 --- /dev/null +++ b/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.result.js @@ -0,0 +1,519 @@ +module.exports = { + "type": "Program", + "range": [ + 1, + 69 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "body": [ + { + "type": "TSModuleDeclaration", + "range": [ + 1, + 69 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "modifiers": [ + { + "type": "TSDeclareKeyword", + "range": [ + 1, + 8 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 7 + } + } + } + ], + "name": { + "type": "Identifier", + "range": [ + 19, + 23 + ], + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "name": "Test" + }, + "body": { + "type": "TSModuleBlock", + "range": [ + 24, + 69 + ], + "loc": { + "start": { + "line": 2, + "column": 23 + }, + "end": { + "line": 6, + "column": 1 + } + }, + "statements": [ + { + "type": "ClassDeclaration", + "range": [ + 30, + 67 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + } + }, + "id": { + "type": "Identifier", + "range": [ + 36, + 39 + ], + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 13 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [ + { + "type": "TSAmbientMethodDefinition", + "range": [ + 50, + 61 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "key": { + "type": "Identifier", + "range": [ + 50, + 53 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 11 + } + }, + "name": "bar" + }, + "value": { + "type": "TSAmbientFunctionExpression", + "id": null, + "generator": false, + "expression": false, + "async": false, + "body": null, + "range": [ + 53, + 61 + ], + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 19 + } + }, + "returnType": { + "type": "TypeAnnotation", + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + }, + "range": [ + 57, + 60 + ], + "typeAnnotation": { + "type": "TSAnyKeyword", + "range": [ + 57, + 60 + ], + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + } + } + }, + "params": [] + }, + "computed": false, + "static": false, + "kind": "method", + "accessibility": null, + "decorators": [] + } + ], + "range": [ + 40, + 67 + ], + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 5, + "column": 5 + } + } + }, + "superClass": null, + "implements": [], + "decorators": [] + } + ] + } + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Identifier", + "value": "declare", + "range": [ + 1, + 8 + ], + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 7 + } + } + }, + { + "type": "Identifier", + "value": "namespace", + "range": [ + 9, + 18 + ], + "loc": { + "start": { + "line": 2, + "column": 8 + }, + "end": { + "line": 2, + "column": 17 + } + } + }, + { + "type": "Identifier", + "value": "Test", + "range": [ + 19, + 23 + ], + "loc": { + "start": { + "line": 2, + "column": 18 + }, + "end": { + "line": 2, + "column": 22 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 24, + 25 + ], + "loc": { + "start": { + "line": 2, + "column": 23 + }, + "end": { + "line": 2, + "column": 24 + } + } + }, + { + "type": "Keyword", + "value": "class", + "range": [ + 30, + 35 + ], + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 9 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 36, + 39 + ], + "loc": { + "start": { + "line": 3, + "column": 10 + }, + "end": { + "line": 3, + "column": 13 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 40, + 41 + ], + "loc": { + "start": { + "line": 3, + "column": 14 + }, + "end": { + "line": 3, + "column": 15 + } + } + }, + { + "type": "Identifier", + "value": "bar", + "range": [ + 50, + 53 + ], + "loc": { + "start": { + "line": 4, + "column": 8 + }, + "end": { + "line": 4, + "column": 11 + } + } + }, + { + "type": "Punctuator", + "value": "(", + "range": [ + 53, + 54 + ], + "loc": { + "start": { + "line": 4, + "column": 11 + }, + "end": { + "line": 4, + "column": 12 + } + } + }, + { + "type": "Punctuator", + "value": ")", + "range": [ + 54, + 55 + ], + "loc": { + "start": { + "line": 4, + "column": 12 + }, + "end": { + "line": 4, + "column": 13 + } + } + }, + { + "type": "Punctuator", + "value": ":", + "range": [ + 55, + 56 + ], + "loc": { + "start": { + "line": 4, + "column": 13 + }, + "end": { + "line": 4, + "column": 14 + } + } + }, + { + "type": "Identifier", + "value": "any", + "range": [ + 57, + 60 + ], + "loc": { + "start": { + "line": 4, + "column": 15 + }, + "end": { + "line": 4, + "column": 18 + } + } + }, + { + "type": "Punctuator", + "value": ";", + "range": [ + 60, + 61 + ], + "loc": { + "start": { + "line": 4, + "column": 18 + }, + "end": { + "line": 4, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 66, + 67 + ], + "loc": { + "start": { + "line": 5, + "column": 4 + }, + "end": { + "line": 5, + "column": 5 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 68, + 69 + ], + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 6, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.src.ts b/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.src.ts new file mode 100644 index 0000000..85f67a3 --- /dev/null +++ b/tests/fixtures/typescript/namespaces-and-modules/declare-namespace-with-ambient-class.src.ts @@ -0,0 +1,6 @@ + +declare namespace Test { + class Foo { + bar(): any; + } +}