diff --git a/src/ast-node-types.ts b/src/ast-node-types.ts index d35277f..58dc30f 100644 --- a/src/ast-node-types.ts +++ b/src/ast-node-types.ts @@ -21,7 +21,6 @@ export enum AST_NODE_TYPES { ClassBody = 'ClassBody', ClassDeclaration = 'ClassDeclaration', ClassExpression = 'ClassExpression', - ClassImplements = 'ClassImplements', ClassProperty = 'ClassProperty', ConditionalExpression = 'ConditionalExpression', ContinueStatement = 'ContinueStatement', @@ -108,6 +107,7 @@ export enum AST_NODE_TYPES { TSConditionalType = 'TSConditionalType', TSConstructorType = 'TSConstructorType', TSCallSignatureDeclaration = 'TSCallSignatureDeclaration', + TSClassImplements = 'TSClassImplements', TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration', TSDeclareKeyword = 'TSDeclareKeyword', TSDeclareFunction = 'TSDeclareFunction', diff --git a/src/convert.ts b/src/convert.ts index 1e420b9..bfd00b3 100644 --- a/src/convert.ts +++ b/src/convert.ts @@ -274,12 +274,12 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { nodeType: AST_NODE_TYPES, child: ts.ExpressionWithTypeArguments ): ESTreeNode { - const id = convertChild(child.expression)!; + const expression = convertChild(child.expression)!; const classImplementsNode: ESTreeNode = { type: nodeType, - loc: id.loc, - range: id.range, - id + loc: expression.loc, + range: expression.range, + expression }; if (child.typeArguments && child.typeArguments.length) { classImplementsNode.typeParameters = convertTypeArgumentsToTypeParameters( @@ -1500,9 +1500,8 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { }); if (implementsClause) { - (result as any).implements = implementsClause.types.map(el => - // ClassImplements node to match what Flow does. - convertHeritageClause(AST_NODE_TYPES.ClassImplements, el) + result.implements = implementsClause.types.map(el => + convertHeritageClause(AST_NODE_TYPES.TSClassImplements, el) ); } @@ -2405,7 +2404,6 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { ); } - const hasImplementsClause = interfaceHeritageClauses.length > 0; const interfaceOpenBrace = nodeUtils.findNextToken( interfaceLastClassToken, ast, @@ -2426,13 +2424,38 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { Object.assign(result, { type: AST_NODE_TYPES.TSInterfaceDeclaration, body: interfaceBody, - id: convertChild(node.name), - heritage: hasImplementsClause - ? interfaceHeritageClauses[0].types.map(el => - convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, el) - ) - : [] + id: convertChild(node.name) }); + + if (interfaceHeritageClauses.length > 0) { + const interfaceExtends = []; + const interfaceImplements = []; + + for (const heritageClause of interfaceHeritageClauses) { + if (heritageClause.token === SyntaxKind.ExtendsKeyword) { + for (const n of heritageClause.types) { + interfaceExtends.push( + convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, n) + ); + } + } else if (heritageClause.token === SyntaxKind.ImplementsKeyword) { + for (const n of heritageClause.types) { + interfaceImplements.push( + convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, n) + ); + } + } + } + + if (interfaceExtends.length) { + result.extends = interfaceExtends; + } + + if (interfaceImplements.length) { + result.implements = interfaceImplements; + } + } + /** * Semantically, decorators are not allowed on interface declarations, * but the TypeScript compiler will parse them and produce a valid AST, diff --git a/src/semantic-errors.ts b/src/semantic-errors.ts index 067a702..3513c4d 100644 --- a/src/semantic-errors.ts +++ b/src/semantic-errors.ts @@ -68,7 +68,10 @@ function whitelistSupportedDiagnostics( case 1121: // ts 3.2 "Octal literals are not allowed in strict mode." case 1123: // ts 3.2: "Variable declaration list cannot be empty." case 1141: // ts 3.2 "String literal expected." + case 1172: // ts 3.2 "'extends' clause already seen." case 1173: // ts 3.2 "'extends' clause must precede 'implements' clause." + case 1175: // ts 3.2 "'implements' clause already seen." + case 1176: // ts 3.2 "Interface declaration cannot have 'implements' clause." case 1190: // ts 3.2 "The variable declaration of a 'for...of' statement cannot have an initializer." case 1200: // ts 3.2 "Line terminator not permitted before arrow." case 1206: // ts 3.2 "Decorators are not valid here." diff --git a/src/temp-types-based-on-js-source.ts b/src/temp-types-based-on-js-source.ts index cf7124a..a002b74 100644 --- a/src/temp-types-based-on-js-source.ts +++ b/src/temp-types-based-on-js-source.ts @@ -34,6 +34,8 @@ export interface ESTreeNode { value?: string; expression?: ESTreeNode | null; decorators?: (ESTreeNode | null)[]; + implements?: ESTreeNode[]; + extends?: ESTreeNode[]; const?: boolean; declare?: boolean; global?: boolean; diff --git a/tests/ast-alignment/fixtures-to-test.ts b/tests/ast-alignment/fixtures-to-test.ts index d6182fb..30d8bbd 100644 --- a/tests/ast-alignment/fixtures-to-test.ts +++ b/tests/ast-alignment/fixtures-to-test.ts @@ -314,25 +314,6 @@ tester.addFixturePatternConfig('typescript/basics', { * TODO: remove me in next babel > 7.2.3 */ 'arrow-function-with-type-parameters', - /** - * Babel: ClassDeclaration + abstract: true - * ts-estree: TSAbstractClassDeclaration - */ - 'abstract-class-with-abstract-properties', - /** - * Babel: ClassProperty + abstract: true - * ts-estree: TSAbstractClassProperty - */ - 'abstract-class-with-abstract-readonly-property', - /** - * Babel: TSExpressionWithTypeArguments - * ts-estree: ClassImplements - */ - 'class-with-implements-generic-multiple', - 'class-with-implements-generic', - 'class-with-implements', - 'class-with-extends-and-implements', - 'class-with-mixin', /** * Babel error: parameterName is not included into range of TSTypeAnnotation * TODO: report it to babel @@ -341,26 +322,11 @@ tester.addFixturePatternConfig('typescript/basics', { /** * there is difference in range between babel and ts-estree */ + 'class-with-implements-generic-multiple', + 'class-with-implements-generic', 'export-declare-const-named-enum', - /** - * Other major AST differences (e.g. fundamentally different node types) - */ - 'interface-extends-multiple', - 'interface-extends', - 'interface-type-parameters', 'interface-with-extends-type-parameters', - 'interface-with-generic', - 'interface-with-jsdoc', 'interface-with-optional-properties', - 'interface-without-type-annotation', - 'type-guard-in-interface', - 'typed-this', - /** - * AST difference - * ts-estree: heritage = [] - * babel: heritage = undefined - */ - 'interface-with-method', /** * Babel bug for parsing exported abstract interface * https://github.com/babel/babel/issues/9304 @@ -471,21 +437,7 @@ tester.addFixturePatternConfig('typescript/types', { }); tester.addFixturePatternConfig('typescript/declare', { - fileType: 'ts', - ignore: [ - /** - * AST difference - * ts-estree: heritage = [] - * babel: heritage = undefined - */ - 'interface', - /** - * AST difference - * ts-estree: TSAbstractClassDeclaration - * babel: ClassDeclaration[abstract=true] - */ - 'abstract-class' - ] + fileType: 'ts' }); tester.addFixturePatternConfig('typescript/namespaces-and-modules', { diff --git a/tests/ast-alignment/utils.ts b/tests/ast-alignment/utils.ts index 1857972..34c3dab 100644 --- a/tests/ast-alignment/utils.ts +++ b/tests/ast-alignment/utils.ts @@ -231,6 +231,36 @@ export function preprocessBabylonAST(ast: any): any { type: AST_NODE_TYPES.Identifier }; } + }, + /** + * Babel: ClassDeclaration + abstract: true + * ts-estree: TSAbstractClassDeclaration + */ + ClassDeclaration(node: any) { + if (node.abstract) { + node.type = 'TSAbstractClassDeclaration'; + delete node.abstract; + } + }, + /** + * Babel: ClassProperty + abstract: true + * ts-estree: TSAbstractClassProperty + */ + ClassProperty(node: any, parent: any) { + if (node.abstract) { + node.type = 'TSAbstractClassProperty'; + delete node.abstract; + } + }, + TSExpressionWithTypeArguments(node: any, parent: any) { + if (parent.type === 'TSInterfaceDeclaration') { + node.type = 'TSInterfaceHeritage'; + } else if ( + parent.type === 'ClassExpression' || + parent.type === 'ClassDeclaration' + ) { + node.type = 'TSClassImplements'; + } } } ); diff --git a/tests/fixtures/typescript/errorRecovery/class-multiple-implements.src.ts b/tests/fixtures/typescript/errorRecovery/class-multiple-implements.src.ts new file mode 100644 index 0000000..4ecd2ee --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/class-multiple-implements.src.ts @@ -0,0 +1 @@ +class a implements b implements c {} diff --git a/tests/fixtures/typescript/errorRecovery/interface-implements.src.ts b/tests/fixtures/typescript/errorRecovery/interface-implements.src.ts new file mode 100644 index 0000000..d3b8c72 --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/interface-implements.src.ts @@ -0,0 +1 @@ +interface d implements e {} diff --git a/tests/fixtures/typescript/errorRecovery/interface-multiple-extends.src.ts b/tests/fixtures/typescript/errorRecovery/interface-multiple-extends.src.ts new file mode 100644 index 0000000..343867f --- /dev/null +++ b/tests/fixtures/typescript/errorRecovery/interface-multiple-extends.src.ts @@ -0,0 +1 @@ +interface foo extends bar extends baz {} diff --git a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index b55b744..312d444 100644 --- a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -2191,6 +2191,15 @@ Object { } `; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/class-multiple-implements.src.ts.src 1`] = ` +Object { + "column": 21, + "index": 21, + "lineNumber": 1, + "message": "'implements' clause already seen.", +} +`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/decorator-on-enum-declaration.src.ts.src 1`] = ` Object { "column": 0, @@ -2238,6 +2247,15 @@ Object { } `; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/interface-implements.src.ts.src 1`] = ` +Object { + "column": 12, + "index": 12, + "lineNumber": 1, + "message": "Interface declaration cannot have 'implements' clause.", +} +`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/interface-index-signature-export.src.ts.src 1`] = ` Object { "column": 2, @@ -2328,6 +2346,15 @@ Object { } `; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/interface-multiple-extends.src.ts.src 1`] = ` +Object { + "column": 26, + "index": 26, + "lineNumber": 1, + "message": "'extends' clause already seen.", +} +`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/errorRecovery/interface-property-export.src.ts.src 1`] = ` Object { "column": 2, diff --git a/tests/lib/__snapshots__/typescript.ts.snap b/tests/lib/__snapshots__/typescript.ts.snap index c3aff24..183fd7e 100644 --- a/tests/lib/__snapshots__/typescript.ts.snap +++ b/tests/lib/__snapshots__/typescript.ts.snap @@ -2919,7 +2919,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -9740,7 +9739,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 77, @@ -9772,7 +9771,7 @@ Object { 66, 77, ], - "type": "ClassImplements", + "type": "TSClassImplements", }, ], "loc": Object { @@ -11926,7 +11925,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 24, @@ -11958,7 +11957,7 @@ Object { 21, 24, ], - "type": "ClassImplements", + "type": "TSClassImplements", }, ], "loc": Object { @@ -12150,7 +12149,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 56, @@ -12182,7 +12181,7 @@ Object { 45, 56, ], - "type": "ClassImplements", + "type": "TSClassImplements", }, ], "loc": Object { @@ -12427,7 +12426,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 24, @@ -12459,7 +12458,7 @@ Object { 21, 24, ], - "type": "ClassImplements", + "type": "TSClassImplements", "typeParameters": Object { "loc": Object { "end": Object { @@ -12759,7 +12758,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 24, @@ -12791,7 +12790,7 @@ Object { 21, 24, ], - "type": "ClassImplements", + "type": "TSClassImplements", "typeParameters": Object { "loc": Object { "end": Object { @@ -13488,7 +13487,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 38, @@ -13520,7 +13519,7 @@ Object { 123, 124, ], - "type": "ClassImplements", + "type": "TSClassImplements", }, ], "loc": Object { @@ -13703,7 +13702,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -41565,9 +41563,9 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [ + "extends": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 25, @@ -41788,9 +41786,9 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [ + "extends": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 25, @@ -41825,7 +41823,7 @@ Object { "type": "TSInterfaceHeritage", }, Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 29, @@ -42082,7 +42080,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -43574,7 +43571,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -45761,7 +45757,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -46074,9 +46069,9 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [ + "extends": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 28, @@ -46513,7 +46508,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -46829,7 +46823,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -47409,7 +47402,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -48176,7 +48168,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -48760,7 +48751,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -56298,7 +56288,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -62299,7 +62288,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -65746,7 +65734,6 @@ Object { "type": "TSInterfaceBody", }, "declare": true, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -77904,7 +77891,7 @@ Object { }, "implements": Array [ Object { - "id": Object { + "expression": Object { "loc": Object { "end": Object { "column": 32, @@ -77936,7 +77923,7 @@ Object { 29, 32, ], - "type": "ClassImplements", + "type": "TSClassImplements", }, ], "loc": Object { @@ -78327,68 +78314,86 @@ Object { } `; -exports[`typescript fixtures/errorRecovery/decorator-on-enum-declaration.src 1`] = ` +exports[`typescript fixtures/errorRecovery/class-multiple-implements.src 1`] = ` Object { "body": Array [ Object { - "decorators": Array [ + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 34, + "line": 1, + }, + }, + "range": Array [ + 34, + 36, + ], + "type": "ClassBody", + }, + "id": Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "name": "a", + "range": Array [ + 6, + 7, + ], + "type": "Identifier", + }, + "implements": Array [ Object { "expression": Object { "loc": Object { "end": Object { - "column": 4, + "column": 20, "line": 1, }, "start": Object { - "column": 1, + "column": 19, "line": 1, }, }, - "name": "dec", + "name": "b", "range": Array [ - 1, - 4, + 19, + 20, ], "type": "Identifier", }, "loc": Object { "end": Object { - "column": 4, + "column": 20, "line": 1, }, "start": Object { - "column": 0, + "column": 19, "line": 1, }, }, "range": Array [ - 0, - 4, + 19, + 20, ], - "type": "Decorator", + "type": "TSClassImplements", }, ], - "id": Object { - "loc": Object { - "end": Object { - "column": 11, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, - }, - "name": "E", - "range": Array [ - 10, - 11, - ], - "type": "Identifier", - }, "loc": Object { "end": Object { - "column": 14, + "column": 36, "line": 1, }, "start": Object { @@ -78396,18 +78401,18 @@ Object { "line": 1, }, }, - "members": Array [], "range": Array [ 0, - 14, + 36, ], - "type": "TSEnumDeclaration", + "superClass": null, + "type": "ClassDeclaration", }, ], "loc": Object { "end": Object { - "column": 14, - "line": 1, + "column": 0, + "line": 2, }, "start": Object { "column": 0, @@ -78416,14 +78421,14 @@ Object { }, "range": Array [ 0, - 14, + 37, ], "sourceType": "script", "tokens": Array [ Object { "loc": Object { "end": Object { - "column": 1, + "column": 5, "line": 1, }, "start": Object { @@ -78433,79 +78438,115 @@ Object { }, "range": Array [ 0, - 1, + 5, ], - "type": "Punctuator", - "value": "@", + "type": "Keyword", + "value": "class", }, Object { "loc": Object { "end": Object { - "column": 4, + "column": 7, "line": 1, }, "start": Object { - "column": 1, + "column": 6, "line": 1, }, }, "range": Array [ - 1, - 4, + 6, + 7, ], "type": "Identifier", - "value": "dec", + "value": "a", }, Object { "loc": Object { "end": Object { - "column": 9, + "column": 18, "line": 1, }, "start": Object { - "column": 5, + "column": 8, "line": 1, }, }, "range": Array [ - 5, - 9, + 8, + 18, ], "type": "Keyword", - "value": "enum", + "value": "implements", }, Object { "loc": Object { "end": Object { - "column": 11, + "column": 20, "line": 1, }, "start": Object { - "column": 10, + "column": 19, "line": 1, }, }, "range": Array [ - 10, - 11, + 19, + 20, ], "type": "Identifier", - "value": "E", + "value": "b", }, Object { "loc": Object { "end": Object { - "column": 13, + "column": 31, "line": 1, }, "start": Object { - "column": 12, + "column": 21, "line": 1, }, }, "range": Array [ - 12, - 13, + 21, + 31, + ], + "type": "Keyword", + "value": "implements", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 32, + "line": 1, + }, + }, + "range": Array [ + 32, + 33, + ], + "type": "Identifier", + "value": "c", + }, + Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 1, + }, + "start": Object { + "column": 34, + "line": 1, + }, + }, + "range": Array [ + 34, + 35, ], "type": "Punctuator", "value": "{", @@ -78513,17 +78554,17 @@ Object { Object { "loc": Object { "end": Object { - "column": 14, + "column": 36, "line": 1, }, "start": Object { - "column": 13, + "column": 35, "line": 1, }, }, "range": Array [ - 13, - 14, + 35, + 36, ], "type": "Punctuator", "value": "}", @@ -78533,53 +78574,16 @@ Object { } `; -exports[`typescript fixtures/errorRecovery/decorator-on-interface-declaration.src 1`] = ` +exports[`typescript fixtures/errorRecovery/decorator-on-enum-declaration.src 1`] = ` Object { "body": Array [ Object { - "body": Object { - "body": Array [], - "loc": Object { - "end": Object { - "column": 14, - "line": 2, - }, - "start": Object { - "column": 12, - "line": 2, - }, - }, - "range": Array [ - 20, - 22, - ], - "type": "TSInterfaceBody", - }, "decorators": Array [ Object { "expression": Object { - "arguments": Array [], - "callee": Object { - "loc": Object { - "end": Object { - "column": 5, - "line": 1, - }, - "start": Object { - "column": 1, - "line": 1, - }, - }, - "name": "deco", - "range": Array [ - 1, - 5, - ], - "type": "Identifier", - }, "loc": Object { "end": Object { - "column": 7, + "column": 4, "line": 1, }, "start": Object { @@ -78587,15 +78591,16 @@ Object { "line": 1, }, }, + "name": "dec", "range": Array [ 1, - 7, + 4, ], - "type": "CallExpression", + "type": "Identifier", }, "loc": Object { "end": Object { - "column": 7, + "column": 4, "line": 1, }, "start": Object { @@ -78605,51 +78610,51 @@ Object { }, "range": Array [ 0, - 7, + 4, ], "type": "Decorator", }, ], - "heritage": Array [], "id": Object { "loc": Object { "end": Object { "column": 11, - "line": 2, + "line": 1, }, "start": Object { "column": 10, - "line": 2, + "line": 1, }, }, - "name": "M", + "name": "E", "range": Array [ - 18, - 19, + 10, + 11, ], "type": "Identifier", }, "loc": Object { "end": Object { "column": 14, - "line": 2, + "line": 1, }, "start": Object { "column": 0, "line": 1, }, }, + "members": Array [], "range": Array [ 0, - 22, + 14, ], - "type": "TSInterfaceDeclaration", + "type": "TSEnumDeclaration", }, ], "loc": Object { "end": Object { "column": 14, - "line": 2, + "line": 1, }, "start": Object { "column": 0, @@ -78658,7 +78663,248 @@ Object { }, "range": Array [ 0, - 22, + 14, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 1, + ], + "type": "Punctuator", + "value": "@", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "range": Array [ + 1, + 4, + ], + "type": "Identifier", + "value": "dec", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 9, + ], + "type": "Keyword", + "value": "enum", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Identifier", + "value": "E", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 13, + "line": 1, + }, + }, + "range": Array [ + 13, + 14, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/errorRecovery/decorator-on-interface-declaration.src 1`] = ` +Object { + "body": Array [ + Object { + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 14, + "line": 2, + }, + "start": Object { + "column": 12, + "line": 2, + }, + }, + "range": Array [ + 20, + 22, + ], + "type": "TSInterfaceBody", + }, + "decorators": Array [ + Object { + "expression": Object { + "arguments": Array [], + "callee": Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "name": "deco", + "range": Array [ + 1, + 5, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "range": Array [ + 1, + 7, + ], + "type": "CallExpression", + }, + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 7, + ], + "type": "Decorator", + }, + ], + "id": Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 2, + }, + "start": Object { + "column": 10, + "line": 2, + }, + }, + "name": "M", + "range": Array [ + 18, + 19, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 14, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 22, + ], + "type": "TSInterfaceDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 14, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 22, ], "sourceType": "script", "tokens": Array [ @@ -80051,7 +80297,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -80198,6 +80443,229 @@ Object { } `; +exports[`typescript fixtures/errorRecovery/interface-implements.src 1`] = ` +Object { + "body": Array [ + Object { + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 27, + ], + "type": "TSInterfaceBody", + }, + "id": Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "name": "d", + "range": Array [ + 10, + 11, + ], + "type": "Identifier", + }, + "implements": Array [ + Object { + "expression": Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "name": "e", + "range": Array [ + 23, + 24, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "TSInterfaceHeritage", + }, + ], + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 27, + ], + "type": "TSInterfaceDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 28, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 9, + ], + "type": "Keyword", + "value": "interface", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Identifier", + "value": "d", + }, + Object { + "loc": Object { + "end": Object { + "column": 22, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 22, + ], + "type": "Keyword", + "value": "implements", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 24, + ], + "type": "Identifier", + "value": "e", + }, + Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 26, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 27, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/errorRecovery/interface-index-signature-export.src 1`] = ` Object { "body": Array [ @@ -80327,7 +80795,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -80747,7 +81214,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -81167,7 +81633,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -81587,7 +82052,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -82007,7 +82471,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -82446,7 +82909,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -82903,7 +83365,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -83360,7 +83821,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -83817,7 +84277,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -84274,7 +84733,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -84583,6 +85041,300 @@ Object { } `; +exports[`typescript fixtures/errorRecovery/interface-multiple-extends.src 1`] = ` +Object { + "body": Array [ + Object { + "body": Object { + "body": Array [], + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 38, + "line": 1, + }, + }, + "range": Array [ + 38, + 40, + ], + "type": "TSInterfaceBody", + }, + "extends": Array [ + Object { + "expression": Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "name": "bar", + "range": Array [ + 22, + 25, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 25, + ], + "type": "TSInterfaceHeritage", + }, + Object { + "expression": Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 34, + "line": 1, + }, + }, + "name": "baz", + "range": Array [ + 34, + 37, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 34, + "line": 1, + }, + }, + "range": Array [ + 34, + 37, + ], + "type": "TSInterfaceHeritage", + }, + ], + "id": Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 10, + 13, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 40, + ], + "type": "TSInterfaceDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 41, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 9, + ], + "type": "Keyword", + "value": "interface", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 13, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 21, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 21, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 22, + "line": 1, + }, + }, + "range": Array [ + 22, + 25, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 33, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 34, + "line": 1, + }, + }, + "range": Array [ + 34, + 37, + ], + "type": "Identifier", + "value": "baz", + }, + Object { + "loc": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 38, + "line": 1, + }, + }, + "range": Array [ + 38, + 39, + ], + "type": "Punctuator", + "value": "{", + }, + Object { + "loc": Object { + "end": Object { + "column": 40, + "line": 1, + }, + "start": Object { + "column": 39, + "line": 1, + }, + }, + "range": Array [ + 39, + 40, + ], + "type": "Punctuator", + "value": "}", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/errorRecovery/interface-property-export.src 1`] = ` Object { "body": Array [ @@ -84677,7 +85429,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -84990,7 +85741,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -85303,7 +86053,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -85616,7 +86365,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -85929,7 +86677,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -86260,7 +87007,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object { @@ -90388,7 +91134,6 @@ Object { ], "type": "TSInterfaceBody", }, - "heritage": Array [], "id": Object { "loc": Object { "end": Object {