Skip to content

Commit

Permalink
Support json module emit when module emit is commonjs, amd, es2015 or…
Browse files Browse the repository at this point in the history
… esnext

Fixes #25755 and #26020
  • Loading branch information
sheetalkamat committed Aug 31, 2018
1 parent acc3502 commit 0c77406
Show file tree
Hide file tree
Showing 16 changed files with 97 additions and 51 deletions.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,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 {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2892,7 +2892,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
},
Expand Down
4 changes: 3 additions & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/compiler/transformers/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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:
//
Expand Down Expand Up @@ -158,7 +162,7 @@ namespace ts {
// Add the dependency array argument:
//
// ["require", "exports", module1", "module2", ...]
createArrayLiteral([
createArrayLiteral(jsonSourceFile ? emptyArray : [
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
Expand All @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7004,6 +7004,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;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
});
Original file line number Diff line number Diff line change
@@ -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))
}
Original file line number Diff line number Diff line change
@@ -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"
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}

0 comments on commit 0c77406

Please sign in to comment.