diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab42c5fe42d..0e5040ceb4c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2275,7 +2275,7 @@ namespace ts { else if (!compilerOptions.resolveJsonModule && fileExtensionIs(moduleReference, Extension.Json) && getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && - getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) { + hasJsonModuleEmitEnabled(compilerOptions)) { error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3abf2eab2d4..4057a5528aa 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2912,7 +2912,7 @@ "category": "Error", "code": 5070 }, - "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": { + "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": { "category": "Error", "code": 5071 }, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 613fe7f5c84..8cb1d4f34a9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1780,7 +1780,9 @@ namespace ts { function emitExpressionStatement(node: ExpressionStatement) { emitExpression(node.expression); - if (!isJsonSourceFile(currentSourceFile)) { + // Emit semicolon in non json files + // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation) + if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) { writeSemicolon(); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3e6c6b9f195..c129d75f156 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2549,9 +2549,9 @@ namespace ts { if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) { createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); } - // Any emit other than common js is error - else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) { - createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module"); + // Any emit other than common js, amd, es2015 or esnext is error + else if (!hasJsonModuleEmitEnabled(options)) { + createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module"); } } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 09bf1b75b9c..1b3a623c32d 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -53,7 +53,10 @@ namespace ts { * @param node The SourceFile node. */ function transformSourceFile(node: SourceFile) { - if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) { + if (node.isDeclarationFile || + !(isEffectiveExternalModule(node, compilerOptions) || + node.transformFlags & TransformFlags.ContainsDynamicImport || + (isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) { return node; } @@ -117,6 +120,7 @@ namespace ts { function transformAMDModule(node: SourceFile) { const define = createIdentifier("define"); const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); + const jsonSourceFile = isJsonSourceFile(node) && node; // An AMD define function has the following shape: // @@ -158,7 +162,7 @@ namespace ts { // Add the dependency array argument: // // ["require", "exports", module1", "module2", ...] - createArrayLiteral([ + createArrayLiteral(jsonSourceFile ? emptyArray : [ createLiteral("require"), createLiteral("exports"), ...aliasedModuleNames, @@ -168,7 +172,9 @@ namespace ts { // Add the module body function argument: // // function (require, exports, module1, module2) ... - createFunctionExpression( + jsonSourceFile ? + jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() : + createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ca9923c4dbb..47bf4193bd6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7033,6 +7033,18 @@ namespace ts { return moduleResolution; } + export function hasJsonModuleEmitEnabled(options: CompilerOptions) { + switch (getEmitModuleKind(options)) { + case ModuleKind.CommonJS: + case ModuleKind.AMD: + case ModuleKind.ES2015: + case ModuleKind.ESNext: + return true; + default: + return false; + } + } + export function unreachableCodeIsError(options: CompilerOptions): boolean { return options.allowUnreachableCode === false; } diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt deleted file mode 100644 index eab6745285b..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js new file mode 100644 index 00000000000..f6aa6d997be --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts] //// + +//// [file1.ts] +import * as b from './b.json'; + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [out/output.js] +define("b", [], { + "a": true, + "b": "hello" +}); +define("file1", ["require", "exports"], function (require, exports) { + "use strict"; + exports.__esModule = true; +}); diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols new file mode 100644 index 00000000000..827f2e674e6 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/file1.ts === +import * as b from './b.json'; +>b : Symbol(b, Decl(file1.ts, 0, 6)) + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types new file mode 100644 index 00000000000..9e5cc29d342 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/file1.ts === +import * as b from './b.json'; +>b : { "a": boolean; "b": string; } + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt deleted file mode 100644 index eab6745285b..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt deleted file mode 100644 index b9c37651205..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt index 8a40ac52e90..6772461f487 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt @@ -1,8 +1,8 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. tests/cases/compiler/file1.ts(1,1): error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (1 errors) ==== import * as b from './b.json'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt index eab6745285b..8b570387ce7 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt @@ -1,7 +1,7 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (0 errors) ==== import * as b from './b.json'; diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt index eab6745285b..8b570387ce7 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt @@ -1,7 +1,7 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (0 errors) ==== import * as b from './b.json'; diff --git a/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts b/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts new file mode 100644 index 00000000000..6c73015d222 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts @@ -0,0 +1,14 @@ +// @module: amd +// @moduleResolution: node +// @outFile: out/output.js +// @fullEmitPaths: true +// @resolveJsonModule: true + +// @Filename: file1.ts +import * as b from './b.json'; + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file