From ef4fc0d221196c6dc2b3cd164254db8151a96b1a Mon Sep 17 00:00:00 2001 From: Reyad Attiyat Date: Thu, 4 May 2017 19:27:49 -0500 Subject: [PATCH] Fix: Handle case where class has extends but no super class (fixes #249) --- lib/ast-converter.js | 2 +- .../class-empty-extends-implements.result.js | 204 ++++++++++++++++ .../class-empty-extends-implements.src.ts | 3 + .../class-empty-extends.result.js | 168 +++++++++++++ .../errorRecovery/class-empty-extends.src.ts | 3 + .../class-extends-empty-implements.result.js | 221 ++++++++++++++++++ .../class-extends-empty-implements.src.ts | 3 + .../interface-empty-extends.result.js | 166 +++++++++++++ .../interface-empty-extends.src.ts | 3 + 9 files changed, 772 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.result.js create mode 100644 tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.src.ts create mode 100644 tests/fixtures/typescript/errorRecovery/class-empty-extends.result.js create mode 100644 tests/fixtures/typescript/errorRecovery/class-empty-extends.src.ts create mode 100644 tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.result.js create mode 100644 tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.src.ts create mode 100644 tests/fixtures/typescript/errorRecovery/interface-empty-extends.result.js create mode 100644 tests/fixtures/typescript/errorRecovery/interface-empty-extends.src.ts diff --git a/lib/ast-converter.js b/lib/ast-converter.js index fb9f114..2824bfa 100644 --- a/lib/ast-converter.js +++ b/lib/ast-converter.js @@ -1581,7 +1581,7 @@ module.exports = function(ast, extra) { superClass, hasImplements = false; - if (hasExtends) { + if (hasExtends && heritageClauses[0].types.length > 0) { superClass = heritageClauses.shift(); if (superClass.types[0] && superClass.types[0].typeArguments) { result.superTypeParameters = convertTypeArgumentsToTypeParameters(superClass.types[0].typeArguments); diff --git a/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.result.js b/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.result.js new file mode 100644 index 0000000..dec45ce --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.result.js @@ -0,0 +1,204 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "range": [ + 0, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [], + "range": [ + 33, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "decorators": [] + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Keyword", + "value": "class", + "range": [ + 0, + 5 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + } + }, + { + "type": "Keyword", + "value": "extends", + "range": [ + 10, + 17 + ], + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 17 + } + } + }, + { + "type": "Keyword", + "value": "implements", + "range": [ + 18, + 28 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 28 + } + } + }, + { + "type": "Identifier", + "value": "Bar", + "range": [ + 29, + 32 + ], + "loc": { + "start": { + "line": 1, + "column": 29 + }, + "end": { + "line": 1, + "column": 32 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 33, + 34 + ], + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 34 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 36, + 37 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.src.ts b/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.src.ts new file mode 100644 index 0000000..0d08522 --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-empty-extends-implements.src.ts @@ -0,0 +1,3 @@ +class Foo extends implements Bar { + +} diff --git a/tests/fixtures/typescript/errorRecovery/class-empty-extends.result.js b/tests/fixtures/typescript/errorRecovery/class-empty-extends.result.js new file mode 100644 index 0000000..5f0f82e --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-empty-extends.result.js @@ -0,0 +1,168 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 22 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "range": [ + 0, + 22 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [], + "range": [ + 18, + 22 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "decorators": [] + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Keyword", + "value": "class", + "range": [ + 0, + 5 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + } + }, + { + "type": "Keyword", + "value": "extends", + "range": [ + 10, + 17 + ], + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 17 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 18, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 21, + 22 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/errorRecovery/class-empty-extends.src.ts b/tests/fixtures/typescript/errorRecovery/class-empty-extends.src.ts new file mode 100644 index 0000000..47a27e7 --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-empty-extends.src.ts @@ -0,0 +1,3 @@ +class Foo extends { + +} diff --git a/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.result.js b/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.result.js new file mode 100644 index 0000000..4c1f0ac --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.result.js @@ -0,0 +1,221 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "ClassDeclaration", + "range": [ + 0, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "id": { + "type": "Identifier", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + }, + "name": "Foo" + }, + "body": { + "type": "ClassBody", + "body": [], + "range": [ + 33, + 37 + ], + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + "superClass": { + "type": "Identifier", + "range": [ + 18, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "name": "Bar" + }, + "implements": [], + "decorators": [] + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Keyword", + "value": "class", + "range": [ + 0, + 5 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 6, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 9 + } + } + }, + { + "type": "Keyword", + "value": "extends", + "range": [ + 10, + 17 + ], + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 17 + } + } + }, + { + "type": "Identifier", + "value": "Bar", + "range": [ + 18, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 21 + } + } + }, + { + "type": "Keyword", + "value": "implements", + "range": [ + 22, + 32 + ], + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 32 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 33, + 34 + ], + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 34 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 36, + 37 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.src.ts b/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.src.ts new file mode 100644 index 0000000..42b4c05 --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-extends-empty-implements.src.ts @@ -0,0 +1,3 @@ +class Foo extends Bar implements { + +} diff --git a/tests/fixtures/typescript/errorRecovery/interface-empty-extends.result.js b/tests/fixtures/typescript/errorRecovery/interface-empty-extends.result.js new file mode 100644 index 0000000..2561f9e --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/interface-empty-extends.result.js @@ -0,0 +1,166 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 26 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": [ + { + "type": "TSInterfaceDeclaration", + "range": [ + 0, + 26 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + }, + "body": { + "type": "TSInterfaceBody", + "body": [], + "range": [ + 22, + 26 + ], + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + "id": { + "type": "Identifier", + "range": [ + 10, + 13 + ], + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "name": "Foo" + }, + "heritage": [] + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Keyword", + "value": "interface", + "range": [ + 0, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 9 + } + } + }, + { + "type": "Identifier", + "value": "Foo", + "range": [ + 10, + 13 + ], + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + { + "type": "Keyword", + "value": "extends", + "range": [ + 14, + 21 + ], + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 21 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 22, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 25, + 26 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + } + ] +}; diff --git a/tests/fixtures/typescript/errorRecovery/interface-empty-extends.src.ts b/tests/fixtures/typescript/errorRecovery/interface-empty-extends.src.ts new file mode 100644 index 0000000..dae1275 --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/interface-empty-extends.src.ts @@ -0,0 +1,3 @@ +interface Foo extends { + +}