diff --git a/src/ast-node-types.ts b/src/ast-node-types.ts index fbe848e..41ee3fb 100644 --- a/src/ast-node-types.ts +++ b/src/ast-node-types.ts @@ -151,6 +151,7 @@ export const AST_NODE_TYPES: { [key: string]: string } = { TSThisType: 'TSThisType', TSTypeAnnotation: 'TSTypeAnnotation', TSTypeAliasDeclaration: 'TSTypeAliasDeclaration', + TSTypeAssertion: 'TSTypeAssertion', TSTypeLiteral: 'TSTypeLiteral', TSTypeOperator: 'TSTypeOperator', TSTypeParameter: 'TSTypeParameter', diff --git a/src/convert.ts b/src/convert.ts index 96b7715..098c3df 100644 --- a/src/convert.ts +++ b/src/convert.ts @@ -2680,6 +2680,14 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { }); break; } + case SyntaxKind.TypeAssertionExpression: { + Object.assign(result, { + type: AST_NODE_TYPES.TSTypeAssertion, + typeAnnotation: convertChildType(node.type), + expression: convertChild(node.expression) + }); + break; + } case SyntaxKind.ImportEqualsDeclaration: { Object.assign(result, { type: AST_NODE_TYPES.TSImportEqualsDeclaration, diff --git a/tests/ast-alignment/fixtures-to-test.ts b/tests/ast-alignment/fixtures-to-test.ts index 7bdf2a8..5fc0962 100644 --- a/tests/ast-alignment/fixtures-to-test.ts +++ b/tests/ast-alignment/fixtures-to-test.ts @@ -6,11 +6,13 @@ import jsxKnownIssues from '../jsx-known-issues'; interface Fixture { filename: string; + jsx: boolean; ignoreSourceType: boolean; } interface FixturePatternConfig { pattern: string; + jsx: boolean; ignoreSourceType: boolean; } @@ -69,6 +71,11 @@ function createFixturePatternConfigFor( config.ignore = config.ignore || []; config.fileType = config.fileType || 'js'; config.ignoreSourceType = config.ignoreSourceType || []; + const jsx = + config.fileType === 'js' || + config.fileType === 'jsx' || + config.fileType === 'tsx'; + /** * The TypeScript compiler gives us the "externalModuleIndicator" to allow typescript-estree do dynamically detect the "sourceType". * Babel has similar feature sourceType='unambiguous' but its not perfect, and in some specific cases we sill have to enforce it. @@ -85,7 +92,8 @@ function createFixturePatternConfigFor( fixturesRequiringSourceTypeModule.push({ // It needs to be the full path from within fixtures/ for the pattern pattern: `${fixturesSubPath}/${fixture}.src.${config.fileType}`, - ignoreSourceType: true + ignoreSourceType: true, + jsx }); } } @@ -93,7 +101,8 @@ function createFixturePatternConfigFor( pattern: `${fixturesSubPath}/!(${config.ignore.join('|')}).src.${ config.fileType }`, - ignoreSourceType: false + ignoreSourceType: false, + jsx }; } @@ -403,7 +412,11 @@ let fixturePatternConfigsToTest = [ * Not yet supported in Babel https://github.com/babel/babel/issues/9228 * Directive field is not added to module and namespace */ - 'directive-in-namespace' + 'directive-in-namespace', + /** + * there is difference in range between babel and tsep + */ + 'type-assertion' ], ignoreSourceType: [ // https://github.com/babel/babel/issues/9213 @@ -525,7 +538,8 @@ fixturePatternConfigsToTest.forEach(fixturePatternConfig => { matchingFixtures.forEach(filename => { fixturesToTest.push({ filename, - ignoreSourceType: fixturePatternConfig.ignoreSourceType + ignoreSourceType: fixturePatternConfig.ignoreSourceType, + jsx: fixturePatternConfig.jsx }); }); }); diff --git a/tests/ast-alignment/parse.ts b/tests/ast-alignment/parse.ts index c5df123..c37f5dc 100644 --- a/tests/ast-alignment/parse.ts +++ b/tests/ast-alignment/parse.ts @@ -1,8 +1,7 @@ import codeFrame from 'babel-code-frame'; import * as parser from '../../src/parser'; import * as parseUtils from './utils'; -import { ParserOptions as BabelParserOptions } from '@babel/parser'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserPlugin } from '@babel/parser'; function createError(message: string, line: number, column: number) { // Construct an error similar to the ones thrown by Babylon. @@ -14,55 +13,42 @@ function createError(message: string, line: number, column: number) { return error; } -function parseWithBabelParser( - text: string, - parserOptions?: BabelParserOptions -) { - parserOptions = parserOptions || {}; +function parseWithBabelParser(text: string, jsx: boolean = true) { const babel = require('@babel/parser'); - return babel.parse( - text, - Object.assign( - { - sourceType: 'unambiguous', - allowImportExportEverywhere: true, - allowReturnOutsideFunction: true, - ranges: true, - plugins: [ - 'jsx', - 'typescript', - 'objectRestSpread', - 'decorators-legacy', - 'classProperties', - 'asyncGenerators', - 'dynamicImport', - 'estree', - 'bigInt' - ] - }, - parserOptions - ) - ); + const plugins: ParserPlugin[] = [ + 'typescript', + 'objectRestSpread', + 'decorators-legacy', + 'classProperties', + 'asyncGenerators', + 'dynamicImport', + 'estree', + 'bigInt' + ]; + if (jsx) { + plugins.push('jsx'); + } + + return babel.parse(text, { + sourceType: 'unambiguous', + allowImportExportEverywhere: true, + allowReturnOutsideFunction: true, + ranges: true, + plugins + }); } -function parseWithTypeScriptESTree( - text: string, - parserOptions?: ParserOptions -) { - parserOptions = parserOptions || ({} as ParserOptions); +function parseWithTypeScriptESTree(text: string, jsx: boolean = true) { try { - return parser.parse(text, Object.assign( - { - loc: true, - range: true, - tokens: false, - comment: false, - useJSXTextNode: true, - errorOnUnknownASTType: true, - jsx: true - }, - parserOptions - ) as any); + return parser.parse(text, { + loc: true, + range: true, + tokens: false, + comment: false, + useJSXTextNode: true, + errorOnUnknownASTType: true, + jsx + }); } catch (e) { throw createError(e.message, e.lineNumber, e.column); } @@ -70,8 +56,7 @@ function parseWithTypeScriptESTree( interface ASTComparisonParseOptions { parser: string; - typeScriptESTreeOptions?: ParserOptions; - babelParserOptions?: BabelParserOptions; + jsx?: boolean; } export function parse(text: string, opts: ASTComparisonParseOptions) { @@ -88,12 +73,12 @@ export function parse(text: string, opts: ASTComparisonParseOptions) { switch (opts.parser) { case 'typescript-estree': result.ast = parseUtils.normalizeNodeTypes( - parseWithTypeScriptESTree(text, opts.typeScriptESTreeOptions) + parseWithTypeScriptESTree(text, opts.jsx) ); break; case '@babel/parser': result.ast = parseUtils.normalizeNodeTypes( - parseWithBabelParser(text, opts.babelParserOptions) + parseWithBabelParser(text, opts.jsx) ); break; default: diff --git a/tests/ast-alignment/spec.ts b/tests/ast-alignment/spec.ts index 31814b9..2f27fb2 100644 --- a/tests/ast-alignment/spec.ts +++ b/tests/ast-alignment/spec.ts @@ -11,14 +11,16 @@ fixturesToTest.forEach(fixture => { * Parse with typescript-estree */ const typeScriptESTreeResult = parse(source, { - parser: 'typescript-estree' + parser: 'typescript-estree', + jsx: fixture.jsx }); /** * Parse the source with @babel/parser typescript-plugin */ const babelParserResult = parse(source, { - parser: '@babel/parser' + parser: '@babel/parser', + jsx: fixture.jsx }); /** diff --git a/tests/fixtures/typescript/basics/type-assertion.src.ts b/tests/fixtures/typescript/basics/type-assertion.src.ts new file mode 100644 index 0000000..67e0d69 --- /dev/null +++ b/tests/fixtures/typescript/basics/type-assertion.src.ts @@ -0,0 +1 @@ +const foo = 2; diff --git a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index 0d2ea6a..504efbb 100644 --- a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -1782,6 +1782,8 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" en exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/basics/type-alias-object-without-annotation.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/basics/type-assertion.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/basics/type-guard.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/basics/type-parameters-comments.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; diff --git a/tests/lib/__snapshots__/typescript.ts.snap b/tests/lib/__snapshots__/typescript.ts.snap index a41f38c..bec36dc 100644 --- a/tests/lib/__snapshots__/typescript.ts.snap +++ b/tests/lib/__snapshots__/typescript.ts.snap @@ -48113,6 +48113,283 @@ Object { } `; +exports[`typescript fixtures/basics/type-assertion.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "name": "foo", + "range": Array [ + 6, + 9, + ], + "type": "Identifier", + }, + "init": Object { + "expression": Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 27, + ], + "raw": "2", + "type": "Literal", + "value": 2, + }, + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 27, + ], + "type": "TSTypeAssertion", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 13, + "line": 1, + }, + }, + "range": Array [ + 13, + 16, + ], + "type": "TSAnyKeyword", + }, + }, + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 27, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "const", + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 28, + ], + "type": "VariableDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 29, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 5, + ], + "type": "Keyword", + "value": "const", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 9, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Punctuator", + "value": "=", + }, + 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": 16, + "line": 1, + }, + "start": Object { + "column": 13, + "line": 1, + }, + }, + "range": Array [ + 13, + 16, + ], + "type": "Identifier", + "value": "any", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 16, + "line": 1, + }, + }, + "range": Array [ + 16, + 17, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 26, + "line": 1, + }, + }, + "range": Array [ + 26, + 27, + ], + "type": "Numeric", + "value": "2", + }, + Object { + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 27, + "line": 1, + }, + }, + "range": Array [ + 27, + 28, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/basics/type-guard.src 1`] = ` Object { "body": Array [