Skip to content

Commit

Permalink
Fix parse failure in TS when default-importing the name "type" (#722)
Browse files Browse the repository at this point in the history
The token `from` is actually a `tt.name`, so we can use our existing lookahead
to distinguish that case. The line `import type from from './foo';` is invalid,
so we know that `from` after `type` is always a true `from` token, meaning that
`type` is just the imported name.

Also add a TODO comment to the babel test checker with a little more thoughts on
how to approach the remaining flagged issues.
  • Loading branch information
alangpierce authored Jul 14, 2022
1 parent f9aeb43 commit 66da4d1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
13 changes: 12 additions & 1 deletion spec-compliance-tests/babel-tests/check-babel-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ const FIXTURES_DIR = `${BABEL_TESTS_DIR}/packages/babel-parser/test/fixtures`;
const BABEL_REPO_URL = "https://github.com/babel/babel.git";
const BABEL_REVISION = "bcf8b2273b8cba44c9b93c8977f05d508bfc1b91";

/*
* TODO: Work through these failures to better understand and characterize them.
*
* There seem to be a few categories of test failures:
* - Real errors that should be fixed when possible.
* - Cases that are so obscure and hard to implement that Sucrase intentionally
* skips them. These should ideally have an inline explanation here.
* - Cases that are unsupported in Sucrase but are flagged as failures, e.g.
* syntax not part of the spec that is supported by Babel. Many of these may
* be possible to fix automatically by improving the step where we run Babel
* to see if it also fails.
*/
const KNOWN_FAILURES = `
es2015/let/let-declaration-in-escape-id
es2015/yield/accessor-name-inst-computed-yield-expr
Expand Down Expand Up @@ -72,7 +84,6 @@ typescript/import/export-import
typescript/import/export-import-require
typescript/import/export-import-type-as-identifier
typescript/import/export-import-type-require
typescript/import/import-default-id-type
typescript/import/type-asi
typescript/import/type-equals-require
`
Expand Down
6 changes: 3 additions & 3 deletions src/parser/traverser/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1088,8 +1088,8 @@ export function parseImport(): void {
return;
}
if (isTypeScriptEnabled && isContextual(ContextualKeyword._type)) {
const lookahead = lookaheadType();
if (lookahead === tt.name) {
const lookahead = lookaheadTypeAndKeyword();
if (lookahead.type === tt.name && lookahead.contextualKeyword !== ContextualKeyword._from) {
// One of these `import type` cases:
// import type T = require('T');
// import type A from 'A';
Expand All @@ -1100,7 +1100,7 @@ export function parseImport(): void {
}
// If this is an `import type...from` statement, then we already ate the
// type token, so proceed to the regular import parser.
} else if (lookahead === tt.star || lookahead === tt.braceL) {
} else if (lookahead.type === tt.star || lookahead.type === tt.braceL) {
// One of these `import type` cases, in which case we can eat the type token
// and proceed as normal:
// import type * as A from 'A';
Expand Down
26 changes: 26 additions & 0 deletions test/typescript-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2225,6 +2225,32 @@ describe("typescript transform", () => {
);
});

it("allows a default import named type in ESM mode", () => {
assertTypeScriptESMResult(
`
import type from './type';
console.log(type);
`,
`
import type from './type';
console.log(type);
`,
);
});

it("allows a default import named type in CJS mode", () => {
assertTypeScriptResult(
`
import type from './type';
console.log(type);
`,
`"use strict";${IMPORT_DEFAULT_PREFIX}
var _type = require('./type'); var _type2 = _interopRequireDefault(_type);
console.log(_type2.default);
`,
);
});

it("parses and removes named import type statements in ESM mode", () => {
assertTypeScriptESMResult(
`
Expand Down

0 comments on commit 66da4d1

Please sign in to comment.