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): added allowInvalidAST option to not throw on invalid tokens #6247

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
7 changes: 6 additions & 1 deletion docs/architecture/TypeScript-ESTree.mdx
Expand Up @@ -31,6 +31,12 @@ Parses the given string of code with the options provided and returns an ESTree-

```ts
interface ParseOptions {
/**
* Prevents the parser from throwing an error if it receives an invalid AST from TypeScript.
* This case only usually occurs when attempting to lint invalid code.
*/
allowInvalidAST?: boolean;
bradzacher marked this conversation as resolved.
Show resolved Hide resolved

/**
* create a top-level comments array containing all comments
*/
Expand Down Expand Up @@ -99,7 +105,6 @@ interface ParseOptions {

const PARSE_DEFAULT_OPTIONS: ParseOptions = {
comment: false,
errorOnUnknownASTType: false,
filePath: 'estree.ts', // or 'estree.tsx', if you pass jsx: true
jsx: false,
loc: false,
Expand Down
@@ -0,0 +1 @@
export class { }
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration ClassDeclaration _error_ export-missing-name TSESTree - Error 1`] = `[TSError: A class declaration without the 'default' modifier must have a name.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration ClassDeclaration _error_ export-missing-name Babel - Error 1`] = `[SyntaxError: A class name is required. (1:13)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration ClassDeclaration _error_ export-missing-name Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration ExportNamedDeclaration _error_ anonymous-class TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures declaration ExportNamedDeclaration _error_ anonymous-class TSESTree - Error 1`] = `[TSError: A class declaration without the 'default' modifier must have a name.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration ExportNamedDeclaration _error_ anonymous-class Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures declaration ExportNamedDeclaration _error_ anonymous-class Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
@decl enum Test {}
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSEnumDeclaration _error_ decorator TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSEnumDeclaration _error_ decorator Babel - Error 1`] = `[SyntaxError: Leading decorators must be attached to a class declaration. (1:6)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSEnumDeclaration _error_ decorator Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
@decl interface Test {}
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSInterfaceDeclaration _error_ decorator TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSInterfaceDeclaration _error_ decorator Babel - Error 1`] = `[SyntaxError: Leading decorators must be attached to a class declaration. (1:6)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSInterfaceDeclaration _error_ decorator Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
@decl type Test = {};
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSTypeAliasDeclaration _error_ decorator TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSTypeAliasDeclaration _error_ decorator Babel - Error 1`] = `[SyntaxError: Leading decorators must be attached to a class declaration. (1:6)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration TSTypeAliasDeclaration _error_ decorator Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
@decl type Test = {};
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ decorator TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ decorator Babel - Error 1`] = `[SyntaxError: Leading decorators must be attached to a class declaration. (1:6)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ decorator Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ missing-id-without-value TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures declaration VariableDeclaration _error_ missing-id-without-value TSESTree - Error 1`] = `[TSError: A variable declaration list must have at least one variable declarator.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ missing-id-without-value Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures declaration VariableDeclaration _error_ missing-id-without-value Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
const;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ no-variables TSESTree - Error 1`] = `[TSError: A variable declaration list must have at least one variable declarator.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ no-variables Babel - Error 1`] = `[SyntaxError: Unexpected token (1:5)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures declaration VariableDeclaration _error_ no-variables Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-enum-declaration TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-enum-declaration TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-enum-declaration Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-enum-declaration Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-interface-declaration TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-interface-declaration TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-interface-declaration Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-interface-declaration Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-variable TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-variable TSESTree - Error 1`] = `[TSError: Decorators are not valid here.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-variable Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ decorator-on-variable Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ solo-const TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ solo-const TSESTree - Error 1`] = `[TSError: A variable declaration list must have at least one variable declarator.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ solo-const Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ solo-const Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1,3 @@
{
throw
}
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures statement ThrowStatement _error_ missing-argument TSESTree - Error 1`] = `[TSError: A throw statement must throw an expression.]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures statement ThrowStatement _error_ missing-argument Babel - Error 1`] = `[SyntaxError: Illegal newline after throw. (2:9)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures statement ThrowStatement _error_ missing-argument Error Alignment 1`] = `"Both errored"`;
6 changes: 0 additions & 6 deletions packages/ast-spec/tests/fixtures-with-differences-errors.shot
Expand Up @@ -8,7 +8,6 @@ Object {
"declaration/ClassDeclaration/fixtures/_error_/missing-type-param/fixture.ts",
"declaration/ExportAllDeclaration/fixtures/_error_/kind-type/fixture.ts",
"declaration/ExportAllDeclaration/fixtures/_error_/type-kind/fixture.ts",
"declaration/ExportNamedDeclaration/fixtures/_error_/anonymous-class/fixture.ts",
"declaration/ExportNamedDeclaration/fixtures/_error_/assertion/fixture.ts",
"declaration/FunctionDeclaration/fixtures/_error_/missing-type-param/fixture.ts",
"declaration/TSDeclareFunction/fixtures/_error_/async/fixture.ts",
Expand All @@ -20,7 +19,6 @@ Object {
"declaration/TSInterfaceDeclaration/fixtures/_error_/missing-type-param/fixture.ts",
"declaration/TSInterfaceDeclaration/fixtures/_error_/non-identifier-extends/fixture.ts",
"declaration/TSTypeAliasDeclaration/fixtures/_error_/missing-type-parameter/fixture.ts",
"declaration/VariableDeclaration/fixtures/_error_/missing-id-without-value/fixture.ts",
"element/AccessorProperty/fixtures/_error_/modifier-override-with-no-extends/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/abstract-class-with-abstract-static-constructor/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/abstract-class-with-override-property/fixture.ts",
Expand All @@ -45,10 +43,7 @@ Object {
"legacy-fixtures/errorRecovery/fixtures/_error_/class-empty-extends/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/class-extends-empty-implements/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/class-multiple-implements/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/decorator-on-enum-declaration/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/decorator-on-function/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/decorator-on-interface-declaration/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/decorator-on-variable/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/empty-type-arguments-in-call-expression/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/empty-type-arguments-in-new-expression/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/empty-type-arguments/fixture.ts",
Expand Down Expand Up @@ -77,7 +72,6 @@ Object {
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-public/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-static/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-with-optional-index-signature/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/solo-const/fixture.ts",
"legacy-fixtures/parameter-decorators/fixtures/_error_/parameter-array-pattern-decorator/fixture.ts",
"legacy-fixtures/parameter-decorators/fixtures/_error_/parameter-rest-element-decorator/fixture.ts",
},
Expand Down
1 change: 1 addition & 0 deletions packages/ast-spec/tests/util/parsers/typescript-estree.ts
Expand Up @@ -8,6 +8,7 @@ export function parseTSESTree(
): ParserResponse {
try {
const result = parse(contents, {
allowInvalidAST: fixture.config.allowInvalidAST,
comment: false,
jsx: fixture.ext.endsWith('x'),
loc: true,
Expand Down
6 changes: 6 additions & 0 deletions packages/ast-spec/typings/global.d.ts
Expand Up @@ -4,6 +4,12 @@
* This is a convenient property because it saves us from a lot of `../`!
*/
interface ASTFixtureConfig {
/**
* Prevents the parser from throwing an error if it receives an invalid AST from TypeScript.
* This case only usually occurs when attempting to lint invalid code.
*/
readonly allowInvalidAST?: boolean;

/**
* Specifies that we expect that babel doesn't yet support the code in this fixture, so we expect that it will error.
* This should not be used if we expect babel to throw for this feature due to a valid parser error!
Expand Down
2 changes: 0 additions & 2 deletions packages/parser/tests/lib/parser.ts
Expand Up @@ -35,7 +35,6 @@ describe('parser', () => {
// ts-estree specific
filePath: 'isolated-file.src.ts',
project: 'tsconfig.json',
errorOnUnknownASTType: false,
errorOnTypeScriptSyntacticAndSemanticIssues: false,
tsconfigRootDir: 'tests/fixtures/services',
extraFileExtensions: ['.foo'],
Expand Down Expand Up @@ -89,7 +88,6 @@ describe('parser', () => {
// ts-estree specific
filePath: 'isolated-file.src.ts',
project: 'tsconfig.json',
errorOnUnknownASTType: false,
errorOnTypeScriptSyntacticAndSemanticIssues: false,
tsconfigRootDir: 'tests/fixtures/services',
extraFileExtensions: ['.foo'],
Expand Down
1 change: 1 addition & 0 deletions packages/typescript-estree/src/ast-converter.ts
Expand Up @@ -26,6 +26,7 @@ export function astConverter(
* Recursively convert the TypeScript AST into an ESTree-compatible AST
*/
const instance = new Converter(ast, {
allowInvalidAST: parseSettings.allowInvalidAST || false,
errorOnUnknownASTType: parseSettings.errorOnUnknownASTType || false,
shouldPreserveNodeMaps,
});
Expand Down