From 7af2fcc89800454ff6c37ed1af1fff711fb1ef71 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 22:24:20 +0800 Subject: [PATCH 01/30] feat: add emitExtension compiler options --- src/compiler/commandLineParser.ts | 9 +++++++++ src/compiler/diagnosticMessages.json | 16 ++++++++++++++++ src/compiler/program.ts | 11 +++++++++++ src/compiler/types.ts | 1 + 4 files changed, 37 insertions(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6fd9803aaacf4..5bd2d0df97c40 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -997,6 +997,15 @@ namespace ts { }, description: Diagnostics.List_of_language_service_plugins }, + { + name: "emitExtension", + type: "string", + category: Diagnostics.Basic_Options, + + description: Diagnostics.Specify_the_extension_name_of_the_emitted_files, + showInSimplifiedHelpView: true, + affectsEmit: true, + } ]; /* @internal */ diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 726d75b67660c..617452301352e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4527,6 +4527,22 @@ "category": "Error", "code": 6504 }, + "Specify the extension name of the emitted files.": { + "category": "Message", + "code": 6505 + }, + "emitExtension must start with '.', but here has '{0}', try to replace it with '.{0}'.": { + "category": "Error", + "code": 6506 + }, + "emitExtension can only be \".jsx\" when JSX is set to \"preserve\"": { + "category": "Error", + "code": 6507 + }, + "emitExtension can not be \".d.ts\"": { + "category": "Error", + "code": 6508 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e3f3e27a8272f..8370323948382 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2963,6 +2963,17 @@ namespace ts { } function verifyCompilerOptions() { + if (options.emitExtension) { + if (!startsWith(options.emitExtension, ".")) { + createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_must_start_with_but_here_has_0_try_to_replace_it_with_0, options.emitExtension); + } + if (options.emitExtension !== Extension.Jsx && options.jsx === JsxEmit.Preserve) { + createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_can_only_be_jsx_when_JSX_is_set_to_preserve, options.emitExtension); + } + if (options.emitExtension === Extension.Dts) { + createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_can_not_be_d_ts, options.emitExtension); + } + } if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index cf083fac5e897..410a4aef23ece 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5134,6 +5134,7 @@ namespace ts { declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; + emitExtension?: string; declarationDir?: string; /* @internal */ diagnostics?: boolean; /* @internal */ extendedDiagnostics?: boolean; From 2a46cb07044ffd6250cc18c39a2e0daa928ef823 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 22:25:04 +0800 Subject: [PATCH 02/30] test: add test for emitExtension compiler options --- tests/cases/compiler/emitExtensionOptionsDTS.ts | 5 +++++ tests/cases/compiler/emitExtensionOptionsJSXPreserveBad.ts | 6 ++++++ .../cases/compiler/emitExtensionOptionsJSXPreserveNormal.ts | 5 +++++ tests/cases/compiler/emitExtensionOptionsNormal.ts | 4 ++++ tests/cases/compiler/emitExtensionOptionsStartWithNonDot.ts | 5 +++++ 5 files changed, 25 insertions(+) create mode 100644 tests/cases/compiler/emitExtensionOptionsDTS.ts create mode 100644 tests/cases/compiler/emitExtensionOptionsJSXPreserveBad.ts create mode 100644 tests/cases/compiler/emitExtensionOptionsJSXPreserveNormal.ts create mode 100644 tests/cases/compiler/emitExtensionOptionsNormal.ts create mode 100644 tests/cases/compiler/emitExtensionOptionsStartWithNonDot.ts diff --git a/tests/cases/compiler/emitExtensionOptionsDTS.ts b/tests/cases/compiler/emitExtensionOptionsDTS.ts new file mode 100644 index 0000000000000..c2a1ba062574b --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsDTS.ts @@ -0,0 +1,5 @@ +// @emitExtension: .d.ts + +// @Filename 1.ts +// emitExtension can not be ".d.ts" +export default 0 diff --git a/tests/cases/compiler/emitExtensionOptionsJSXPreserveBad.ts b/tests/cases/compiler/emitExtensionOptionsJSXPreserveBad.ts new file mode 100644 index 0000000000000..26abd6682c735 --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsJSXPreserveBad.ts @@ -0,0 +1,6 @@ +// @emitExtension: .mjs +// @jsx: preserve + +// @Filename: 0.ts +// emitExtension can only be ".jsx" when JSX is set to "preserve" +export default 1 diff --git a/tests/cases/compiler/emitExtensionOptionsJSXPreserveNormal.ts b/tests/cases/compiler/emitExtensionOptionsJSXPreserveNormal.ts new file mode 100644 index 0000000000000..917103d7972fc --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsJSXPreserveNormal.ts @@ -0,0 +1,5 @@ +// @emitExtension: .jsx +// @jsx: preserve + +// @Filename: 0.ts +export default 1 diff --git a/tests/cases/compiler/emitExtensionOptionsNormal.ts b/tests/cases/compiler/emitExtensionOptionsNormal.ts new file mode 100644 index 0000000000000..4358a79ecb197 --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsNormal.ts @@ -0,0 +1,4 @@ +// @emitExtension: .mjs + +// @Filename: 0.ts +export default 0 diff --git a/tests/cases/compiler/emitExtensionOptionsStartWithNonDot.ts b/tests/cases/compiler/emitExtensionOptionsStartWithNonDot.ts new file mode 100644 index 0000000000000..482a602bc5c55 --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsStartWithNonDot.ts @@ -0,0 +1,5 @@ +// @emitExtension: mjs + +// @Filename: 0.ts +// emitExtension must start with '.' +export default 0 From 8802a6a3d7485c293c7f156611071f2fe09ba1c8 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 22:25:25 +0800 Subject: [PATCH 03/30] test: accept baseline for emitExtension --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../reference/emitExtensionOptionsDTS.errors.txt | 9 +++++++++ tests/baselines/reference/emitExtensionOptionsDTS.js | 12 ++++++++++++ .../reference/emitExtensionOptionsDTS.symbols | 6 ++++++ .../reference/emitExtensionOptionsDTS.types | 6 ++++++ .../emitExtensionOptionsJSXPreserveBad.errors.txt | 8 ++++++++ .../reference/emitExtensionOptionsJSXPreserveBad.js | 10 ++++++++++ .../emitExtensionOptionsJSXPreserveBad.symbols | 5 +++++ .../emitExtensionOptionsJSXPreserveBad.types | 5 +++++ .../emitExtensionOptionsJSXPreserveNormal.js | 8 ++++++++ .../emitExtensionOptionsJSXPreserveNormal.symbols | 4 ++++ .../emitExtensionOptionsJSXPreserveNormal.types | 4 ++++ .../reference/emitExtensionOptionsNormal.js | 8 ++++++++ .../reference/emitExtensionOptionsNormal.symbols | 4 ++++ .../reference/emitExtensionOptionsNormal.types | 4 ++++ .../emitExtensionOptionsStartWithNonDot.errors.txt | 8 ++++++++ .../reference/emitExtensionOptionsStartWithNonDot.js | 10 ++++++++++ .../emitExtensionOptionsStartWithNonDot.symbols | 5 +++++ .../emitExtensionOptionsStartWithNonDot.types | 5 +++++ .../emitExtension/tsconfig.json | 5 +++++ .../Default initialized TSConfig/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + 30 files changed, 137 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionOptionsDTS.errors.txt create mode 100644 tests/baselines/reference/emitExtensionOptionsDTS.js create mode 100644 tests/baselines/reference/emitExtensionOptionsDTS.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsDTS.types create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.errors.txt create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.types create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.types create mode 100644 tests/baselines/reference/emitExtensionOptionsNormal.js create mode 100644 tests/baselines/reference/emitExtensionOptionsNormal.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsNormal.types create mode 100644 tests/baselines/reference/emitExtensionOptionsStartWithNonDot.errors.txt create mode 100644 tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js create mode 100644 tests/baselines/reference/emitExtensionOptionsStartWithNonDot.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsStartWithNonDot.types create mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/emitExtension/tsconfig.json diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5c0326d63ca24..76e9f4d444de6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2657,6 +2657,7 @@ declare namespace ts { declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; + emitExtension?: string; declarationDir?: string; disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5bd7da4518176..ec735ccd1dd9a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2657,6 +2657,7 @@ declare namespace ts { declaration?: boolean; declarationMap?: boolean; emitDeclarationOnly?: boolean; + emitExtension?: string; declarationDir?: string; disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.errors.txt b/tests/baselines/reference/emitExtensionOptionsDTS.errors.txt new file mode 100644 index 0000000000000..7a9dceec4e7f4 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsDTS.errors.txt @@ -0,0 +1,9 @@ +error TS6508: emitExtension can not be ".d.ts" + + +!!! error TS6508: emitExtension can not be ".d.ts" +==== tests/cases/compiler/emitExtensionOptionsDTS.ts (0 errors) ==== + // @Filename 1.ts + // emitExtension can not be ".d.ts" + export default 0 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.js b/tests/baselines/reference/emitExtensionOptionsDTS.js new file mode 100644 index 0000000000000..3f7bc7e5ffcbb --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsDTS.js @@ -0,0 +1,12 @@ +//// [emitExtensionOptionsDTS.ts] +// @Filename 1.ts +// emitExtension can not be ".d.ts" +export default 0 + + +//// [emitExtensionOptionsDTS.js] +"use strict"; +exports.__esModule = true; +// @Filename 1.ts +// emitExtension can not be ".d.ts" +exports["default"] = 0; diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.symbols b/tests/baselines/reference/emitExtensionOptionsDTS.symbols new file mode 100644 index 0000000000000..ec7e3ce26a257 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsDTS.symbols @@ -0,0 +1,6 @@ +=== tests/cases/compiler/emitExtensionOptionsDTS.ts === +// @Filename 1.ts +No type information for this code.// emitExtension can not be ".d.ts" +No type information for this code.export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.types b/tests/baselines/reference/emitExtensionOptionsDTS.types new file mode 100644 index 0000000000000..ec7e3ce26a257 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsDTS.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/emitExtensionOptionsDTS.ts === +// @Filename 1.ts +No type information for this code.// emitExtension can not be ".d.ts" +No type information for this code.export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.errors.txt b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.errors.txt new file mode 100644 index 0000000000000..c89d9197ca2d1 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.errors.txt @@ -0,0 +1,8 @@ +error TS6507: emitExtension can only be ".jsx" when JSX is set to "preserve" + + +!!! error TS6507: emitExtension can only be ".jsx" when JSX is set to "preserve" +==== tests/cases/compiler/0.ts (0 errors) ==== + // emitExtension can only be ".jsx" when JSX is set to "preserve" + export default 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js new file mode 100644 index 0000000000000..12701447dfc56 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js @@ -0,0 +1,10 @@ +//// [0.ts] +// emitExtension can only be ".jsx" when JSX is set to "preserve" +export default 1 + + +//// [0.js] +"use strict"; +exports.__esModule = true; +// emitExtension can only be ".jsx" when JSX is set to "preserve" +exports["default"] = 1; diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.symbols b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.symbols new file mode 100644 index 0000000000000..6cf028860bb10 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/0.ts === +// emitExtension can only be ".jsx" when JSX is set to "preserve" +No type information for this code.export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.types b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.types new file mode 100644 index 0000000000000..6cf028860bb10 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/0.ts === +// emitExtension can only be ".jsx" when JSX is set to "preserve" +No type information for this code.export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js new file mode 100644 index 0000000000000..03af88e6156f2 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js @@ -0,0 +1,8 @@ +//// [0.ts] +export default 1 + + +//// [0.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 1; diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.symbols b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.symbols new file mode 100644 index 0000000000000..2e9d59769cb1a --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.types b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.types new file mode 100644 index 0000000000000..2e9d59769cb1a --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.types @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsNormal.js b/tests/baselines/reference/emitExtensionOptionsNormal.js new file mode 100644 index 0000000000000..0eb2e0d107a11 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsNormal.js @@ -0,0 +1,8 @@ +//// [0.ts] +export default 0 + + +//// [0.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; diff --git a/tests/baselines/reference/emitExtensionOptionsNormal.symbols b/tests/baselines/reference/emitExtensionOptionsNormal.symbols new file mode 100644 index 0000000000000..4240767327d08 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsNormal.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsNormal.types b/tests/baselines/reference/emitExtensionOptionsNormal.types new file mode 100644 index 0000000000000..4240767327d08 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsNormal.types @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.errors.txt b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.errors.txt new file mode 100644 index 0000000000000..3fd1276fdb81a --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.errors.txt @@ -0,0 +1,8 @@ +error TS6506: emitExtension must start with '.', but here has 'mjs', try to replace it with '.mjs'. + + +!!! error TS6506: emitExtension must start with '.', but here has 'mjs', try to replace it with '.mjs'. +==== tests/cases/compiler/0.ts (0 errors) ==== + // emitExtension must start with '.' + export default 0 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js new file mode 100644 index 0000000000000..821360c88142a --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js @@ -0,0 +1,10 @@ +//// [0.ts] +// emitExtension must start with '.' +export default 0 + + +//// [0.js] +"use strict"; +exports.__esModule = true; +// emitExtension must start with '.' +exports["default"] = 0; diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.symbols b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.symbols new file mode 100644 index 0000000000000..8b32c60e43171 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/0.ts === +// emitExtension must start with '.' +No type information for this code.export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.types b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.types new file mode 100644 index 0000000000000..8b32c60e43171 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.types @@ -0,0 +1,5 @@ +=== tests/cases/compiler/0.ts === +// emitExtension must start with '.' +No type information for this code.export default 0 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/emitExtension/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/emitExtension/tsconfig.json new file mode 100644 index 0000000000000..c4ecd585230f8 --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/emitExtension/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "emitExtension": "someString" + } +} diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 54d53fdf72db4..6d304c1439246 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json index 1ce4f0225001f..db8c3d3f6cf58 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index edbfb38c2e1a3..cb778e5b729b6 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index aad370c1e6974..c8ec6a21b68b3 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 4c1a8235295f9..69f7ef1ccd768 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 965fb1e28b98c..892f7115dc2cb 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 54d53fdf72db4..6d304c1439246 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index d6d044fa42b81..ba56fd44d288a 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 27af8c27249b1..10b61f3692eab 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -21,6 +21,7 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ From df61bf38e10df87c3946dabe8c436e30e76e610f Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:22:48 +0800 Subject: [PATCH 04/30] feat: emit files as emitExtension specify --- src/compiler/emitter.ts | 8 ++++++-- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers.ts | 2 +- src/compiler/utilities.ts | 8 +++++++- src/harness/compilerImpl.ts | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 51d268a682681..0506d0639d68f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -107,15 +107,19 @@ namespace ts { return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined; } - // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. + // JavaScript files are emitted as LanguageVariant.JSX, as JSX syntax is allowed in .js files also. // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve + // If compilerOptions.emitExtension is set, respect the output extension. /* @internal */ - export function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension { + export function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string { if (isJsonSourceFile(sourceFile)) { return Extension.Json; } + if (options.emitExtension) { + return options.emitExtension; + } if (options.jsx === JsxEmit.Preserve) { if (isSourceFileJS(sourceFile)) { if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) { diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 82e39ecfad460..392b8a6e6b5e2 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1070,7 +1070,7 @@ namespace ts { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" - if (hasJSFileExtension(candidate)) { + if (hasJSFileExtension(candidate, state.compilerOptions)) { const extensionless = removeFileExtension(candidate); if (state.traceEnabled) { const extension = candidate.substring(extensionless.length); diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index f0ea43ed68b41..18331d98bad38 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -30,7 +30,7 @@ namespace ts.moduleSpecifiers { function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string): Preferences { return { relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, - ending: hasJSFileExtension(oldImportSpecifier) ? + ending: hasJSFileExtension(oldImportSpecifier, compilerOptions) ? Ending.JsExtension : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, }; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2acaa3200fb89..aec117802952e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5900,7 +5900,13 @@ namespace ts { return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX; } - export function hasJSFileExtension(fileName: string): boolean { + export function hasJSFileExtension(fileName: string, compilerOptions?: CompilerOptions): boolean { + if (compilerOptions && compilerOptions.emitExtension) { + return some( + [compilerOptions.emitExtension].concat(supportedJSExtensions), + extension => fileExtensionIs(fileName, extension) + ); + } return some(supportedJSExtensions, extension => fileExtensionIs(fileName, extension)); } diff --git a/src/harness/compilerImpl.ts b/src/harness/compilerImpl.ts index 19d6545c999fa..0418238249ba5 100644 --- a/src/harness/compilerImpl.ts +++ b/src/harness/compilerImpl.ts @@ -70,7 +70,7 @@ namespace compiler { const dts = this.dts = new collections.SortedMap({ comparer: this.vfs.stringComparer, sort: "insertion" }); const maps = this.maps = new collections.SortedMap({ comparer: this.vfs.stringComparer, sort: "insertion" }); for (const document of this.host.outputs) { - if (vpath.isJavaScript(document.file) || ts.fileExtensionIs(document.file, ts.Extension.Json)) { + if (vpath.isJavaScript(document.file, options) || ts.fileExtensionIs(document.file, ts.Extension.Json)) { js.set(document.file, document); } else if (vpath.isDeclaration(document.file)) { From dc756567c9c2febfa2811873a40710f7d0888dc3 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:23:49 +0800 Subject: [PATCH 05/30] test: add test for emit as emitExtension specify --- tests/cases/compiler/emitExtensionEmitCustomExtname.ts | 8 ++++++++ .../compiler/emitExtensionEmitCustomExtnamePathEscape.ts | 4 ++++ .../compiler/emitExtensionEmitCustomExtnameWithDot.ts | 8 ++++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/cases/compiler/emitExtensionEmitCustomExtname.ts create mode 100644 tests/cases/compiler/emitExtensionEmitCustomExtnamePathEscape.ts create mode 100644 tests/cases/compiler/emitExtensionEmitCustomExtnameWithDot.ts diff --git a/tests/cases/compiler/emitExtensionEmitCustomExtname.ts b/tests/cases/compiler/emitExtensionEmitCustomExtname.ts new file mode 100644 index 0000000000000..cc4405db27027 --- /dev/null +++ b/tests/cases/compiler/emitExtensionEmitCustomExtname.ts @@ -0,0 +1,8 @@ +// @emitExtension: .cpp + +// @Filename: 0.ts +export default 1 + +// @Filename: 1.ts +import x from './0' +x + 1 diff --git a/tests/cases/compiler/emitExtensionEmitCustomExtnamePathEscape.ts b/tests/cases/compiler/emitExtensionEmitCustomExtnamePathEscape.ts new file mode 100644 index 0000000000000..6a3e638c2eb4e --- /dev/null +++ b/tests/cases/compiler/emitExtensionEmitCustomExtnamePathEscape.ts @@ -0,0 +1,4 @@ +// @emitExtension: ../../../../index.js + +// @Filename: 0.ts +export default 1 diff --git a/tests/cases/compiler/emitExtensionEmitCustomExtnameWithDot.ts b/tests/cases/compiler/emitExtensionEmitCustomExtnameWithDot.ts new file mode 100644 index 0000000000000..0d417a411a70b --- /dev/null +++ b/tests/cases/compiler/emitExtensionEmitCustomExtnameWithDot.ts @@ -0,0 +1,8 @@ +// @emitExtension: .strange.js + +// @Filename: 0.ts +export default 1 + +// @Filename: 1.ts +import x from './0' +x + 1 From 3ea10e622772e8948cf0dd8e229f1bd2f4aa30fc Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:25:32 +0800 Subject: [PATCH 06/30] test: accept baseline for emit file as emitExtension specify --- .../emitExtensionEmitCustomExtname.js | 19 +++++++++++++++++++ .../emitExtensionEmitCustomExtname.symbols | 10 ++++++++++ .../emitExtensionEmitCustomExtname.types | 12 ++++++++++++ .../emitExtensionEmitCustomExtnameWithDot.js | 19 +++++++++++++++++++ ...tExtensionEmitCustomExtnameWithDot.symbols | 10 ++++++++++ ...mitExtensionEmitCustomExtnameWithDot.types | 12 ++++++++++++ .../reference/emitExtensionOptionsDTS.js | 2 +- .../emitExtensionOptionsJSXPreserveBad.js | 2 +- .../emitExtensionOptionsJSXPreserveNormal.js | 2 +- .../reference/emitExtensionOptionsNormal.js | 2 +- .../emitExtensionOptionsStartWithNonDot.js | 2 +- 11 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtname.js create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtname.symbols create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtname.types create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.js create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.symbols create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.types diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtname.js b/tests/baselines/reference/emitExtensionEmitCustomExtname.js new file mode 100644 index 0000000000000..b1cc654f268b9 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtname.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/emitExtensionEmitCustomExtname.ts] //// + +//// [0.ts] +export default 1 + +//// [1.ts] +import x from './0' +x + 1 + + +//// [0.cpp] +"use strict"; +exports.__esModule = true; +exports["default"] = 1; +//// [1.cpp] +"use strict"; +exports.__esModule = true; +var _0_1 = require("./0"); +_0_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtname.symbols b/tests/baselines/reference/emitExtensionEmitCustomExtname.symbols new file mode 100644 index 0000000000000..6aa09396d3d29 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtname.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : Symbol(x, Decl(1.ts, 0, 6)) + +x + 1 +>x : Symbol(x, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtname.types b/tests/baselines/reference/emitExtensionEmitCustomExtname.types new file mode 100644 index 0000000000000..a00a4fa80ddc6 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtname.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : 1 + +x + 1 +>x + 1 : number +>x : 1 +>1 : 1 + diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.js b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.js new file mode 100644 index 0000000000000..f77b3e5bebe22 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/emitExtensionEmitCustomExtnameWithDot.ts] //// + +//// [0.ts] +export default 1 + +//// [1.ts] +import x from './0' +x + 1 + + +//// [0.strange.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 1; +//// [1.strange.js] +"use strict"; +exports.__esModule = true; +var _0_1 = require("./0"); +_0_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.symbols b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.symbols new file mode 100644 index 0000000000000..6aa09396d3d29 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : Symbol(x, Decl(1.ts, 0, 6)) + +x + 1 +>x : Symbol(x, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.types b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.types new file mode 100644 index 0000000000000..a00a4fa80ddc6 --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnameWithDot.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : 1 + +x + 1 +>x + 1 : number +>x : 1 +>1 : 1 + diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.js b/tests/baselines/reference/emitExtensionOptionsDTS.js index 3f7bc7e5ffcbb..3d748b0e1a1a8 100644 --- a/tests/baselines/reference/emitExtensionOptionsDTS.js +++ b/tests/baselines/reference/emitExtensionOptionsDTS.js @@ -4,7 +4,7 @@ export default 0 -//// [emitExtensionOptionsDTS.js] +//// [emitExtensionOptionsDTS.d.ts] "use strict"; exports.__esModule = true; // @Filename 1.ts diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js index 12701447dfc56..a348d020db894 100644 --- a/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveBad.js @@ -3,7 +3,7 @@ export default 1 -//// [0.js] +//// [0.mjs] "use strict"; exports.__esModule = true; // emitExtension can only be ".jsx" when JSX is set to "preserve" diff --git a/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js index 03af88e6156f2..e70dfbafba0c4 100644 --- a/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js +++ b/tests/baselines/reference/emitExtensionOptionsJSXPreserveNormal.js @@ -2,7 +2,7 @@ export default 1 -//// [0.js] +//// [0.jsx] "use strict"; exports.__esModule = true; exports["default"] = 1; diff --git a/tests/baselines/reference/emitExtensionOptionsNormal.js b/tests/baselines/reference/emitExtensionOptionsNormal.js index 0eb2e0d107a11..2d09dc08704df 100644 --- a/tests/baselines/reference/emitExtensionOptionsNormal.js +++ b/tests/baselines/reference/emitExtensionOptionsNormal.js @@ -2,7 +2,7 @@ export default 0 -//// [0.js] +//// [0.mjs] "use strict"; exports.__esModule = true; exports["default"] = 0; diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js index 821360c88142a..4f1b90ab4d6a4 100644 --- a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js +++ b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js @@ -3,7 +3,7 @@ export default 0 -//// [0.js] +//// [0mjs] "use strict"; exports.__esModule = true; // emitExtension must start with '.' From abb729e8b7921e9f45abdcf506ca537df36117f6 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:25:56 +0800 Subject: [PATCH 07/30] feat: ban invalid char in emitExtension --- src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/program.ts | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 617452301352e..7155df268fe4a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4543,6 +4543,10 @@ "category": "Error", "code": 6508 }, + "emitExtension contains invalid chars": { + "category": "Error", + "code": 6509 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8370323948382..8891315889bff 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2973,6 +2973,12 @@ namespace ts { if (options.emitExtension === Extension.Dts) { createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_can_not_be_d_ts, options.emitExtension); } + // To keep it simple at the first time, + // just accept . - a-z A-Z 0-9 + // If there is demand, can extend to any Unicode and ban chars like / \ < > : + if (!options.emitExtension.match(/^(\.|-|[a-zA-Z0-9])+$/g)) { + createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_contains_invalid_chars, options.emitExtension); + } } if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); From f34b9722856598eebb00a175f5ee80239766b602 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:26:11 +0800 Subject: [PATCH 08/30] test: add test for ban invalid char in emitExtension --- tests/cases/compiler/emitExtensionOptionsInvalidChars.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/cases/compiler/emitExtensionOptionsInvalidChars.ts diff --git a/tests/cases/compiler/emitExtensionOptionsInvalidChars.ts b/tests/cases/compiler/emitExtensionOptionsInvalidChars.ts new file mode 100644 index 0000000000000..eeb7b9dd00d3e --- /dev/null +++ b/tests/cases/compiler/emitExtensionOptionsInvalidChars.ts @@ -0,0 +1,8 @@ +// @emitExtension: .!<>/\.js + +// @Filename: 0.ts +export default 1 + +// @Filename: 1.ts +import x from './0' +x + 1 From 5df3fbd6fe64969c461d43a0baebb54020d7daa2 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sat, 14 Dec 2019 23:26:28 +0800 Subject: [PATCH 09/30] test: accept baseline for ban invalid char in emitExtension --- .../emitExtensionEmitCustomExtnamePathEscape.errors.txt | 7 +++++++ .../reference/emitExtensionEmitCustomExtnamePathEscape.js | 8 ++++++++ .../emitExtensionEmitCustomExtnamePathEscape.symbols | 4 ++++ .../emitExtensionEmitCustomExtnamePathEscape.types | 4 ++++ 4 files changed, 23 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.errors.txt create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.symbols create mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.types diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.errors.txt b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.errors.txt new file mode 100644 index 0000000000000..c8155b54709db --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.errors.txt @@ -0,0 +1,7 @@ +error TS6509: emitExtension contains invalid chars + + +!!! error TS6509: emitExtension contains invalid chars +==== tests/cases/compiler/0.ts (0 errors) ==== + export default 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js new file mode 100644 index 0000000000000..d4140dc0545ba --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js @@ -0,0 +1,8 @@ +//// [0.ts] +export default 1 + + +//// [index.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 1; diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.symbols b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.symbols new file mode 100644 index 0000000000000..2e9d59769cb1a --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.types b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.types new file mode 100644 index 0000000000000..2e9d59769cb1a --- /dev/null +++ b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.types @@ -0,0 +1,4 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file From 1e9b6250e0cf9177f7ff94145f4e977f5cbf97f6 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 11:31:02 +0800 Subject: [PATCH 10/30] chore: add compilerOptions to extname related functions --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 6 ++-- src/compiler/factory.ts | 2 +- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/moduleSpecifiers.ts | 23 +++++++-------- src/compiler/program.ts | 10 ++++--- src/compiler/transformers/declarations.ts | 4 +-- src/compiler/tsbuildPublic.ts | 2 +- src/compiler/utilities.ts | 28 ++++++++++--------- src/harness/harnessIO.ts | 4 +-- src/harness/harnessLanguageService.ts | 2 +- src/jsTyping/jsTyping.ts | 6 ++-- src/server/editorServices.ts | 2 +- src/server/project.ts | 2 +- src/services/codefixes/helpers.ts | 22 +++++++-------- src/services/codefixes/importFixes.ts | 8 +++--- src/services/codefixes/inferFromUsage.ts | 6 ++-- src/services/completions.ts | 24 ++++++++-------- src/services/jsDoc.ts | 2 +- src/services/navigationBar.ts | 2 +- src/services/refactors/moveToNewFile.ts | 5 ++-- src/services/rename.ts | 10 +++---- src/services/sourcemaps.ts | 2 +- src/services/stringCompletions.ts | 10 +++---- src/services/utilities.ts | 4 +-- src/testRunner/projectsRunner.ts | 6 ++-- src/testRunner/test262Runner.ts | 6 ++-- .../unittests/tsserver/resolutionCache.ts | 2 +- ...tatus.DiagnosticsPresent_OutputsSkipped.js | 1 + .../declarationDir-is-specified.js | 1 + ...-outDir-and-declarationDir-is-specified.js | 1 + .../when-outDir-is-specified.js | 1 + .../with-outFile.js | 1 + .../without-outDir-or-outFile-is-specified.js | 1 + 35 files changed, 112 insertions(+), 100 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 081f99f01f82c..c91bd63ece362 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2689,7 +2689,7 @@ namespace ts { } function bindSourceFileAsExternalModule() { - bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String); + bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName, options)}"` as __String); } function bindExportAssignment(node: ExportAssignment) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4fe8e264e559b..7e0a1b115b109 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6452,7 +6452,7 @@ namespace ts { getCurrentDirectory: () => context.tracker.moduleResolverHost!.getCurrentDirectory(), getCommonSourceDirectory: () => context.tracker.moduleResolverHost!.getCommonSourceDirectory() }; - const newName = getResolvedExternalModuleName(resolverHost, targetFile); + const newName = getResolvedExternalModuleName(resolverHost, compilerOptions, targetFile); return createLiteral(newName); } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 0506d0639d68f..782204af2fe35 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -58,11 +58,11 @@ namespace ts { const outPath = options.outFile || options.out; let buildInfoExtensionLess: string; if (outPath) { - buildInfoExtensionLess = removeFileExtension(outPath); + buildInfoExtensionLess = removeFileExtension(outPath, options); } else { if (!configFile) return undefined; - const configFileExtensionLess = removeFileExtension(configFile); + const configFileExtensionLess = removeFileExtension(configFile, options); buildInfoExtensionLess = options.outDir ? options.rootDir ? resolvePath(options.outDir, getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) : @@ -77,7 +77,7 @@ namespace ts { const outPath = options.outFile || options.out!; const jsFilePath = options.emitDeclarationOnly ? undefined : outPath; const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined; + const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath, options) + Extension.Dts : undefined; const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options); return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 48646e5b89dc2..c7428a75b7f78 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1594,7 +1594,7 @@ namespace ts { return createLiteral(file.moduleName); } if (!file.isDeclarationFile && (options.out || options.outFile)) { - return createLiteral(getExternalModuleNameFromPath(host, file.fileName)); + return createLiteral(getExternalModuleNameFromPath(host, options, file.fileName)); } return undefined; } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 392b8a6e6b5e2..e5f4d12ab4330 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1071,7 +1071,7 @@ namespace ts { // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" if (hasJSFileExtension(candidate, state.compilerOptions)) { - const extensionless = removeFileExtension(candidate); + const extensionless = removeFileExtension(candidate, state.compilerOptions); if (state.traceEnabled) { const extension = candidate.substring(extensionless.length); trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 18331d98bad38..50cac1d60c5ad 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -21,7 +21,7 @@ namespace ts.moduleSpecifiers { case "minimal": return Ending.Minimal; case "index": return Ending.Index; case "js": return Ending.JsExtension; - default: return usesJsExtensionOnImports(importingSourceFile) ? Ending.JsExtension + default: return usesJsExtensionOnImports(importingSourceFile, compilerOptions) ? Ending.JsExtension : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; } } @@ -131,7 +131,7 @@ namespace ts.moduleSpecifiers { } const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions); - const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl, compilerOptions), importRelativeToBaseUrl, compilerOptions, paths); const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths; if (relativePreference === RelativePreference.NonRelative) { @@ -152,8 +152,8 @@ namespace ts.moduleSpecifiers { return count; } - function usesJsExtensionOnImports({ imports }: SourceFile): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSFileExtension(text) : undefined) || false; + function usesJsExtensionOnImports({ imports }: SourceFile, compilerOptions: CompilerOptions): boolean { + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJSFileExtension(text, compilerOptions) : undefined) || false; } function numberOfDirectorySeparators(str: string) { @@ -273,10 +273,10 @@ namespace ts.moduleSpecifiers { } } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, paths: MapLike): string | undefined { + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex: string, relativeToBaseUrl: string, options: CompilerOptions, paths: MapLike): string | undefined { for (const key in paths) { for (const patternText of paths[key]) { - const pattern = removeFileExtension(normalizePath(patternText)); + const pattern = removeFileExtension(normalizePath(patternText), options); const indexOfStar = pattern.indexOf("*"); if (indexOfStar !== -1) { const prefix = pattern.substr(0, indexOfStar); @@ -306,7 +306,7 @@ namespace ts.moduleSpecifiers { const relativePath = normalizedSourcePath !== undefined ? ensurePathIsNonModuleName(getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs ? removeExtensionAndIndexPostFix(relativePath, ending, compilerOptions) - : removeFileExtension(relativePath); + : removeFileExtension(relativePath, compilerOptions); } function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions, packageNameOnly?: boolean): string | undefined { @@ -331,8 +331,9 @@ namespace ts.moduleSpecifiers { if (versionPaths) { const subModuleName = moduleFileName.slice(parts.packageRootIndex + 1); const fromPaths = tryGetModuleNameFromPaths( - removeFileExtension(subModuleName), + removeFileExtension(subModuleName, options), removeExtensionAndIndexPostFix(subModuleName, Ending.Minimal, options), + options, versionPaths.paths ); if (fromPaths !== undefined) { @@ -365,14 +366,14 @@ namespace ts.moduleSpecifiers { const mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; if (isString(mainFileRelative)) { const mainExportFile = toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (removeFileExtension(mainExportFile) === removeFileExtension(getCanonicalFileName(path))) { + if (removeFileExtension(mainExportFile, options) === removeFileExtension(getCanonicalFileName(path), options)) { return packageRootPath; } } } // We still have a file name - remove the extension - const fullModulePathWithoutExtension = removeFileExtension(path); + const fullModulePathWithoutExtension = removeFileExtension(path, options); // If the file is /index, it can be imported by its directory name // IFF there is not _also_ a file by the same name @@ -469,7 +470,7 @@ namespace ts.moduleSpecifiers { function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions): string { if (fileExtensionIs(fileName, Extension.Json)) return fileName; - const noExtension = removeFileExtension(fileName); + const noExtension = removeFileExtension(fileName, options); switch (ending) { case Ending.Minimal: return removeSuffix(noExtension, "/index"); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 8891315889bff..b9ef7a40e919c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2220,12 +2220,13 @@ namespace ts { /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */ function getSourceFileFromReference(referencingFile: SourceFile | UnparsedSource, ref: FileReference): SourceFile | undefined { - return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)) || undefined); + return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)) || undefined, options); } function getSourceFileFromReferenceWorker( fileName: string, getSourceFile: (fileName: string) => SourceFile | undefined, + options: CompilerOptions, fail?: (diagnostic: DiagnosticMessage, ...argument: string[]) => void, refFile?: SourceFile): SourceFile | undefined { @@ -2233,7 +2234,7 @@ namespace ts { const canonicalFileName = host.getCanonicalFileName(fileName); if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule, extension => fileExtensionIs(canonicalFileName, extension))) { if (fail) { - if (hasJSFileExtension(canonicalFileName)) { + if (hasJSFileExtension(canonicalFileName, options)) { fail(Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName); } else { @@ -2280,6 +2281,7 @@ namespace ts { getSourceFileFromReferenceWorker( fileName, fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, ignoreNoDefaultLib, refFile, packageId), // TODO: GH#18217 + options, (diagnostic, ...args) => fileProcessingDiagnostics.add( createRefFileDiagnostic(refFile, diagnostic, ...args) ), @@ -3438,7 +3440,7 @@ namespace ts { // If options have --outFile or --out just check that const out = options.outFile || options.out; if (out) { - return isSameFile(filePath, out) || isSameFile(filePath, removeFileExtension(out) + Extension.Dts); + return isSameFile(filePath, out) || isSameFile(filePath, removeFileExtension(out, options) + Extension.Dts); } // If declarationDir is specified, return if its a file in that directory @@ -3453,7 +3455,7 @@ namespace ts { if (fileExtensionIsOneOf(filePath, supportedJSExtensions) || fileExtensionIs(filePath, Extension.Dts)) { // Otherwise just check if sourceFile with the name exists - const filePathWithoutExtension = removeFileExtension(filePath); + const filePathWithoutExtension = removeFileExtension(filePath, options); return !!getSourceFileByPath((filePathWithoutExtension + Extension.Ts) as Path) || !!getSourceFileByPath((filePathWithoutExtension + Extension.Tsx) as Path); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 743aa1b476932..7d9addc054d50 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -237,7 +237,7 @@ namespace ts { const newFile = updateSourceFileNode(sourceFile, [createModuleDeclaration( [], [createModifier(SyntaxKind.DeclareKeyword)], - createLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), + createLiteral(getResolvedExternalModuleName(context.getEmitHost(), options, sourceFile)), createModuleBlock(setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)) )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); return newFile; @@ -632,7 +632,7 @@ namespace ts { resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType); if (isStringLiteralLike(input)) { if (isBundledEmit) { - const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent); + const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent, options); if (newName) { return createLiteral(newName); } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 3eb793b7599bb..adeca69acb32d 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1800,7 +1800,7 @@ namespace ts { // If options have --outFile or --out, check if its that const out = configFile.options.outFile || configFile.options.out; - if (out && (isSameFile(state, fileName, out) || isSameFile(state, fileName, removeFileExtension(out) + Extension.Dts))) { + if (out && (isSameFile(state, fileName, out) || isSameFile(state, fileName, removeFileExtension(out, state.projectCompilerOptions) + Extension.Dts))) { return true; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index aec117802952e..55b1e140a8937 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3767,27 +3767,27 @@ namespace ts { getCurrentDirectory(): string; } - export function getResolvedExternalModuleName(host: ResolveModuleNameResolutionHost, file: SourceFile, referenceFile?: SourceFile): string { - return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName); + export function getResolvedExternalModuleName(host: ResolveModuleNameResolutionHost, options: CompilerOptions, file: SourceFile, referenceFile?: SourceFile): string { + return file.moduleName || getExternalModuleNameFromPath(host, options, file.fileName, referenceFile && referenceFile.fileName); } - export function getExternalModuleNameFromDeclaration(host: ResolveModuleNameResolutionHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string | undefined { + export function getExternalModuleNameFromDeclaration(host: ResolveModuleNameResolutionHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, compilerOptions: CompilerOptions): string | undefined { const file = resolver.getExternalModuleFileFromDeclaration(declaration); if (!file || file.isDeclarationFile) { return undefined; } - return getResolvedExternalModuleName(host, file); + return getResolvedExternalModuleName(host, compilerOptions, file); } /** * Resolves a local path to a path which is absolute to the base of the emit */ - export function getExternalModuleNameFromPath(host: ResolveModuleNameResolutionHost, fileName: string, referencePath?: string): string { + export function getExternalModuleNameFromPath(host: ResolveModuleNameResolutionHost, options: CompilerOptions, fileName: string, referencePath?: string): string { const getCanonicalFileName = (f: string) => host.getCanonicalFileName(f); const dir = toPath(referencePath ? getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName); const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()); const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - const extensionless = removeFileExtension(relativePath); + const extensionless = removeFileExtension(relativePath, options); return referencePath ? ensurePathIsNonModuleName(extensionless) : extensionless; } @@ -3795,10 +3795,10 @@ namespace ts { const compilerOptions = host.getCompilerOptions(); let emitOutputFilePathWithoutExtension: string; if (compilerOptions.outDir) { - emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir)); + emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir), compilerOptions); } else { - emitOutputFilePathWithoutExtension = removeFileExtension(fileName); + emitOutputFilePathWithoutExtension = removeFileExtension(fileName, compilerOptions); } return emitOutputFilePathWithoutExtension + extension; @@ -3814,7 +3814,7 @@ namespace ts { const path = outputDir ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName) : fileName; - return removeFileExtension(path) + Extension.Dts; + return removeFileExtension(path, options) + Extension.Dts; } export interface EmitFileNames { @@ -5390,7 +5390,7 @@ namespace ts { return compilerOptions.target || ScriptTarget.ES3; } - export function getEmitModuleKind(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}) { + export function getEmitModuleKind(compilerOptions: { module?: CompilerOptions["module"], target?: CompilerOptions["target"] }) { return typeof compilerOptions.module === "number" ? compilerOptions.module : getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS; @@ -5900,7 +5900,7 @@ namespace ts { return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX; } - export function hasJSFileExtension(fileName: string, compilerOptions?: CompilerOptions): boolean { + export function hasJSFileExtension(fileName: string, compilerOptions: CompilerOptions): boolean { if (compilerOptions && compilerOptions.emitExtension) { return some( [compilerOptions.emitExtension].concat(supportedJSExtensions), @@ -5979,8 +5979,10 @@ namespace ts { } const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx, Extension.Json]; - export function removeFileExtension(path: string): string { - for (const ext of extensionsToRemove) { + export function removeFileExtension(path: string, options: CompilerOptions): string { + const extra = options && options.emitExtension; + const remove: string[] = extra ? (extensionsToRemove as string[]).concat(extra) : extensionsToRemove; + for (const ext of remove) { const extensionless = tryRemoveExtension(path, ext); if (extensionless !== undefined) { return extensionless; diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 7aebbb1cd2ce5..678f6f1024925 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -470,7 +470,7 @@ namespace Harness { if (vpath.isDeclaration(file.unitName) || vpath.isJson(file.unitName)) { dtsFiles.push(file); } - else if (vpath.isTypeScript(file.unitName) || (vpath.isJavaScript(file.unitName) && options.allowJs)) { + else if (vpath.isTypeScript(file.unitName) || (vpath.isJavaScript(file.unitName, options) && options.allowJs)) { const declFile = findResultCodeFile(file.unitName); if (declFile && !findUnit(declFile.file, declInputFiles) && !findUnit(declFile.file, declOtherFiles)) { dtsFiles.push({ unitName: declFile.file, content: Utils.removeByteOrderMark(declFile.text) }); @@ -499,7 +499,7 @@ namespace Harness { sourceFileName = outFile; } - const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.Extension.Dts; + const dTsFileName = ts.removeFileExtension(sourceFileName, options) + ts.Extension.Dts; return result.dts.get(dTsFileName); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index fbaf9ba545d0a..5aa3bb4005e4a 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -291,7 +291,7 @@ namespace Harness.LanguageService { getHost(): LanguageServiceAdapterHost { return this.host; } getLanguageService(): ts.LanguageService { return ts.createLanguageService(this.host); } getClassifier(): ts.Classifier { return ts.createClassifier(); } - getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJSFileExtension(fileName)); } + getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJSFileExtension(fileName, this.host.getCompilationSettings())); } } /// Shim adapter diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index 70efac4aee1e5..182b937a8fc1d 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -123,7 +123,7 @@ namespace ts.JsTyping { // Only infer typings for .js and .jsx files fileNames = mapDefined(fileNames, fileName => { const path = normalizePath(fileName); - if (hasJSFileExtension(path)) { + if (hasJSFileExtension(path, {})) { return path; } }); @@ -219,9 +219,9 @@ namespace ts.JsTyping { */ function getTypingNamesFromSourceFileNames(fileNames: string[]) { const fromFileNames = mapDefined(fileNames, j => { - if (!hasJSFileExtension(j)) return undefined; + if (!hasJSFileExtension(j, {})) return undefined; - const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase())); + const inferredTypingName = removeFileExtension(getBaseFileName(j.toLowerCase()), {}); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); return safeList.get(cleanedTypingName); }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 24f311d20bf72..0416649c9bad3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -3492,7 +3492,7 @@ namespace ts.server { if (typeAcquisition.enable || typeAcquisition.enableAutoDiscovery) { const baseName = getBaseFileName(toFileNameLowerCase(normalizedNames[i])); if (fileExtensionIs(baseName, "js")) { - const inferredTypingName = removeFileExtension(baseName); + const inferredTypingName = removeFileExtension(baseName, {}); const cleanedTypingName = removeMinAndVersionNumbers(inferredTypingName); const typeName = this.legacySafelist.get(cleanedTypingName); if (typeName !== undefined) { diff --git a/src/server/project.ts b/src/server/project.ts index ffcc55791c9df..42827f6ca0a9d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1024,7 +1024,7 @@ namespace ts.server { if (isGeneratedFileWatcher(this.generatedFilesMap)) { // --out if (!outPath || !this.isValidGeneratedFileWatcher( - removeFileExtension(outPath) + Extension.Dts, + removeFileExtension(outPath, this.compilerOptions) + Extension.Dts, this.generatedFilesMap, )) { this.clearGeneratedFileWatch(); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 48f2ee9858496..f7acaa94df89e 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -37,7 +37,7 @@ namespace ts.codefix { return undefined; } const checker = context.program.getTypeChecker(); - const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions()); + const compilerOptions = context.program.getCompilerOptions(); const declaration = declarations[0]; const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName; const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration)); @@ -52,7 +52,7 @@ namespace ts.codefix { const flags = preferences.quotePreference === "single" ? NodeBuilderFlags.UseSingleQuotesForStringLiteralType : undefined; let typeNode = checker.typeToTypeNode(type, enclosingDeclaration, flags, getNoopSymbolTrackerWithResolver(context)); if (importAdder) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, compilerOptions); if (importableReference) { typeNode = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); @@ -74,7 +74,7 @@ namespace ts.codefix { ? [allAccessors.firstAccessor, allAccessors.secondAccessor] : [allAccessors.firstAccessor]; if (importAdder) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, compilerOptions); if (importableReference) { typeNode = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); @@ -161,7 +161,7 @@ namespace ts.codefix { ): MethodDeclaration | undefined { const program = context.program; const checker = program.getTypeChecker(); - const scriptTarget = getEmitScriptTarget(program.getCompilerOptions()); + const compilerOptions = program.getCompilerOptions(); const signatureDeclaration = checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration, NodeBuilderFlags.NoTruncation | NodeBuilderFlags.SuppressAnyReturnType, getNoopSymbolTrackerWithResolver(context)); if (!signatureDeclaration) { return undefined; @@ -172,14 +172,14 @@ namespace ts.codefix { forEach(signatureDeclaration.typeParameters, (typeParameterDecl, i) => { const typeParameter = signature.typeParameters![i]; if (typeParameterDecl.constraint) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.constraint, typeParameter.constraint, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.constraint, typeParameter.constraint, compilerOptions); if (importableReference) { typeParameterDecl.constraint = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } } if (typeParameterDecl.default) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.default, typeParameter.default, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeParameterDecl.default, typeParameter.default, compilerOptions); if (importableReference) { typeParameterDecl.default = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); @@ -189,14 +189,14 @@ namespace ts.codefix { } forEach(signatureDeclaration.parameters, (parameterDecl, i) => { const parameter = signature.parameters[i]; - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(parameterDecl.type, checker.getTypeAtLocation(parameter.valueDeclaration), scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(parameterDecl.type, checker.getTypeAtLocation(parameter.valueDeclaration), compilerOptions); if (importableReference) { parameterDecl.type = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); } }); if (signatureDeclaration.type) { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(signatureDeclaration.type, signature.resolvedReturnType, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(signatureDeclaration.type, signature.resolvedReturnType, compilerOptions); if (importableReference) { signatureDeclaration.type = importableReference.typeReference; importSymbols(importAdder, importableReference.symbols); @@ -408,11 +408,11 @@ namespace ts.codefix { * returns an equivalent type reference node with any nested ImportTypeNodes also replaced * with type references, and a list of symbols that must be imported to use the type reference. */ - export function tryGetAutoImportableReferenceFromImportTypeNode(importTypeNode: TypeNode | undefined, type: Type | undefined, scriptTarget: ScriptTarget) { + export function tryGetAutoImportableReferenceFromImportTypeNode(importTypeNode: TypeNode | undefined, type: Type | undefined, compilerOptions: CompilerOptions) { if (importTypeNode && isLiteralImportTypeNode(importTypeNode) && importTypeNode.qualifier && (!type || type.symbol)) { // Symbol for the left-most thing after the dot const firstIdentifier = getFirstIdentifier(importTypeNode.qualifier); - const name = getNameForExportedSymbol(firstIdentifier.symbol, scriptTarget); + const name = getNameForExportedSymbol(firstIdentifier.symbol, compilerOptions); const qualifier = name !== firstIdentifier.text ? replaceFirstIdentifierOfEntityName(importTypeNode.qualifier, createIdentifier(name)) : importTypeNode.qualifier; @@ -421,7 +421,7 @@ namespace ts.codefix { const typeArguments: TypeNode[] = []; if (importTypeNode.typeArguments) { importTypeNode.typeArguments.forEach(arg => { - const ref = tryGetAutoImportableReferenceFromImportTypeNode(arg, /*undefined*/ type, scriptTarget); + const ref = tryGetAutoImportableReferenceFromImportTypeNode(arg, /*undefined*/ type, compilerOptions); if (ref) { symbols.push(...ref.symbols); typeArguments.push(ref.typeReference); diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 57fd8c1dc6a79..944ae8ad35fc6 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -56,7 +56,7 @@ namespace ts.codefix { function addImportFromExportedSymbol(exportedSymbol: Symbol, usageIsTypeOnly?: boolean) { const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); - const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); + const symbolName = getNameForExportedSymbol(exportedSymbol, compilerOptions); const checker = program.getTypeChecker(); const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); const exportInfos = getAllReExportingModules(sourceFile, symbol, moduleSymbol, symbolName, sourceFile, compilerOptions, checker, program.getSourceFiles()); @@ -591,7 +591,7 @@ namespace ts.codefix { defaultExport.escapedName !== InternalSymbolName.ExportEquals) { return { symbolForMeaning: defaultExport, name: defaultExport.getName() }; } - return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, compilerOptions.target!) }; + return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, compilerOptions) }; } function getNameForExportDefault(symbol: Symbol): string | undefined { @@ -861,8 +861,8 @@ namespace ts.codefix { || (!!globalCachePath && startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent)); } - export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget): string { - return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name)), target); + export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, compilerOptions: CompilerOptions): string { + return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name), compilerOptions), getEmitScriptTarget(compilerOptions)); } export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget): string { diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 0af71bbbb9ca0..4ac3a9c299b2e 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -310,7 +310,7 @@ namespace ts.codefix { const typeTag = isGetAccessorDeclaration(declaration) ? createJSDocReturnTag(typeExpression, "") : createJSDocTypeTag(typeExpression, ""); addJSDocTags(changes, sourceFile, parent, [typeTag]); } - else if (!tryReplaceImportTypeNodeWithAutoImport(typeNode, declaration, type, sourceFile, changes, importAdder, getEmitScriptTarget(program.getCompilerOptions()))) { + else if (!tryReplaceImportTypeNodeWithAutoImport(typeNode, declaration, type, sourceFile, changes, importAdder, program.getCompilerOptions())) { changes.tryInsertTypeAnnotation(sourceFile, declaration, typeNode); } } @@ -323,9 +323,9 @@ namespace ts.codefix { sourceFile: SourceFile, changes: textChanges.ChangeTracker, importAdder: ImportAdder, - scriptTarget: ScriptTarget + options: CompilerOptions ): boolean { - const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, scriptTarget); + const importableReference = tryGetAutoImportableReferenceFromImportTypeNode(typeNode, type, options); if (importableReference && changes.tryInsertTypeAnnotation(sourceFile, declaration, importableReference.typeReference)) { forEach(importableReference.symbols, s => importAdder.addImportFromExportedSymbol(s, /*usageIsTypeOnly*/ true)); return true; diff --git a/src/services/completions.ts b/src/services/completions.ts index 11f16ccf8fe2f..7a2f3c4c2cc53 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -227,7 +227,7 @@ namespace ts.Completions { location, sourceFile, typeChecker, - compilerOptions.target!, + compilerOptions, log, completionKind, preferences, @@ -250,7 +250,7 @@ namespace ts.Completions { location, sourceFile, typeChecker, - compilerOptions.target!, + compilerOptions, log, completionKind, preferences, @@ -436,7 +436,7 @@ namespace ts.Completions { location: Node | undefined, sourceFile: SourceFile, typeChecker: TypeChecker, - target: ScriptTarget, + options: CompilerOptions, log: Log, kind: CompletionKind, preferences: UserPreferences, @@ -454,7 +454,7 @@ namespace ts.Completions { const uniques = createMap(); for (const symbol of symbols) { const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined; - const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind); + const info = getCompletionEntryDisplayNameForSymbol(symbol, options, origin, kind); if (!info) { continue; } @@ -564,7 +564,7 @@ namespace ts.Completions { // completion entry. return firstDefined(symbols, (symbol): SymbolCompletion | undefined => { const origin = symbolToOriginInfoMap[getSymbolId(symbol)]; - const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target!, origin, completionKind); + const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions, origin, completionKind); return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source ? { type: "symbol" as const, symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer, isTypeOnlyLocation } : undefined; @@ -673,7 +673,7 @@ namespace ts.Completions { exportedSymbol, moduleSymbol, sourceFile, - getNameForExportedSymbol(symbol, compilerOptions.target!), + getNameForExportedSymbol(symbol, compilerOptions), host, program, formatContext, @@ -1360,7 +1360,7 @@ namespace ts.Completions { if (shouldOfferImportCompletions()) { const lowerCaseTokenText = previousToken && isIdentifier(previousToken) ? previousToken.text.toLowerCase() : ""; - const autoImportSuggestions = getSymbolsFromOtherSourceFileExports(program.getCompilerOptions().target!, host); + const autoImportSuggestions = getSymbolsFromOtherSourceFileExports(program.getCompilerOptions(), host); if (!detailsEntryId && importSuggestionsCache) { importSuggestionsCache.set(sourceFile.fileName, autoImportSuggestions, host.getProjectVersion && host.getProjectVersion()); } @@ -1541,7 +1541,7 @@ namespace ts.Completions { * occur for that symbol---that is, the original symbol is not in Bucket A, so we should include the alias. Move * everything from Bucket C to Bucket A. */ - function getSymbolsFromOtherSourceFileExports(target: ScriptTarget, host: LanguageServiceHost): readonly AutoImportSuggestion[] { + function getSymbolsFromOtherSourceFileExports(compilerOptions: CompilerOptions, host: LanguageServiceHost): readonly AutoImportSuggestion[] { const cached = importSuggestionsCache && importSuggestionsCache.get( sourceFile.fileName, typeChecker, @@ -1640,7 +1640,7 @@ namespace ts.Completions { const origin: SymbolOriginInfoExport = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport }; results.push({ symbol, - symbolName: getNameForExportedSymbol(symbol, target), + symbolName: getNameForExportedSymbol(symbol, compilerOptions), origin, skipFilter, }); @@ -2396,11 +2396,11 @@ namespace ts.Completions { } function getCompletionEntryDisplayNameForSymbol( symbol: Symbol, - target: ScriptTarget, + options: CompilerOptions, origin: SymbolOriginInfo | undefined, kind: CompletionKind, ): CompletionEntryDisplayNameForSymbol | undefined { - const name = originIsExport(origin) ? getNameForExportedSymbol(symbol, target) : symbol.name; + const name = originIsExport(origin) ? getNameForExportedSymbol(symbol, options) : symbol.name; if (name === undefined // If the symbol is external module, don't show it in the completion list // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) @@ -2411,7 +2411,7 @@ namespace ts.Completions { } const validNameResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false }; - if (isIdentifierText(name, target) || symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) { + if (isIdentifierText(name, options.target) || symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) { return validNameResult; } switch (kind) { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 7118fe8b76181..0e13028b945f2 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -294,7 +294,7 @@ namespace ts.JsDoc { const preamble = "/**" + newLine + indentationStr + " * "; const result = preamble + newLine + - parameterDocComments(parameters, hasJSFileExtension(sourceFile.fileName), indentationStr, newLine) + + parameterDocComments(parameters, hasJSFileExtension(sourceFile.fileName, {}), indentationStr, newLine) + indentationStr + " */" + (tokenStart === position ? newLine + indentationStr : ""); diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 38faf25da7f99..7c42a9a71a1d7 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -680,7 +680,7 @@ namespace ts.NavigationBar { case SyntaxKind.SourceFile: const sourceFile = node; return isExternalModule(sourceFile) - ? `"${escapeString(getBaseFileName(removeFileExtension(normalizePath(sourceFile.fileName))))}"` + ? `"${escapeString(getBaseFileName(removeFileExtension(normalizePath(sourceFile.fileName), {})))}"` : ""; case SyntaxKind.ExportAssignment: return isExportAssignment(node) && node.isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default; diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index a9b8171cbc98b..a4cab4615294d 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -130,7 +130,7 @@ namespace ts.refactor { updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName); return [ - ...getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference), + ...getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference, program.getCompilerOptions()), ...addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax), ]; } @@ -398,6 +398,7 @@ namespace ts.refactor { checker: TypeChecker, useEs6ModuleSyntax: boolean, quotePreference: QuotePreference, + compilerOptions: CompilerOptions, ): readonly SupportedImportStatement[] { const copiedOldImports: SupportedImportStatement[] = []; for (const oldStatement of oldFile.statements) { @@ -429,7 +430,7 @@ namespace ts.refactor { } }); - append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, quotePreference)); + append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName), compilerOptions), useEs6ModuleSyntax, quotePreference)); return copiedOldImports; } diff --git a/src/services/rename.ts b/src/services/rename.ts index 4cdb4f14dc857..8932c51ba0054 100644 --- a/src/services/rename.ts +++ b/src/services/rename.ts @@ -3,7 +3,7 @@ namespace ts.Rename { export function getRenameInfo(program: Program, sourceFile: SourceFile, position: number, options?: RenameInfoOptions): RenameInfo { const node = getAdjustedRenameLocation(getTouchingPropertyName(sourceFile, position)); if (nodeIsEligibleForRename(node)) { - const renameInfo = getRenameInfoForNode(node, program.getTypeChecker(), sourceFile, declaration => program.isSourceFileDefaultLibrary(declaration.getSourceFile()), options); + const renameInfo = getRenameInfoForNode(node, program.getTypeChecker(), sourceFile, declaration => program.isSourceFileDefaultLibrary(declaration.getSourceFile()), program.getCompilerOptions(), options); if (renameInfo) { return renameInfo; } @@ -11,7 +11,7 @@ namespace ts.Rename { return getRenameInfoError(Diagnostics.You_cannot_rename_this_element); } - function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, isDefinedInLibraryFile: (declaration: Node) => boolean, options?: RenameInfoOptions): RenameInfo | undefined { + function getRenameInfoForNode(node: Node, typeChecker: TypeChecker, sourceFile: SourceFile, isDefinedInLibraryFile: (declaration: Node) => boolean, compilerOptions: CompilerOptions, options?: RenameInfoOptions): RenameInfo | undefined { const symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) return; // Only allow a symbol to be renamed if it actually has at least one declaration. @@ -29,7 +29,7 @@ namespace ts.Rename { } if (isStringLiteralLike(node) && tryGetImportFromModuleSpecifier(node)) { - return options && options.allowRenameOfImportPath ? getRenameInfoForModule(node, sourceFile, symbol) : undefined; + return options && options.allowRenameOfImportPath ? getRenameInfoForModule(node, sourceFile, symbol, compilerOptions) : undefined; } const kind = SymbolDisplay.getSymbolKind(typeChecker, symbol, node); @@ -41,14 +41,14 @@ namespace ts.Rename { return getRenameInfoSuccess(displayName, fullDisplayName, kind, SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile); } - function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol): RenameInfo | undefined { + function getRenameInfoForModule(node: StringLiteralLike, sourceFile: SourceFile, moduleSymbol: Symbol, compilerOptions: CompilerOptions): RenameInfo | undefined { if (!isExternalModuleNameRelative(node.text)) { return getRenameInfoError(Diagnostics.You_cannot_rename_a_module_via_a_global_import); } const moduleSourceFile = find(moduleSymbol.declarations, isSourceFile); if (!moduleSourceFile) return undefined; - const withoutIndex = endsWith(node.text, "/index") || endsWith(node.text, "/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName), "/index"); + const withoutIndex = endsWith(node.text, "/index") || endsWith(node.text, "/index.js") ? undefined : tryRemoveSuffix(removeFileExtension(moduleSourceFile.fileName, compilerOptions), "/index"); const name = withoutIndex === undefined ? moduleSourceFile.fileName : withoutIndex; const kind = withoutIndex === undefined ? ScriptElementKind.moduleElement : ScriptElementKind.directory; const indexAfterLastSlash = node.text.lastIndexOf("/") + 1; diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index b582ba0065d86..435e82244070d 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -79,7 +79,7 @@ namespace ts { const outPath = options.outFile || options.out; const declarationPath = outPath ? - removeFileExtension(outPath) + Extension.Dts : + removeFileExtension(outPath, options) + Extension.Dts : getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName); if (declarationPath === undefined) return undefined; diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 313b37430e2ed..703c9ff656893 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -8,11 +8,11 @@ namespace ts.Completions.StringCompletions { if (isInString(sourceFile, position, contextToken)) { if (!contextToken || !isStringLiteralLike(contextToken)) return undefined; const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, checker, options, host); - return convertStringLiteralCompletions(entries, sourceFile, checker, log, preferences); + return convertStringLiteralCompletions(entries, sourceFile, checker, log, preferences, options); } } - function convertStringLiteralCompletions(completion: StringLiteralCompletion | undefined, sourceFile: SourceFile, checker: TypeChecker, log: Log, preferences: UserPreferences): CompletionInfo | undefined { + function convertStringLiteralCompletions(completion: StringLiteralCompletion | undefined, sourceFile: SourceFile, checker: TypeChecker, log: Log, preferences: UserPreferences, compilerOptions: CompilerOptions): CompletionInfo | undefined { if (completion === undefined) { return undefined; } @@ -27,7 +27,7 @@ namespace ts.Completions.StringCompletions { sourceFile, sourceFile, checker, - ScriptTarget.ESNext, + compilerOptions, log, CompletionKind.String, preferences @@ -363,7 +363,7 @@ namespace ts.Completions.StringCompletions { continue; } - const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath)); + const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath), host.getCompilationSettings()); foundFiles.set(foundFileName, tryGetExtensionFromPath(filePath)); } @@ -528,7 +528,7 @@ namespace ts.Completions.StringCompletions { const matches = mapDefined(tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]), match => { const extension = tryGetExtensionFromPath(match); const name = trimPrefixAndSuffix(match); - return name === undefined ? undefined : nameAndKind(removeFileExtension(name), ScriptElementKind.scriptElement, extension); + return name === undefined ? undefined : nameAndKind(removeFileExtension(name, host.getCompilationSettings()), ScriptElementKind.scriptElement, extension); }); const directories = mapDefined(tryGetDirectories(host, baseDirectory).map(d => combinePaths(baseDirectory, d)), dir => { const name = trimPrefixAndSuffix(dir); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 58a39726589a9..8de613aa1822e 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2760,11 +2760,11 @@ namespace ts { return isArray(valueOrArray) ? first(valueOrArray) : valueOrArray; } - export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTarget) { + export function getNameForExportedSymbol(symbol: Symbol, compilerOptions: CompilerOptions) { if (symbol.escapedName === InternalSymbolName.ExportEquals || symbol.escapedName === InternalSymbolName.Default) { // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase. return firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined) - || codefix.moduleSymbolToValidIdentifier(Debug.checkDefined(symbol.parent), scriptTarget); + || codefix.moduleSymbolToValidIdentifier(Debug.checkDefined(symbol.parent), compilerOptions); } return symbol.name; } diff --git a/src/testRunner/projectsRunner.ts b/src/testRunner/projectsRunner.ts index d90972fe09a76..430cda43d0910 100644 --- a/src/testRunner/projectsRunner.ts +++ b/src/testRunner/projectsRunner.ts @@ -357,10 +357,10 @@ namespace project { if (compilerOptions.outDir) { let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program!.getCurrentDirectory()); sourceFilePath = sourceFilePath.replace(compilerResult.program!.getCommonSourceDirectory(), ""); - emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath)); + emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath), compilerOptions); } else { - emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName); + emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName, compilerOptions); } const outputDtsFileName = emitOutputFilePathWithoutExtension + ts.Extension.Dts; @@ -371,7 +371,7 @@ namespace project { } } else { - const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out!) + ts.Extension.Dts; + const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out!, compilerOptions) + ts.Extension.Dts; const outputDtsFile = findOutputDtsFile(outputDtsFileName)!; if (!ts.contains(allInputFiles, outputDtsFile)) { allInputFiles.unshift(outputDtsFile); diff --git a/src/testRunner/test262Runner.ts b/src/testRunner/test262Runner.ts index 728d3fb322790..a43b5e34e3328 100644 --- a/src/testRunner/test262Runner.ts +++ b/src/testRunner/test262Runner.ts @@ -34,7 +34,7 @@ namespace Harness { before(() => { const content = IO.readFile(filePath)!; - const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test"; + const testFilename = ts.removeFileExtension(filePath, {}).replace(/\//g, "_") + ".test"; const testCaseContent = TestCaseParser.makeUnitsFromTest(content, testFilename); const inputFiles: Compiler.TestFile[] = testCaseContent.testUnitData.map(unit => { @@ -51,7 +51,7 @@ namespace Harness { testState.compilerResult = Compiler.compileFiles( [Test262BaselineRunner.helperFile].concat(inputFiles), - /*otherFiles*/ [], + /*otherFiles*/[], /* harnessOptions */ undefined, Test262BaselineRunner.options, /* currentDirectory */ undefined); @@ -107,4 +107,4 @@ namespace Harness { } } } -} \ No newline at end of file +} diff --git a/src/testRunner/unittests/tsserver/resolutionCache.ts b/src/testRunner/unittests/tsserver/resolutionCache.ts index d89a739c8d1ca..e0ade5f39f1af 100644 --- a/src/testRunner/unittests/tsserver/resolutionCache.ts +++ b/src/testRunner/unittests/tsserver/resolutionCache.ts @@ -530,7 +530,7 @@ namespace ts.projectSystem { function getExpectedRelativeModuleResolutionTrace(host: TestServerHost, file: File, module: File, moduleName: string, expectedTrace: string[] = []) { getExpectedResolutionTraceHeader(expectedTrace, file, moduleName); - expectedTrace.push(`Loading module as file / folder, candidate module location '${removeFileExtension(module.path)}', target file type 'TypeScript'.`); + expectedTrace.push(`Loading module as file / folder, candidate module location '${removeFileExtension(module.path, {})}', target file type 'TypeScript'.`); getExpectedMissedLocationResolutionTrace(host, expectedTrace, getDirectoryPath(normalizePath(combinePaths(getDirectoryPath(file.path), moduleName))), module, moduleName.substring(moduleName.lastIndexOf("/") + 1), /*useNodeModules*/ false); getExpectedResolutionTraceFooter(expectedTrace, module, moduleName, /*addRealPathTrace*/ false); return expectedTrace; diff --git a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js index e9c781c0616d5..072ebe6107dff 100644 --- a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js +++ b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js @@ -44,6 +44,7 @@ Options: --noFallthroughCasesInSwitch Report errors for fallthrough cases in switch statement. --types Type declaration files to be included in compilation. --esModuleInterop Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. + --emitExtension Specify the extension name of the emitted files. @ Insert command line options and files from a file. exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js index 36c9d0609c14f..310ece479e6ea 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js @@ -42,6 +42,7 @@ interface Array { length: number; [n: number]: T; } // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js index f755ab350ecce..9eac42aa21b2a 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js @@ -42,6 +42,7 @@ interface Array { length: number; [n: number]: T; } // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js index 933745206f23a..b6e25f2ccfff9 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js @@ -42,6 +42,7 @@ interface Array { length: number; [n: number]: T; } // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js index 9bb54d9380e23..7aae8c1d457e4 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js @@ -42,6 +42,7 @@ interface Array { length: number; [n: number]: T; } // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js index 158a39b488077..489c21a84589b 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js @@ -42,6 +42,7 @@ interface Array { length: number; [n: number]: T; } // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + // "emitExtension": "", /* Specify the extension name of the emitted files. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ From 4f8bc054b93795b9006fb4c8bc6340e61747ae28 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 11:55:36 +0800 Subject: [PATCH 11/30] feat: no emit on invalid char in emitExtension --- src/compiler/program.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b9ef7a40e919c..61a5a9fdc6ef3 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2980,6 +2980,8 @@ namespace ts { // If there is demand, can extend to any Unicode and ban chars like / \ < > : if (!options.emitExtension.match(/^(\.|-|[a-zA-Z0-9])+$/g)) { createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_contains_invalid_chars, options.emitExtension); + // Don't emit any file with this error, or it will break the file system unconditionally + options.noEmitOnError = true; } } if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { From 8b91e95d0e7fb77c8f550db0d260fbb34f34a893 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 11:56:06 +0800 Subject: [PATCH 12/30] test: accept baseline for no emit on invalid char in emitExtension --- .../emitExtensionEmitCustomExtnamePathEscape.js | 8 -------- .../emitExtensionOptionsInvalidChars.errors.txt | 11 +++++++++++ .../emitExtensionOptionsInvalidChars.symbols | 10 ++++++++++ .../reference/emitExtensionOptionsInvalidChars.types | 12 ++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) delete mode 100644 tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js create mode 100644 tests/baselines/reference/emitExtensionOptionsInvalidChars.errors.txt create mode 100644 tests/baselines/reference/emitExtensionOptionsInvalidChars.symbols create mode 100644 tests/baselines/reference/emitExtensionOptionsInvalidChars.types diff --git a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js b/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js deleted file mode 100644 index d4140dc0545ba..0000000000000 --- a/tests/baselines/reference/emitExtensionEmitCustomExtnamePathEscape.js +++ /dev/null @@ -1,8 +0,0 @@ -//// [0.ts] -export default 1 - - -//// [index.js] -"use strict"; -exports.__esModule = true; -exports["default"] = 1; diff --git a/tests/baselines/reference/emitExtensionOptionsInvalidChars.errors.txt b/tests/baselines/reference/emitExtensionOptionsInvalidChars.errors.txt new file mode 100644 index 0000000000000..7fc6947d78253 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsInvalidChars.errors.txt @@ -0,0 +1,11 @@ +error TS6509: emitExtension contains invalid chars + + +!!! error TS6509: emitExtension contains invalid chars +==== tests/cases/compiler/0.ts (0 errors) ==== + export default 1 + +==== tests/cases/compiler/1.ts (0 errors) ==== + import x from './0' + x + 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionOptionsInvalidChars.symbols b/tests/baselines/reference/emitExtensionOptionsInvalidChars.symbols new file mode 100644 index 0000000000000..6aa09396d3d29 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsInvalidChars.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : Symbol(x, Decl(1.ts, 0, 6)) + +x + 1 +>x : Symbol(x, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionOptionsInvalidChars.types b/tests/baselines/reference/emitExtensionOptionsInvalidChars.types new file mode 100644 index 0000000000000..a00a4fa80ddc6 --- /dev/null +++ b/tests/baselines/reference/emitExtensionOptionsInvalidChars.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/0.ts === +export default 1 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import x from './0' +>x : 1 + +x + 1 +>x + 1 : number +>x : 1 +>1 : 1 + From 9a6b88f4b55e80e7238e8514c75aa4493fdf22ea Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 11:56:40 +0800 Subject: [PATCH 13/30] test: add test for resolve custom ext to ts file --- .../emitExtensionResolveExtToTSFile.js | 19 +++++++++++++++++++ .../emitExtensionResolveExtToTSFile.symbols | 10 ++++++++++ .../emitExtensionResolveExtToTSFile.types | 12 ++++++++++++ .../emitExtensionResolveExtToTSFile.ts | 8 ++++++++ 4 files changed, 49 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionResolveExtToTSFile.js create mode 100644 tests/baselines/reference/emitExtensionResolveExtToTSFile.symbols create mode 100644 tests/baselines/reference/emitExtensionResolveExtToTSFile.types create mode 100644 tests/cases/compiler/emitExtensionResolveExtToTSFile.ts diff --git a/tests/baselines/reference/emitExtensionResolveExtToTSFile.js b/tests/baselines/reference/emitExtensionResolveExtToTSFile.js new file mode 100644 index 0000000000000..bd5700a332e87 --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveExtToTSFile.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/emitExtensionResolveExtToTSFile.ts] //// + +//// [0.ts] +export default 0 + +//// [1.ts] +import value from './0.mjs' +value + 1 + + +//// [0.mjs] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +//// [1.mjs] +"use strict"; +exports.__esModule = true; +var _0_mjs_1 = require("./0.mjs"); +_0_mjs_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionResolveExtToTSFile.symbols b/tests/baselines/reference/emitExtensionResolveExtToTSFile.symbols new file mode 100644 index 0000000000000..941e79f112989 --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveExtToTSFile.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import value from './0.mjs' +>value : Symbol(value, Decl(1.ts, 0, 6)) + +value + 1 +>value : Symbol(value, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionResolveExtToTSFile.types b/tests/baselines/reference/emitExtensionResolveExtToTSFile.types new file mode 100644 index 0000000000000..58225b7dd313e --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveExtToTSFile.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import value from './0.mjs' +>value : 0 + +value + 1 +>value + 1 : number +>value : 0 +>1 : 1 + diff --git a/tests/cases/compiler/emitExtensionResolveExtToTSFile.ts b/tests/cases/compiler/emitExtensionResolveExtToTSFile.ts new file mode 100644 index 0000000000000..95c594e17df07 --- /dev/null +++ b/tests/cases/compiler/emitExtensionResolveExtToTSFile.ts @@ -0,0 +1,8 @@ +// @emitExtension: .mjs + +// @Filename: 0.ts +export default 0 + +// @Filename: 1.ts +import value from './0.mjs' +value + 1 From 24449749e1bbaca7950d96c03befeb452be10f4f Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:05:41 +0800 Subject: [PATCH 14/30] test: add test for deno case import --- .../reference/emitExtensionResolveTSFile.js | 21 +++++++++++++++++++ .../emitExtensionResolveTSFile.symbols | 11 ++++++++++ .../emitExtensionResolveTSFile.types | 13 ++++++++++++ .../compiler/emitExtensionResolveTSFile.ts | 10 +++++++++ 4 files changed, 55 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionResolveTSFile.js create mode 100644 tests/baselines/reference/emitExtensionResolveTSFile.symbols create mode 100644 tests/baselines/reference/emitExtensionResolveTSFile.types create mode 100644 tests/cases/compiler/emitExtensionResolveTSFile.ts diff --git a/tests/baselines/reference/emitExtensionResolveTSFile.js b/tests/baselines/reference/emitExtensionResolveTSFile.js new file mode 100644 index 0000000000000..40c7a96dc5049 --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveTSFile.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/emitExtensionResolveTSFile.ts] //// + +//// [0.ts] +// For the deno case +export default 0 + +//// [1.ts] +import num from './0.ts' +num + 1 + + +//// [0.ts] +"use strict"; +exports.__esModule = true; +// For the deno case +exports["default"] = 0; +//// [1.ts] +"use strict"; +exports.__esModule = true; +var _0_ts_1 = require("./0.ts"); +_0_ts_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionResolveTSFile.symbols b/tests/baselines/reference/emitExtensionResolveTSFile.symbols new file mode 100644 index 0000000000000..d69465f43b5bf --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveTSFile.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +num + 1 +>num : Symbol(num, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionResolveTSFile.types b/tests/baselines/reference/emitExtensionResolveTSFile.types new file mode 100644 index 0000000000000..b851a65aeeded --- /dev/null +++ b/tests/baselines/reference/emitExtensionResolveTSFile.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : 0 + +num + 1 +>num + 1 : number +>num : 0 +>1 : 1 + diff --git a/tests/cases/compiler/emitExtensionResolveTSFile.ts b/tests/cases/compiler/emitExtensionResolveTSFile.ts new file mode 100644 index 0000000000000..529be1c28641d --- /dev/null +++ b/tests/cases/compiler/emitExtensionResolveTSFile.ts @@ -0,0 +1,10 @@ +// @emitExtension: .ts +// @outDir: ../out/ + +// @Filename: 0.ts +// For the deno case +export default 0 + +// @Filename: 1.ts +import num from './0.ts' +num + 1 From f86fee034f76999800070e38b3a1052d05e38241 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:09:44 +0800 Subject: [PATCH 15/30] test: add test for non-deno case ts import --- ...mitExtensionRejectResolveTSFile.errors.txt | 13 ++++++++++++ .../emitExtensionRejectResolveTSFile.js | 21 +++++++++++++++++++ .../emitExtensionRejectResolveTSFile.symbols | 11 ++++++++++ .../emitExtensionRejectResolveTSFile.types | 13 ++++++++++++ .../emitExtensionRejectResolveTSFile.ts | 10 +++++++++ 5 files changed, 68 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt create mode 100644 tests/baselines/reference/emitExtensionRejectResolveTSFile.js create mode 100644 tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols create mode 100644 tests/baselines/reference/emitExtensionRejectResolveTSFile.types create mode 100644 tests/cases/compiler/emitExtensionRejectResolveTSFile.ts diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt new file mode 100644 index 0000000000000..e42abcf3017f0 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + // For the deno case + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + import num from './0.ts' + ~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. + num + 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.js b/tests/baselines/reference/emitExtensionRejectResolveTSFile.js new file mode 100644 index 0000000000000..380b5bceaedc6 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/emitExtensionRejectResolveTSFile.ts] //// + +//// [0.ts] +// For the deno case +export default 0 + +//// [1.ts] +import num from './0.ts' +num + 1 + + +//// [0.mjs] +"use strict"; +exports.__esModule = true; +// For the deno case +exports["default"] = 0; +//// [1.mjs] +"use strict"; +exports.__esModule = true; +var _0_ts_1 = require("./0.ts"); +_0_ts_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols b/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols new file mode 100644 index 0000000000000..d69465f43b5bf --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +num + 1 +>num : Symbol(num, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.types b/tests/baselines/reference/emitExtensionRejectResolveTSFile.types new file mode 100644 index 0000000000000..462864414fd02 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : any + +num + 1 +>num + 1 : any +>num : any +>1 : 1 + diff --git a/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts b/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts new file mode 100644 index 0000000000000..5c91ad354bc02 --- /dev/null +++ b/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts @@ -0,0 +1,10 @@ +// @emitExtension: .mjs +// @outDir: ../out/ + +// @Filename: 0.ts +// For the deno case +export default 0 + +// @Filename: 1.ts +import num from './0.ts' +num + 1 From e76c62c9380fd28c4207494760c5593fc2484a03 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:13:18 +0800 Subject: [PATCH 16/30] test: add test for mixed use of .ts and .tsx --- ...tensionRejectMixedResolveTSFile.errors.txt | 17 +++++++++++ .../emitExtensionRejectMixedResolveTSFile.js | 30 +++++++++++++++++++ ...tExtensionRejectMixedResolveTSFile.symbols | 19 ++++++++++++ ...mitExtensionRejectMixedResolveTSFile.types | 20 +++++++++++++ .../emitExtensionRejectMixedResolveTSFile.ts | 15 ++++++++++ 5 files changed, 101 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt create mode 100644 tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.js create mode 100644 tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.symbols create mode 100644 tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.types create mode 100644 tests/cases/compiler/emitExtensionRejectMixedResolveTSFile.ts diff --git a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt new file mode 100644 index 0000000000000..2e17b3ad98dd4 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + // For the deno case + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + import num from './0.ts' + ~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. + import num2 from './2.tsx' + num + num2 + +==== tests/cases/compiler/2.tsx (0 errors) ==== + export default 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.js b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.js new file mode 100644 index 0000000000000..fd53042178292 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/emitExtensionRejectMixedResolveTSFile.ts] //// + +//// [0.ts] +// For the deno case +export default 0 + +//// [1.ts] +import num from './0.ts' +import num2 from './2.tsx' +num + num2 + +//// [2.tsx] +export default 1 + + +//// [0.tsx] +"use strict"; +exports.__esModule = true; +// For the deno case +exports["default"] = 0; +//// [2.tsx] +"use strict"; +exports.__esModule = true; +exports["default"] = 1; +//// [1.tsx] +"use strict"; +exports.__esModule = true; +var _0_ts_1 = require("./0.ts"); +var _2_tsx_1 = require("./2.tsx"); +_0_ts_1["default"] + _2_tsx_1["default"]; diff --git a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.symbols b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.symbols new file mode 100644 index 0000000000000..ec9427ca8b594 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +import num2 from './2.tsx' +>num2 : Symbol(num2, Decl(1.ts, 1, 6)) + +num + num2 +>num : Symbol(num, Decl(1.ts, 0, 6)) +>num2 : Symbol(num2, Decl(1.ts, 1, 6)) + +=== tests/cases/compiler/2.tsx === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.types b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.types new file mode 100644 index 0000000000000..dcf9317b46d49 --- /dev/null +++ b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : any + +import num2 from './2.tsx' +>num2 : 1 + +num + num2 +>num + num2 : any +>num : any +>num2 : 1 + +=== tests/cases/compiler/2.tsx === +export default 1 +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/cases/compiler/emitExtensionRejectMixedResolveTSFile.ts b/tests/cases/compiler/emitExtensionRejectMixedResolveTSFile.ts new file mode 100644 index 0000000000000..70a88447c351f --- /dev/null +++ b/tests/cases/compiler/emitExtensionRejectMixedResolveTSFile.ts @@ -0,0 +1,15 @@ +// @emitExtension: .tsx +// @outDir: ../out/ +// @jsx: react + +// @Filename: 0.ts +// For the deno case +export default 0 + +// @Filename: 1.ts +import num from './0.ts' +import num2 from './2.tsx' +num + num2 + +// @Filename: 2.tsx +export default 1 From 8de5006f9388baa5329ab22993d65f69ac81fd64 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:28:08 +0800 Subject: [PATCH 17/30] chore: change diag message 2691 with emitExtension --- src/compiler/checker.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e0a1b115b109..f665e5afa20e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3053,7 +3053,12 @@ namespace ts { const tsExtension = tryExtractTSExtension(moduleReference); if (tsExtension) { const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; - error(errorNode, diag, tsExtension, removeExtension(moduleReference, tsExtension)); + let rightPath = removeExtension(moduleReference, tsExtension); + if (compilerOptions.emitExtension) { + // e.g.: Consider importing '{1}.mjs' instead. + rightPath += compilerOptions.emitExtension; + } + error(errorNode, diag, tsExtension, rightPath); } else if (!compilerOptions.resolveJsonModule && fileExtensionIs(moduleReference, Extension.Json) && From 84f7a6a96069ec91bbdcc9b98db001429fc93922 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:28:24 +0800 Subject: [PATCH 18/30] test: add test for diag message 2691 with emitExtension --- .../emitExtensionDiag2691.errors.txt | 13 ++++++++++++ .../reference/emitExtensionDiag2691.js | 21 +++++++++++++++++++ .../reference/emitExtensionDiag2691.symbols | 11 ++++++++++ .../reference/emitExtensionDiag2691.types | 13 ++++++++++++ ...tensionRejectMixedResolveTSFile.errors.txt | 4 ++-- ...mitExtensionRejectResolveTSFile.errors.txt | 4 ++-- tests/cases/compiler/emitExtensionDiag2691.ts | 9 ++++++++ 7 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/emitExtensionDiag2691.errors.txt create mode 100644 tests/baselines/reference/emitExtensionDiag2691.js create mode 100644 tests/baselines/reference/emitExtensionDiag2691.symbols create mode 100644 tests/baselines/reference/emitExtensionDiag2691.types create mode 100644 tests/cases/compiler/emitExtensionDiag2691.ts diff --git a/tests/baselines/reference/emitExtensionDiag2691.errors.txt b/tests/baselines/reference/emitExtensionDiag2691.errors.txt new file mode 100644 index 0000000000000..013bfd1eff326 --- /dev/null +++ b/tests/baselines/reference/emitExtensionDiag2691.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.mjs' instead. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + // For the deno case + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + import num from './0.ts' + ~~~~~~~~ +!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.mjs' instead. + num + 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionDiag2691.js b/tests/baselines/reference/emitExtensionDiag2691.js new file mode 100644 index 0000000000000..7240b61f2bec7 --- /dev/null +++ b/tests/baselines/reference/emitExtensionDiag2691.js @@ -0,0 +1,21 @@ +//// [tests/cases/compiler/emitExtensionDiag2691.ts] //// + +//// [0.ts] +// For the deno case +export default 0 + +//// [1.ts] +import num from './0.ts' +num + 1 + + +//// [0.mjs] +"use strict"; +exports.__esModule = true; +// For the deno case +exports["default"] = 0; +//// [1.mjs] +"use strict"; +exports.__esModule = true; +var _0_ts_1 = require("./0.ts"); +_0_ts_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionDiag2691.symbols b/tests/baselines/reference/emitExtensionDiag2691.symbols new file mode 100644 index 0000000000000..d69465f43b5bf --- /dev/null +++ b/tests/baselines/reference/emitExtensionDiag2691.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +num + 1 +>num : Symbol(num, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionDiag2691.types b/tests/baselines/reference/emitExtensionDiag2691.types new file mode 100644 index 0000000000000..462864414fd02 --- /dev/null +++ b/tests/baselines/reference/emitExtensionDiag2691.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/0.ts === +// For the deno case +No type information for this code.export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.ts' +>num : any + +num + 1 +>num + 1 : any +>num : any +>1 : 1 + diff --git a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt index 2e17b3ad98dd4..5c2a135561407 100644 --- a/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt +++ b/tests/baselines/reference/emitExtensionRejectMixedResolveTSFile.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. +tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.tsx' instead. ==== tests/cases/compiler/0.ts (0 errors) ==== @@ -8,7 +8,7 @@ tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a ==== tests/cases/compiler/1.ts (1 errors) ==== import num from './0.ts' ~~~~~~~~ -!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. +!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.tsx' instead. import num2 from './2.tsx' num + num2 diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt index e42abcf3017f0..013bfd1eff326 100644 --- a/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. +tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.mjs' instead. ==== tests/cases/compiler/0.ts (0 errors) ==== @@ -8,6 +8,6 @@ tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a ==== tests/cases/compiler/1.ts (1 errors) ==== import num from './0.ts' ~~~~~~~~ -!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0' instead. +!!! error TS2691: An import path cannot end with a '.ts' extension. Consider importing './0.mjs' instead. num + 1 \ No newline at end of file diff --git a/tests/cases/compiler/emitExtensionDiag2691.ts b/tests/cases/compiler/emitExtensionDiag2691.ts new file mode 100644 index 0000000000000..fc99f1a03a926 --- /dev/null +++ b/tests/cases/compiler/emitExtensionDiag2691.ts @@ -0,0 +1,9 @@ +// @emitExtension: .mjs + +// @Filename: 0.ts +// For the deno case +export default 0 + +// @Filename: 1.ts +import num from './0.ts' +num + 1 From 05a7cbe2bbeec596cd70019a9bf1d4913ee28720 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 15:37:39 +0800 Subject: [PATCH 19/30] test: add test case for extension name !== emitExtension --- ...mitExtensionRejectResolveTSFile.errors.txt | 1 - .../emitExtensionRejectResolveTSFile.js | 2 -- .../emitExtensionRejectResolveTSFile.symbols | 3 +-- .../emitExtensionRejectResolveTSFile.types | 3 +-- .../emitExtensionUnknownExtension.errors.txt | 12 ++++++++++++ .../emitExtensionUnknownExtension.js | 19 +++++++++++++++++++ .../emitExtensionUnknownExtension.symbols | 10 ++++++++++ .../emitExtensionUnknownExtension.types | 12 ++++++++++++ .../emitExtensionRejectResolveTSFile.ts | 1 - .../compiler/emitExtensionUnknownExtension.ts | 8 ++++++++ 10 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/emitExtensionUnknownExtension.errors.txt create mode 100644 tests/baselines/reference/emitExtensionUnknownExtension.js create mode 100644 tests/baselines/reference/emitExtensionUnknownExtension.symbols create mode 100644 tests/baselines/reference/emitExtensionUnknownExtension.types create mode 100644 tests/cases/compiler/emitExtensionUnknownExtension.ts diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt index 013bfd1eff326..5b7e101de3def 100644 --- a/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.errors.txt @@ -2,7 +2,6 @@ tests/cases/compiler/1.ts(1,17): error TS2691: An import path cannot end with a ==== tests/cases/compiler/0.ts (0 errors) ==== - // For the deno case export default 0 ==== tests/cases/compiler/1.ts (1 errors) ==== diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.js b/tests/baselines/reference/emitExtensionRejectResolveTSFile.js index 380b5bceaedc6..e95f89638d53e 100644 --- a/tests/baselines/reference/emitExtensionRejectResolveTSFile.js +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.js @@ -1,7 +1,6 @@ //// [tests/cases/compiler/emitExtensionRejectResolveTSFile.ts] //// //// [0.ts] -// For the deno case export default 0 //// [1.ts] @@ -12,7 +11,6 @@ num + 1 //// [0.mjs] "use strict"; exports.__esModule = true; -// For the deno case exports["default"] = 0; //// [1.mjs] "use strict"; diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols b/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols index d69465f43b5bf..c088de76473ed 100644 --- a/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.symbols @@ -1,6 +1,5 @@ === tests/cases/compiler/0.ts === -// For the deno case -No type information for this code.export default 0 +export default 0 No type information for this code. No type information for this code.=== tests/cases/compiler/1.ts === import num from './0.ts' diff --git a/tests/baselines/reference/emitExtensionRejectResolveTSFile.types b/tests/baselines/reference/emitExtensionRejectResolveTSFile.types index 462864414fd02..608eded70d200 100644 --- a/tests/baselines/reference/emitExtensionRejectResolveTSFile.types +++ b/tests/baselines/reference/emitExtensionRejectResolveTSFile.types @@ -1,6 +1,5 @@ === tests/cases/compiler/0.ts === -// For the deno case -No type information for this code.export default 0 +export default 0 No type information for this code. No type information for this code.=== tests/cases/compiler/1.ts === import num from './0.ts' diff --git a/tests/baselines/reference/emitExtensionUnknownExtension.errors.txt b/tests/baselines/reference/emitExtensionUnknownExtension.errors.txt new file mode 100644 index 0000000000000..ca921037ad4b3 --- /dev/null +++ b/tests/baselines/reference/emitExtensionUnknownExtension.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/1.ts(1,17): error TS2307: Cannot find module './0.cjs'. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + import num from './0.cjs' + ~~~~~~~~~ +!!! error TS2307: Cannot find module './0.cjs'. + num + 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionUnknownExtension.js b/tests/baselines/reference/emitExtensionUnknownExtension.js new file mode 100644 index 0000000000000..2aad2e7b842e6 --- /dev/null +++ b/tests/baselines/reference/emitExtensionUnknownExtension.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/emitExtensionUnknownExtension.ts] //// + +//// [0.ts] +export default 0 + +//// [1.ts] +import num from './0.cjs' +num + 1 + + +//// [0.mjs] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +//// [1.mjs] +"use strict"; +exports.__esModule = true; +var _0_cjs_1 = require("./0.cjs"); +_0_cjs_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionUnknownExtension.symbols b/tests/baselines/reference/emitExtensionUnknownExtension.symbols new file mode 100644 index 0000000000000..ca2d67e4a4eaa --- /dev/null +++ b/tests/baselines/reference/emitExtensionUnknownExtension.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.cjs' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +num + 1 +>num : Symbol(num, Decl(1.ts, 0, 6)) + diff --git a/tests/baselines/reference/emitExtensionUnknownExtension.types b/tests/baselines/reference/emitExtensionUnknownExtension.types new file mode 100644 index 0000000000000..6dfc32fca4662 --- /dev/null +++ b/tests/baselines/reference/emitExtensionUnknownExtension.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.cjs' +>num : any + +num + 1 +>num + 1 : any +>num : any +>1 : 1 + diff --git a/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts b/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts index 5c91ad354bc02..096ea063dfda1 100644 --- a/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts +++ b/tests/cases/compiler/emitExtensionRejectResolveTSFile.ts @@ -2,7 +2,6 @@ // @outDir: ../out/ // @Filename: 0.ts -// For the deno case export default 0 // @Filename: 1.ts diff --git a/tests/cases/compiler/emitExtensionUnknownExtension.ts b/tests/cases/compiler/emitExtensionUnknownExtension.ts new file mode 100644 index 0000000000000..eb52432bd5559 --- /dev/null +++ b/tests/cases/compiler/emitExtensionUnknownExtension.ts @@ -0,0 +1,8 @@ +// @emitExtension: .mjs + +// @Filename: 0.ts +export default 0 + +// @Filename: 1.ts +import num from './0.cjs' +num + 1 From bcad885845c3ef455d2b1d40692e169596e08e3f Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 17:28:44 +0800 Subject: [PATCH 20/30] feat: add new flag noImplicitExtensionName --- src/compiler/commandLineParser.ts | 10 +++++++++- src/compiler/diagnosticMessages.json | 8 ++++++++ src/compiler/types.ts | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 5bd2d0df97c40..7c416b510bb3f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1005,7 +1005,15 @@ namespace ts { description: Diagnostics.Specify_the_extension_name_of_the_emitted_files, showInSimplifiedHelpView: true, affectsEmit: true, - } + }, + { + name: "noImplicitExtensionName", + type: "boolean", + affectsSemanticDiagnostics: true, + showInSimplifiedHelpView: true, + category: Diagnostics.Additional_Checks, + description: Diagnostics.Report_error_for_implicit_extension_name, + }, ]; /* @internal */ diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7155df268fe4a..9df55bdd4df06 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4547,6 +4547,14 @@ "category": "Error", "code": 6509 }, + "Report error for implicit extension name.": { + "category": "Message", + "code": 6510 + }, + "Import with an implicit extension name is not allowed. Try to import from '{0}{1}' instead.": { + "category": "Error", + "code": 6511 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 410a4aef23ece..0b64051a7f533 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5173,6 +5173,7 @@ namespace ts { noErrorTruncation?: boolean; noFallthroughCasesInSwitch?: boolean; noImplicitAny?: boolean; // Always combine with strict property + noImplicitExtensionName?: boolean noImplicitReturns?: boolean; noImplicitThis?: boolean; // Always combine with strict property noStrictGenericChecks?: boolean; From 53a13b297ba9f78014512ddd1c25ca9a61129d0b Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 17:29:01 +0800 Subject: [PATCH 21/30] test: accept baseline for new option --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../noImplicitExtensionName/tsconfig.json | 5 +++++ .../tsConfig/Default initialized TSConfig/tsconfig.json | 1 + .../Initialized TSConfig with advanced options/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../Initialized TSConfig with files options/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + 12 files changed, 16 insertions(+) create mode 100644 tests/baselines/reference/showConfig/Shows tsconfig for single option/noImplicitExtensionName/tsconfig.json diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 76e9f4d444de6..f715b9336228d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2687,6 +2687,7 @@ declare namespace ts { noErrorTruncation?: boolean; noFallthroughCasesInSwitch?: boolean; noImplicitAny?: boolean; + noImplicitExtensionName?: boolean; noImplicitReturns?: boolean; noImplicitThis?: boolean; noStrictGenericChecks?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ec735ccd1dd9a..dc114da2eeacd 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2687,6 +2687,7 @@ declare namespace ts { noErrorTruncation?: boolean; noFallthroughCasesInSwitch?: boolean; noImplicitAny?: boolean; + noImplicitExtensionName?: boolean; noImplicitReturns?: boolean; noImplicitThis?: boolean; noStrictGenericChecks?: boolean; diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/noImplicitExtensionName/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/noImplicitExtensionName/tsconfig.json new file mode 100644 index 0000000000000..178987a00f2c9 --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/noImplicitExtensionName/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "noImplicitExtensionName": true + } +} diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 6d304c1439246..0e92eaf0eb34e 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json index db8c3d3f6cf58..efc97d9a6844b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index cb778e5b729b6..1cbe9031c5e95 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index c8ec6a21b68b3..db5c681dc4c94 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 69f7ef1ccd768..ab4b3286eb96c 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 892f7115dc2cb..86f78e4566661 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 6d304c1439246..0e92eaf0eb34e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index ba56fd44d288a..1a5dba930f3d7 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 10b61f3692eab..d79d8e9c14ac2 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -38,6 +38,7 @@ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ From 715fc61047343f59cfe8ab33dc545817d33688a4 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 18:54:03 +0800 Subject: [PATCH 22/30] feat: add new check rule for noImplicitExtensionName --- src/compiler/checker.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f665e5afa20e4..a1bef1c89206c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33718,16 +33718,23 @@ namespace ts { Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module); return false; } - if (inAmbientExternalModule && isExternalModuleNameRelative(moduleName.text)) { - // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration - // no need to do this again. - if (!isTopLevelInExternalModuleAugmentation(node)) { - // TypeScript 1.0 spec (April 2013): 12.1.6 - // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference - // other external modules only through top - level external module names. - // Relative external module names are not permitted. - error(node, Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); - return false; + if (isExternalModuleNameRelative(moduleName.text)) { + if (inAmbientExternalModule) { + // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration + // no need to do this again. + if (!isTopLevelInExternalModuleAugmentation(node)) { + // TypeScript 1.0 spec (April 2013): 12.1.6 + // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference + // other external modules only through top - level external module names. + // Relative external module names are not permitted. + error(node, Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); + return false; + } + } else if (compilerOptions.noImplicitExtensionName) { + const extensionLess = removeFileExtension(moduleName.text, compilerOptions); + if (extensionLess === moduleName.text) { + error(node, Diagnostics.Import_with_an_implicit_extension_name_is_not_allowed_Try_to_import_from_0_1_instead, extensionLess, compilerOptions.emitExtension || ".js"); + } } } return true; From b2b57f8b615a9e8fadfe47346f4ff48c78d146e3 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 18:54:26 +0800 Subject: [PATCH 23/30] test: add test for noImplicitExtensionName --- .../noImplicitExtensionNameError.errors.txt | 15 +++++++++++ .../reference/noImplicitExtensionNameError.js | 25 +++++++++++++++++ .../noImplicitExtensionNameError.symbols | 16 +++++++++++ .../noImplicitExtensionNameError.types | 17 ++++++++++++ ...mplicitExtensionNameNonRelative.errors.txt | 19 +++++++++++++ .../noImplicitExtensionNameNonRelative.js | 27 +++++++++++++++++++ ...noImplicitExtensionNameNonRelative.symbols | 17 ++++++++++++ .../noImplicitExtensionNameNonRelative.types | 18 +++++++++++++ ...tExtensionNameWithEmitExtension.errors.txt | 14 ++++++++++ ...oImplicitExtensionNameWithEmitExtension.js | 23 ++++++++++++++++ ...icitExtensionNameWithEmitExtension.symbols | 15 +++++++++++ ...plicitExtensionNameWithEmitExtension.types | 16 +++++++++++ .../compiler/noImplicitExtensionNameError.ts | 11 ++++++++ .../noImplicitExtensionNameNonRelative.ts | 12 +++++++++ ...oImplicitExtensionNameWithEmitExtension.ts | 11 ++++++++ 15 files changed, 256 insertions(+) create mode 100644 tests/baselines/reference/noImplicitExtensionNameError.errors.txt create mode 100644 tests/baselines/reference/noImplicitExtensionNameError.js create mode 100644 tests/baselines/reference/noImplicitExtensionNameError.symbols create mode 100644 tests/baselines/reference/noImplicitExtensionNameError.types create mode 100644 tests/baselines/reference/noImplicitExtensionNameNonRelative.errors.txt create mode 100644 tests/baselines/reference/noImplicitExtensionNameNonRelative.js create mode 100644 tests/baselines/reference/noImplicitExtensionNameNonRelative.symbols create mode 100644 tests/baselines/reference/noImplicitExtensionNameNonRelative.types create mode 100644 tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.errors.txt create mode 100644 tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.js create mode 100644 tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.symbols create mode 100644 tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.types create mode 100644 tests/cases/compiler/noImplicitExtensionNameError.ts create mode 100644 tests/cases/compiler/noImplicitExtensionNameNonRelative.ts create mode 100644 tests/cases/compiler/noImplicitExtensionNameWithEmitExtension.ts diff --git a/tests/baselines/reference/noImplicitExtensionNameError.errors.txt b/tests/baselines/reference/noImplicitExtensionNameError.errors.txt new file mode 100644 index 0000000000000..825dd6c8504b9 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameError.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/1.ts(2,1): error TS6511: Import with an implicit extension name is not allowed. Try to import from './0.js' instead. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + // Should be error + import num from './0' + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS6511: Import with an implicit extension name is not allowed. Try to import from './0.js' instead. + // Should be okay + import num2 from './0.js' + num + num2 + \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitExtensionNameError.js b/tests/baselines/reference/noImplicitExtensionNameError.js new file mode 100644 index 0000000000000..ce3deb1c2201c --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameError.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/noImplicitExtensionNameError.ts] //// + +//// [0.ts] +export default 0 + +//// [1.ts] +// Should be error +import num from './0' +// Should be okay +import num2 from './0.js' +num + num2 + + +//// [0.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +//// [1.js] +"use strict"; +exports.__esModule = true; +// Should be error +var _0_1 = require("./0"); +// Should be okay +var _0_js_1 = require("./0.js"); +_0_1["default"] + _0_js_1["default"]; diff --git a/tests/baselines/reference/noImplicitExtensionNameError.symbols b/tests/baselines/reference/noImplicitExtensionNameError.symbols new file mode 100644 index 0000000000000..b88cddd70441e --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameError.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +// Should be error +import num from './0' +>num : Symbol(num, Decl(1.ts, 1, 6)) + +// Should be okay +import num2 from './0.js' +>num2 : Symbol(num2, Decl(1.ts, 3, 6)) + +num + num2 +>num : Symbol(num, Decl(1.ts, 1, 6)) +>num2 : Symbol(num2, Decl(1.ts, 3, 6)) + diff --git a/tests/baselines/reference/noImplicitExtensionNameError.types b/tests/baselines/reference/noImplicitExtensionNameError.types new file mode 100644 index 0000000000000..2be25dbee6de0 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameError.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +// Should be error +import num from './0' +>num : 0 + +// Should be okay +import num2 from './0.js' +>num2 : 0 + +num + num2 +>num + num2 : number +>num : 0 +>num2 : 0 + diff --git a/tests/baselines/reference/noImplicitExtensionNameNonRelative.errors.txt b/tests/baselines/reference/noImplicitExtensionNameNonRelative.errors.txt new file mode 100644 index 0000000000000..b8648fa5afd27 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameNonRelative.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/1.ts(4,17): error TS2307: Cannot find module 'fs/my_file'. +tests/cases/compiler/1.ts(5,18): error TS2307: Cannot find module 'fs/my_file.js'. + + +==== tests/cases/compiler/fs/my_file.ts (0 errors) ==== + export default 0 + +==== tests/cases/compiler/1.ts (2 errors) ==== + // Should both be okay. + // This check is not applied to non-relative import. + // e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports + import num from 'fs/my_file' + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'fs/my_file'. + import num2 from 'fs/my_file.js' + ~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'fs/my_file.js'. + num + num2 + \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitExtensionNameNonRelative.js b/tests/baselines/reference/noImplicitExtensionNameNonRelative.js new file mode 100644 index 0000000000000..f96038d32a0a1 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameNonRelative.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/noImplicitExtensionNameNonRelative.ts] //// + +//// [my_file.ts] +export default 0 + +//// [1.ts] +// Should both be okay. +// This check is not applied to non-relative import. +// e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports +import num from 'fs/my_file' +import num2 from 'fs/my_file.js' +num + num2 + + +//// [my_file.js] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +//// [1.js] +"use strict"; +exports.__esModule = true; +// Should both be okay. +// This check is not applied to non-relative import. +// e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports +var my_file_1 = require("fs/my_file"); +var my_file_js_1 = require("fs/my_file.js"); +my_file_1["default"] + my_file_js_1["default"]; diff --git a/tests/baselines/reference/noImplicitExtensionNameNonRelative.symbols b/tests/baselines/reference/noImplicitExtensionNameNonRelative.symbols new file mode 100644 index 0000000000000..83a7f9c2f2db8 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameNonRelative.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/fs/my_file.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +// Should both be okay. +// This check is not applied to non-relative import. +// e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports +import num from 'fs/my_file' +>num : Symbol(num, Decl(1.ts, 3, 6)) + +import num2 from 'fs/my_file.js' +>num2 : Symbol(num2, Decl(1.ts, 4, 6)) + +num + num2 +>num : Symbol(num, Decl(1.ts, 3, 6)) +>num2 : Symbol(num2, Decl(1.ts, 4, 6)) + diff --git a/tests/baselines/reference/noImplicitExtensionNameNonRelative.types b/tests/baselines/reference/noImplicitExtensionNameNonRelative.types new file mode 100644 index 0000000000000..6e5696caf7799 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameNonRelative.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/fs/my_file.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +// Should both be okay. +// This check is not applied to non-relative import. +// e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports +import num from 'fs/my_file' +>num : any + +import num2 from 'fs/my_file.js' +>num2 : any + +num + num2 +>num + num2 : any +>num : any +>num2 : any + diff --git a/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.errors.txt b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.errors.txt new file mode 100644 index 0000000000000..d45a8b1133ea3 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/1.ts(3,1): error TS6511: Import with an implicit extension name is not allowed. Try to import from './0.mjs' instead. + + +==== tests/cases/compiler/0.ts (0 errors) ==== + export default 0 + +==== tests/cases/compiler/1.ts (1 errors) ==== + import num from './0.mjs' + // should be error + import num2 from './0' + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS6511: Import with an implicit extension name is not allowed. Try to import from './0.mjs' instead. + num + num2 + \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.js b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.js new file mode 100644 index 0000000000000..6af322ece93b0 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/noImplicitExtensionNameWithEmitExtension.ts] //// + +//// [0.ts] +export default 0 + +//// [1.ts] +import num from './0.mjs' +// should be error +import num2 from './0' +num + num2 + + +//// [0.mjs] +"use strict"; +exports.__esModule = true; +exports["default"] = 0; +//// [1.mjs] +"use strict"; +exports.__esModule = true; +var _0_mjs_1 = require("./0.mjs"); +// should be error +var _0_1 = require("./0"); +_0_mjs_1["default"] + _0_1["default"]; diff --git a/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.symbols b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.symbols new file mode 100644 index 0000000000000..1af3b466f8b3d --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.mjs' +>num : Symbol(num, Decl(1.ts, 0, 6)) + +// should be error +import num2 from './0' +>num2 : Symbol(num2, Decl(1.ts, 2, 6)) + +num + num2 +>num : Symbol(num, Decl(1.ts, 0, 6)) +>num2 : Symbol(num2, Decl(1.ts, 2, 6)) + diff --git a/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.types b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.types new file mode 100644 index 0000000000000..e108d98a7fe03 --- /dev/null +++ b/tests/baselines/reference/noImplicitExtensionNameWithEmitExtension.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/0.ts === +export default 0 +No type information for this code. +No type information for this code.=== tests/cases/compiler/1.ts === +import num from './0.mjs' +>num : 0 + +// should be error +import num2 from './0' +>num2 : 0 + +num + num2 +>num + num2 : number +>num : 0 +>num2 : 0 + diff --git a/tests/cases/compiler/noImplicitExtensionNameError.ts b/tests/cases/compiler/noImplicitExtensionNameError.ts new file mode 100644 index 0000000000000..074f1ee5cc412 --- /dev/null +++ b/tests/cases/compiler/noImplicitExtensionNameError.ts @@ -0,0 +1,11 @@ +// @noImplicitExtensionName: true + +// @Filename: 0.ts +export default 0 + +// @Filename: 1.ts +// Should be error +import num from './0' +// Should be okay +import num2 from './0.js' +num + num2 diff --git a/tests/cases/compiler/noImplicitExtensionNameNonRelative.ts b/tests/cases/compiler/noImplicitExtensionNameNonRelative.ts new file mode 100644 index 0000000000000..968d32487b8d2 --- /dev/null +++ b/tests/cases/compiler/noImplicitExtensionNameNonRelative.ts @@ -0,0 +1,12 @@ +// @noImplicitExtensionName: true + +// @Filename: fs/my_file.ts +export default 0 + +// @Filename: 1.ts +// Should both be okay. +// This check is not applied to non-relative import. +// e.g. Node's ESModule support https://nodejs.org/api/esm.html#esm_package_exports +import num from 'fs/my_file' +import num2 from 'fs/my_file.js' +num + num2 diff --git a/tests/cases/compiler/noImplicitExtensionNameWithEmitExtension.ts b/tests/cases/compiler/noImplicitExtensionNameWithEmitExtension.ts new file mode 100644 index 0000000000000..c62101c909cc5 --- /dev/null +++ b/tests/cases/compiler/noImplicitExtensionNameWithEmitExtension.ts @@ -0,0 +1,11 @@ +// @noImplicitExtensionName: true +// @emitExtension: .mjs + +// @Filename: 0.ts +export default 0 + +// @Filename: 1.ts +import num from './0.mjs' +// should be error +import num2 from './0' +num + num2 From 9bf30f18ef74961e745e8c162ac295a2f487aa96 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 19:14:02 +0800 Subject: [PATCH 24/30] style: fix linter error --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a1bef1c89206c..c17a2d3c5e39e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33730,7 +33730,8 @@ namespace ts { error(node, Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); return false; } - } else if (compilerOptions.noImplicitExtensionName) { + } + else if (compilerOptions.noImplicitExtensionName) { const extensionLess = removeFileExtension(moduleName.text, compilerOptions); if (extensionLess === moduleName.text) { error(node, Diagnostics.Import_with_an_implicit_extension_name_is_not_allowed_Try_to_import_from_0_1_instead, extensionLess, compilerOptions.emitExtension || ".js"); From 67622bc7023e70fdf46eb2348940959947b705b0 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 22:44:14 +0800 Subject: [PATCH 25/30] chore: set emitExtension as affectsSemanticDiagnostics --- src/compiler/commandLineParser.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7c416b510bb3f..c58bb34b1e29e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1001,7 +1001,8 @@ namespace ts { name: "emitExtension", type: "string", category: Diagnostics.Basic_Options, - + // will effect noImplicitExtensionName + affectsSemanticDiagnostics: true, description: Diagnostics.Specify_the_extension_name_of_the_emitted_files, showInSimplifiedHelpView: true, affectsEmit: true, From b8f5f34e2bbcc99f3d322d51d2fbda15d68cd0c2 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 22:44:43 +0800 Subject: [PATCH 26/30] feat: no emit on emitExtension error --- src/compiler/program.ts | 2 ++ tests/baselines/reference/emitExtensionOptionsDTS.js | 12 ------------ .../reference/emitExtensionOptionsStartWithNonDot.js | 10 ---------- 3 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 tests/baselines/reference/emitExtensionOptionsDTS.js delete mode 100644 tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 61a5a9fdc6ef3..cf031a856ae79 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2968,12 +2968,14 @@ namespace ts { if (options.emitExtension) { if (!startsWith(options.emitExtension, ".")) { createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_must_start_with_but_here_has_0_try_to_replace_it_with_0, options.emitExtension); + options.noEmitOnError = true; } if (options.emitExtension !== Extension.Jsx && options.jsx === JsxEmit.Preserve) { createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_can_only_be_jsx_when_JSX_is_set_to_preserve, options.emitExtension); } if (options.emitExtension === Extension.Dts) { createOptionValueDiagnostic("emitExtension", Diagnostics.emitExtension_can_not_be_d_ts, options.emitExtension); + options.noEmitOnError = true; } // To keep it simple at the first time, // just accept . - a-z A-Z 0-9 diff --git a/tests/baselines/reference/emitExtensionOptionsDTS.js b/tests/baselines/reference/emitExtensionOptionsDTS.js deleted file mode 100644 index 3d748b0e1a1a8..0000000000000 --- a/tests/baselines/reference/emitExtensionOptionsDTS.js +++ /dev/null @@ -1,12 +0,0 @@ -//// [emitExtensionOptionsDTS.ts] -// @Filename 1.ts -// emitExtension can not be ".d.ts" -export default 0 - - -//// [emitExtensionOptionsDTS.d.ts] -"use strict"; -exports.__esModule = true; -// @Filename 1.ts -// emitExtension can not be ".d.ts" -exports["default"] = 0; diff --git a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js b/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js deleted file mode 100644 index 4f1b90ab4d6a4..0000000000000 --- a/tests/baselines/reference/emitExtensionOptionsStartWithNonDot.js +++ /dev/null @@ -1,10 +0,0 @@ -//// [0.ts] -// emitExtension must start with '.' -export default 0 - - -//// [0mjs] -"use strict"; -exports.__esModule = true; -// emitExtension must start with '.' -exports["default"] = 0; From 4cd59994109550184614fa46cff1ba38c218e54c Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 22:48:12 +0800 Subject: [PATCH 27/30] feat: supress error 2961 when emitExtension is .ts --- src/compiler/checker.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c17a2d3c5e39e..53ccae2f67d72 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3052,13 +3052,18 @@ namespace ts { else { const tsExtension = tryExtractTSExtension(moduleReference); if (tsExtension) { - const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; - let rightPath = removeExtension(moduleReference, tsExtension); - if (compilerOptions.emitExtension) { - // e.g.: Consider importing '{1}.mjs' instead. - rightPath += compilerOptions.emitExtension; + if (compilerOptions.emitExtension === tsExtension) { + error(errorNode, moduleNotFoundError, moduleReference); + } + else { + const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; + let rightPath = removeExtension(moduleReference, tsExtension); + if (compilerOptions.emitExtension) { + // e.g.: Consider importing '{1}.mjs' instead. + rightPath += compilerOptions.emitExtension; + } + error(errorNode, diag, tsExtension, rightPath); } - error(errorNode, diag, tsExtension, rightPath); } else if (!compilerOptions.resolveJsonModule && fileExtensionIs(moduleReference, Extension.Json) && @@ -33731,10 +33736,12 @@ namespace ts { return false; } } - else if (compilerOptions.noImplicitExtensionName) { + // Skip noImplicitExtensionName check for files in node_modules + else if (compilerOptions.noImplicitExtensionName && !getSourceFileOfNode(node).fileName.includes("node_modules")) { const extensionLess = removeFileExtension(moduleName.text, compilerOptions); if (extensionLess === moduleName.text) { error(node, Diagnostics.Import_with_an_implicit_extension_name_is_not_allowed_Try_to_import_from_0_1_instead, extensionLess, compilerOptions.emitExtension || ".js"); + return false; } } } From e8dd540b54d58a13c115ea9d12587b4137cd4b32 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Sun, 15 Dec 2019 22:48:22 +0800 Subject: [PATCH 28/30] test: add test for supress error 2961 when emitExtension is .ts --- .../reference/emitExtensionTSNotFound.errors.txt | 10 ++++++++++ tests/baselines/reference/emitExtensionTSNotFound.js | 12 ++++++++++++ .../reference/emitExtensionTSNotFound.symbols | 8 ++++++++ .../reference/emitExtensionTSNotFound.types | 10 ++++++++++ tests/cases/compiler/emitExtensionTSNotFound.ts | 7 +++++++ 5 files changed, 47 insertions(+) create mode 100644 tests/baselines/reference/emitExtensionTSNotFound.errors.txt create mode 100644 tests/baselines/reference/emitExtensionTSNotFound.js create mode 100644 tests/baselines/reference/emitExtensionTSNotFound.symbols create mode 100644 tests/baselines/reference/emitExtensionTSNotFound.types create mode 100644 tests/cases/compiler/emitExtensionTSNotFound.ts diff --git a/tests/baselines/reference/emitExtensionTSNotFound.errors.txt b/tests/baselines/reference/emitExtensionTSNotFound.errors.txt new file mode 100644 index 0000000000000..7ac1a4ac4d0bc --- /dev/null +++ b/tests/baselines/reference/emitExtensionTSNotFound.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/0.ts(2,17): error TS2307: Cannot find module './1.ts'. + + +==== tests/cases/compiler/0.ts (1 errors) ==== + // should not emit error 2961 + import num from './1.ts' + ~~~~~~~~ +!!! error TS2307: Cannot find module './1.ts'. + num + 1 + \ No newline at end of file diff --git a/tests/baselines/reference/emitExtensionTSNotFound.js b/tests/baselines/reference/emitExtensionTSNotFound.js new file mode 100644 index 0000000000000..c5b997eca9808 --- /dev/null +++ b/tests/baselines/reference/emitExtensionTSNotFound.js @@ -0,0 +1,12 @@ +//// [0.ts] +// should not emit error 2961 +import num from './1.ts' +num + 1 + + +//// [0.ts] +"use strict"; +exports.__esModule = true; +// should not emit error 2961 +var _1_ts_1 = require("./1.ts"); +_1_ts_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionTSNotFound.symbols b/tests/baselines/reference/emitExtensionTSNotFound.symbols new file mode 100644 index 0000000000000..f694e348354a2 --- /dev/null +++ b/tests/baselines/reference/emitExtensionTSNotFound.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/0.ts === +// should not emit error 2961 +import num from './1.ts' +>num : Symbol(num, Decl(0.ts, 1, 6)) + +num + 1 +>num : Symbol(num, Decl(0.ts, 1, 6)) + diff --git a/tests/baselines/reference/emitExtensionTSNotFound.types b/tests/baselines/reference/emitExtensionTSNotFound.types new file mode 100644 index 0000000000000..83e3ecddf8074 --- /dev/null +++ b/tests/baselines/reference/emitExtensionTSNotFound.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/0.ts === +// should not emit error 2961 +import num from './1.ts' +>num : any + +num + 1 +>num + 1 : any +>num : any +>1 : 1 + diff --git a/tests/cases/compiler/emitExtensionTSNotFound.ts b/tests/cases/compiler/emitExtensionTSNotFound.ts new file mode 100644 index 0000000000000..15063f9cb4c37 --- /dev/null +++ b/tests/cases/compiler/emitExtensionTSNotFound.ts @@ -0,0 +1,7 @@ +// @emitExtension: .ts +// @outDir: ./out/ + +// @Filename: 0.ts +// should not emit error 2961 +import num from './1.ts' +num + 1 From 7bb645718c27832076e892303e24ba00fb87ad1a Mon Sep 17 00:00:00 2001 From: Jack Works Date: Fri, 13 Mar 2020 11:55:37 +0800 Subject: [PATCH 29/30] test: accept new baseline --- ...how-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js | 1 + .../declarationDir-is-specified.js | 1 + .../when-outDir-and-declarationDir-is-specified.js | 1 + .../when-outDir-is-specified.js | 1 + .../with-outFile.js | 1 + .../without-outDir-or-outFile-is-specified.js | 1 + 6 files changed, 6 insertions(+) diff --git a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js index 072ebe6107dff..63e61057d2a9d 100644 --- a/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js +++ b/tests/baselines/reference/tsc/runWithoutArgs/initial-build/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js @@ -45,6 +45,7 @@ Options: --types Type declaration files to be included in compilation. --esModuleInterop Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. --emitExtension Specify the extension name of the emitted files. + --noImplicitExtensionName Report error for implicit extension name. @ Insert command line options and files from a file. exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js index 310ece479e6ea..ef1e5e7b04cef 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js @@ -59,6 +59,7 @@ interface Array { length: number; [n: number]: T; } // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js index 9eac42aa21b2a..ae5e11ddf7e9a 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js @@ -59,6 +59,7 @@ interface Array { length: number; [n: number]: T; } // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js index b6e25f2ccfff9..bde47e262c9e7 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js @@ -59,6 +59,7 @@ interface Array { length: number; [n: number]: T; } // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js index 7aae8c1d457e4..7c90aef43367e 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js @@ -59,6 +59,7 @@ interface Array { length: number; [n: number]: T; } // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js index 489c21a84589b..4e961e8541257 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js @@ -59,6 +59,7 @@ interface Array { length: number; [n: number]: T; } // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noImplicitExtensionName": true, /* Report error for implicit extension name. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ From 78e53a12b5c4c477e559f6e40e963fd7b805869b Mon Sep 17 00:00:00 2001 From: Jack Works Date: Fri, 13 Mar 2020 12:51:27 +0800 Subject: [PATCH 30/30] fix: run test again --- tests/baselines/reference/emitExtensionTSNotFound.errors.txt | 2 +- tests/baselines/reference/emitExtensionTSNotFound.js | 4 ++-- tests/baselines/reference/emitExtensionTSNotFound.symbols | 2 +- tests/baselines/reference/emitExtensionTSNotFound.types | 2 +- tests/cases/compiler/emitExtensionTSNotFound.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/emitExtensionTSNotFound.errors.txt b/tests/baselines/reference/emitExtensionTSNotFound.errors.txt index 7ac1a4ac4d0bc..12df1f73a57c4 100644 --- a/tests/baselines/reference/emitExtensionTSNotFound.errors.txt +++ b/tests/baselines/reference/emitExtensionTSNotFound.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/0.ts(2,17): error TS2307: Cannot find module './1.ts'. ==== tests/cases/compiler/0.ts (1 errors) ==== - // should not emit error 2961 + // should not emit error 2691 but 2307 import num from './1.ts' ~~~~~~~~ !!! error TS2307: Cannot find module './1.ts'. diff --git a/tests/baselines/reference/emitExtensionTSNotFound.js b/tests/baselines/reference/emitExtensionTSNotFound.js index c5b997eca9808..acd0168414aa2 100644 --- a/tests/baselines/reference/emitExtensionTSNotFound.js +++ b/tests/baselines/reference/emitExtensionTSNotFound.js @@ -1,5 +1,5 @@ //// [0.ts] -// should not emit error 2961 +// should not emit error 2691 but 2307 import num from './1.ts' num + 1 @@ -7,6 +7,6 @@ num + 1 //// [0.ts] "use strict"; exports.__esModule = true; -// should not emit error 2961 +// should not emit error 2691 but 2307 var _1_ts_1 = require("./1.ts"); _1_ts_1["default"] + 1; diff --git a/tests/baselines/reference/emitExtensionTSNotFound.symbols b/tests/baselines/reference/emitExtensionTSNotFound.symbols index f694e348354a2..68a783d50c14b 100644 --- a/tests/baselines/reference/emitExtensionTSNotFound.symbols +++ b/tests/baselines/reference/emitExtensionTSNotFound.symbols @@ -1,5 +1,5 @@ === tests/cases/compiler/0.ts === -// should not emit error 2961 +// should not emit error 2691 but 2307 import num from './1.ts' >num : Symbol(num, Decl(0.ts, 1, 6)) diff --git a/tests/baselines/reference/emitExtensionTSNotFound.types b/tests/baselines/reference/emitExtensionTSNotFound.types index 83e3ecddf8074..4a1c9e32c8bc5 100644 --- a/tests/baselines/reference/emitExtensionTSNotFound.types +++ b/tests/baselines/reference/emitExtensionTSNotFound.types @@ -1,5 +1,5 @@ === tests/cases/compiler/0.ts === -// should not emit error 2961 +// should not emit error 2691 but 2307 import num from './1.ts' >num : any diff --git a/tests/cases/compiler/emitExtensionTSNotFound.ts b/tests/cases/compiler/emitExtensionTSNotFound.ts index 15063f9cb4c37..fd69020767b30 100644 --- a/tests/cases/compiler/emitExtensionTSNotFound.ts +++ b/tests/cases/compiler/emitExtensionTSNotFound.ts @@ -2,6 +2,6 @@ // @outDir: ./out/ // @Filename: 0.ts -// should not emit error 2961 +// should not emit error 2691 but 2307 import num from './1.ts' num + 1