From e8fcf8fa2a201949ecfb489de972a635ab2cb3c9 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 10 Apr 2015 12:10:38 -0700 Subject: [PATCH] initial support for system module --- src/compiler/checker.ts | 18 +- src/compiler/commandLineParser.ts | 7 +- .../diagnosticInformationMap.generated.ts | 7 +- src/compiler/diagnosticMessages.json | 10 +- src/compiler/emitter.ts | 362 ++++++++++++++++-- src/compiler/program.ts | 2 +- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 16 + 8 files changed, 366 insertions(+), 57 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea86b2b9b04..bee917a2cb6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10616,9 +10616,15 @@ module ts { checkExternalModuleExports(container); - if (node.isExportEquals && languageVersion >= ScriptTarget.ES6) { - // export assignment is deprecated in es6 or above - grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead); + if (node.isExportEquals) { + if (languageVersion >= ScriptTarget.ES6) { + // export assignment is deprecated in es6 or above + grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead); + } + else if (compilerOptions.module === ModuleKind.System) { + // system modules does not support export assignment + grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_with_module_flag_is_system); + } } } @@ -11432,9 +11438,11 @@ module ts { function getExportNameSubstitution(symbol: Symbol, location: Node, getGeneratedNameForNode: (Node: Node) => string): string { if (isExternalModuleSymbol(symbol.parent)) { - // If this is es6 or higher, just use the name of the export + // 1. If this is es6 or higher, just use the name of the export // no need to qualify it. - if (languageVersion >= ScriptTarget.ES6) { + // 2. export mechanism for System modules is different from CJS\AMD + // and it does not need qualifications for exports + if (languageVersion >= ScriptTarget.ES6 || compilerOptions.module === ModuleKind.System) { return undefined; } return "exports." + unescapeIdentifier(symbol.name); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 48817798d81..201aaf743ae 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -50,11 +50,12 @@ module ts { shortName: "m", type: { "commonjs": ModuleKind.CommonJS, - "amd": ModuleKind.AMD + "amd": ModuleKind.AMD, + "system": ModuleKind.System, }, - description: Diagnostics.Specify_module_code_generation_Colon_commonjs_or_amd, + description: Diagnostics.Specify_module_code_generation_Colon_commonjs_system_or_amd, paramType: Diagnostics.KIND, - error: Diagnostics.Argument_for_module_option_must_be_commonjs_or_amd + error: Diagnostics.Argument_for_module_option_must_be_commonjs_system_or_amd }, { name: "noEmit", diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 5062be5ed46..b18b59377b0 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -161,7 +161,7 @@ module ts { A_type_annotation_on_an_export_statement_is_only_allowed_in_an_ambient_external_module_declaration: { code: 1201, category: DiagnosticCategory.Error, key: "A type annotation on an export statement is only allowed in an ambient external module declaration." }, 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_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile external modules into amd or commonjs when targeting es6 or higher." }, + Cannot_compile_external_modules_into_amd_system_or_commonjs_when_targeting_es6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile external modules into amd, system or commonjs when targeting es6 or higher." }, 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." }, @@ -169,6 +169,7 @@ module ts { Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." }, Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}'. Class definitions are automatically in strict mode." }, A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" }, + Export_assignment_is_not_supported_with_module_flag_is_system: { code: 1212, category: DiagnosticCategory.Error, key: "Export assignment is not supported with '--module' flag is 'system'." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, @@ -456,7 +457,7 @@ module 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_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs' or 'amd'" }, + Specify_module_code_generation_Colon_commonjs_system_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs', 'system' or 'amd'" }, 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." }, @@ -477,7 +478,7 @@ module 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_or_amd: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs' or 'amd'." }, + Argument_for_module_option_must_be_commonjs_system_or_amd: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs', 'system' or 'amd'." }, 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 or -. For example '{0}' or '{1}'." }, Unsupported_locale_0: { code: 6049, category: DiagnosticCategory.Error, key: "Unsupported locale '{0}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4476b0cad4a..cf7e60fa311 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -635,7 +635,7 @@ "category": "Error", "code": 1203 }, - "Cannot compile external modules into amd or commonjs when targeting es6 or higher.": { + "Cannot compile external modules into amd, system or commonjs when targeting es6 or higher.": { "category": "Error", "code": 1204 }, @@ -667,6 +667,10 @@ "category": "Error", "code": 1211 }, + "Export assignment is not supported with '--module' flag is 'system'.": { + "category": "Error", + "code": 1212 + }, "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 @@ -1816,7 +1820,7 @@ "category": "Message", "code": 6015 }, - "Specify module code generation: 'commonjs' or 'amd'": { + "Specify module code generation: 'commonjs', 'system' or 'amd'": { "category": "Message", "code": 6016 }, @@ -1900,7 +1904,7 @@ "category": "Error", "code": 6045 }, - "Argument for '--module' option must be 'commonjs' or 'amd'.": { + "Argument for '--module' option must be 'commonjs', 'system' or 'amd'.": { "category": "Error", "code": 6046 }, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 940edf04191..77f9c9a7f3b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -117,6 +117,7 @@ var __param = this.__param || function(index, decorator) { return function (targ let decreaseIndent = writer.decreaseIndent; let currentSourceFile: SourceFile; + let exportFunctionForFile: string; let generatedNameSet: Map = {}; let nodeToGeneratedName: string[] = []; @@ -191,6 +192,7 @@ var __param = this.__param || function(index, decorator) { return function (targ function emitSourceFile(sourceFile: SourceFile): void { currentSourceFile = sourceFile; + exportFunctionForFile = undefined; emit(sourceFile); } @@ -1136,7 +1138,7 @@ var __param = this.__param || function(index, decorator) { return function (targ if (!computedPropertyNamesToGeneratedNames) { computedPropertyNamesToGeneratedNames = []; } - + let generatedName = computedPropertyNamesToGeneratedNames[getNodeId(node)]; if (generatedName) { // we have already generated a variable for this node, write that value instead. @@ -1584,7 +1586,7 @@ var __param = this.__param || function(index, decorator) { return function (targ result.name = name; return result; - } + } function createElementAccessExpression(expression: LeftHandSideExpression, argumentExpression: Expression): ElementAccessExpression { let result = createSynthesizedNode(SyntaxKind.ElementAccessExpression); @@ -2060,6 +2062,10 @@ var __param = this.__param || function(index, decorator) { return function (targ } function emitStartOfVariableDeclarationList(decl: Node, startPos?: number): void { + if (currentFileIsEmittedAsSystemModule() && isSourceFileLevelDeclaration(decl)) { + Debug.assert(compilerOptions.module === ModuleKind.System); + return; + } let tokenKind = SyntaxKind.VarKeyword; if (decl && languageVersion >= ScriptTarget.ES6) { if (isLet(decl)) { @@ -2072,6 +2078,7 @@ var __param = this.__param || function(index, decorator) { return function (targ if (startPos !== undefined) { emitToken(tokenKind, startPos); + write(" ") } else { switch (tokenKind) { @@ -2093,7 +2100,6 @@ var __param = this.__param || function(index, decorator) { return function (targ let variableDeclarationList = node.initializer; let declarations = variableDeclarationList.declarations; emitStartOfVariableDeclarationList(declarations[0], endPos); - write(" "); emitCommaList(declarations); } else if (node.initializer) { @@ -2120,7 +2126,6 @@ var __param = this.__param || function(index, decorator) { return function (targ if (variableDeclarationList.declarations.length >= 1) { let decl = variableDeclarationList.declarations[0]; emitStartOfVariableDeclarationList(decl, endPos); - write(" "); emit(decl); } } @@ -2415,7 +2420,7 @@ var __param = this.__param || function(index, decorator) { return function (targ write(getGeneratedNameForNode(container)); write("."); } - else if (languageVersion < ScriptTarget.ES6) { + else if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) { write("exports."); } } @@ -2435,14 +2440,28 @@ var __param = this.__param || function(index, decorator) { return function (targ if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); - if (node.flags & NodeFlags.Default) { - write("exports.default"); + if (compilerOptions.module === ModuleKind.System) { + write(`${exportFunctionForFile}("`); + if (node.flags & NodeFlags.Default) { + write("default"); + } + else { + emitNodeWithoutSourceMap(node.name); + } + write(`", `); + emitDeclarationName(node); + write(")") } else { - emitModuleMemberName(node); + if (node.flags & NodeFlags.Default) { + write("exports.default"); + } + else { + emitModuleMemberName(node); + } + write(" = "); + emitDeclarationName(node); } - write(" = "); - emitDeclarationName(node); emitEnd(node); write(";"); } @@ -2453,12 +2472,21 @@ var __param = this.__param || function(index, decorator) { return function (targ for (let specifier of exportSpecifiers[name.text]) { writeLine(); emitStart(specifier.name); - emitContainingModuleName(specifier); - write("."); - emitNodeWithoutSourceMap(specifier.name); - emitEnd(specifier.name); - write(" = "); - emitExpressionIdentifier(name); + if (compilerOptions.module === ModuleKind.System) { + write(`${exportFunctionForFile}("`); + emitNodeWithoutSourceMap(specifier.name); + write(`", `); + emitExpressionIdentifier(name); + write(")") + } + else { + emitContainingModuleName(specifier); + write("."); + emitNodeWithoutSourceMap(specifier.name); + emitEnd(specifier.name); + write(" = "); + emitExpressionIdentifier(name); + } write(";"); } } @@ -2477,7 +2505,18 @@ var __param = this.__param || function(index, decorator) { return function (targ let emitCount = 0; // An exported declaration is actually emitted as an assignment (to a property on the module object), so // temporary variables in an exported declaration need to have real declarations elsewhere - let isDeclaration = (root.kind === SyntaxKind.VariableDeclaration && !(getCombinedNodeFlags(root) & NodeFlags.Export)) || root.kind === SyntaxKind.Parameter; + // Also temporary variables should be explicitly allocated for source level declarations when module target is system + // because actual variable declarations are hoisted + let canDefineTempVariablesInplace = false; + if (root.kind === SyntaxKind.VariableDeclaration) { + let isExported = getCombinedNodeFlags(root) & NodeFlags.Export; + let isSourceLevelForSystemModuleKind = currentFileIsEmittedAsSystemModule() && isSourceFileLevelDeclaration(root); + canDefineTempVariablesInplace = !isExported && !isSourceLevelForSystemModuleKind; + } + else if (root.kind === SyntaxKind.Parameter) { + canDefineTempVariablesInplace = true; + } + if (root.kind === SyntaxKind.BinaryExpression) { emitAssignmentExpression(root); } @@ -2508,7 +2547,7 @@ var __param = this.__param || function(index, decorator) { return function (targ // as the location for determining uniqueness of the variable we are about to // generate. let identifier = createTempVariable(TempFlags.Auto); - if (!isDeclaration) { + if (!canDefineTempVariablesInplace) { recordTempDeclaration(identifier); } emitAssignment(identifier, expr); @@ -2788,6 +2827,10 @@ var __param = this.__param || function(index, decorator) { return function (targ if (resolver.resolvesToSomeValue(parent, (node).text)) { let variableId = resolver.getBlockScopedVariableId(node); + if (blockScopedVariableToGeneratedName && blockScopedVariableToGeneratedName[variableId]) { + // already renamed + return; + } if (!blockScopedVariableToGeneratedName) { blockScopedVariableToGeneratedName = []; } @@ -4418,6 +4461,8 @@ var __param = this.__param || function(index, decorator) { return function (targ } function emitExportDeclaration(node: ExportDeclaration) { + Debug.assert(compilerOptions.module !== ModuleKind.System); + if (languageVersion < ScriptTarget.ES6) { if (node.moduleSpecifier && (!node.exportClause || resolver.isValueAliasDeclaration(node))) { emitStart(node); @@ -4523,9 +4568,16 @@ var __param = this.__param || function(index, decorator) { return function (targ else { writeLine(); emitStart(node); - emitContainingModuleName(node); - write(".default = "); - emit(node.expression); + if (compilerOptions.module === ModuleKind.System) { + write(`${exportFunctionForFile}("default",`); + emit(node.expression); + write(")"); + } + else { + emitContainingModuleName(node); + write(".default = "); + emit(node.expression); + } write(";"); emitEnd(node); } @@ -4611,6 +4663,248 @@ var __param = this.__param || function(index, decorator) { return function (targ } } + function writeModuleNamesForExternalImports(startWithComma: boolean): void { + let started = startWithComma; + for (let importNode of externalImports) { + if (started) { + write(", "); + } + else { + started = true; + } + let moduleName = getExternalModuleName(importNode); + if (moduleName.kind === SyntaxKind.StringLiteral) { + emitLiteral(moduleName); + } + else { + write("\"\""); + } + } + } + + function writeLocalNameForExternalImport(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): void { + let namespaceDeclaration = getNamespaceDeclarationNode(importNode); + if (namespaceDeclaration && !isDefaultImport(importNode)) { + emit(namespaceDeclaration.name); + } + else { + write(getGeneratedNameForNode(importNode)); + } + } + + function writeLocalNamesForExternalImports(startWithComma: boolean): void { + let started = startWithComma; + for (let importNode of externalImports) { + + if (started) { + write(", "); + } + else { + started = true; + } + + writeLocalNameForExternalImport(importNode); + } + + } + + function emitVariableDeclarationsForImports(): void { + if (externalImports.length === 0) { + return; + } + + writeLine(); + let started = false; + for (let importNode of externalImports) { + if (importNode.kind === SyntaxKind.ExportDeclaration) { + continue; + } + + if (!started) { + write("var "); + started = true; + } + else { + write(", "); + } + writeLocalNameForExternalImport(importNode); + } + + if (started) { + write(";"); + } + } + + function hoistTopLevelVariableAndFunctionDeclarations(node: SourceFile): void { + let hoistedLocals: Identifier[]; + let hoistedFunctionDeclarations: FunctionDeclaration[]; + + visit(node); + + if (hoistedLocals) { + writeLine(); + write("var "); + for (let i = 0; i < hoistedLocals.length; ++i) { + let local = hoistedLocals[i]; + if (i !== 0) { + write(", "); + } + emit(local); + } + write(";") + } + + if (hoistedFunctionDeclarations) { + for (let f of hoistedFunctionDeclarations) { + writeLine(); + emit(f); + } + } + + function visit(node: Node): void { + if (node.kind === SyntaxKind.FunctionDeclaration) { + (hoistedFunctionDeclarations || (hoistedFunctionDeclarations = [])).push(node); + return; + } + + if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) { + let name = (node).name; + if (name.kind === SyntaxKind.Identifier) { + renameNonTopLevelLetAndConst(name); + (hoistedLocals || (hoistedLocals = [])).push(name); + } + else { + forEachChild(name, visit); + } + return; + } + + if (isBindingPattern(node)) { + forEach((node).elements, visit); + return; + } + + if (!isDeclaration(node)) { + forEachChild(node, visit); + } + } + } + + function currentFileIsEmittedAsSystemModule(): boolean { + return exportFunctionForFile !== undefined; + } + + function emitSystemModuleBody(node: SourceFile, startIndex: number): void { + emitVariableDeclarationsForImports(); + writeLine(); + hoistTopLevelVariableAndFunctionDeclarations(node); + writeLine(); + write("return {"); + increaseIndent(); + writeLine(); + emitSetters(); + writeLine(); + emitExecute(node, startIndex); + decreaseIndent(); + writeLine(); + write("}"); // return + } + + function emitSetters() { + write("setters:[") + let setterParameterName = makeUniqueName("v"); + for (let i = 0; i < externalImports.length; ++i) { + if (i !== 0) { + write(","); + } + + writeLine(); + increaseIndent(); + write(`function (${setterParameterName}) {`); + let importNode = externalImports[i]; + + switch (importNode.kind) { + case SyntaxKind.ImportDeclaration: + if (!(importNode).importClause) { + break; + } + // fall-through + case SyntaxKind.ImportEqualsDeclaration: + increaseIndent(); + writeLine(); + writeLocalNameForExternalImport(importNode); + write(` = ${setterParameterName}`); + writeLine(); + decreaseIndent(); + break; + case SyntaxKind.ExportDeclaration: + increaseIndent(); + + if ((importNode).exportClause) { + for (let e of (importNode).exportClause.elements) { + writeLine(); + write(`${exportFunctionForFile}("`); + emitNodeWithoutSourceMap(e.name); + write(`", ${setterParameterName}["`); + emitNodeWithoutSourceMap(e.propertyName || e.name); + write(`"];`); + } + } + else { + writeLine(); + // export * from + write(`for (var n in ${setterParameterName}) ${exportFunctionForFile}(n, ${setterParameterName}[n]);`); + } + + writeLine(); + decreaseIndent(); + break; + } + + write("}") + decreaseIndent(); + } + write("],"); + } + + function emitExecute(node: SourceFile, startIndex: number) { + write("execute: function() {"); + increaseIndent(); + writeLine(); + for (let i = startIndex; i < node.statements.length; ++i) { + let statement = node.statements[i]; + switch (statement.kind) { + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.FunctionDeclaration: + continue; + } + writeLine(); + emit(statement); + } + decreaseIndent(); + writeLine(); + write("}") // execute + emitTempDeclarations(/*newLine*/ true); + } + + function emitSystemModule(node: SourceFile, startIndex: number): void { + collectExternalModuleInfo(node); + Debug.assert(!exportFunctionForFile); + exportFunctionForFile = makeUniqueName("exports"); + write("System.register(["); + writeModuleNamesForExternalImports(/*startWithComma*/ false); + write(`], function(${exportFunctionForFile}) {`); + writeLine(); + increaseIndent(); + emitCaptureThisForNodeIfNecessary(node); + emitSystemModuleBody(node, startIndex); + decreaseIndent(); + writeLine(); + write("});"); + } + function emitAMDModule(node: SourceFile, startIndex: number) { collectExternalModuleInfo(node); writeLine(); @@ -4620,32 +4914,14 @@ var __param = this.__param || function(index, decorator) { return function (targ write("\"" + node.amdModuleName + "\", "); } write("[\"require\", \"exports\""); - for (let importNode of externalImports) { - write(", "); - let moduleName = getExternalModuleName(importNode); - if (moduleName.kind === SyntaxKind.StringLiteral) { - emitLiteral(moduleName); - } - else { - write("\"\""); - } - } + writeModuleNamesForExternalImports(/*startWithComma*/ true); for (let amdDependency of node.amdDependencies) { let text = "\"" + amdDependency.path + "\""; write(", "); write(text); } write("], function (require, exports"); - for (let importNode of externalImports) { - write(", "); - let namespaceDeclaration = getNamespaceDeclarationNode(importNode); - if (namespaceDeclaration && !isDefaultImport(importNode)) { - emit(namespaceDeclaration.name); - } - else { - write(getGeneratedNameForNode(importNode)); - } - } + writeLocalNamesForExternalImports(/*startWithComma*/ true); for (let amdDependency of node.amdDependencies) { if (amdDependency.name) { write(", "); @@ -4757,7 +5033,9 @@ var __param = this.__param || function(index, decorator) { return function (targ else if (compilerOptions.module === ModuleKind.AMD) { emitAMDModule(node, startIndex); } - else { + else if (compilerOptions.module === ModuleKind.System) { + emitSystemModule(node, startIndex); + } else { emitCommonJSModule(node, startIndex); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 69faeda2db0..b3dc9ea9b8d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -505,7 +505,7 @@ module ts { // Cannot specify module gen target when in es6 or above if (options.module && languageVersion >= ScriptTarget.ES6) { - diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher)); + diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_external_modules_into_amd_system_or_commonjs_when_targeting_es6_or_higher)); } // there has to be common source directory if user specified --outdir || --sourceRoot diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 34eb86440f4..b855294d83f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1619,6 +1619,7 @@ module ts { None = 0, CommonJS = 1, AMD = 2, + System = 3, } export interface LineAndCharacter { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0826e7748aa..b3917473543 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -189,6 +189,22 @@ module ts { return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node); } + /* @internal */ + export function isSourceFileLevelDeclaration(node: Node): boolean { + let current = node; + while (current) { + if (current.kind === SyntaxKind.SourceFile) { + return true; + } + else if (isFunctionLike(current) || current.kind === SyntaxKind.ModuleBlock) { + return false; + } + else { + current = current.parent; + } + } + } + // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' export function escapeIdentifier(identifier: string): string { return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;