diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index cca3a8d6713..c77324eefd4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5429,17 +5429,43 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi (!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) { emitLeadingComments(node); emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); - write("var "); + + // variable declaration for import-equals declaration can be hoisted in system modules + // in this case 'var' should be omitted and emit should contain only initialization + let variableDeclarationIsHoisted = shouldHoistVariable(node, /*checkIfSourceFileLevelDecl*/ true); + + // is it top level export import v = a.b.c in system module? + // if yes - it needs to be rewritten as exporter('v', v = a.b.c) + let isExported = isSourceFileLevelDeclarationInSystemJsModule(node, /*isExported*/ true); + + if (!variableDeclarationIsHoisted) { + Debug.assert(!isExported); + + if (isES6ExportedDeclaration(node)) { + write("export "); + write("var "); + } + else if (!(node.flags & NodeFlags.Export)) { + write("var "); + } } - else if (!(node.flags & NodeFlags.Export)) { - write("var "); + + + if (isExported) { + write(`${exportFunctionForFile}("`); + emitNodeWithoutSourceMap(node.name); + write(`", `); } + emitModuleMemberName(node); write(" = "); emit(node.moduleReference); - write(";"); + + if (isExported) { + write(")"); + } + + write(";"); emitEnd(node); emitExportImportAssignments(node); emitTrailingComments(node); @@ -5965,6 +5991,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } return; } + + if (isInternalModuleImportEqualsDeclaration(node)) { + if (!hoistedVars) { + hoistedVars = []; + } + + hoistedVars.push(node.name); + return; + } if (isBindingPattern(node)) { forEach((node).elements, visit); @@ -6169,14 +6204,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi writeLine(); for (let i = startIndex; i < node.statements.length; ++i) { let statement = node.statements[i]; - // - imports/exports are not emitted for system modules + // - external module related imports/exports are not emitted for system modules // - function declarations are not emitted because they were already hoisted switch (statement.kind) { case SyntaxKind.ExportDeclaration: case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.FunctionDeclaration: continue; + case SyntaxKind.ImportEqualsDeclaration: + if (!isInternalModuleImportEqualsDeclaration(statement)) { + continue; + } } writeLine(); emit(statement); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9d7877ca6e3..56eb2415cf9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -965,7 +965,7 @@ namespace ts { return ((node).moduleReference).expression; } - export function isInternalModuleImportEqualsDeclaration(node: Node) { + export function isInternalModuleImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration { return node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind !== SyntaxKind.ExternalModuleReference; } diff --git a/tests/baselines/reference/aliasesInSystemModule1.errors.txt b/tests/baselines/reference/aliasesInSystemModule1.errors.txt new file mode 100644 index 00000000000..9b89332e458 --- /dev/null +++ b/tests/baselines/reference/aliasesInSystemModule1.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/aliasesInSystemModule1.ts(2,24): error TS2307: Cannot find module 'foo'. + + +==== tests/cases/compiler/aliasesInSystemModule1.ts (1 errors) ==== + + import alias = require('foo'); + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + import cls = alias.Class; + export import cls2 = alias.Class; + + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); + + module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); + } + \ No newline at end of file diff --git a/tests/baselines/reference/aliasesInSystemModule1.js b/tests/baselines/reference/aliasesInSystemModule1.js new file mode 100644 index 00000000000..28ac1e9b4ad --- /dev/null +++ b/tests/baselines/reference/aliasesInSystemModule1.js @@ -0,0 +1,42 @@ +//// [aliasesInSystemModule1.ts] + +import alias = require('foo'); +import cls = alias.Class; +export import cls2 = alias.Class; + +let x = new alias.Class(); +let y = new cls(); +let z = new cls2(); + +module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); +} + + +//// [aliasesInSystemModule1.js] +System.register(['foo'], function(exports_1) { + var alias; + var cls, cls2, x, y, z, M; + return { + setters:[ + function (_alias) { + alias = _alias; + }], + execute: function() { + cls = alias.Class; + exports_1("cls2", cls2 = alias.Class); + x = new alias.Class(); + y = new cls(); + z = new cls2(); + (function (M) { + M.cls = alias.Class; + var x = new alias.Class(); + var y = new M.cls(); + var z = new cls2(); + })(M || (M = {})); + } + } +}); diff --git a/tests/baselines/reference/aliasesInSystemModule2.errors.txt b/tests/baselines/reference/aliasesInSystemModule2.errors.txt new file mode 100644 index 00000000000..618e61c7f3c --- /dev/null +++ b/tests/baselines/reference/aliasesInSystemModule2.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/aliasesInSystemModule2.ts(2,21): error TS2307: Cannot find module 'foo'. + + +==== tests/cases/compiler/aliasesInSystemModule2.ts (1 errors) ==== + + import {alias} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + import cls = alias.Class; + export import cls2 = alias.Class; + + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); + + module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); + } \ No newline at end of file diff --git a/tests/baselines/reference/aliasesInSystemModule2.js b/tests/baselines/reference/aliasesInSystemModule2.js new file mode 100644 index 00000000000..0256d03a179 --- /dev/null +++ b/tests/baselines/reference/aliasesInSystemModule2.js @@ -0,0 +1,41 @@ +//// [aliasesInSystemModule2.ts] + +import {alias} from "foo"; +import cls = alias.Class; +export import cls2 = alias.Class; + +let x = new alias.Class(); +let y = new cls(); +let z = new cls2(); + +module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); +} + +//// [aliasesInSystemModule2.js] +System.register(["foo"], function(exports_1) { + var foo_1; + var cls, cls2, x, y, z, M; + return { + setters:[ + function (_foo_1) { + foo_1 = _foo_1; + }], + execute: function() { + cls = foo_1.alias.Class; + exports_1("cls2", cls2 = foo_1.alias.Class); + x = new foo_1.alias.Class(); + y = new cls(); + z = new cls2(); + (function (M) { + M.cls = foo_1.alias.Class; + var x = new foo_1.alias.Class(); + var y = new M.cls(); + var z = new cls2(); + })(M || (M = {})); + } + } +}); diff --git a/tests/cases/compiler/aliasesInSystemModule1.ts b/tests/cases/compiler/aliasesInSystemModule1.ts new file mode 100644 index 00000000000..33d205e5a07 --- /dev/null +++ b/tests/cases/compiler/aliasesInSystemModule1.ts @@ -0,0 +1,18 @@ +// @module: system +// @isolatedModules: true + +import alias = require('foo'); +import cls = alias.Class; +export import cls2 = alias.Class; + +let x = new alias.Class(); +let y = new cls(); +let z = new cls2(); + +module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); +} + \ No newline at end of file diff --git a/tests/cases/compiler/aliasesInSystemModule2.ts b/tests/cases/compiler/aliasesInSystemModule2.ts new file mode 100644 index 00000000000..3daa7e5a7bd --- /dev/null +++ b/tests/cases/compiler/aliasesInSystemModule2.ts @@ -0,0 +1,17 @@ +// @module: system +// @isolatedModules: true + +import {alias} from "foo"; +import cls = alias.Class; +export import cls2 = alias.Class; + +let x = new alias.Class(); +let y = new cls(); +let z = new cls2(); + +module M { + export import cls = alias.Class; + let x = new alias.Class(); + let y = new cls(); + let z = new cls2(); +} \ No newline at end of file