Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(typescript-estree): support type annotations on catch clauses #2306

Merged
merged 1 commit into from Jul 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
456 changes: 456 additions & 0 deletions packages/parser/tests/lib/__snapshots__/typescript.ts.snap

Large diffs are not rendered by default.

@@ -0,0 +1,11 @@
try {

} catch (e: any) {

}

try {

} catch (e: unknown) {

}
@@ -0,0 +1,5 @@
try {

} catch (e: string) {

}
39 changes: 27 additions & 12 deletions packages/typescript-estree/src/convert.ts
Expand Up @@ -258,6 +258,21 @@ export class Converter {
return result as T;
}

private convertBindingNameWithTypeAnnotation(
name: ts.BindingName,
tsType: ts.TypeNode | undefined,
parent?: ts.Node,
): TSESTree.BindingName {
const id = this.convertPattern(name);

if (tsType) {
id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
this.fixParentLocation(id, id.typeAnnotation.range);
}

return id;
}

/**
* Converts a child into a type annotation. This creates an intermediary
* TypeAnnotation node to match what Flow does.
Expand All @@ -267,12 +282,12 @@ export class Converter {
*/
private convertTypeAnnotation(
child: ts.TypeNode,
parent: ts.Node,
parent: ts.Node | undefined,
): TSESTree.TSTypeAnnotation {
// in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
const offset =
parent.kind === SyntaxKind.FunctionType ||
parent.kind === SyntaxKind.ConstructorType
parent?.kind === SyntaxKind.FunctionType ||
parent?.kind === SyntaxKind.ConstructorType
? 2
: 1;
const annotationStartCol = child.getFullStart() - offset;
Expand Down Expand Up @@ -697,7 +712,10 @@ export class Converter {
return this.createNode<TSESTree.CatchClause>(node, {
type: AST_NODE_TYPES.CatchClause,
param: node.variableDeclaration
? this.convertChild(node.variableDeclaration.name)
? this.convertBindingNameWithTypeAnnotation(
node.variableDeclaration.name,
node.variableDeclaration.type,
)
: null,
body: this.convertChild(node.block),
});
Expand Down Expand Up @@ -805,21 +823,18 @@ export class Converter {
case SyntaxKind.VariableDeclaration: {
const result = this.createNode<TSESTree.VariableDeclarator>(node, {
type: AST_NODE_TYPES.VariableDeclarator,
id: this.convertPattern(node.name),
id: this.convertBindingNameWithTypeAnnotation(
node.name,
node.type,
node,
),
init: this.convertChild(node.initializer),
});

if (node.exclamationToken) {
result.definite = true;
}

if (node.type) {
result.id.typeAnnotation = this.convertTypeAnnotation(
node.type,
node,
);
this.fixParentLocation(result.id, result.id.typeAnnotation.range);
}
return result;
}

Expand Down
Expand Up @@ -81,6 +81,7 @@ function whitelistSupportedDiagnostics(
case 1175: // "'implements' clause already seen."
case 1176: // "Interface declaration cannot have 'implements' clause."
case 1190: // "The variable declaration of a 'for...of' statement cannot have an initializer."
case 1196: // "Catch clause variable type annotation must be 'any' or 'unknown' if specified."
case 1200: // "Line terminator not permitted before arrow."
case 1206: // "Decorators are not valid here."
case 1211: // "A class declaration without the 'default' modifier must have a name."
Expand Down
Expand Up @@ -418,6 +418,12 @@ tester.addFixturePatternConfig('typescript/basics', {
* babel uses a representation that does not match the ESTree spec: https://github.com/estree/estree/pull/205
*/
'export-star-as-ns-from',
/**
* TS 4.0 catch clause with type annotation
* Not supported in babel yet
*/
'catch-clause-with-annotation',
'catch-clause-with-invalid-annotation',
],
ignoreSourceType: [
/**
Expand Down
Expand Up @@ -1736,6 +1736,17 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e

exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/cast-as-simple.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-clause-with-annotation.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/catch-clause-with-invalid-annotation.src 1`] = `
Object {
"column": 12,
"index": 19,
"lineNumber": 3,
"message": "Catch clause variable type annotation must be 'any' or 'unknown' if specified.",
}
`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-abstract.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/class-multi-line-keyword-declare.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
Expand Down