Skip to content
This repository was archived by the owner on Jan 14, 2019. It is now read-only.

feat(ast): heritage array is now optional, not empty array #120

Merged
merged 6 commits into from
Jan 12, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ast-node-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export enum AST_NODE_TYPES {
ClassBody = 'ClassBody',
ClassDeclaration = 'ClassDeclaration',
ClassExpression = 'ClassExpression',
ClassImplements = 'ClassImplements',
ClassProperty = 'ClassProperty',
ConditionalExpression = 'ConditionalExpression',
ContinueStatement = 'ContinueStatement',
Expand Down Expand Up @@ -108,6 +107,7 @@ export enum AST_NODE_TYPES {
TSConditionalType = 'TSConditionalType',
TSConstructorType = 'TSConstructorType',
TSCallSignatureDeclaration = 'TSCallSignatureDeclaration',
TSClassImplements = 'TSClassImplements',
TSConstructSignatureDeclaration = 'TSConstructSignatureDeclaration',
TSDeclareKeyword = 'TSDeclareKeyword',
TSDeclareFunction = 'TSDeclareFunction',
Expand Down
37 changes: 27 additions & 10 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}

Expand Down Expand Up @@ -2405,7 +2404,6 @@ export default function convert(config: ConvertConfig): ESTreeNode | null {
);
}

const hasImplementsClause = interfaceHeritageClauses.length > 0;
const interfaceOpenBrace = nodeUtils.findNextToken(
interfaceLastClassToken,
ast,
Expand All @@ -2426,13 +2424,32 @@ 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) {
interfaceHeritageClauses.forEach(heritageClause => {
if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
result.extends = result.extends || [];
result.extends = [
...result.extends,
...heritageClause.types.map(n =>
convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, n)
)
];
}
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
result.implements = result.implements || [];
result.implements = [
...result.implements,
...heritageClause.types.map(n =>
convertHeritageClause(AST_NODE_TYPES.TSInterfaceHeritage, n)
)
];
}
});
}

/**
* Semantically, decorators are not allowed on interface declarations,
* but the TypeScript compiler will parse them and produce a valid AST,
Expand Down
3 changes: 3 additions & 0 deletions src/semantic-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
2 changes: 2 additions & 0 deletions src/temp-types-based-on-js-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface ESTreeNode {
value?: string;
expression?: ESTreeNode | null;
decorators?: (ESTreeNode | null)[];
implements?: ESTreeNode[];
extends?: ESTreeNode[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends can be array of nodes or node

extends in class is node, in interface is array

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's superClass in classes right? Extends isn't used?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh you are right, there was change with that :>

const?: boolean;
declare?: boolean;
global?: boolean;
Expand Down
54 changes: 3 additions & 51 deletions tests/ast-alignment/fixtures-to-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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', {
Expand Down
41 changes: 41 additions & 0 deletions tests/ast-alignment/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,47 @@ 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;
}
},
/**
* Babel has `expression` on TSExpressionWithTypeArguments
* which we convert to TSInterfaceHeritage and TSClassImplements
*
* TODO: Confirm how the value of this field could be anything
* other than an Identifier?
*/
TSExpressionWithTypeArguments(node: any, parent: any) {
if (parent.type === 'TSInterfaceDeclaration') {
node.type = 'TSInterfaceHeritage';
node.id = node.expression;
delete node.expression;
} else if (
parent.type === 'ClassExpression' ||
parent.type === 'ClassDeclaration'
) {
node.type = 'TSClassImplements';
node.id = node.expression;
delete node.expression;
}
}
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class a implements b implements c {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
interface d implements e {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
interface foo extends bar extends baz {}
27 changes: 27 additions & 0 deletions tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading