From ff7169530b18a874d396ace114be3e2e4dbfa31c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 6 Oct 2015 12:49:42 -0700 Subject: [PATCH 01/22] trial of change --- src/compiler/checker.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 40db300d310..ec2a5bfb020 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1020,11 +1020,14 @@ namespace ts { return links.resolvedExports || (links.resolvedExports = getExportsForModule(moduleSymbol)); } - function extendExportSymbols(target: SymbolTable, source: SymbolTable) { + function extendExportSymbols(originalModule: Symbol, target: SymbolTable, source: SymbolTable) { for (let id in source) { if (id !== "default" && !hasProperty(target, id)) { target[id] = source[id]; } + else if (id !== "default" && hasProperty(target, id)) { + diagnostics.add(createFileDiagnostic(getSourceFileOfNode(originalModule.valueDeclaration), 0, 0, Diagnostics.Duplicate_identifier_0, id)); + } } } @@ -1043,7 +1046,7 @@ namespace ts { if (!result) { result = cloneSymbolTable(moduleSymbol.exports); } - extendExportSymbols(result, symbol.exports); + extendExportSymbols(moduleSymbol, result, symbol.exports); } // All export * declarations are collected in an __export symbol by the binder let exportStars = symbol.exports["__export"]; From b9800f09b7e8f398b2f58025175ea42a3d1e522a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 6 Oct 2015 15:50:35 -0700 Subject: [PATCH 02/22] Handle export * reexport errors smartly --- src/compiler/checker.ts | 52 +++++++++++++------ src/compiler/diagnosticMessages.json | 4 ++ .../reference/exportStar-amd.errors.txt | 8 ++- .../baselines/reference/exportStar.errors.txt | 8 ++- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ec2a5bfb020..e4423773555 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1020,41 +1020,62 @@ namespace ts { return links.resolvedExports || (links.resolvedExports = getExportsForModule(moduleSymbol)); } - function extendExportSymbols(originalModule: Symbol, target: SymbolTable, source: SymbolTable) { + interface ExportStarDiagnosticsLookupTable { + [id: string]: {specifierText: string, exportsWithDuplicate: ExportDeclaration[]}; + } + + function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: ExportStarDiagnosticsLookupTable, exportNode?: ExportDeclaration) { for (let id in source) { if (id !== "default" && !hasProperty(target, id)) { target[id] = source[id]; + if (lookupTable && exportNode) { + lookupTable[id] = { + specifierText: getTextOfNode(exportNode.moduleSpecifier), + exportsWithDuplicate: [] + }; + } } - else if (id !== "default" && hasProperty(target, id)) { - diagnostics.add(createFileDiagnostic(getSourceFileOfNode(originalModule.valueDeclaration), 0, 0, Diagnostics.Duplicate_identifier_0, id)); + else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id)) { + lookupTable[id].exportsWithDuplicate.push(exportNode); } } } function getExportsForModule(moduleSymbol: Symbol): SymbolTable { - let result: SymbolTable; let visitedSymbols: Symbol[] = []; - visit(moduleSymbol); - return result || moduleSymbol.exports; + return visit(moduleSymbol) || moduleSymbol.exports; // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example, // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error. - function visit(symbol: Symbol) { + function visit(symbol: Symbol): SymbolTable { if (symbol && symbol.flags & SymbolFlags.HasExports && !contains(visitedSymbols, symbol)) { visitedSymbols.push(symbol); - if (symbol !== moduleSymbol) { - if (!result) { - result = cloneSymbolTable(moduleSymbol.exports); - } - extendExportSymbols(moduleSymbol, result, symbol.exports); - } + let symbols: SymbolTable = cloneSymbolTable(symbol.exports); // All export * declarations are collected in an __export symbol by the binder let exportStars = symbol.exports["__export"]; if (exportStars) { + let nestedSymbols: SymbolTable = {}; + let lookupTable: ExportStarDiagnosticsLookupTable = {}; for (let node of exportStars.declarations) { - visit(resolveExternalModuleName(node, (node).moduleSpecifier)); + let resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier); + let exportedSymbols = visit(resolvedModule); + extendExportSymbols( + nestedSymbols, + exportedSymbols, + lookupTable, + node as ExportDeclaration + ); } + for (let id in lookupTable) { + if (id !== "export=" && lookupTable[id].exportsWithDuplicate.length && !(id in symbols)) { // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + for (let node of lookupTable[id].exportsWithDuplicate) { + diagnostics.add(createDiagnosticForNode(node, Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable[id].specifierText, id)); + } + } + } + extendExportSymbols(symbols, nestedSymbols); } + return symbols; } } } @@ -13701,13 +13722,14 @@ namespace ts { function checkExternalModuleExports(node: SourceFile | ModuleDeclaration) { let moduleSymbol = getSymbolOfNode(node); - let links = getSymbolLinks(moduleSymbol); + let links: SymbolLinks = getSymbolLinks(moduleSymbol); if (!links.exportsChecked) { let exportEqualsSymbol = moduleSymbol.exports["export="]; if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) { let declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } + getExportsOfModule(moduleSymbol); // Checks for export * conflicts links.exportsChecked = true; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f6656edb250..0f14ea0b021 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -832,6 +832,10 @@ "category": "Error", "code": 2307 }, + "An 'export * from {0}' declaration has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { + "category": "Error", + "code": 2308 + }, "An export assignment cannot be used in a module with other exported elements.": { "category": "Error", "code": 2309 diff --git a/tests/baselines/reference/exportStar-amd.errors.txt b/tests/baselines/reference/exportStar-amd.errors.txt index adab0516103..237290485b0 100644 --- a/tests/baselines/reference/exportStar-amd.errors.txt +++ b/tests/baselines/reference/exportStar-amd.errors.txt @@ -1,4 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -16,10 +18,14 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/c var z = "z"; export { x, y, z }; -==== tests/cases/conformance/es6/modules/t4.ts (0 errors) ==== +==== tests/cases/conformance/es6/modules/t4.ts (2 errors) ==== export * from "./t1"; export * from "./t2"; export * from "./t3"; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; diff --git a/tests/baselines/reference/exportStar.errors.txt b/tests/baselines/reference/exportStar.errors.txt index adab0516103..237290485b0 100644 --- a/tests/baselines/reference/exportStar.errors.txt +++ b/tests/baselines/reference/exportStar.errors.txt @@ -1,4 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -16,10 +18,14 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/c var z = "z"; export { x, y, z }; -==== tests/cases/conformance/es6/modules/t4.ts (0 errors) ==== +==== tests/cases/conformance/es6/modules/t4.ts (2 errors) ==== export * from "./t1"; export * from "./t2"; export * from "./t3"; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; From d8aa469a7d26caf4fa2b4504f3ae626abd0a6e72 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 6 Oct 2015 17:59:14 -0700 Subject: [PATCH 03/22] forbid duplicate var exports --- src/compiler/checker.ts | 21 +++- src/compiler/diagnosticMessages.json | 4 + ...lowedWithNamedImport1WithExport.errors.txt | 20 +++- ...llowedWithNamedImportWithExport.errors.txt | 20 +++- .../es6ImportNamedImportWithExport.errors.txt | 32 ++++- .../moduleDuplicateIdentifiers.errors.txt | 44 +++++++ .../reference/moduleDuplicateIdentifiers.js | 58 +++++++++ .../multipleDefaultExports02.errors.txt | 8 +- ...tExternalModuleImportWithExport.errors.txt | 55 +++++++++ ...ientExternalModuleImportWithExport.symbols | 105 ---------------- ...mbientExternalModuleImportWithExport.types | 113 ------------------ ...ternalModuleImportWithoutExport.errors.txt | 55 +++++++++ ...tExternalModuleImportWithoutExport.symbols | 105 ---------------- ...entExternalModuleImportWithoutExport.types | 113 ------------------ .../typeofANonExportedType.errors.txt | 8 +- .../reference/typeofAnExportedType.errors.txt | 8 +- .../compiler/moduleDuplicateIdentifiers.ts | 30 +++++ 17 files changed, 356 insertions(+), 443 deletions(-) create mode 100644 tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt create mode 100644 tests/baselines/reference/moduleDuplicateIdentifiers.js create mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.errors.txt delete mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.symbols delete mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.types create mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.errors.txt delete mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.symbols delete mode 100644 tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.types create mode 100644 tests/cases/compiler/moduleDuplicateIdentifiers.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e4423773555..1a692572802 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13729,7 +13729,26 @@ namespace ts { let declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } - getExportsOfModule(moduleSymbol); // Checks for export * conflicts + let exports = getExportsOfModule(moduleSymbol); // Checks for export * conflicts + for (let id in exports) { + if (id === "__export") continue; + if (!(exports[id].flags & SymbolFlags.Namespace || exports[id].flags & SymbolFlags.Interface) && exports[id].declarations.length > 1) { // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, and interfaces) + let exportedDeclarations: Declaration[] = []; + for (let declaration of exports[id].declarations) { + if (declaration.kind === SyntaxKind.FunctionDeclaration) { + if (!(declaration as FunctionDeclaration).body) { + continue; + } + } + exportedDeclarations.push(declaration); + } + if (exportedDeclarations.length > 1) { + for (let declaration of exportedDeclarations) { + diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, id)); + } + } + } + } links.exportsChecked = true; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0f14ea0b021..51fd7a1fa2e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -892,6 +892,10 @@ "category": "Error", "code": 2322 }, + "Cannot redeclare exported variable '{0}'.": { + "category": "Error", + "code": 2323 + }, "Property '{0}' is missing in type '{1}'.": { "category": "Error", "code": 2324 diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1WithExport.errors.txt b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1WithExport.errors.txt index 76c424a74d4..97c66a17960 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1WithExport.errors.txt +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1WithExport.errors.txt @@ -1,15 +1,21 @@ tests/cases/compiler/client.ts(1,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(2,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(3,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(3,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. +tests/cases/compiler/client.ts(4,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(5,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(5,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. +tests/cases/compiler/client.ts(6,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(7,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(7,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'. tests/cases/compiler/client.ts(7,37): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. +tests/cases/compiler/client.ts(8,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(9,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(9,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'. +tests/cases/compiler/client.ts(10,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(11,34): error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'. +tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported variable 'x1'. ==== tests/cases/compiler/server.ts (0 errors) ==== @@ -17,23 +23,29 @@ tests/cases/compiler/client.ts(11,34): error TS2305: Module '"tests/cases/compil var a = 10; export default a; -==== tests/cases/compiler/client.ts (12 errors) ==== +==== tests/cases/compiler/client.ts (18 errors) ==== export import defaultBinding1, { } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = defaultBinding1; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding2, { a } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. ~ !!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. export var x1: number = defaultBinding2; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding3, { a as b } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. ~ !!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. export var x1: number = defaultBinding3; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding4, { x, a as y } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. @@ -42,16 +54,22 @@ tests/cases/compiler/client.ts(11,34): error TS2305: Module '"tests/cases/compil ~ !!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'a'. export var x1: number = defaultBinding4; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding5, { x as z, } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. ~ !!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'x'. export var x1: number = defaultBinding5; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding6, { m, } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. ~ !!! error TS2305: Module '"tests/cases/compiler/server"' has no exported member 'm'. export var x1: number = defaultBinding6; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. \ No newline at end of file diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.errors.txt b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.errors.txt index 83f91787b87..859fe59b47f 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.errors.txt +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImportWithExport.errors.txt @@ -1,9 +1,15 @@ tests/cases/compiler/client.ts(1,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(2,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(3,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(4,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(5,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(6,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(7,12): error TS2323: Cannot redeclare exported variable 'x1'. +tests/cases/compiler/client.ts(8,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(9,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(10,12): error TS2323: Cannot redeclare exported variable 'x1'. tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported variable 'x1'. ==== tests/cases/compiler/server.ts (0 errors) ==== @@ -13,7 +19,7 @@ tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot export var m = a; export default {}; -==== tests/cases/compiler/client.ts (6 errors) ==== +==== tests/cases/compiler/client.ts (12 errors) ==== export import defaultBinding1, { } from "server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. @@ -21,21 +27,33 @@ tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = a; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding3, { a as b } from "server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = b; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding4, { x, a as y } from "server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = x; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export var x1: number = y; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding5, { x as z, } from "server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = z; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. export import defaultBinding6, { m, } from "server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var x1: number = m; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'x1'. \ No newline at end of file diff --git a/tests/baselines/reference/es6ImportNamedImportWithExport.errors.txt b/tests/baselines/reference/es6ImportNamedImportWithExport.errors.txt index a5a4301683e..3b2d6b0cbd0 100644 --- a/tests/baselines/reference/es6ImportNamedImportWithExport.errors.txt +++ b/tests/baselines/reference/es6ImportNamedImportWithExport.errors.txt @@ -1,11 +1,21 @@ tests/cases/compiler/client.ts(1,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(2,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(3,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(4,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(5,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(6,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(7,12): error TS2323: Cannot redeclare exported variable 'xxxx'. +tests/cases/compiler/client.ts(8,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(9,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(10,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(11,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(12,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(13,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(14,12): error TS2323: Cannot redeclare exported variable 'xxxx'. +tests/cases/compiler/client.ts(15,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(16,1): error TS1191: An import declaration cannot have modifiers. +tests/cases/compiler/client.ts(17,12): error TS2323: Cannot redeclare exported variable 'xxxx'. +tests/cases/compiler/client.ts(18,12): error TS2323: Cannot redeclare exported variable 'xxxx'. tests/cases/compiler/client.ts(19,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(21,1): error TS1191: An import declaration cannot have modifiers. tests/cases/compiler/client.ts(25,1): error TS1191: An import declaration cannot have modifiers. @@ -23,7 +33,7 @@ tests/cases/compiler/client.ts(26,1): error TS1191: An import declaration cannot export var z2 = 10; export var aaaa = 10; -==== tests/cases/compiler/client.ts (12 errors) ==== +==== tests/cases/compiler/client.ts (22 errors) ==== export import { } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. @@ -31,33 +41,53 @@ tests/cases/compiler/client.ts(26,1): error TS1191: An import declaration cannot ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = a; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { a as b } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = b; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { x, a as y } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = x; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export var xxxx = y; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { x as z, } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = z; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { m, } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = m; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { a1, x1 } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = a1; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export var xxxx = x1; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { a1 as a11, x1 as x11 } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. export var xxxx = a11; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export var xxxx = x11; + ~~~~ +!!! error TS2323: Cannot redeclare exported variable 'xxxx'. export import { z1 } from "./server"; ~~~~~~ !!! error TS1191: An import declaration cannot have modifiers. diff --git a/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt b/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt new file mode 100644 index 00000000000..67ab99eee4b --- /dev/null +++ b/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt @@ -0,0 +1,44 @@ +tests/cases/compiler/moduleDuplicateIdentifiers.ts(1,12): error TS2323: Cannot redeclare exported variable 'Foo'. +tests/cases/compiler/moduleDuplicateIdentifiers.ts(2,12): error TS2323: Cannot redeclare exported variable 'Foo'. +tests/cases/compiler/moduleDuplicateIdentifiers.ts(20,14): error TS2300: Duplicate identifier 'Kettle'. +tests/cases/compiler/moduleDuplicateIdentifiers.ts(24,14): error TS2300: Duplicate identifier 'Kettle'. + + +==== tests/cases/compiler/moduleDuplicateIdentifiers.ts (4 errors) ==== + export var Foo = 2; + ~~~ +!!! error TS2323: Cannot redeclare exported variable 'Foo'. + export var Foo = 42; // Should error + ~~~ +!!! error TS2323: Cannot redeclare exported variable 'Foo'. + + export interface Bar { + _brand1: any; + } + + export interface Bar { + _brand2: any; + } + + export namespace FooBar { + export var member1 = 2; + } + + export namespace FooBar { + export var member2 = 42; + } + + export class Kettle { + ~~~~~~ +!!! error TS2300: Duplicate identifier 'Kettle'. + member1 = 2; + } + + export class Kettle { + ~~~~~~ +!!! error TS2300: Duplicate identifier 'Kettle'. + member2 = 42; + } + + export var Pot = 2; + Pot = 42; // Shouldn't error \ No newline at end of file diff --git a/tests/baselines/reference/moduleDuplicateIdentifiers.js b/tests/baselines/reference/moduleDuplicateIdentifiers.js new file mode 100644 index 00000000000..e428ccd3c81 --- /dev/null +++ b/tests/baselines/reference/moduleDuplicateIdentifiers.js @@ -0,0 +1,58 @@ +//// [moduleDuplicateIdentifiers.ts] +export var Foo = 2; +export var Foo = 42; // Should error + +export interface Bar { + _brand1: any; +} + +export interface Bar { + _brand2: any; +} + +export namespace FooBar { + export var member1 = 2; +} + +export namespace FooBar { + export var member2 = 42; +} + +export class Kettle { + member1 = 2; +} + +export class Kettle { + member2 = 42; +} + +export var Pot = 2; +Pot = 42; // Shouldn't error + +//// [moduleDuplicateIdentifiers.js] +exports.Foo = 2; +exports.Foo = 42; // Should error +var FooBar; +(function (FooBar) { + FooBar.member1 = 2; +})(FooBar = exports.FooBar || (exports.FooBar = {})); +var FooBar; +(function (FooBar) { + FooBar.member2 = 42; +})(FooBar = exports.FooBar || (exports.FooBar = {})); +var Kettle = (function () { + function Kettle() { + this.member1 = 2; + } + return Kettle; +})(); +exports.Kettle = Kettle; +var Kettle = (function () { + function Kettle() { + this.member2 = 42; + } + return Kettle; +})(); +exports.Kettle = Kettle; +exports.Pot = 2; +exports.Pot = 42; // Shouldn't error diff --git a/tests/baselines/reference/multipleDefaultExports02.errors.txt b/tests/baselines/reference/multipleDefaultExports02.errors.txt index 235f8f7c3e3..3f27db47c94 100644 --- a/tests/baselines/reference/multipleDefaultExports02.errors.txt +++ b/tests/baselines/reference/multipleDefaultExports02.errors.txt @@ -1,17 +1,23 @@ +tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2323: Cannot redeclare exported variable 'default'. tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2393: Duplicate function implementation. +tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2323: Cannot redeclare exported variable 'default'. tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ==== +==== tests/cases/conformance/es6/modules/m1.ts (4 errors) ==== export default function foo() { ~~~ +!!! error TS2323: Cannot redeclare exported variable 'default'. + ~~~ !!! error TS2393: Duplicate function implementation. } export default function bar() { ~~~ +!!! error TS2323: Cannot redeclare exported variable 'default'. + ~~~ !!! error TS2393: Duplicate function implementation. } diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.errors.txt b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.errors.txt new file mode 100644 index 00000000000..52d6c4c0fff --- /dev/null +++ b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_core.ts(15,12): error TS2323: Cannot redeclare exported variable 'publicUse_im_public_mi_public'. +tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_core.ts(17,12): error TS2323: Cannot redeclare exported variable 'publicUse_im_public_mi_public'. + + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_core.ts (2 errors) ==== + /// + /// + // Privacy errors - importing private elements + export import im_public_mi_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require"); + export import im_public_mu_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require1"); + export import im_public_mi_public = require("m"); + export import im_public_mu_public = require("m2"); + + // Usage of privacy error imports + var privateUse_im_public_mi_private = new im_public_mi_private.c_public(); + export var publicUse_im_public_mi_private = new im_public_mi_private.c_public(); + var privateUse_im_public_mu_private = new im_public_mu_private.c_public(); + export var publicUse_im_public_mu_private = new im_public_mu_private.c_public(); + var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); + export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2323: Cannot redeclare exported variable 'publicUse_im_public_mi_public'. + var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); + export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2323: Cannot redeclare exported variable 'publicUse_im_public_mi_public'. + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require.ts (0 errors) ==== + // Public elements + export class c_public { + foo: string; + } + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts (0 errors) ==== + export class c_public { + bar: string; + } + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts (0 errors) ==== + // private elements + // Export - Error ambient modules allowed only in global + declare module 'm' { + export class c_private { + baz: string; + } + } + + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require3.ts (0 errors) ==== + declare module 'm2' { + export class c_private { + bing: string; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.symbols b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.symbols deleted file mode 100644 index 2dcddbbfa06..00000000000 --- a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.symbols +++ /dev/null @@ -1,105 +0,0 @@ -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_core.ts === -/// -/// -// Privacy errors - importing private elements -export import im_public_mi_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require"); ->im_public_mi_private : Symbol(im_public_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 0, 0)) - -export import im_public_mu_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require1"); ->im_public_mu_private : Symbol(im_public_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 3, 111)) - -export import im_public_mi_public = require("m"); ->im_public_mi_public : Symbol(im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 4, 112)) - -export import im_public_mu_public = require("m2"); ->im_public_mu_public : Symbol(im_public_mu_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 5, 49)) - -// Usage of privacy error imports -var privateUse_im_public_mi_private = new im_public_mi_private.c_public(); ->privateUse_im_public_mi_private : Symbol(privateUse_im_public_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 9, 3)) ->im_public_mi_private.c_public : Symbol(im_public_mi_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 0, 0)) ->im_public_mi_private : Symbol(im_public_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 0, 0)) ->c_public : Symbol(im_public_mi_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 0, 0)) - -export var publicUse_im_public_mi_private = new im_public_mi_private.c_public(); ->publicUse_im_public_mi_private : Symbol(publicUse_im_public_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 10, 10)) ->im_public_mi_private.c_public : Symbol(im_public_mi_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 0, 0)) ->im_public_mi_private : Symbol(im_public_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 0, 0)) ->c_public : Symbol(im_public_mi_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 0, 0)) - -var privateUse_im_public_mu_private = new im_public_mu_private.c_public(); ->privateUse_im_public_mu_private : Symbol(privateUse_im_public_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 11, 3)) ->im_public_mu_private.c_public : Symbol(im_public_mu_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 0)) ->im_public_mu_private : Symbol(im_public_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 3, 111)) ->c_public : Symbol(im_public_mu_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 0)) - -export var publicUse_im_public_mu_private = new im_public_mu_private.c_public(); ->publicUse_im_public_mu_private : Symbol(publicUse_im_public_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 12, 10)) ->im_public_mu_private.c_public : Symbol(im_public_mu_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 0)) ->im_public_mu_private : Symbol(im_public_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 3, 111)) ->c_public : Symbol(im_public_mu_private.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 0)) - -var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); ->privateUse_im_public_mi_public : Symbol(privateUse_im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 13, 3), Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 15, 3)) ->im_public_mi_public.c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) ->im_public_mi_public : Symbol(im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 4, 112)) ->c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) - -export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); ->publicUse_im_public_mi_public : Symbol(publicUse_im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 14, 10), Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 16, 10)) ->im_public_mi_public.c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) ->im_public_mi_public : Symbol(im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 4, 112)) ->c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) - -var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); ->privateUse_im_public_mi_public : Symbol(privateUse_im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 13, 3), Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 15, 3)) ->im_public_mi_public.c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) ->im_public_mi_public : Symbol(im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 4, 112)) ->c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) - -export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); ->publicUse_im_public_mi_public : Symbol(publicUse_im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 14, 10), Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 16, 10)) ->im_public_mi_public.c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) ->im_public_mi_public : Symbol(im_public_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_core.ts, 4, 112)) ->c_private : Symbol(im_public_mi_public.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require.ts === -// Public elements -export class c_public { ->c_public : Symbol(c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 0, 0)) - - foo: string; ->foo : Symbol(foo, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require.ts, 1, 23)) -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts === -export class c_public { ->c_public : Symbol(c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 0)) - - bar: string; ->bar : Symbol(bar, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts, 0, 23)) -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts === -// private elements -// Export - Error ambient modules allowed only in global -declare module 'm' { - export class c_private { ->c_private : Symbol(c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 2, 20)) - - baz: string; ->baz : Symbol(baz, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts, 3, 28)) - } -} - - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require3.ts === -declare module 'm2' { - export class c_private { ->c_private : Symbol(c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require3.ts, 0, 21)) - - bing: string; ->bing : Symbol(bing, Decl(privacyTopLevelAmbientExternalModuleImportWithExport_require3.ts, 1, 28)) - } -} - diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.types b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.types deleted file mode 100644 index 5c082bef5de..00000000000 --- a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithExport.types +++ /dev/null @@ -1,113 +0,0 @@ -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_core.ts === -/// -/// -// Privacy errors - importing private elements -export import im_public_mi_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require"); ->im_public_mi_private : typeof im_public_mi_private - -export import im_public_mu_private = require("./privacyTopLevelAmbientExternalModuleImportWithExport_require1"); ->im_public_mu_private : typeof im_public_mu_private - -export import im_public_mi_public = require("m"); ->im_public_mi_public : typeof im_public_mi_public - -export import im_public_mu_public = require("m2"); ->im_public_mu_public : typeof im_public_mu_public - -// Usage of privacy error imports -var privateUse_im_public_mi_private = new im_public_mi_private.c_public(); ->privateUse_im_public_mi_private : im_public_mi_private.c_public ->new im_public_mi_private.c_public() : im_public_mi_private.c_public ->im_public_mi_private.c_public : typeof im_public_mi_private.c_public ->im_public_mi_private : typeof im_public_mi_private ->c_public : typeof im_public_mi_private.c_public - -export var publicUse_im_public_mi_private = new im_public_mi_private.c_public(); ->publicUse_im_public_mi_private : im_public_mi_private.c_public ->new im_public_mi_private.c_public() : im_public_mi_private.c_public ->im_public_mi_private.c_public : typeof im_public_mi_private.c_public ->im_public_mi_private : typeof im_public_mi_private ->c_public : typeof im_public_mi_private.c_public - -var privateUse_im_public_mu_private = new im_public_mu_private.c_public(); ->privateUse_im_public_mu_private : im_public_mu_private.c_public ->new im_public_mu_private.c_public() : im_public_mu_private.c_public ->im_public_mu_private.c_public : typeof im_public_mu_private.c_public ->im_public_mu_private : typeof im_public_mu_private ->c_public : typeof im_public_mu_private.c_public - -export var publicUse_im_public_mu_private = new im_public_mu_private.c_public(); ->publicUse_im_public_mu_private : im_public_mu_private.c_public ->new im_public_mu_private.c_public() : im_public_mu_private.c_public ->im_public_mu_private.c_public : typeof im_public_mu_private.c_public ->im_public_mu_private : typeof im_public_mu_private ->c_public : typeof im_public_mu_private.c_public - -var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); ->privateUse_im_public_mi_public : im_public_mi_public.c_private ->new im_public_mi_public.c_private() : im_public_mi_public.c_private ->im_public_mi_public.c_private : typeof im_public_mi_public.c_private ->im_public_mi_public : typeof im_public_mi_public ->c_private : typeof im_public_mi_public.c_private - -export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); ->publicUse_im_public_mi_public : im_public_mi_public.c_private ->new im_public_mi_public.c_private() : im_public_mi_public.c_private ->im_public_mi_public.c_private : typeof im_public_mi_public.c_private ->im_public_mi_public : typeof im_public_mi_public ->c_private : typeof im_public_mi_public.c_private - -var privateUse_im_public_mi_public = new im_public_mi_public.c_private(); ->privateUse_im_public_mi_public : im_public_mi_public.c_private ->new im_public_mi_public.c_private() : im_public_mi_public.c_private ->im_public_mi_public.c_private : typeof im_public_mi_public.c_private ->im_public_mi_public : typeof im_public_mi_public ->c_private : typeof im_public_mi_public.c_private - -export var publicUse_im_public_mi_public = new im_public_mi_public.c_private(); ->publicUse_im_public_mi_public : im_public_mi_public.c_private ->new im_public_mi_public.c_private() : im_public_mi_public.c_private ->im_public_mi_public.c_private : typeof im_public_mi_public.c_private ->im_public_mi_public : typeof im_public_mi_public ->c_private : typeof im_public_mi_public.c_private - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require.ts === -// Public elements -export class c_public { ->c_public : c_public - - foo: string; ->foo : string -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require1.ts === -export class c_public { ->c_public : c_public - - bar: string; ->bar : string -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require2.ts === -// private elements -// Export - Error ambient modules allowed only in global -declare module 'm' { - export class c_private { ->c_private : c_private - - baz: string; ->baz : string - } -} - - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithExport_require3.ts === -declare module 'm2' { - export class c_private { ->c_private : c_private - - bing: string; ->bing : string - } -} - diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.errors.txt b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.errors.txt new file mode 100644 index 00000000000..cc81762bce3 --- /dev/null +++ b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts(15,12): error TS2323: Cannot redeclare exported variable 'publicUse_im_private_mi_public'. +tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts(17,12): error TS2323: Cannot redeclare exported variable 'publicUse_im_private_mi_public'. + + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts (2 errors) ==== + /// + /// + // Privacy errors - importing private elements + import im_private_mi_private = require("m"); + import im_private_mu_private = require("m2"); + import im_private_mi_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require"); + import im_private_mu_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require1"); + + // Usage of privacy error imports + var privateUse_im_private_mi_private = new im_private_mi_private.c_private(); + export var publicUse_im_private_mi_private = new im_private_mi_private.c_private(); + var privateUse_im_private_mu_private = new im_private_mu_private.c_private(); + export var publicUse_im_private_mu_private = new im_private_mu_private.c_private(); + var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); + export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2323: Cannot redeclare exported variable 'publicUse_im_private_mi_public'. + var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); + export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2323: Cannot redeclare exported variable 'publicUse_im_private_mi_public'. + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts (0 errors) ==== + + // Public elements + export class c_public { + foo: string; + } + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require1.ts (0 errors) ==== + export class c_public { + bar: string; + } + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts (0 errors) ==== + // private elements + // Export - Error ambient modules allowed only in global + declare module 'm' { + export class c_private { + baz: string + } + } + +==== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts (0 errors) ==== + declare module 'm2' { + export class c_private { + bing: string; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.symbols b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.symbols deleted file mode 100644 index e366538124f..00000000000 --- a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.symbols +++ /dev/null @@ -1,105 +0,0 @@ -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts === -/// -/// -// Privacy errors - importing private elements -import im_private_mi_private = require("m"); ->im_private_mi_private : Symbol(im_private_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 0, 0)) - -import im_private_mu_private = require("m2"); ->im_private_mu_private : Symbol(im_private_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 3, 44)) - -import im_private_mi_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require"); ->im_private_mi_public : Symbol(im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 4, 45)) - -import im_private_mu_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require1"); ->im_private_mu_public : Symbol(im_private_mu_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 5, 105)) - -// Usage of privacy error imports -var privateUse_im_private_mi_private = new im_private_mi_private.c_private(); ->privateUse_im_private_mi_private : Symbol(privateUse_im_private_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 9, 3)) ->im_private_mi_private.c_private : Symbol(im_private_mi_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 2, 20)) ->im_private_mi_private : Symbol(im_private_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 0, 0)) ->c_private : Symbol(im_private_mi_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 2, 20)) - -export var publicUse_im_private_mi_private = new im_private_mi_private.c_private(); ->publicUse_im_private_mi_private : Symbol(publicUse_im_private_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 10, 10)) ->im_private_mi_private.c_private : Symbol(im_private_mi_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 2, 20)) ->im_private_mi_private : Symbol(im_private_mi_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 0, 0)) ->c_private : Symbol(im_private_mi_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 2, 20)) - -var privateUse_im_private_mu_private = new im_private_mu_private.c_private(); ->privateUse_im_private_mu_private : Symbol(privateUse_im_private_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 11, 3)) ->im_private_mu_private.c_private : Symbol(im_private_mu_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 0, 21)) ->im_private_mu_private : Symbol(im_private_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 3, 44)) ->c_private : Symbol(im_private_mu_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 0, 21)) - -export var publicUse_im_private_mu_private = new im_private_mu_private.c_private(); ->publicUse_im_private_mu_private : Symbol(publicUse_im_private_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 12, 10)) ->im_private_mu_private.c_private : Symbol(im_private_mu_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 0, 21)) ->im_private_mu_private : Symbol(im_private_mu_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 3, 44)) ->c_private : Symbol(im_private_mu_private.c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 0, 21)) - -var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); ->privateUse_im_private_mi_public : Symbol(privateUse_im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 13, 3), Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 15, 3)) ->im_private_mi_public.c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) ->im_private_mi_public : Symbol(im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 4, 45)) ->c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) - -export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); ->publicUse_im_private_mi_public : Symbol(publicUse_im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 14, 10), Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 16, 10)) ->im_private_mi_public.c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) ->im_private_mi_public : Symbol(im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 4, 45)) ->c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) - -var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); ->privateUse_im_private_mi_public : Symbol(privateUse_im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 13, 3), Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 15, 3)) ->im_private_mi_public.c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) ->im_private_mi_public : Symbol(im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 4, 45)) ->c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) - -export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); ->publicUse_im_private_mi_public : Symbol(publicUse_im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 14, 10), Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 16, 10)) ->im_private_mi_public.c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) ->im_private_mi_public : Symbol(im_private_mi_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts, 4, 45)) ->c_public : Symbol(im_private_mi_public.c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts === - -// Public elements -export class c_public { ->c_public : Symbol(c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 0, 0)) - - foo: string; ->foo : Symbol(foo, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts, 2, 23)) -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require1.ts === -export class c_public { ->c_public : Symbol(c_public, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require1.ts, 0, 0)) - - bar: string; ->bar : Symbol(bar, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require1.ts, 0, 23)) -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts === -// private elements -// Export - Error ambient modules allowed only in global -declare module 'm' { - export class c_private { ->c_private : Symbol(c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 2, 20)) - - baz: string ->baz : Symbol(baz, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts, 3, 28)) - } -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts === -declare module 'm2' { - export class c_private { ->c_private : Symbol(c_private, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 0, 21)) - - bing: string; ->bing : Symbol(bing, Decl(privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts, 1, 28)) - } -} - diff --git a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.types b/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.types deleted file mode 100644 index 437d35fb64a..00000000000 --- a/tests/baselines/reference/privacyTopLevelAmbientExternalModuleImportWithoutExport.types +++ /dev/null @@ -1,113 +0,0 @@ -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_core.ts === -/// -/// -// Privacy errors - importing private elements -import im_private_mi_private = require("m"); ->im_private_mi_private : typeof im_private_mi_private - -import im_private_mu_private = require("m2"); ->im_private_mu_private : typeof im_private_mu_private - -import im_private_mi_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require"); ->im_private_mi_public : typeof im_private_mi_public - -import im_private_mu_public = require("privacyTopLevelAmbientExternalModuleImportWithoutExport_require1"); ->im_private_mu_public : typeof im_private_mu_public - -// Usage of privacy error imports -var privateUse_im_private_mi_private = new im_private_mi_private.c_private(); ->privateUse_im_private_mi_private : im_private_mi_private.c_private ->new im_private_mi_private.c_private() : im_private_mi_private.c_private ->im_private_mi_private.c_private : typeof im_private_mi_private.c_private ->im_private_mi_private : typeof im_private_mi_private ->c_private : typeof im_private_mi_private.c_private - -export var publicUse_im_private_mi_private = new im_private_mi_private.c_private(); ->publicUse_im_private_mi_private : im_private_mi_private.c_private ->new im_private_mi_private.c_private() : im_private_mi_private.c_private ->im_private_mi_private.c_private : typeof im_private_mi_private.c_private ->im_private_mi_private : typeof im_private_mi_private ->c_private : typeof im_private_mi_private.c_private - -var privateUse_im_private_mu_private = new im_private_mu_private.c_private(); ->privateUse_im_private_mu_private : im_private_mu_private.c_private ->new im_private_mu_private.c_private() : im_private_mu_private.c_private ->im_private_mu_private.c_private : typeof im_private_mu_private.c_private ->im_private_mu_private : typeof im_private_mu_private ->c_private : typeof im_private_mu_private.c_private - -export var publicUse_im_private_mu_private = new im_private_mu_private.c_private(); ->publicUse_im_private_mu_private : im_private_mu_private.c_private ->new im_private_mu_private.c_private() : im_private_mu_private.c_private ->im_private_mu_private.c_private : typeof im_private_mu_private.c_private ->im_private_mu_private : typeof im_private_mu_private ->c_private : typeof im_private_mu_private.c_private - -var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); ->privateUse_im_private_mi_public : im_private_mi_public.c_public ->new im_private_mi_public.c_public() : im_private_mi_public.c_public ->im_private_mi_public.c_public : typeof im_private_mi_public.c_public ->im_private_mi_public : typeof im_private_mi_public ->c_public : typeof im_private_mi_public.c_public - -export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); ->publicUse_im_private_mi_public : im_private_mi_public.c_public ->new im_private_mi_public.c_public() : im_private_mi_public.c_public ->im_private_mi_public.c_public : typeof im_private_mi_public.c_public ->im_private_mi_public : typeof im_private_mi_public ->c_public : typeof im_private_mi_public.c_public - -var privateUse_im_private_mi_public = new im_private_mi_public.c_public(); ->privateUse_im_private_mi_public : im_private_mi_public.c_public ->new im_private_mi_public.c_public() : im_private_mi_public.c_public ->im_private_mi_public.c_public : typeof im_private_mi_public.c_public ->im_private_mi_public : typeof im_private_mi_public ->c_public : typeof im_private_mi_public.c_public - -export var publicUse_im_private_mi_public = new im_private_mi_public.c_public(); ->publicUse_im_private_mi_public : im_private_mi_public.c_public ->new im_private_mi_public.c_public() : im_private_mi_public.c_public ->im_private_mi_public.c_public : typeof im_private_mi_public.c_public ->im_private_mi_public : typeof im_private_mi_public ->c_public : typeof im_private_mi_public.c_public - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require.ts === - -// Public elements -export class c_public { ->c_public : c_public - - foo: string; ->foo : string -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require1.ts === -export class c_public { ->c_public : c_public - - bar: string; ->bar : string -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require2.ts === -// private elements -// Export - Error ambient modules allowed only in global -declare module 'm' { - export class c_private { ->c_private : c_private - - baz: string ->baz : string - } -} - -=== tests/cases/compiler/privacyTopLevelAmbientExternalModuleImportWithoutExport_require3.ts === -declare module 'm2' { - export class c_private { ->c_private : c_private - - bing: string; ->bing : string - } -} - diff --git a/tests/baselines/reference/typeofANonExportedType.errors.txt b/tests/baselines/reference/typeofANonExportedType.errors.txt index d07468f62e1..0fb239f6aee 100644 --- a/tests/baselines/reference/typeofANonExportedType.errors.txt +++ b/tests/baselines/reference/typeofANonExportedType.errors.txt @@ -1,8 +1,10 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts(2,1): error TS1148: Cannot compile modules unless the '--module' flag is provided. +tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts(20,12): error TS2323: Cannot redeclare exported variable 'r5'. +tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts(21,12): error TS2323: Cannot redeclare exported variable 'r5'. tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts(42,12): error TS2502: 'r12' is referenced directly or indirectly in its own type annotation. -==== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts (2 errors) ==== +==== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType.ts (4 errors) ==== var x = 1; export var r1: typeof x; ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -25,7 +27,11 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/typeofANonExportedType export var i: I; var i2: I; export var r5: typeof i; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'r5'. export var r5: typeof i2; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'r5'. module M { export var foo = ''; diff --git a/tests/baselines/reference/typeofAnExportedType.errors.txt b/tests/baselines/reference/typeofAnExportedType.errors.txt index cb6d8c68887..51dd7cf06b6 100644 --- a/tests/baselines/reference/typeofAnExportedType.errors.txt +++ b/tests/baselines/reference/typeofAnExportedType.errors.txt @@ -1,8 +1,10 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts(1,1): error TS1148: Cannot compile modules unless the '--module' flag is provided. +tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts(20,12): error TS2323: Cannot redeclare exported variable 'r5'. +tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts(21,12): error TS2323: Cannot redeclare exported variable 'r5'. tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts(42,12): error TS2502: 'r12' is referenced directly or indirectly in its own type annotation. -==== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts (2 errors) ==== +==== tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.ts (4 errors) ==== export var x = 1; ~~~~~~~~~~~~~~~~~ !!! error TS1148: Cannot compile modules unless the '--module' flag is provided. @@ -25,7 +27,11 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/typeofAnExportedType.t export var i: I; var i2: I; export var r5: typeof i; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'r5'. export var r5: typeof i2; + ~~ +!!! error TS2323: Cannot redeclare exported variable 'r5'. export module M { export var foo = ''; diff --git a/tests/cases/compiler/moduleDuplicateIdentifiers.ts b/tests/cases/compiler/moduleDuplicateIdentifiers.ts new file mode 100644 index 00000000000..283a6d241bf --- /dev/null +++ b/tests/cases/compiler/moduleDuplicateIdentifiers.ts @@ -0,0 +1,30 @@ +// @module: commonjs +export var Foo = 2; +export var Foo = 42; // Should error + +export interface Bar { + _brand1: any; +} + +export interface Bar { + _brand2: any; +} + +export namespace FooBar { + export var member1 = 2; +} + +export namespace FooBar { + export var member2 = 42; +} + +export class Kettle { + member1 = 2; +} + +export class Kettle { + member2 = 42; +} + +export var Pot = 2; +Pot = 42; // Shouldn't error \ No newline at end of file From 0115d688775ccdd18a34ce31ea7997e99a80fac3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 7 Oct 2015 10:49:47 -0700 Subject: [PATCH 04/22] PR Feedback, add enums to exceptions --- src/compiler/checker.ts | 18 ++++++++---- .../moduleDuplicateIdentifiers.errors.txt | 19 +++++++++--- .../reference/moduleDuplicateIdentifiers.js | 29 ++++++++++++++++--- .../compiler/moduleDuplicateIdentifiers.ts | 18 +++++++++--- 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1a692572802..419779c3f2d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1067,9 +1067,15 @@ namespace ts { ); } for (let id in lookupTable) { - if (id !== "export=" && lookupTable[id].exportsWithDuplicate.length && !(id in symbols)) { // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + if (id !== "export=" && lookupTable[id].exportsWithDuplicate.length && !(id in symbols)) { for (let node of lookupTable[id].exportsWithDuplicate) { - diagnostics.add(createDiagnosticForNode(node, Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable[id].specifierText, id)); + diagnostics.add(createDiagnosticForNode( + node, + Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, + lookupTable[id].specifierText, + id + )); } } } @@ -13722,7 +13728,7 @@ namespace ts { function checkExternalModuleExports(node: SourceFile | ModuleDeclaration) { let moduleSymbol = getSymbolOfNode(node); - let links: SymbolLinks = getSymbolLinks(moduleSymbol); + let links = getSymbolLinks(moduleSymbol); if (!links.exportsChecked) { let exportEqualsSymbol = moduleSymbol.exports["export="]; if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) { @@ -13732,9 +13738,11 @@ namespace ts { let exports = getExportsOfModule(moduleSymbol); // Checks for export * conflicts for (let id in exports) { if (id === "__export") continue; - if (!(exports[id].flags & SymbolFlags.Namespace || exports[id].flags & SymbolFlags.Interface) && exports[id].declarations.length > 1) { // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, and interfaces) + let exportedSymbol = exports[id]; + // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) + if (!(exportedSymbol.flags & SymbolFlags.Namespace || exportedSymbol.flags & SymbolFlags.Interface || exportedSymbol.flags & SymbolFlags.Enum) && exportedSymbol.declarations.length > 1) { let exportedDeclarations: Declaration[] = []; - for (let declaration of exports[id].declarations) { + for (let declaration of exportedSymbol.declarations) { if (declaration.kind === SyntaxKind.FunctionDeclaration) { if (!(declaration as FunctionDeclaration).body) { continue; diff --git a/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt b/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt index 67ab99eee4b..22bd6641a83 100644 --- a/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt +++ b/tests/baselines/reference/moduleDuplicateIdentifiers.errors.txt @@ -16,7 +16,7 @@ tests/cases/compiler/moduleDuplicateIdentifiers.ts(24,14): error TS2300: Duplica _brand1: any; } - export interface Bar { + export interface Bar { // Shouldn't error _brand2: any; } @@ -24,7 +24,7 @@ tests/cases/compiler/moduleDuplicateIdentifiers.ts(24,14): error TS2300: Duplica export var member1 = 2; } - export namespace FooBar { + export namespace FooBar { // Shouldn't error export var member2 = 42; } @@ -34,11 +34,22 @@ tests/cases/compiler/moduleDuplicateIdentifiers.ts(24,14): error TS2300: Duplica member1 = 2; } - export class Kettle { + export class Kettle { // Should error ~~~~~~ !!! error TS2300: Duplicate identifier 'Kettle'. member2 = 42; } export var Pot = 2; - Pot = 42; // Shouldn't error \ No newline at end of file + Pot = 42; // Shouldn't error + + export enum Utensils { + Spoon, + Fork, + Knife + } + + export enum Utensils { // Shouldn't error + Spork = 3 + } + \ No newline at end of file diff --git a/tests/baselines/reference/moduleDuplicateIdentifiers.js b/tests/baselines/reference/moduleDuplicateIdentifiers.js index e428ccd3c81..e02914bd874 100644 --- a/tests/baselines/reference/moduleDuplicateIdentifiers.js +++ b/tests/baselines/reference/moduleDuplicateIdentifiers.js @@ -6,7 +6,7 @@ export interface Bar { _brand1: any; } -export interface Bar { +export interface Bar { // Shouldn't error _brand2: any; } @@ -14,7 +14,7 @@ export namespace FooBar { export var member1 = 2; } -export namespace FooBar { +export namespace FooBar { // Shouldn't error export var member2 = 42; } @@ -22,12 +22,23 @@ export class Kettle { member1 = 2; } -export class Kettle { +export class Kettle { // Should error member2 = 42; } export var Pot = 2; -Pot = 42; // Shouldn't error +Pot = 42; // Shouldn't error + +export enum Utensils { + Spoon, + Fork, + Knife +} + +export enum Utensils { // Shouldn't error + Spork = 3 +} + //// [moduleDuplicateIdentifiers.js] exports.Foo = 2; @@ -56,3 +67,13 @@ var Kettle = (function () { exports.Kettle = Kettle; exports.Pot = 2; exports.Pot = 42; // Shouldn't error +(function (Utensils) { + Utensils[Utensils["Spoon"] = 0] = "Spoon"; + Utensils[Utensils["Fork"] = 1] = "Fork"; + Utensils[Utensils["Knife"] = 2] = "Knife"; +})(exports.Utensils || (exports.Utensils = {})); +var Utensils = exports.Utensils; +(function (Utensils) { + Utensils[Utensils["Spork"] = 3] = "Spork"; +})(exports.Utensils || (exports.Utensils = {})); +var Utensils = exports.Utensils; diff --git a/tests/cases/compiler/moduleDuplicateIdentifiers.ts b/tests/cases/compiler/moduleDuplicateIdentifiers.ts index 283a6d241bf..47be2bc5dbb 100644 --- a/tests/cases/compiler/moduleDuplicateIdentifiers.ts +++ b/tests/cases/compiler/moduleDuplicateIdentifiers.ts @@ -6,7 +6,7 @@ export interface Bar { _brand1: any; } -export interface Bar { +export interface Bar { // Shouldn't error _brand2: any; } @@ -14,7 +14,7 @@ export namespace FooBar { export var member1 = 2; } -export namespace FooBar { +export namespace FooBar { // Shouldn't error export var member2 = 42; } @@ -22,9 +22,19 @@ export class Kettle { member1 = 2; } -export class Kettle { +export class Kettle { // Should error member2 = 42; } export var Pot = 2; -Pot = 42; // Shouldn't error \ No newline at end of file +Pot = 42; // Shouldn't error + +export enum Utensils { + Spoon, + Fork, + Knife +} + +export enum Utensils { // Shouldn't error + Spork = 3 +} From 63fe64f067624878943325ac4c7f3f1826c2b848 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 8 Oct 2015 15:31:45 -0700 Subject: [PATCH 05/22] use a map, backticks --- src/compiler/checker.ts | 9 +++++---- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/exportStar-amd.errors.txt | 8 ++++---- tests/baselines/reference/exportStar.errors.txt | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 419779c3f2d..1eddcc54d78 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1020,11 +1020,12 @@ namespace ts { return links.resolvedExports || (links.resolvedExports = getExportsForModule(moduleSymbol)); } - interface ExportStarDiagnosticsLookupTable { - [id: string]: {specifierText: string, exportsWithDuplicate: ExportDeclaration[]}; + interface ExportedSymbolDiagnostics { + specifierText: string; + exportsWithDuplicate: ExportDeclaration[]; } - function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: ExportStarDiagnosticsLookupTable, exportNode?: ExportDeclaration) { + function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map, exportNode?: ExportDeclaration) { for (let id in source) { if (id !== "default" && !hasProperty(target, id)) { target[id] = source[id]; @@ -1055,7 +1056,7 @@ namespace ts { let exportStars = symbol.exports["__export"]; if (exportStars) { let nestedSymbols: SymbolTable = {}; - let lookupTable: ExportStarDiagnosticsLookupTable = {}; + let lookupTable: Map = {}; for (let node of exportStars.declarations) { let resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier); let exportedSymbols = visit(resolvedModule); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 51fd7a1fa2e..ca2c15a7d96 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -832,7 +832,7 @@ "category": "Error", "code": 2307 }, - "An 'export * from {0}' declaration has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { + "An `export * from {0}` declaration has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { "category": "Error", "code": 2308 }, diff --git a/tests/baselines/reference/exportStar-amd.errors.txt b/tests/baselines/reference/exportStar-amd.errors.txt index 237290485b0..714890d5a14 100644 --- a/tests/baselines/reference/exportStar-amd.errors.txt +++ b/tests/baselines/reference/exportStar-amd.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -23,9 +23,9 @@ tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from export * from "./t2"; export * from "./t3"; ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; diff --git a/tests/baselines/reference/exportStar.errors.txt b/tests/baselines/reference/exportStar.errors.txt index 237290485b0..714890d5a14 100644 --- a/tests/baselines/reference/exportStar.errors.txt +++ b/tests/baselines/reference/exportStar.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -23,9 +23,9 @@ tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An 'export * from export * from "./t2"; export * from "./t3"; ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An 'export * from "./t1"' declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; From cb152003782114103ff4a3472d62381139e33dfa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Nov 2015 16:58:10 -0800 Subject: [PATCH 06/22] fix lints --- src/compiler/checker.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3ba60d9a4a2..929b1f706c0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14009,14 +14009,14 @@ namespace ts { const declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } - let exports = getExportsOfModule(moduleSymbol); // Checks for export * conflicts - for (let id in exports) { + const exports = getExportsOfModule(moduleSymbol); // Checks for export * conflicts + for (const id in exports) { if (id === "__export") continue; - let exportedSymbol = exports[id]; + const exportedSymbol = exports[id]; // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) if (!(exportedSymbol.flags & SymbolFlags.Namespace || exportedSymbol.flags & SymbolFlags.Interface || exportedSymbol.flags & SymbolFlags.Enum) && exportedSymbol.declarations.length > 1) { - let exportedDeclarations: Declaration[] = []; - for (let declaration of exportedSymbol.declarations) { + const exportedDeclarations: Declaration[] = []; + for (const declaration of exportedSymbol.declarations) { if (declaration.kind === SyntaxKind.FunctionDeclaration) { if (!(declaration as FunctionDeclaration).body) { continue; @@ -14025,7 +14025,7 @@ namespace ts { exportedDeclarations.push(declaration); } if (exportedDeclarations.length > 1) { - for (let declaration of exportedDeclarations) { + for (const declaration of exportedDeclarations) { diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, id)); } } From 65b90686e79e438a1e26cef48ac67d209e8020f6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Nov 2015 17:06:00 -0800 Subject: [PATCH 07/22] accept new baselines --- .../reference/multipleDefaultExports04.errors.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/multipleDefaultExports04.errors.txt b/tests/baselines/reference/multipleDefaultExports04.errors.txt index e67659f6b9f..bf137e3cc17 100644 --- a/tests/baselines/reference/multipleDefaultExports04.errors.txt +++ b/tests/baselines/reference/multipleDefaultExports04.errors.txt @@ -1,15 +1,21 @@ +tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(2,25): error TS2323: Cannot redeclare exported variable 'default'. tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(2,25): error TS2393: Duplicate function implementation. +tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(5,25): error TS2323: Cannot redeclare exported variable 'default'. tests/cases/conformance/es6/modules/multipleDefaultExports04.ts(5,25): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/modules/multipleDefaultExports04.ts (2 errors) ==== +==== tests/cases/conformance/es6/modules/multipleDefaultExports04.ts (4 errors) ==== export default function f() { ~ +!!! error TS2323: Cannot redeclare exported variable 'default'. + ~ !!! error TS2393: Duplicate function implementation. } export default function f() { ~ +!!! error TS2323: Cannot redeclare exported variable 'default'. + ~ !!! error TS2393: Duplicate function implementation. } \ No newline at end of file From b91a5a510096c04d13289333efe7816d24f461e7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 19 Nov 2015 13:17:20 -0800 Subject: [PATCH 08/22] factor for loop into filter, minor style changes --- src/compiler/checker.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 929b1f706c0..0b72b8c3db3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1103,9 +1103,10 @@ namespace ts { ); } for (const id in lookupTable) { + const { exportsWithDuplicate } = lookupTable[id]; // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself - if (id !== "export=" && lookupTable[id].exportsWithDuplicate.length && !(id in symbols)) { - for (const node of lookupTable[id].exportsWithDuplicate) { + if (id !== "export=" && exportsWithDuplicate.length && !(id in symbols)) { + for (const node of exportsWithDuplicate) { diagnostics.add(createDiagnosticForNode( node, Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, @@ -14009,21 +14010,16 @@ namespace ts { const declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } - const exports = getExportsOfModule(moduleSymbol); // Checks for export * conflicts + // Checks for export * conflicts + const exports = getExportsOfModule(moduleSymbol); for (const id in exports) { - if (id === "__export") continue; + if (id === "__export") { + continue; + } const exportedSymbol = exports[id]; // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) if (!(exportedSymbol.flags & SymbolFlags.Namespace || exportedSymbol.flags & SymbolFlags.Interface || exportedSymbol.flags & SymbolFlags.Enum) && exportedSymbol.declarations.length > 1) { - const exportedDeclarations: Declaration[] = []; - for (const declaration of exportedSymbol.declarations) { - if (declaration.kind === SyntaxKind.FunctionDeclaration) { - if (!(declaration as FunctionDeclaration).body) { - continue; - } - } - exportedDeclarations.push(declaration); - } + const exportedDeclarations: Declaration[] = filter(exportedSymbol.declarations, isNotOverload); if (exportedDeclarations.length > 1) { for (const declaration of exportedDeclarations) { diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, id)); @@ -14033,6 +14029,10 @@ namespace ts { } links.exportsChecked = true; } + + function isNotOverload(declaration: Declaration): boolean { + return (declaration.kind !== SyntaxKind.FunctionDeclaration || typeof (declaration as FunctionDeclaration).body !== "undefined"); + } } function checkTypePredicate(node: TypePredicateNode) { From d9c6f3d6c64abe93ee9b3e71e67d72217ce36bc2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 19 Nov 2015 13:20:58 -0800 Subject: [PATCH 09/22] invert the conditional I was asked to invert --- src/compiler/checker.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f6e1da3e9ea..d95d3e07686 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1143,15 +1143,16 @@ namespace ts { for (const id in lookupTable) { const { exportsWithDuplicate } = lookupTable[id]; // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself - if (id !== "export=" && exportsWithDuplicate.length && !(id in symbols)) { - for (const node of exportsWithDuplicate) { - diagnostics.add(createDiagnosticForNode( - node, - Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, - lookupTable[id].specifierText, - id - )); - } + if (id === "export=" || !exportsWithDuplicate.length || id in symbols) { + continue; + } + for (const node of exportsWithDuplicate) { + diagnostics.add(createDiagnosticForNode( + node, + Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, + lookupTable[id].specifierText, + id + )); } } extendExportSymbols(symbols, nestedSymbols); From d0fc3948b58d006ef003174af7e1c3e7c7b084e1 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 12:22:08 -0800 Subject: [PATCH 10/22] Correct comments, use destructuring --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d95d3e07686..2a853611a43 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1142,7 +1142,7 @@ namespace ts { } for (const id in lookupTable) { const { exportsWithDuplicate } = lookupTable[id]; - // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + // Its not an error if the file with multiple export *'s with duplicate names exports a member with that name itself if (id === "export=" || !exportsWithDuplicate.length || id in symbols) { continue; } @@ -14079,10 +14079,10 @@ namespace ts { if (id === "__export") { continue; } - const exportedSymbol = exports[id]; - // 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) - if (!(exportedSymbol.flags & SymbolFlags.Namespace || exportedSymbol.flags & SymbolFlags.Interface || exportedSymbol.flags & SymbolFlags.Enum) && exportedSymbol.declarations.length > 1) { - const exportedDeclarations: Declaration[] = filter(exportedSymbol.declarations, isNotOverload); + const {declarations, flags} = exports[id]; + // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) + if (!(flags & (SymbolFlags.Namespace |SymbolFlags.Interface | SymbolFlags.Enum)) && declarations.length > 1) { + const exportedDeclarations: Declaration[] = filter(declarations, isNotOverload); if (exportedDeclarations.length > 1) { for (const declaration of exportedDeclarations) { diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, id)); From 6a8e78cdc08ea1c8b4b1b9654638b9517153ef56 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 12:43:28 -0800 Subject: [PATCH 11/22] fix ES6 emit for namespaces to only emit one export binding --- src/compiler/emitter.ts | 19 +++++++++++-------- .../es6ModuleInternalNamedImports2.js | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index bdeac582bbf..83d3e24351e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6318,15 +6318,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi const emitVarForModule = !hoistedInDeclarationScope && !isModuleMergedWithES6Class(node); if (emitVarForModule) { - emitStart(node); - if (isES6ExportedDeclaration(node)) { - write("export "); + const isES6ExportedNamespace = isES6ExportedDeclaration(node); + if ((!isES6ExportedNamespace) || !forEach(node.symbol && node.symbol.declarations, declaration => declaration.kind === SyntaxKind.ModuleDeclaration && declaration.pos < node.pos)) { + emitStart(node); + if (isES6ExportedNamespace) { + write("export "); + } + write("var "); + emit(node.name); + write(";"); + emitEnd(node); + writeLine(); } - write("var "); - emit(node.name); - write(";"); - emitEnd(node); - writeLine(); } emitStart(node); diff --git a/tests/baselines/reference/es6ModuleInternalNamedImports2.js b/tests/baselines/reference/es6ModuleInternalNamedImports2.js index 9dee8153e56..98226a1e52b 100644 --- a/tests/baselines/reference/es6ModuleInternalNamedImports2.js +++ b/tests/baselines/reference/es6ModuleInternalNamedImports2.js @@ -58,7 +58,6 @@ export var M; // alias M.M_A = M_M; })(M || (M = {})); -export var M; (function (M) { // Reexports export { M_V as v }; From 60234342d58b06f7a51b6feaa149dc35f9e76ecb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 12:44:49 -0800 Subject: [PATCH 12/22] fix whitespace --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2a853611a43..289265b7572 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14081,7 +14081,7 @@ namespace ts { } const {declarations, flags} = exports[id]; // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) - if (!(flags & (SymbolFlags.Namespace |SymbolFlags.Interface | SymbolFlags.Enum)) && declarations.length > 1) { + if (!(flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) && declarations.length > 1) { const exportedDeclarations: Declaration[] = filter(declarations, isNotOverload); if (exportedDeclarations.length > 1) { for (const declaration of exportedDeclarations) { From a9be53093c9de71ebb857a0469a97bac59855d87 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 12:55:29 -0800 Subject: [PATCH 13/22] change enum emit --- src/compiler/emitter.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 83d3e24351e..f31885dcd03 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6206,9 +6206,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (!shouldHoistDeclarationInSystemJsModule(node)) { // do not emit var if variable was already hoisted - if (!(node.flags & NodeFlags.Export) || isES6ExportedDeclaration(node)) { + + const isES6ExportedEnum = isES6ExportedDeclaration(node); + if (!(node.flags & NodeFlags.Export) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.ModuleDeclaration))) { emitStart(node); - if (isES6ExportedDeclaration(node)) { + if (isES6ExportedEnum) { write("export "); } write("var "); @@ -6307,6 +6309,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi return languageVersion === ScriptTarget.ES6 && !!(resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalModuleMergesWithClass); } + function isFirstDeclarationOfKind(node: Declaration, declarations: Declaration[], kind: SyntaxKind) { + return !forEach(declarations, declaration => declaration.kind === kind && declaration.pos < node.pos); + } + function emitModuleDeclaration(node: ModuleDeclaration) { // Emit only if this module is non-ambient. const shouldEmit = shouldEmitModuleDeclaration(node); @@ -6319,7 +6325,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (emitVarForModule) { const isES6ExportedNamespace = isES6ExportedDeclaration(node); - if ((!isES6ExportedNamespace) || !forEach(node.symbol && node.symbol.declarations, declaration => declaration.kind === SyntaxKind.ModuleDeclaration && declaration.pos < node.pos)) { + if ((!isES6ExportedNamespace) || isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.ModuleDeclaration)) { emitStart(node); if (isES6ExportedNamespace) { write("export "); From 3b6fa314da2a1cac1dedc4e83a056e7ce8ab334e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 13:12:34 -0800 Subject: [PATCH 14/22] new tests --- src/compiler/emitter.ts | 2 +- .../reference/enumExportMergingES6.js | 23 +++++++++++++++++ .../reference/enumExportMergingES6.symbols | 22 ++++++++++++++++ .../reference/enumExportMergingES6.types | 25 +++++++++++++++++++ .../conformance/enums/enumExportMergingES6.ts | 10 ++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/enumExportMergingES6.js create mode 100644 tests/baselines/reference/enumExportMergingES6.symbols create mode 100644 tests/baselines/reference/enumExportMergingES6.types create mode 100644 tests/cases/conformance/enums/enumExportMergingES6.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f31885dcd03..64af2c71442 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6208,7 +6208,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // do not emit var if variable was already hoisted const isES6ExportedEnum = isES6ExportedDeclaration(node); - if (!(node.flags & NodeFlags.Export) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.ModuleDeclaration))) { + if ((!(node.flags & NodeFlags.Export)) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.EnumDeclaration))) { emitStart(node); if (isES6ExportedEnum) { write("export "); diff --git a/tests/baselines/reference/enumExportMergingES6.js b/tests/baselines/reference/enumExportMergingES6.js new file mode 100644 index 00000000000..7a5ea5f2718 --- /dev/null +++ b/tests/baselines/reference/enumExportMergingES6.js @@ -0,0 +1,23 @@ +//// [enumExportMergingES6.ts] +export enum Animals { + Cat = 1 +} +export enum Animals { + Dog = 2 +} +export enum Animals { + CatDog = Cat | Dog +} + + +//// [enumExportMergingES6.js] +export var Animals; +(function (Animals) { + Animals[Animals["Cat"] = 1] = "Cat"; +})(Animals || (Animals = {})); +(function (Animals) { + Animals[Animals["Dog"] = 2] = "Dog"; +})(Animals || (Animals = {})); +(function (Animals) { + Animals[Animals["CatDog"] = 3] = "CatDog"; +})(Animals || (Animals = {})); diff --git a/tests/baselines/reference/enumExportMergingES6.symbols b/tests/baselines/reference/enumExportMergingES6.symbols new file mode 100644 index 00000000000..66fc31c5e18 --- /dev/null +++ b/tests/baselines/reference/enumExportMergingES6.symbols @@ -0,0 +1,22 @@ +=== tests/cases/conformance/enums/enumExportMergingES6.ts === +export enum Animals { +>Animals : Symbol(Animals, Decl(enumExportMergingES6.ts, 0, 0), Decl(enumExportMergingES6.ts, 2, 1), Decl(enumExportMergingES6.ts, 5, 1)) + + Cat = 1 +>Cat : Symbol(Animals.Cat, Decl(enumExportMergingES6.ts, 0, 21)) +} +export enum Animals { +>Animals : Symbol(Animals, Decl(enumExportMergingES6.ts, 0, 0), Decl(enumExportMergingES6.ts, 2, 1), Decl(enumExportMergingES6.ts, 5, 1)) + + Dog = 2 +>Dog : Symbol(Animals.Dog, Decl(enumExportMergingES6.ts, 3, 21)) +} +export enum Animals { +>Animals : Symbol(Animals, Decl(enumExportMergingES6.ts, 0, 0), Decl(enumExportMergingES6.ts, 2, 1), Decl(enumExportMergingES6.ts, 5, 1)) + + CatDog = Cat | Dog +>CatDog : Symbol(Animals.CatDog, Decl(enumExportMergingES6.ts, 6, 21)) +>Cat : Symbol(Animals.Cat, Decl(enumExportMergingES6.ts, 0, 21)) +>Dog : Symbol(Animals.Dog, Decl(enumExportMergingES6.ts, 3, 21)) +} + diff --git a/tests/baselines/reference/enumExportMergingES6.types b/tests/baselines/reference/enumExportMergingES6.types new file mode 100644 index 00000000000..da2fc22cb8a --- /dev/null +++ b/tests/baselines/reference/enumExportMergingES6.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/enums/enumExportMergingES6.ts === +export enum Animals { +>Animals : Animals + + Cat = 1 +>Cat : Animals +>1 : number +} +export enum Animals { +>Animals : Animals + + Dog = 2 +>Dog : Animals +>2 : number +} +export enum Animals { +>Animals : Animals + + CatDog = Cat | Dog +>CatDog : Animals +>Cat | Dog : number +>Cat : Animals +>Dog : Animals +} + diff --git a/tests/cases/conformance/enums/enumExportMergingES6.ts b/tests/cases/conformance/enums/enumExportMergingES6.ts new file mode 100644 index 00000000000..0a5185ecdd5 --- /dev/null +++ b/tests/cases/conformance/enums/enumExportMergingES6.ts @@ -0,0 +1,10 @@ +// @target: es6 +export enum Animals { + Cat = 1 +} +export enum Animals { + Dog = 2 +} +export enum Animals { + CatDog = Cat | Dog +} From f782c82ba3f1fcb4d80b9e0a1c9440d4f04d6786 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Nov 2015 17:02:01 -0800 Subject: [PATCH 15/22] Add comments, change error message --- src/compiler/checker.ts | 14 +++++++++----- src/compiler/diagnosticMessages.json | 2 +- .../baselines/reference/exportStar-amd.errors.txt | 8 ++++---- tests/baselines/reference/exportStar.errors.txt | 8 ++++---- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 289265b7572..70b39980882 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1093,12 +1093,16 @@ namespace ts { return links.resolvedExports || (links.resolvedExports = getExportsForModule(moduleSymbol)); } - interface ExportedSymbolDiagnostics { + interface ExportCollisionTracker { specifierText: string; exportsWithDuplicate: ExportDeclaration[]; } - function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map, exportNode?: ExportDeclaration) { + /** + * Extends one symbol table with abother while collecting information on name collisions for error message generation into the `lookupTable` argument + * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables + */ + function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map, exportNode?: ExportDeclaration) { for (const id in source) { if (id !== "default" && !hasProperty(target, id)) { target[id] = source[id]; @@ -1129,7 +1133,7 @@ namespace ts { const exportStars = symbol.exports["__export"]; if (exportStars) { const nestedSymbols: SymbolTable = {}; - const lookupTable: Map = {}; + const lookupTable: Map = {}; for (const node of exportStars.declarations) { const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier); const exportedSymbols = visit(resolvedModule); @@ -1149,7 +1153,7 @@ namespace ts { for (const node of exportsWithDuplicate) { diagnostics.add(createDiagnosticForNode( node, - Diagnostics.An_export_Asterisk_from_0_declaration_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, + Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable[id].specifierText, id )); @@ -14094,7 +14098,7 @@ namespace ts { } function isNotOverload(declaration: Declaration): boolean { - return (declaration.kind !== SyntaxKind.FunctionDeclaration || typeof (declaration as FunctionDeclaration).body !== "undefined"); + return declaration.kind !== SyntaxKind.FunctionDeclaration || !!(declaration as FunctionDeclaration).body; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a0976e6cc6a..b2a63085ae4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -836,7 +836,7 @@ "category": "Error", "code": 2307 }, - "An `export * from {0}` declaration has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { + "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { "category": "Error", "code": 2308 }, diff --git a/tests/baselines/reference/exportStar-amd.errors.txt b/tests/baselines/reference/exportStar-amd.errors.txt index 714890d5a14..edd5c0d51bd 100644 --- a/tests/baselines/reference/exportStar-amd.errors.txt +++ b/tests/baselines/reference/exportStar-amd.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: Module "./t1" has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: Module "./t1" has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -23,9 +23,9 @@ tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from export * from "./t2"; export * from "./t3"; ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: Module "./t1" has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: Module "./t1" has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; diff --git a/tests/baselines/reference/exportStar.errors.txt b/tests/baselines/reference/exportStar.errors.txt index 714890d5a14..edd5c0d51bd 100644 --- a/tests/baselines/reference/exportStar.errors.txt +++ b/tests/baselines/reference/exportStar.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/es6/modules/main.ts(1,8): error TS1192: Module '"tests/cases/conformance/es6/modules/t4"' has no default export. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. -tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: Module "./t1" has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: Module "./t1" has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/t1.ts (0 errors) ==== @@ -23,9 +23,9 @@ tests/cases/conformance/es6/modules/t4.ts(3,1): error TS2308: An `export * from export * from "./t2"; export * from "./t3"; ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: Module "./t1" has already exported a member named 'x'. Consider explicitly re-exporting to resolve the ambiguity. ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2308: An `export * from "./t1"` declaration has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. +!!! error TS2308: Module "./t1" has already exported a member named 'y'. Consider explicitly re-exporting to resolve the ambiguity. ==== tests/cases/conformance/es6/modules/main.ts (1 errors) ==== import hello, { x, y, z, foo } from "./t4"; From d167e55097dc0950d416ae818e3762bdbd3745ee Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 25 Nov 2015 18:38:25 -0800 Subject: [PATCH 16/22] accept baseline --- tests/baselines/reference/moduleDuplicateIdentifiers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/baselines/reference/moduleDuplicateIdentifiers.js b/tests/baselines/reference/moduleDuplicateIdentifiers.js index e02914bd874..842d1587911 100644 --- a/tests/baselines/reference/moduleDuplicateIdentifiers.js +++ b/tests/baselines/reference/moduleDuplicateIdentifiers.js @@ -41,6 +41,7 @@ export enum Utensils { // Shouldn't error //// [moduleDuplicateIdentifiers.js] +"use strict"; exports.Foo = 2; exports.Foo = 42; // Should error var FooBar; From 54ab1e99c0320ff0a8784bff0ca14b0580e66741 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 26 Nov 2015 14:24:12 -0800 Subject: [PATCH 17/22] fix module record nonambiguous case, add test for it --- src/compiler/checker.ts | 2 +- ...oduleSameValueDuplicateExportedBindings.js | 28 +++++++++++++++++++ ...SameValueDuplicateExportedBindings.symbols | 11 ++++++++ ...leSameValueDuplicateExportedBindings.types | 12 ++++++++ ...oduleSameValueDuplicateExportedBindings.ts | 10 +++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types create mode 100644 tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 28691b3a30e..1dce8d2406d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1113,7 +1113,7 @@ namespace ts { }; } } - else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id)) { + else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id) && target[id] !== source[id]) { lookupTable[id].exportsWithDuplicate.push(exportNode); } } diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js new file mode 100644 index 00000000000..8a12973dc02 --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts] //// + +//// [a.ts] +export * from "./b"; +export * from "./c"; + +//// [b.ts] +export * from "./c"; + +//// [c.ts] +export var foo = 42; + +//// [c.js] +"use strict"; +exports.foo = 42; +//// [b.js] +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./c")); +//// [a.js] +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./b")); +__export(require("./c")); diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols new file mode 100644 index 00000000000..2f8bba9b6ab --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/a.ts === +export * from "./b"; +No type information for this code.export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/b.ts === +export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/c.ts === +export var foo = 42; +>foo : Symbol(foo, Decl(c.ts, 0, 10)) + diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types new file mode 100644 index 00000000000..57be71c802b --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export * from "./b"; +No type information for this code.export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/b.ts === +export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/c.ts === +export var foo = 42; +>foo : number +>42 : number + diff --git a/tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts b/tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts new file mode 100644 index 00000000000..d51de9c2e5a --- /dev/null +++ b/tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts @@ -0,0 +1,10 @@ +// @module: commonjs +// @filename: a.ts +export * from "./b"; +export * from "./c"; + +// @filename: b.ts +export * from "./c"; + +// @filename: c.ts +export var foo = 42; \ No newline at end of file From d3f2f55ae8fef7a21ae012108e362e6d4fb71a38 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 30 Nov 2015 12:44:13 -0800 Subject: [PATCH 18/22] rename tests, add another test, reoslve symbols for comparison --- src/compiler/checker.ts | 2 +- ...uleSameValueDuplicateExportedBindings1.js} | 2 +- ...meValueDuplicateExportedBindings1.symbols} | 0 ...SameValueDuplicateExportedBindings1.types} | 0 ...duleSameValueDuplicateExportedBindings2.js | 34 +++++++++++++++++++ ...ameValueDuplicateExportedBindings2.symbols | 19 +++++++++++ ...eSameValueDuplicateExportedBindings2.types | 19 +++++++++++ ...uleSameValueDuplicateExportedBindings1.ts} | 0 ...duleSameValueDuplicateExportedBindings2.ts | 13 +++++++ 9 files changed, 87 insertions(+), 2 deletions(-) rename tests/baselines/reference/{moduleSameValueDuplicateExportedBindings.js => moduleSameValueDuplicateExportedBindings1.js} (93%) rename tests/baselines/reference/{moduleSameValueDuplicateExportedBindings.symbols => moduleSameValueDuplicateExportedBindings1.symbols} (100%) rename tests/baselines/reference/{moduleSameValueDuplicateExportedBindings.types => moduleSameValueDuplicateExportedBindings1.types} (100%) create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.js create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.symbols create mode 100644 tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types rename tests/cases/compiler/{moduleSameValueDuplicateExportedBindings.ts => moduleSameValueDuplicateExportedBindings1.ts} (100%) create mode 100644 tests/cases/compiler/moduleSameValueDuplicateExportedBindings2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1dce8d2406d..fb70bd747a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1113,7 +1113,7 @@ namespace ts { }; } } - else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id) && target[id] !== source[id]) { + else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id) && resolveSymbol(target[id]) !== resolveSymbol(source[id])) { lookupTable[id].exportsWithDuplicate.push(exportNode); } } diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.js similarity index 93% rename from tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js rename to tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.js index 8a12973dc02..4061a32b49f 100644 --- a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.js +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.js @@ -1,4 +1,4 @@ -//// [tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts] //// +//// [tests/cases/compiler/moduleSameValueDuplicateExportedBindings1.ts] //// //// [a.ts] export * from "./b"; diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.symbols similarity index 100% rename from tests/baselines/reference/moduleSameValueDuplicateExportedBindings.symbols rename to tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.symbols diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.types similarity index 100% rename from tests/baselines/reference/moduleSameValueDuplicateExportedBindings.types rename to tests/baselines/reference/moduleSameValueDuplicateExportedBindings1.types diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.js b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.js new file mode 100644 index 00000000000..99a09af149a --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/moduleSameValueDuplicateExportedBindings2.ts] //// + +//// [a.ts] +export * from "./b"; +export * from "./c"; + +//// [b.ts] +export {Animals} from "./c"; + +//// [c.ts] +export enum Animals { + Cat, + Dog +}; + +//// [c.js] +"use strict"; +(function (Animals) { + Animals[Animals["Cat"] = 0] = "Cat"; + Animals[Animals["Dog"] = 1] = "Dog"; +})(exports.Animals || (exports.Animals = {})); +var Animals = exports.Animals; +; +//// [b.js] +"use strict"; +var c_1 = require("./c"); +exports.Animals = c_1.Animals; +//// [a.js] +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./b")); +__export(require("./c")); diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.symbols b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.symbols new file mode 100644 index 00000000000..390fd1b0bed --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/a.ts === +export * from "./b"; +No type information for this code.export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/b.ts === +export {Animals} from "./c"; +>Animals : Symbol(Animals, Decl(b.ts, 0, 8)) + +=== tests/cases/compiler/c.ts === +export enum Animals { +>Animals : Symbol(Animals, Decl(c.ts, 0, 0)) + + Cat, +>Cat : Symbol(Animals.Cat, Decl(c.ts, 0, 21)) + + Dog +>Dog : Symbol(Animals.Dog, Decl(c.ts, 1, 5)) + +}; diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types new file mode 100644 index 00000000000..600b0d946c6 --- /dev/null +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/a.ts === +export * from "./b"; +No type information for this code.export * from "./c"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/b.ts === +export {Animals} from "./c"; +>Animals : typeof Animals + +=== tests/cases/compiler/c.ts === +export enum Animals { +>Animals : Animals + + Cat, +>Cat : Animals + + Dog +>Dog : Animals + +}; diff --git a/tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts b/tests/cases/compiler/moduleSameValueDuplicateExportedBindings1.ts similarity index 100% rename from tests/cases/compiler/moduleSameValueDuplicateExportedBindings.ts rename to tests/cases/compiler/moduleSameValueDuplicateExportedBindings1.ts diff --git a/tests/cases/compiler/moduleSameValueDuplicateExportedBindings2.ts b/tests/cases/compiler/moduleSameValueDuplicateExportedBindings2.ts new file mode 100644 index 00000000000..1a30004301a --- /dev/null +++ b/tests/cases/compiler/moduleSameValueDuplicateExportedBindings2.ts @@ -0,0 +1,13 @@ +// @module: commonjs +// @filename: a.ts +export * from "./b"; +export * from "./c"; + +// @filename: b.ts +export {Animals} from "./c"; + +// @filename: c.ts +export enum Animals { + Cat, + Dog +}; \ No newline at end of file From 130f3304ea0efe27e63ff4824224a263ddabf7f3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 1 Dec 2015 14:35:26 -0800 Subject: [PATCH 19/22] Style nits for the style nit god --- src/compiler/checker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb70bd747a6..4d936320ba6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1128,7 +1128,7 @@ namespace ts { function visit(symbol: Symbol): SymbolTable { if (symbol && symbol.flags & SymbolFlags.HasExports && !contains(visitedSymbols, symbol)) { visitedSymbols.push(symbol); - const symbols: SymbolTable = cloneSymbolTable(symbol.exports); + const symbols = cloneSymbolTable(symbol.exports); // All export * declarations are collected in an __export symbol by the binder const exportStars = symbol.exports["__export"]; if (exportStars) { @@ -1146,8 +1146,8 @@ namespace ts { } for (const id in lookupTable) { const { exportsWithDuplicate } = lookupTable[id]; - // Its not an error if the file with multiple export *'s with duplicate names exports a member with that name itself - if (id === "export=" || !exportsWithDuplicate.length || id in symbols) { + // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + if (id === "export=" || !exportsWithDuplicate.length || hasProperty(symbols, id)) { continue; } for (const node of exportsWithDuplicate) { @@ -14138,7 +14138,7 @@ namespace ts { if (id === "__export") { continue; } - const {declarations, flags} = exports[id]; + const { declarations, flags } = exports[id]; // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. (TS Exceptions: namespaces, function overloads, enums, and interfaces) if (!(flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) && declarations.length > 1) { const exportedDeclarations: Declaration[] = filter(declarations, isNotOverload); From 02d96f67bbb6093a5f422d7886c8ddd9b12346ae Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 1 Dec 2015 14:57:59 -0800 Subject: [PATCH 20/22] trio of missed style nits --- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4d936320ba6..6a99cf9a67c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1146,7 +1146,7 @@ namespace ts { } for (const id in lookupTable) { const { exportsWithDuplicate } = lookupTable[id]; - // It's not an error if the file with multiple export *'s with duplicate names exports a member with that name itself + // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself if (id === "export=" || !exportsWithDuplicate.length || hasProperty(symbols, id)) { continue; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 947b88567d9..19f1e51565b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6211,7 +6211,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi // do not emit var if variable was already hoisted const isES6ExportedEnum = isES6ExportedDeclaration(node); - if ((!(node.flags & NodeFlags.Export)) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.EnumDeclaration))) { + if (!(node.flags & NodeFlags.Export) || (isES6ExportedEnum && isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.EnumDeclaration))) { emitStart(node); if (isES6ExportedEnum) { write("export "); @@ -6328,7 +6328,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (emitVarForModule) { const isES6ExportedNamespace = isES6ExportedDeclaration(node); - if ((!isES6ExportedNamespace) || isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.ModuleDeclaration)) { + if (!isES6ExportedNamespace || isFirstDeclarationOfKind(node, node.symbol && node.symbol.declarations, SyntaxKind.ModuleDeclaration)) { emitStart(node); if (isES6ExportedNamespace) { write("export "); From 98fd75d84ea2a49804e74ca68f1d5096c30042f9 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 4 Dec 2015 13:09:11 -0800 Subject: [PATCH 21/22] fix typo, reduce nesting, defer array allocation until needed --- src/compiler/checker.ts | 87 ++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6a99cf9a67c..d65b202725e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1099,7 +1099,7 @@ namespace ts { } /** - * Extends one symbol table with abother while collecting information on name collisions for error message generation into the `lookupTable` argument + * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables */ function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: Map, exportNode?: ExportDeclaration) { @@ -1108,13 +1108,17 @@ namespace ts { target[id] = source[id]; if (lookupTable && exportNode) { lookupTable[id] = { - specifierText: getTextOfNode(exportNode.moduleSpecifier), - exportsWithDuplicate: [] - }; + specifierText: getTextOfNode(exportNode.moduleSpecifier) + } as ExportCollisionTracker; } } else if (lookupTable && exportNode && id !== "default" && hasProperty(target, id) && resolveSymbol(target[id]) !== resolveSymbol(source[id])) { - lookupTable[id].exportsWithDuplicate.push(exportNode); + if (!lookupTable[id].exportsWithDuplicate) { + lookupTable[id].exportsWithDuplicate = [exportNode]; + } + else { + lookupTable[id].exportsWithDuplicate.push(exportNode); + } } } } @@ -1126,43 +1130,44 @@ namespace ts { // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example, // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error. function visit(symbol: Symbol): SymbolTable { - if (symbol && symbol.flags & SymbolFlags.HasExports && !contains(visitedSymbols, symbol)) { - visitedSymbols.push(symbol); - const symbols = cloneSymbolTable(symbol.exports); - // All export * declarations are collected in an __export symbol by the binder - const exportStars = symbol.exports["__export"]; - if (exportStars) { - const nestedSymbols: SymbolTable = {}; - const lookupTable: Map = {}; - for (const node of exportStars.declarations) { - const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier); - const exportedSymbols = visit(resolvedModule); - extendExportSymbols( - nestedSymbols, - exportedSymbols, - lookupTable, - node as ExportDeclaration - ); - } - for (const id in lookupTable) { - const { exportsWithDuplicate } = lookupTable[id]; - // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself - if (id === "export=" || !exportsWithDuplicate.length || hasProperty(symbols, id)) { - continue; - } - for (const node of exportsWithDuplicate) { - diagnostics.add(createDiagnosticForNode( - node, - Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, - lookupTable[id].specifierText, - id - )); - } - } - extendExportSymbols(symbols, nestedSymbols); - } - return symbols; + if (!(symbol && symbol.flags & SymbolFlags.HasExports && !contains(visitedSymbols, symbol))) { + return; } + visitedSymbols.push(symbol); + const symbols = cloneSymbolTable(symbol.exports); + // All export * declarations are collected in an __export symbol by the binder + const exportStars = symbol.exports["__export"]; + if (exportStars) { + const nestedSymbols: SymbolTable = {}; + const lookupTable: Map = {}; + for (const node of exportStars.declarations) { + const resolvedModule = resolveExternalModuleName(node, (node as ExportDeclaration).moduleSpecifier); + const exportedSymbols = visit(resolvedModule); + extendExportSymbols( + nestedSymbols, + exportedSymbols, + lookupTable, + node as ExportDeclaration + ); + } + for (const id in lookupTable) { + const { exportsWithDuplicate } = lookupTable[id]; + // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself + if (id === "export=" || !exportsWithDuplicate.length || hasProperty(symbols, id)) { + continue; + } + for (const node of exportsWithDuplicate) { + diagnostics.add(createDiagnosticForNode( + node, + Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, + lookupTable[id].specifierText, + id + )); + } + } + extendExportSymbols(symbols, nestedSymbols); + } + return symbols; } } From 835950a674cdbd197d7cdc0d6d158f173c093800 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 4 Dec 2015 13:44:16 -0800 Subject: [PATCH 22/22] check for presence of array --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d65b202725e..6f10792e54e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1153,7 +1153,7 @@ namespace ts { for (const id in lookupTable) { const { exportsWithDuplicate } = lookupTable[id]; // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself - if (id === "export=" || !exportsWithDuplicate.length || hasProperty(symbols, id)) { + if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || hasProperty(symbols, id)) { continue; } for (const node of exportsWithDuplicate) {