Skip to content

Support modules when targeting ES6 and an ES6 ModuleKind #4811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 24, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ namespace ts {
"amd": ModuleKind.AMD,
"system": ModuleKind.System,
"umd": ModuleKind.UMD,
"es6": ModuleKind.ES6,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you do not need that. just leave target as es6 and allow for additional --module flag. today we make it an error to use --target es6 with --module; relaxing this should be sufficient.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internally we checked for language version like it was a module kind in a number of places. Is it just a matter of not wanting to make it able to be specified explicitly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not support target: es5 with module: es6, so why allow it and add additional burden on users.
--target es6 with no --module is implied to be es6, if another --module tareget is specified, emit should use that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, so I'm just removing it as an option for the --module command line flag.

},
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_or_umd,
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6,
paramType: Diagnostics.KIND,
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_or_umd
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6
},
{
name: "newLine",
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ namespace ts {
Line_terminator_not_permitted_before_arrow: { code: 1200, category: DiagnosticCategory.Error, key: "Line terminator not permitted before arrow." },
Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead: { code: 1202, category: DiagnosticCategory.Error, key: "Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead." },
Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead: { code: 1203, category: DiagnosticCategory.Error, key: "Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead." },
Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher." },
Cannot_compile_modules_into_es6_when_targeting_ES5_or_lower: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile modules into 'es6' when targeting 'ES5' or lower." },
Decorators_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1205, category: DiagnosticCategory.Error, key: "Decorators are only available when targeting ECMAScript 5 and higher." },
Decorators_are_not_valid_here: { code: 1206, category: DiagnosticCategory.Error, key: "Decorators are not valid here." },
Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: { code: 1207, category: DiagnosticCategory.Error, key: "Decorators cannot be applied to multiple get/set accessors of the same name." },
Expand Down Expand Up @@ -528,7 +528,7 @@ namespace ts {
Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." },
Do_not_emit_outputs: { code: 6010, category: DiagnosticCategory.Message, key: "Do not emit outputs." },
Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)" },
Specify_module_code_generation_Colon_commonjs_amd_system_or_umd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs', 'amd', 'system' or 'umd'" },
Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'" },
Print_this_message: { code: 6017, category: DiagnosticCategory.Message, key: "Print this message." },
Print_the_compiler_s_version: { code: 6019, category: DiagnosticCategory.Message, key: "Print the compiler's version." },
Compile_the_project_in_the_given_directory: { code: 6020, category: DiagnosticCategory.Message, key: "Compile the project in the given directory." },
Expand All @@ -549,7 +549,7 @@ namespace ts {
Generates_corresponding_map_file: { code: 6043, category: DiagnosticCategory.Message, key: "Generates corresponding '.map' file." },
Compiler_option_0_expects_an_argument: { code: 6044, category: DiagnosticCategory.Error, key: "Compiler option '{0}' expects an argument." },
Unterminated_quoted_string_in_response_file_0: { code: 6045, category: DiagnosticCategory.Error, key: "Unterminated quoted string in response file '{0}'." },
Argument_for_module_option_must_be_commonjs_amd_system_or_umd: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs', 'amd', 'system' or 'umd'." },
Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'." },
Argument_for_target_option_must_be_ES3_ES5_or_ES6: { code: 6047, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'ES3', 'ES5', or 'ES6'." },
Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: 6048, category: DiagnosticCategory.Error, key: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'." },
Unsupported_locale_0: { code: 6049, category: DiagnosticCategory.Error, key: "Unsupported locale '{0}'." },
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@
"category": "Error",
"code": 1203
},
"Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher.": {
"Cannot compile modules into 'es6' when targeting 'ES5' or lower.": {
"category": "Error",
"code": 1204
},
Expand Down Expand Up @@ -2102,7 +2102,7 @@
"category": "Message",
"code": 6015
},
"Specify module code generation: 'commonjs', 'amd', 'system' or 'umd'": {
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'": {
"category": "Message",
"code": 6016
},
Expand Down Expand Up @@ -2186,7 +2186,7 @@
"category": "Error",
"code": 6045
},
"Argument for '--module' option must be 'commonjs', 'amd', 'system' or 'umd'.": {
"Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'.": {
"category": "Error",
"code": 6046
},
Expand Down
43 changes: 19 additions & 24 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi

/** If removeComments is true, no leading-comments needed to be emitted **/
let emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos: number) { } : emitLeadingCommentsOfPositionWorker;

let moduleEmitDelegates: Map<(node: SourceFile, startIndex: number) => void> = {
[ModuleKind.ES6]: emitES6Module,
[ModuleKind.AMD]: emitAMDModule,
[ModuleKind.System]: emitSystemModule,
[ModuleKind.UMD]: emitUMDModule,
[ModuleKind.CommonJS]: emitCommonJSModule,
};

if (compilerOptions.sourceMap || compilerOptions.inlineSourceMap) {
initializeEmitterWithSourceMaps();
Expand Down Expand Up @@ -1493,7 +1501,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
// Identifier references module export
if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) {
if (compilerOptions.module !== ModuleKind.ES6 && compilerOptions.module !== ModuleKind.System) {
write("exports.");
}
}
Expand All @@ -1503,7 +1511,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(".");
}
}
else if (languageVersion < ScriptTarget.ES6) {
else if (compilerOptions.module !== ModuleKind.ES6) {
let declaration = resolver.getReferencedImportDeclaration(node);
if (declaration) {
if (declaration.kind === SyntaxKind.ImportClause) {
Expand Down Expand Up @@ -3049,7 +3057,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(getGeneratedNameForNode(container));
write(".");
}
else if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) {
else if (compilerOptions.module !== ModuleKind.ES6 && compilerOptions.module !== ModuleKind.System) {
write("exports.");
}
}
Expand Down Expand Up @@ -3469,7 +3477,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi

function isES6ExportedDeclaration(node: Node) {
return !!(node.flags & NodeFlags.Export) &&
languageVersion >= ScriptTarget.ES6 &&
compilerOptions.module === ModuleKind.ES6 &&
node.parent.kind === SyntaxKind.SourceFile;
}

Expand Down Expand Up @@ -5421,7 +5429,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}

function emitImportDeclaration(node: ImportDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
if (compilerOptions.module !== ModuleKind.ES6) {
return emitExternalImportDeclaration(node);
}

Expand Down Expand Up @@ -5586,7 +5594,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
function emitExportDeclaration(node: ExportDeclaration) {
Debug.assert(compilerOptions.module !== ModuleKind.System);

if (languageVersion < ScriptTarget.ES6) {
if (compilerOptions.module !== ModuleKind.ES6) {
if (node.moduleSpecifier && (!node.exportClause || resolver.isValueAliasDeclaration(node))) {
emitStart(node);
let generatedName = getGeneratedNameForNode(node);
Expand Down Expand Up @@ -5652,7 +5660,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}

function emitExportOrImportSpecifierList(specifiers: ImportOrExportSpecifier[], shouldEmit: (node: Node) => boolean) {
Debug.assert(languageVersion >= ScriptTarget.ES6);
Debug.assert(compilerOptions.module === ModuleKind.ES6);

let needsComma = false;
for (let specifier of specifiers) {
Expand All @@ -5672,7 +5680,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi

function emitExportAssignment(node: ExportAssignment) {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
if (languageVersion >= ScriptTarget.ES6) {
if (compilerOptions.module === ModuleKind.ES6) {
writeLine();
emitStart(node);
write("export default ");
Expand Down Expand Up @@ -6681,7 +6689,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}

function emitSourceFileNode(node: SourceFile) {
function emitSourceFileNode(node: SourceFile) {
// Start new file on new line
writeLine();
emitShebang();
Expand All @@ -6691,21 +6699,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
let startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false);

if (isExternalModule(node) || compilerOptions.isolatedModules) {
if (languageVersion >= ScriptTarget.ES6) {
emitES6Module(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.AMD) {
emitAMDModule(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.System) {
emitSystemModule(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.UMD) {
emitUMDModule(node, startIndex);
}
else {
emitCommonJSModule(node, startIndex);
}
let emitModule = moduleEmitDelegates[compilerOptions.module] || moduleEmitDelegates[ModuleKind.CommonJS];
emitModule(node, startIndex);
}
else {
externalImports = undefined;
Expand Down
10 changes: 7 additions & 3 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ namespace ts {
let classifiableNames: Map<string>;

let skipDefaultLib = options.noLib;

if (options.target >= ScriptTarget.ES6 && !options.module) { // Preserve old ES6 module behavior
options.module = ModuleKind.ES6;
}

let start = new Date().getTime();

Expand Down Expand Up @@ -1022,9 +1026,9 @@ namespace ts {
programDiagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_unless_the_module_flag_is_provided));
}

// Cannot specify module gen target when in es6 or above
if (options.module && languageVersion >= ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_commonjs_amd_system_or_umd_when_targeting_ES6_or_higher));
// Cannot specify module gen target of es6 when below es6
if (options.module === ModuleKind.ES6 && languageVersion < ScriptTarget.ES6) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es6_when_targeting_ES5_or_lower));
}

// there has to be common source directory if user specified --outdir || --sourceRoot
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2076,6 +2076,7 @@ namespace ts {
AMD = 2,
UMD = 3,
System = 4,
ES6 = 5,
}

export const enum JsxEmit {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
error TS1204: Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher.
tests/cases/compiler/constDeclarations_access_2.ts(2,1): error TS1202: Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from "mod"', 'import {a} from "mod"' or 'import d from "mod"' instead.
tests/cases/compiler/constDeclarations_access_2.ts(4,1): error TS2450: Left-hand side of assignment expression cannot be a constant.
tests/cases/compiler/constDeclarations_access_2.ts(5,1): error TS2450: Left-hand side of assignment expression cannot be a constant.
Expand All @@ -20,7 +19,6 @@ tests/cases/compiler/constDeclarations_access_2.ts(22,3): error TS2449: The oper
tests/cases/compiler/constDeclarations_access_2.ts(24,1): error TS2450: Left-hand side of assignment expression cannot be a constant.


!!! error TS1204: Cannot compile modules into 'commonjs', 'amd', 'system' or 'umd' when targeting 'ES6' or higher.
==== tests/cases/compiler/constDeclarations_access_2.ts (19 errors) ====
///<reference path='constDeclarations_access_1.ts'/>
import m = require('constDeclarations_access_1');
Expand Down
66 changes: 35 additions & 31 deletions tests/baselines/reference/constDeclarations-access5.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,35 +49,39 @@ m.x.toString();


//// [constDeclarations_access_1.js]
export const x = 0;
define(["require", "exports"], function (require, exports) {
exports.x = 0;
});
//// [constDeclarations_access_2.js]
// Errors
m.x = 1;
m.x += 2;
m.x -= 3;
m.x *= 4;
m.x /= 5;
m.x %= 6;
m.x <<= 7;
m.x >>= 8;
m.x >>>= 9;
m.x &= 10;
m.x |= 11;
m.x ^= 12;
m;
m.x++;
m.x--;
++m.x;
--m.x;
++((m.x));
m["x"] = 0;
// OK
var a = m.x + 1;
function f(v) { }
f(m.x);
if (m.x) { }
m.x;
(m.x);
-m.x;
+m.x;
m.x.toString();
define(["require", "exports", 'constDeclarations_access_1'], function (require, exports, m) {
// Errors
m.x = 1;
m.x += 2;
m.x -= 3;
m.x *= 4;
m.x /= 5;
m.x %= 6;
m.x <<= 7;
m.x >>= 8;
m.x >>>= 9;
m.x &= 10;
m.x |= 11;
m.x ^= 12;
m;
m.x++;
m.x--;
++m.x;
--m.x;
++((m.x));
m["x"] = 0;
// OK
var a = m.x + 1;
function f(v) { }
f(m.x);
if (m.x) { }
m.x;
(m.x);
-m.x;
+m.x;
m.x.toString();
});
19 changes: 19 additions & 0 deletions tests/baselines/reference/es5andes6module.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error TS1204: Cannot compile modules into 'es6' when targeting 'ES5' or lower.


!!! error TS1204: Cannot compile modules into 'es6' when targeting 'ES5' or lower.
==== tests/cases/compiler/es5andes6module.ts (0 errors) ====

export default class A
{
constructor ()
{

}

public B()
{
return 42;
}
}

26 changes: 26 additions & 0 deletions tests/baselines/reference/es5andes6module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [es5andes6module.ts]

export default class A
{
constructor ()
{

}

public B()
{
return 42;
}
}


//// [es5andes6module.js]
var A = (function () {
function A() {
}
A.prototype.B = function () {
return 42;
};
return A;
})();
exports.default = A;
18 changes: 0 additions & 18 deletions tests/baselines/reference/es6-amd.errors.txt

This file was deleted.

16 changes: 16 additions & 0 deletions tests/baselines/reference/es6-amd.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
=== tests/cases/compiler/es6-amd.ts ===

class A
>A : Symbol(A, Decl(es6-amd.ts, 0, 0))
{
constructor ()
{

}

public B()
>B : Symbol(B, Decl(es6-amd.ts, 6, 5))
{
return 42;
}
}
Loading