From 43347c79ec1e0cd43551ab183558ec96076e01e4 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 20 Jul 2015 21:49:15 -0700 Subject: [PATCH] treat modules that are merged with values as non-const-enum --- src/compiler/binder.ts | 22 ++++++++++++------- src/compiler/checker.ts | 6 ++++- .../reference/constEnumMergingWithValues1.js | 14 ++++++++++++ .../constEnumMergingWithValues1.symbols | 16 ++++++++++++++ .../constEnumMergingWithValues1.types | 16 ++++++++++++++ .../reference/constEnumMergingWithValues2.js | 18 +++++++++++++++ .../constEnumMergingWithValues2.symbols | 16 ++++++++++++++ .../constEnumMergingWithValues2.types | 16 ++++++++++++++ .../reference/constEnumMergingWithValues3.js | 17 ++++++++++++++ .../constEnumMergingWithValues3.symbols | 17 ++++++++++++++ .../constEnumMergingWithValues3.types | 17 ++++++++++++++ .../reference/constEnumMergingWithValues4.js | 21 ++++++++++++++++++ .../constEnumMergingWithValues4.symbols | 21 ++++++++++++++++++ .../constEnumMergingWithValues4.types | 22 +++++++++++++++++++ .../reference/constEnumMergingWithValues5.js | 19 ++++++++++++++++ .../constEnumMergingWithValues5.symbols | 13 +++++++++++ .../constEnumMergingWithValues5.types | 13 +++++++++++ .../compiler/constEnumMergingWithValues1.ts | 9 ++++++++ .../compiler/constEnumMergingWithValues2.ts | 9 ++++++++ .../compiler/constEnumMergingWithValues3.ts | 9 ++++++++ .../compiler/constEnumMergingWithValues4.ts | 13 +++++++++++ .../compiler/constEnumMergingWithValues5.ts | 9 ++++++++ 22 files changed, 324 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/constEnumMergingWithValues1.js create mode 100644 tests/baselines/reference/constEnumMergingWithValues1.symbols create mode 100644 tests/baselines/reference/constEnumMergingWithValues1.types create mode 100644 tests/baselines/reference/constEnumMergingWithValues2.js create mode 100644 tests/baselines/reference/constEnumMergingWithValues2.symbols create mode 100644 tests/baselines/reference/constEnumMergingWithValues2.types create mode 100644 tests/baselines/reference/constEnumMergingWithValues3.js create mode 100644 tests/baselines/reference/constEnumMergingWithValues3.symbols create mode 100644 tests/baselines/reference/constEnumMergingWithValues3.types create mode 100644 tests/baselines/reference/constEnumMergingWithValues4.js create mode 100644 tests/baselines/reference/constEnumMergingWithValues4.symbols create mode 100644 tests/baselines/reference/constEnumMergingWithValues4.types create mode 100644 tests/baselines/reference/constEnumMergingWithValues5.js create mode 100644 tests/baselines/reference/constEnumMergingWithValues5.symbols create mode 100644 tests/baselines/reference/constEnumMergingWithValues5.types create mode 100644 tests/cases/compiler/constEnumMergingWithValues1.ts create mode 100644 tests/cases/compiler/constEnumMergingWithValues2.ts create mode 100644 tests/cases/compiler/constEnumMergingWithValues3.ts create mode 100644 tests/cases/compiler/constEnumMergingWithValues4.ts create mode 100644 tests/cases/compiler/constEnumMergingWithValues5.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e839d6d6c9a..e842f9a4040 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -518,15 +518,21 @@ namespace ts { } else { declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); - - let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; - if (node.symbol.constEnumOnlyModule === undefined) { - // non-merged case - use the current state - node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; + if (node.symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) { + // if module was already merged with some function, class or non-const enum + // treat is a non-const-enum-only + node.symbol.constEnumOnlyModule = false; } else { - // merged case: module is const enum only if all its pieces are non-instantiated or const enum - node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; + let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly; + if (node.symbol.constEnumOnlyModule === undefined) { + // non-merged case - use the current state + node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly; + } + else { + // merged case: module is const enum only if all its pieces are non-instantiated or const enum + node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly; + } } } } @@ -1056,4 +1062,4 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } } -} +} diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 007edacadc9..a06f13d65f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14028,7 +14028,11 @@ namespace ts { return true; } // const enums and modules that contain only const enums are not considered values from the emit perespective - return target !== unknownSymbol && target && target.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(target); + // unless 'preserveConstEnums' option is set to true + return target !== unknownSymbol && + target && + target.flags & SymbolFlags.Value && + (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target)); } function isConstEnumOrConstEnumOnlyModule(s: Symbol): boolean { diff --git a/tests/baselines/reference/constEnumMergingWithValues1.js b/tests/baselines/reference/constEnumMergingWithValues1.js new file mode 100644 index 00000000000..f47fc227bae --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues1.js @@ -0,0 +1,14 @@ +//// [constEnumMergingWithValues1.ts] + +function foo() {} +module foo { + const enum E { X } +} + +export = foo + +//// [constEnumMergingWithValues1.js] +define(["require", "exports"], function (require, exports) { + function foo() { } + return foo; +}); diff --git a/tests/baselines/reference/constEnumMergingWithValues1.symbols b/tests/baselines/reference/constEnumMergingWithValues1.symbols new file mode 100644 index 00000000000..3dd1c80705c --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/constEnumMergingWithValues1.ts === + +function foo() {} +>foo : Symbol(foo, Decl(constEnumMergingWithValues1.ts, 0, 0), Decl(constEnumMergingWithValues1.ts, 1, 17)) + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues1.ts, 0, 0), Decl(constEnumMergingWithValues1.ts, 1, 17)) + + const enum E { X } +>E : Symbol(E, Decl(constEnumMergingWithValues1.ts, 2, 12)) +>X : Symbol(E.X, Decl(constEnumMergingWithValues1.ts, 3, 18)) +} + +export = foo +>foo : Symbol(foo, Decl(constEnumMergingWithValues1.ts, 0, 0), Decl(constEnumMergingWithValues1.ts, 1, 17)) + diff --git a/tests/baselines/reference/constEnumMergingWithValues1.types b/tests/baselines/reference/constEnumMergingWithValues1.types new file mode 100644 index 00000000000..8d5b15795f7 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues1.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/constEnumMergingWithValues1.ts === + +function foo() {} +>foo : typeof foo + +module foo { +>foo : typeof foo + + const enum E { X } +>E : E +>X : E +} + +export = foo +>foo : typeof foo + diff --git a/tests/baselines/reference/constEnumMergingWithValues2.js b/tests/baselines/reference/constEnumMergingWithValues2.js new file mode 100644 index 00000000000..393ab41fa1f --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues2.js @@ -0,0 +1,18 @@ +//// [constEnumMergingWithValues2.ts] + +class foo {} +module foo { + const enum E { X } +} + +export = foo + +//// [constEnumMergingWithValues2.js] +define(["require", "exports"], function (require, exports) { + var foo = (function () { + function foo() { + } + return foo; + })(); + return foo; +}); diff --git a/tests/baselines/reference/constEnumMergingWithValues2.symbols b/tests/baselines/reference/constEnumMergingWithValues2.symbols new file mode 100644 index 00000000000..bfb438a387d --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues2.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/constEnumMergingWithValues2.ts === + +class foo {} +>foo : Symbol(foo, Decl(constEnumMergingWithValues2.ts, 0, 0), Decl(constEnumMergingWithValues2.ts, 1, 12)) + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues2.ts, 0, 0), Decl(constEnumMergingWithValues2.ts, 1, 12)) + + const enum E { X } +>E : Symbol(E, Decl(constEnumMergingWithValues2.ts, 2, 12)) +>X : Symbol(E.X, Decl(constEnumMergingWithValues2.ts, 3, 18)) +} + +export = foo +>foo : Symbol(foo, Decl(constEnumMergingWithValues2.ts, 0, 0), Decl(constEnumMergingWithValues2.ts, 1, 12)) + diff --git a/tests/baselines/reference/constEnumMergingWithValues2.types b/tests/baselines/reference/constEnumMergingWithValues2.types new file mode 100644 index 00000000000..dd706ef33a1 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues2.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/constEnumMergingWithValues2.ts === + +class foo {} +>foo : foo + +module foo { +>foo : typeof foo + + const enum E { X } +>E : E +>X : E +} + +export = foo +>foo : foo + diff --git a/tests/baselines/reference/constEnumMergingWithValues3.js b/tests/baselines/reference/constEnumMergingWithValues3.js new file mode 100644 index 00000000000..d28f29f0962 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues3.js @@ -0,0 +1,17 @@ +//// [constEnumMergingWithValues3.ts] + +enum foo { A } +module foo { + const enum E { X } +} + +export = foo + +//// [constEnumMergingWithValues3.js] +define(["require", "exports"], function (require, exports) { + var foo; + (function (foo) { + foo[foo["A"] = 0] = "A"; + })(foo || (foo = {})); + return foo; +}); diff --git a/tests/baselines/reference/constEnumMergingWithValues3.symbols b/tests/baselines/reference/constEnumMergingWithValues3.symbols new file mode 100644 index 00000000000..33e020b5679 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues3.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/constEnumMergingWithValues3.ts === + +enum foo { A } +>foo : Symbol(foo, Decl(constEnumMergingWithValues3.ts, 0, 0), Decl(constEnumMergingWithValues3.ts, 1, 14)) +>A : Symbol(foo.A, Decl(constEnumMergingWithValues3.ts, 1, 10)) + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues3.ts, 0, 0), Decl(constEnumMergingWithValues3.ts, 1, 14)) + + const enum E { X } +>E : Symbol(E, Decl(constEnumMergingWithValues3.ts, 2, 12)) +>X : Symbol(E.X, Decl(constEnumMergingWithValues3.ts, 3, 18)) +} + +export = foo +>foo : Symbol(foo, Decl(constEnumMergingWithValues3.ts, 0, 0), Decl(constEnumMergingWithValues3.ts, 1, 14)) + diff --git a/tests/baselines/reference/constEnumMergingWithValues3.types b/tests/baselines/reference/constEnumMergingWithValues3.types new file mode 100644 index 00000000000..df2e8820466 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues3.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/constEnumMergingWithValues3.ts === + +enum foo { A } +>foo : foo +>A : foo + +module foo { +>foo : typeof foo + + const enum E { X } +>E : E +>X : E +} + +export = foo +>foo : foo + diff --git a/tests/baselines/reference/constEnumMergingWithValues4.js b/tests/baselines/reference/constEnumMergingWithValues4.js new file mode 100644 index 00000000000..7ed8b44dc76 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues4.js @@ -0,0 +1,21 @@ +//// [constEnumMergingWithValues4.ts] + +module foo { + const enum E { X } +} + +module foo { + var x = 1; +} + + +export = foo + +//// [constEnumMergingWithValues4.js] +define(["require", "exports"], function (require, exports) { + var foo; + (function (foo) { + var x = 1; + })(foo || (foo = {})); + return foo; +}); diff --git a/tests/baselines/reference/constEnumMergingWithValues4.symbols b/tests/baselines/reference/constEnumMergingWithValues4.symbols new file mode 100644 index 00000000000..817c9aeeff3 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues4.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/constEnumMergingWithValues4.ts === + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues4.ts, 0, 0), Decl(constEnumMergingWithValues4.ts, 3, 1)) + + const enum E { X } +>E : Symbol(E, Decl(constEnumMergingWithValues4.ts, 1, 12)) +>X : Symbol(E.X, Decl(constEnumMergingWithValues4.ts, 2, 18)) +} + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues4.ts, 0, 0), Decl(constEnumMergingWithValues4.ts, 3, 1)) + + var x = 1; +>x : Symbol(x, Decl(constEnumMergingWithValues4.ts, 6, 7)) +} + + +export = foo +>foo : Symbol(foo, Decl(constEnumMergingWithValues4.ts, 0, 0), Decl(constEnumMergingWithValues4.ts, 3, 1)) + diff --git a/tests/baselines/reference/constEnumMergingWithValues4.types b/tests/baselines/reference/constEnumMergingWithValues4.types new file mode 100644 index 00000000000..3da306fedbf --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues4.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/constEnumMergingWithValues4.ts === + +module foo { +>foo : typeof foo + + const enum E { X } +>E : E +>X : E +} + +module foo { +>foo : typeof foo + + var x = 1; +>x : number +>1 : number +} + + +export = foo +>foo : typeof foo + diff --git a/tests/baselines/reference/constEnumMergingWithValues5.js b/tests/baselines/reference/constEnumMergingWithValues5.js new file mode 100644 index 00000000000..378b11cfd22 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues5.js @@ -0,0 +1,19 @@ +//// [constEnumMergingWithValues5.ts] + +module foo { + const enum E { X } +} + +export = foo + +//// [constEnumMergingWithValues5.js] +define(["require", "exports"], function (require, exports) { + var foo; + (function (foo) { + var E; + (function (E) { + E[E["X"] = 0] = "X"; + })(E || (E = {})); + })(foo || (foo = {})); + return foo; +}); diff --git a/tests/baselines/reference/constEnumMergingWithValues5.symbols b/tests/baselines/reference/constEnumMergingWithValues5.symbols new file mode 100644 index 00000000000..6354f64d834 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues5.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/constEnumMergingWithValues5.ts === + +module foo { +>foo : Symbol(foo, Decl(constEnumMergingWithValues5.ts, 0, 0)) + + const enum E { X } +>E : Symbol(E, Decl(constEnumMergingWithValues5.ts, 1, 12)) +>X : Symbol(E.X, Decl(constEnumMergingWithValues5.ts, 2, 18)) +} + +export = foo +>foo : Symbol(foo, Decl(constEnumMergingWithValues5.ts, 0, 0)) + diff --git a/tests/baselines/reference/constEnumMergingWithValues5.types b/tests/baselines/reference/constEnumMergingWithValues5.types new file mode 100644 index 00000000000..617676ba0c0 --- /dev/null +++ b/tests/baselines/reference/constEnumMergingWithValues5.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/constEnumMergingWithValues5.ts === + +module foo { +>foo : typeof foo + + const enum E { X } +>E : E +>X : E +} + +export = foo +>foo : typeof foo + diff --git a/tests/cases/compiler/constEnumMergingWithValues1.ts b/tests/cases/compiler/constEnumMergingWithValues1.ts new file mode 100644 index 00000000000..0c2919c70df --- /dev/null +++ b/tests/cases/compiler/constEnumMergingWithValues1.ts @@ -0,0 +1,9 @@ +//@module: amd +//@filename: m1.ts + +function foo() {} +module foo { + const enum E { X } +} + +export = foo \ No newline at end of file diff --git a/tests/cases/compiler/constEnumMergingWithValues2.ts b/tests/cases/compiler/constEnumMergingWithValues2.ts new file mode 100644 index 00000000000..3f30fdf4d3a --- /dev/null +++ b/tests/cases/compiler/constEnumMergingWithValues2.ts @@ -0,0 +1,9 @@ +//@module: amd +//@filename: m1.ts + +class foo {} +module foo { + const enum E { X } +} + +export = foo \ No newline at end of file diff --git a/tests/cases/compiler/constEnumMergingWithValues3.ts b/tests/cases/compiler/constEnumMergingWithValues3.ts new file mode 100644 index 00000000000..8edadc2eb38 --- /dev/null +++ b/tests/cases/compiler/constEnumMergingWithValues3.ts @@ -0,0 +1,9 @@ +//@module: amd +//@filename: m1.ts + +enum foo { A } +module foo { + const enum E { X } +} + +export = foo \ No newline at end of file diff --git a/tests/cases/compiler/constEnumMergingWithValues4.ts b/tests/cases/compiler/constEnumMergingWithValues4.ts new file mode 100644 index 00000000000..036c62c1de4 --- /dev/null +++ b/tests/cases/compiler/constEnumMergingWithValues4.ts @@ -0,0 +1,13 @@ +//@module: amd +//@filename: m1.ts + +module foo { + const enum E { X } +} + +module foo { + var x = 1; +} + + +export = foo \ No newline at end of file diff --git a/tests/cases/compiler/constEnumMergingWithValues5.ts b/tests/cases/compiler/constEnumMergingWithValues5.ts new file mode 100644 index 00000000000..aebb0abfaec --- /dev/null +++ b/tests/cases/compiler/constEnumMergingWithValues5.ts @@ -0,0 +1,9 @@ +//@module: amd +//@filename: m1.ts +//@preserveConstEnums: true + +module foo { + const enum E { X } +} + +export = foo \ No newline at end of file