diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e07c0eb237e..bef431bec46 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9000,7 +9000,12 @@ module ts { checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkExportsOnMergedDeclarations(node); var symbol = getSymbolOfNode(node); - if (symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length > 1 && !isInAmbientContext(node)) { + + // The following checks only apply on a non-ambient instantiated module declaration. + if (symbol.flags & SymbolFlags.ValueModule + && symbol.declarations.length > 1 + && !isInAmbientContext(node) + && isInstantiatedModule(node, compilerOptions.preserveConstEnums)) { var classOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (classOrFunc) { if (getSourceFileOfNode(node) !== getSourceFileOfNode(classOrFunc)) { @@ -9011,6 +9016,8 @@ module ts { } } } + + // Checks for ambient external modules. if (node.name.kind === SyntaxKind.StringLiteral) { if (!isGlobalSourceFile(node.parent)) { error(node.name, Diagnostics.Ambient_external_modules_cannot_be_nested_in_other_modules); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f3e45a85b6a..ef9a31d5872 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3686,8 +3686,8 @@ module ts { } function emitModuleDeclaration(node: ModuleDeclaration) { - var shouldEmit = getModuleInstanceState(node) === ModuleInstanceState.Instantiated || - (getModuleInstanceState(node) === ModuleInstanceState.ConstEnumOnly && compilerOptions.preserveConstEnums); + // Emit only if this module is non-ambient. + var shouldEmit = isInstantiatedModule(node, compilerOptions.preserveConstEnums); if (!shouldEmit) { return emitPinnedOrTripleSlashComments(node); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index edd8bf156cf..2c2c46805f6 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -525,6 +525,12 @@ module ts { return false; } + export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { + var moduleState = getModuleInstanceState(node) + return moduleState === ModuleInstanceState.Instantiated || + (preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly); + } + export function isExternalModuleImportDeclaration(node: Node) { return node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference; } diff --git a/tests/baselines/reference/cloduleWithPriorInstantiatedModule.errors.txt b/tests/baselines/reference/cloduleWithPriorInstantiatedModule.errors.txt new file mode 100644 index 00000000000..1b0d9cf13ca --- /dev/null +++ b/tests/baselines/reference/cloduleWithPriorInstantiatedModule.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts(2,8): error TS2434: A module declaration cannot be located prior to a class or function with which it is merged + + +==== tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts (1 errors) ==== + // Non-ambient & instantiated module. + module Moclodule { + ~~~~~~~~~ +!!! error TS2434: A module declaration cannot be located prior to a class or function with which it is merged + export interface Someinterface { + foo(): void; + } + var x = 10; + } + + class Moclodule { + } + + // Instantiated module. + module Moclodule { + export class Manager { + } + } \ No newline at end of file diff --git a/tests/baselines/reference/cloduleWithPriorInstantiatedModule.js b/tests/baselines/reference/cloduleWithPriorInstantiatedModule.js new file mode 100644 index 00000000000..601ab0a7536 --- /dev/null +++ b/tests/baselines/reference/cloduleWithPriorInstantiatedModule.js @@ -0,0 +1,39 @@ +//// [cloduleWithPriorInstantiatedModule.ts] +// Non-ambient & instantiated module. +module Moclodule { + export interface Someinterface { + foo(): void; + } + var x = 10; +} + +class Moclodule { +} + +// Instantiated module. +module Moclodule { + export class Manager { + } +} + +//// [cloduleWithPriorInstantiatedModule.js] +// Non-ambient & instantiated module. +var Moclodule; +(function (Moclodule) { + var x = 10; +})(Moclodule || (Moclodule = {})); +var Moclodule = (function () { + function Moclodule() { + } + return Moclodule; +})(); +// Instantiated module. +var Moclodule; +(function (Moclodule) { + var Manager = (function () { + function Manager() { + } + return Manager; + })(); + Moclodule.Manager = Manager; +})(Moclodule || (Moclodule = {})); diff --git a/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.js b/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.js new file mode 100644 index 00000000000..cf06f1134fb --- /dev/null +++ b/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.js @@ -0,0 +1,33 @@ +//// [cloduleWithPriorUninstantiatedModule.ts] +// Non-ambient & uninstantiated module. +module Moclodule { + export interface Someinterface { + foo(): void; + } +} + +class Moclodule { +} + +// Instantiated module. +module Moclodule { + export class Manager { + } +} + +//// [cloduleWithPriorUninstantiatedModule.js] +var Moclodule = (function () { + function Moclodule() { + } + return Moclodule; +})(); +// Instantiated module. +var Moclodule; +(function (Moclodule) { + var Manager = (function () { + function Manager() { + } + return Manager; + })(); + Moclodule.Manager = Manager; +})(Moclodule || (Moclodule = {})); diff --git a/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.types b/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.types new file mode 100644 index 00000000000..8dc14646a6b --- /dev/null +++ b/tests/baselines/reference/cloduleWithPriorUninstantiatedModule.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/cloduleWithPriorUninstantiatedModule.ts === +// Non-ambient & uninstantiated module. +module Moclodule { +>Moclodule : typeof Moclodule + + export interface Someinterface { +>Someinterface : Someinterface + + foo(): void; +>foo : () => void + } +} + +class Moclodule { +>Moclodule : Moclodule +} + +// Instantiated module. +module Moclodule { +>Moclodule : typeof Moclodule + + export class Manager { +>Manager : Manager + } +} diff --git a/tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts b/tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts new file mode 100644 index 00000000000..c6423ce41a7 --- /dev/null +++ b/tests/cases/compiler/cloduleWithPriorInstantiatedModule.ts @@ -0,0 +1,16 @@ +// Non-ambient & instantiated module. +module Moclodule { + export interface Someinterface { + foo(): void; + } + var x = 10; +} + +class Moclodule { +} + +// Instantiated module. +module Moclodule { + export class Manager { + } +} \ No newline at end of file diff --git a/tests/cases/compiler/cloduleWithPriorUninstantiatedModule.ts b/tests/cases/compiler/cloduleWithPriorUninstantiatedModule.ts new file mode 100644 index 00000000000..0c603b71a4d --- /dev/null +++ b/tests/cases/compiler/cloduleWithPriorUninstantiatedModule.ts @@ -0,0 +1,15 @@ +// Non-ambient & uninstantiated module. +module Moclodule { + export interface Someinterface { + foo(): void; + } +} + +class Moclodule { +} + +// Instantiated module. +module Moclodule { + export class Manager { + } +} \ No newline at end of file