diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7b508351aec..0bea9468432 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1053,7 +1053,7 @@ namespace ts { errors.push(createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText)); } const value = convertPropertyValueToJson(element.initializer, option); - if (typeof keyText !== undefined && typeof value !== undefined) { + if (typeof keyText !== "undefined" && typeof value !== "undefined") { result[keyText] = value; // Notify key value set, if user asked for it if (jsonConversionNotifier && diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 8e5bf017924..7c9811c41c8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -955,7 +955,7 @@ namespace ts { * @param map A map-like. * @param key A property key. */ - export function hasProperty(map: MapLike, key: string): boolean { + export function hasProperty(map: MapLike, key: string): boolean { return hasOwnProperty.call(map, key); } @@ -2344,7 +2344,7 @@ namespace ts { export function fail(message?: string, stackCrawlMark?: Function): void { debugger; - const e = new Error(message ? `Debug Failure. ` : "Debug Failure."); + const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure."); if ((Error).captureStackTrace) { (Error).captureStackTrace(e, stackCrawlMark || fail); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0f08d677910..a8234b850e2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3733,7 +3733,7 @@ namespace ts { // 3)we have a MemberExpression which either completes the LeftHandSideExpression, // or starts the beginning of the first four CallExpression productions. let expression: MemberExpression; - if (token() === SyntaxKind.ImportKeyword) { + if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "(" // For example: // var foo3 = require("subfolder diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bbc0fa09780..2f6b0539872 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -803,6 +803,10 @@ namespace ts { // moduleAugmentations has changed oldProgram.structureIsReused = StructureIsReused.SafeModules; } + if ((oldSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport) !== (newSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport)) { + // dynamicImport has changed + oldProgram.structureIsReused = StructureIsReused.SafeModules; + } if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) { // 'types' references has changed diff --git a/tests/baselines/reference/importCallExpressionIncorrect1.errors.txt b/tests/baselines/reference/importCallExpressionIncorrect1.errors.txt new file mode 100644 index 00000000000..4b22567454e --- /dev/null +++ b/tests/baselines/reference/importCallExpressionIncorrect1.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/dynamicImport/1.ts(2,1): error TS1109: Expression expected. + + +==== tests/cases/conformance/dynamicImport/0.ts (0 errors) ==== + export function foo() { return "foo"; } + +==== tests/cases/conformance/dynamicImport/1.ts (1 errors) ==== + import + import { foo } from './0'; + ~~~~~~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionIncorrect1.js b/tests/baselines/reference/importCallExpressionIncorrect1.js new file mode 100644 index 00000000000..c007d1c8c6f --- /dev/null +++ b/tests/baselines/reference/importCallExpressionIncorrect1.js @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionIncorrect1.ts] //// + +//// [0.ts] +export function foo() { return "foo"; } + +//// [1.ts] +import +import { foo } from './0'; + +//// [0.js] +export function foo() { return "foo"; } +//// [1.js] +import ; diff --git a/tests/baselines/reference/importCallExpressionIncorrect2.errors.txt b/tests/baselines/reference/importCallExpressionIncorrect2.errors.txt new file mode 100644 index 00000000000..a83f6f9a1f9 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionIncorrect2.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/dynamicImport/1.ts(1,9): error TS1109: Expression expected. + + +==== tests/cases/conformance/dynamicImport/0.ts (0 errors) ==== + export function foo() { return "foo"; } + +==== tests/cases/conformance/dynamicImport/1.ts (1 errors) ==== + var x = import { foo } from './0'; + ~~~~~~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionIncorrect2.js b/tests/baselines/reference/importCallExpressionIncorrect2.js new file mode 100644 index 00000000000..718bef9b9a8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionIncorrect2.js @@ -0,0 +1,12 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionIncorrect2.ts] //// + +//// [0.ts] +export function foo() { return "foo"; } + +//// [1.ts] +var x = import { foo } from './0'; + +//// [0.js] +export function foo() { return "foo"; } +//// [1.js] +var x = ; diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect1.ts b/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect1.ts new file mode 100644 index 00000000000..25a96ef30c6 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect1.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @target: esnext +// @filename: 0.ts +export function foo() { return "foo"; } + +// @filename: 1.ts +import +import { foo } from './0'; \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect2.ts new file mode 100644 index 00000000000..01309b71ba2 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionIncorrect2.ts @@ -0,0 +1,7 @@ +// @module: esnext +// @target: esnext +// @filename: 0.ts +export function foo() { return "foo"; } + +// @filename: 1.ts +var x = import { foo } from './0'; \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport2.ts b/tests/cases/fourslash/incrementalParsingDynamicImport2.ts new file mode 100644 index 00000000000..f985894c5b0 --- /dev/null +++ b/tests/cases/fourslash/incrementalParsingDynamicImport2.ts @@ -0,0 +1,13 @@ +/// + +// @lib: es2015 + +// @Filename: ./foo.ts +//// export function bar() { return 1; } + +// @Filename: ./0.ts +//// /*1*/ import { bar } from "./foo" +verify.numberOfErrorsInCurrentFile(0); +goTo.marker("1"); +edit.insert("var x = "); +verify.numberOfErrorsInCurrentFile(1); \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport3.ts b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts new file mode 100644 index 00000000000..b3da4c5b538 --- /dev/null +++ b/tests/cases/fourslash/incrementalParsingDynamicImport3.ts @@ -0,0 +1,14 @@ +/// + +// @lib: es2015 + +// @Filename: ./foo.ts +//// export function bar() { return 1; } + +// @Filename: ./0.ts +//// var x = import/*1*/ + +verify.numberOfErrorsInCurrentFile(0); +goTo.marker("1"); +edit.insert("("); +verify.numberOfErrorsInCurrentFile(2); \ No newline at end of file diff --git a/tests/cases/fourslash/incrementalParsingDynamicImport4.ts b/tests/cases/fourslash/incrementalParsingDynamicImport4.ts new file mode 100644 index 00000000000..f4b3960262d --- /dev/null +++ b/tests/cases/fourslash/incrementalParsingDynamicImport4.ts @@ -0,0 +1,15 @@ +/// + +// @lib: es2015 + +// @Filename: ./foo.ts +//// export function bar() { return 1; } + +// @Filename: ./0.ts +//// /*1*/ +//// import { bar } from "./foo" + +verify.numberOfErrorsInCurrentFile(0); +goTo.marker("1"); +edit.insert("import"); +verify.numberOfErrorsInCurrentFile(1); \ No newline at end of file