diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cecc70c3e2d97..cce4cdb2debef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -844,7 +844,7 @@ namespace ts { (source.flags | target.flags) & SymbolFlags.Assignment) { Debug.assert(source !== target); if (!(target.flags & SymbolFlags.Transient)) { - target = cloneSymbol(target); + target = cloneSymbol(resolveSymbol(target)); } // Javascript static-property-assignment declarations always merge, even though they are also values if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) { @@ -873,7 +873,7 @@ namespace ts { else if (target.flags & SymbolFlags.NamespaceModule) { error(getNameOfDeclaration(source.declarations[0]), Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); } - else { + else { // error const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum); const isEitherBlockScoped = !!(target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable); const message = isEitherEnum @@ -942,7 +942,8 @@ namespace ts { function mergeSymbolTable(target: SymbolTable, source: SymbolTable) { source.forEach((sourceSymbol, id) => { - target.set(id, target.has(id) ? mergeSymbol(target.get(id)!, sourceSymbol) : sourceSymbol); + const targetSymbol = target.get(id); + target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol) : sourceSymbol); }); } @@ -1536,8 +1537,7 @@ namespace ts { // If we're in an external module, we can't reference value symbols created from UMD export declarations if (result && isInExternalModule && (meaning & SymbolFlags.Value) === SymbolFlags.Value && !(originalLocation!.flags & NodeFlags.JSDoc)) { - const decls = result.declarations; - if (decls && decls.length === 1 && decls[0].kind === SyntaxKind.NamespaceExportDeclaration) { + if (some(result.declarations, d => isNamespaceExportDeclaration(d) || isSourceFile(d) && !!d.symbol.globalExports)) { error(errorLocation!, Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, unescapeLeadingUnderscores(name)); // TODO: GH#18217 } } diff --git a/tests/baselines/reference/duplicateVarsAcrossFileBoundaries.symbols b/tests/baselines/reference/duplicateVarsAcrossFileBoundaries.symbols index a1f6cdf1b3868..9cedc15a75a5c 100644 --- a/tests/baselines/reference/duplicateVarsAcrossFileBoundaries.symbols +++ b/tests/baselines/reference/duplicateVarsAcrossFileBoundaries.symbols @@ -34,10 +34,10 @@ var z = 0; === tests/cases/compiler/duplicateVarsAcrossFileBoundaries_4.ts === module P { } ->P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0)) +>P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3)) import p = P; ->p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3)) +>p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12)) >P : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0)) var q; @@ -52,5 +52,5 @@ import q = Q; >Q : Symbol(Q, Decl(duplicateVarsAcrossFileBoundaries_5.ts, 0, 0)) var p; ->p : Symbol(p, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 12), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3)) +>p : Symbol(P, Decl(duplicateVarsAcrossFileBoundaries_4.ts, 0, 0), Decl(duplicateVarsAcrossFileBoundaries_5.ts, 2, 3)) diff --git a/tests/baselines/reference/exportAsNamespace_augment.errors.txt b/tests/baselines/reference/exportAsNamespace_augment.errors.txt new file mode 100644 index 0000000000000..76cb643d62ac1 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_augment.errors.txt @@ -0,0 +1,50 @@ +/a.d.ts(3,14): error TS2451: Cannot redeclare block-scoped variable 'conflict'. +/b.ts(6,22): error TS2451: Cannot redeclare block-scoped variable 'conflict'. +/b.ts(12,18): error TS2451: Cannot redeclare block-scoped variable 'conflict'. +/b.ts(15,1): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. +/b.ts(15,7): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. +/b.ts(15,13): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. +/b.ts(15,19): error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. + + +==== /a.d.ts (1 errors) ==== + export as namespace a; + export const x = 0; + export const conflict = 0; + ~~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'. +!!! related TS6203 /b.ts:6:22: 'conflict' was also declared here. +!!! related TS6204 /b.ts:6:22: and here. + +==== /b.ts (6 errors) ==== + import * as a2 from "./a"; + + declare global { + namespace a { + export const y = 0; + export const conflict = 0; + ~~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'. +!!! related TS6203 /a.d.ts:3:14: 'conflict' was also declared here. + } + } + + declare module "./a" { + export const z = 0; + export const conflict = 0; + ~~~~~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'conflict'. +!!! related TS6203 /a.d.ts:3:14: 'conflict' was also declared here. + } + + a.x + a.y + a.z + a.conflict; + ~ +!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. + ~ +!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. + ~ +!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. + ~ +!!! error TS2686: 'a' refers to a UMD global, but the current file is a module. Consider adding an import instead. + a2.x + a2.y + a2.z + a2.conflict; + \ No newline at end of file diff --git a/tests/baselines/reference/exportAsNamespace_augment.js b/tests/baselines/reference/exportAsNamespace_augment.js new file mode 100644 index 0000000000000..6186d698791ea --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_augment.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/exportAsNamespace_augment.ts] //// + +//// [a.d.ts] +export as namespace a; +export const x = 0; +export const conflict = 0; + +//// [b.ts] +import * as a2 from "./a"; + +declare global { + namespace a { + export const y = 0; + export const conflict = 0; + } +} + +declare module "./a" { + export const z = 0; + export const conflict = 0; +} + +a.x + a.y + a.z + a.conflict; +a2.x + a2.y + a2.z + a2.conflict; + + +//// [b.js] +"use strict"; +exports.__esModule = true; +var a2 = require("./a"); +a.x + a.y + a.z + a.conflict; +a2.x + a2.y + a2.z + a2.conflict; diff --git a/tests/baselines/reference/exportAsNamespace_augment.symbols b/tests/baselines/reference/exportAsNamespace_augment.symbols new file mode 100644 index 0000000000000..27c45f371c720 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_augment.symbols @@ -0,0 +1,66 @@ +=== /a.d.ts === +export as namespace a; +>a : Symbol(a, Decl(a.d.ts, 0, 0)) + +export const x = 0; +>x : Symbol(x, Decl(a.d.ts, 1, 12)) + +export const conflict = 0; +>conflict : Symbol(conflict, Decl(a.d.ts, 2, 12)) + +=== /b.ts === +import * as a2 from "./a"; +>a2 : Symbol(a2, Decl(b.ts, 0, 6)) + +declare global { +>global : Symbol(global, Decl(b.ts, 0, 26)) + + namespace a { +>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) + + export const y = 0; +>y : Symbol(y, Decl(b.ts, 4, 20)) + + export const conflict = 0; +>conflict : Symbol(conflict, Decl(b.ts, 5, 20)) + } +} + +declare module "./a" { +>"./a" : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) + + export const z = 0; +>z : Symbol(z, Decl(b.ts, 10, 16)) + + export const conflict = 0; +>conflict : Symbol(conflict, Decl(b.ts, 11, 16)) +} + +a.x + a.y + a.z + a.conflict; +>a.x : Symbol(a2.x, Decl(a.d.ts, 1, 12)) +>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) +>x : Symbol(a2.x, Decl(a.d.ts, 1, 12)) +>a.y : Symbol(a2.y, Decl(b.ts, 4, 20)) +>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) +>y : Symbol(a2.y, Decl(b.ts, 4, 20)) +>a.z : Symbol(a2.z, Decl(b.ts, 10, 16)) +>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) +>z : Symbol(a2.z, Decl(b.ts, 10, 16)) +>a.conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12)) +>a : Symbol(a2, Decl(a.d.ts, 0, 0), Decl(b.ts, 2, 16), Decl(b.ts, 7, 1)) +>conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12)) + +a2.x + a2.y + a2.z + a2.conflict; +>a2.x : Symbol(a2.x, Decl(a.d.ts, 1, 12)) +>a2 : Symbol(a2, Decl(b.ts, 0, 6)) +>x : Symbol(a2.x, Decl(a.d.ts, 1, 12)) +>a2.y : Symbol(a2.y, Decl(b.ts, 4, 20)) +>a2 : Symbol(a2, Decl(b.ts, 0, 6)) +>y : Symbol(a2.y, Decl(b.ts, 4, 20)) +>a2.z : Symbol(a2.z, Decl(b.ts, 10, 16)) +>a2 : Symbol(a2, Decl(b.ts, 0, 6)) +>z : Symbol(a2.z, Decl(b.ts, 10, 16)) +>a2.conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12)) +>a2 : Symbol(a2, Decl(b.ts, 0, 6)) +>conflict : Symbol(a2.conflict, Decl(a.d.ts, 2, 12)) + diff --git a/tests/baselines/reference/exportAsNamespace_augment.types b/tests/baselines/reference/exportAsNamespace_augment.types new file mode 100644 index 0000000000000..0e186f57c6fa1 --- /dev/null +++ b/tests/baselines/reference/exportAsNamespace_augment.types @@ -0,0 +1,78 @@ +=== /a.d.ts === +export as namespace a; +>a : typeof import("/a") + +export const x = 0; +>x : 0 +>0 : 0 + +export const conflict = 0; +>conflict : 0 +>0 : 0 + +=== /b.ts === +import * as a2 from "./a"; +>a2 : typeof a2 + +declare global { +>global : typeof global + + namespace a { +>a : typeof a2 + + export const y = 0; +>y : 0 +>0 : 0 + + export const conflict = 0; +>conflict : 0 +>0 : 0 + } +} + +declare module "./a" { +>"./a" : typeof a2 + + export const z = 0; +>z : 0 +>0 : 0 + + export const conflict = 0; +>conflict : 0 +>0 : 0 +} + +a.x + a.y + a.z + a.conflict; +>a.x + a.y + a.z + a.conflict : number +>a.x + a.y + a.z : number +>a.x + a.y : number +>a.x : 0 +>a : typeof a2 +>x : 0 +>a.y : 0 +>a : typeof a2 +>y : 0 +>a.z : 0 +>a : typeof a2 +>z : 0 +>a.conflict : 0 +>a : typeof a2 +>conflict : 0 + +a2.x + a2.y + a2.z + a2.conflict; +>a2.x + a2.y + a2.z + a2.conflict : number +>a2.x + a2.y + a2.z : number +>a2.x + a2.y : number +>a2.x : 0 +>a2 : typeof a2 +>x : 0 +>a2.y : 0 +>a2 : typeof a2 +>y : 0 +>a2.z : 0 +>a2 : typeof a2 +>z : 0 +>a2.conflict : 0 +>a2 : typeof a2 +>conflict : 0 + diff --git a/tests/cases/compiler/exportAsNamespace_augment.ts b/tests/cases/compiler/exportAsNamespace_augment.ts new file mode 100644 index 0000000000000..2c972a32acc5e --- /dev/null +++ b/tests/cases/compiler/exportAsNamespace_augment.ts @@ -0,0 +1,22 @@ +// @Filename: /a.d.ts +export as namespace a; +export const x = 0; +export const conflict = 0; + +// @Filename: /b.ts +import * as a2 from "./a"; + +declare global { + namespace a { + export const y = 0; + export const conflict = 0; + } +} + +declare module "./a" { + export const z = 0; + export const conflict = 0; +} + +a.x + a.y + a.z + a.conflict; +a2.x + a2.y + a2.z + a2.conflict;