Skip to content

Commit bb193fe

Browse files
committed
augment check for colliding declaration spaces
1 parent d7f6708 commit bb193fe

File tree

8 files changed

+88
-33
lines changed

8 files changed

+88
-33
lines changed

src/compiler/checker.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4941,28 +4941,34 @@ module ts {
49414941
}
49424942
}
49434943

4944+
// run the check only for the first declaration in the list
49444945
if (getDeclarationOfKind(symbol, node.kind) !== node) {
49454946
return;
49464947
}
49474948

49484949
// we use SymbolFlags.ExportValue, SymbolFlags.ExportType and SymbolFlags.ExportNamespace
49494950
// to denote disjoint declarationSpaces (without making new enum type).
4950-
var declarationSpaces: SymbolFlags = 0;
4951-
var hasExport: boolean;
4951+
var exportedDeclarationSpaces: SymbolFlags = 0;
4952+
var nonExportedDeclarationSpaces: SymbolFlags = 0;
4953+
forEach(symbol.declarations, d => {
4954+
var declarationSpaces = getDeclarationSpaces(d);
4955+
if (d.flags & NodeFlags.Export) {
4956+
exportedDeclarationSpaces |= declarationSpaces;
4957+
}
4958+
else {
4959+
nonExportedDeclarationSpaces |= declarationSpaces;
4960+
}
4961+
});
49524962

4953-
var declarations = symbol.declarations;
4954-
for (var i = 0, len = declarations.length; i < len; ++i) {
4955-
var currentDeclarationSpaces = getDeclarationSpaces(declarations[i]);
4956-
var currentDeclarationHasExport = (declarations[i].flags & NodeFlags.Export) !== 0;
4957-
if (declarationSpaces & currentDeclarationSpaces) {
4958-
if (hasExport !== undefined) {
4959-
if (hasExport !== currentDeclarationHasExport) {
4960-
error(declarations[i].name, Diagnostics.All_declarations_of_merged_declaration_0_must_be_exported_or_not_exported, symbolToString(symbol));
4961-
}
4963+
var commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces
4964+
4965+
if (commonDeclarationSpace) {
4966+
// declaration spaces for exported and non-exported declarations intersect
4967+
forEach(symbol.declarations, d => {
4968+
if (getDeclarationSpaces(d) & commonDeclarationSpace) {
4969+
error(d.name, Diagnostics.Individual_declarations_in_a_merged_declaration_0_must_be_all_exported_or_all_local, identifierToString(d.name));
49624970
}
4963-
}
4964-
hasExport = hasExport || currentDeclarationHasExport;
4965-
declarationSpaces |= currentDeclarationSpaces;
4971+
});
49664972
}
49674973

49684974
function getDeclarationSpaces(d: Declaration): SymbolFlags {
@@ -4977,8 +4983,10 @@ module ts {
49774983
case SyntaxKind.EnumDeclaration:
49784984
return SymbolFlags.ExportType | SymbolFlags.ExportValue;
49794985
case SyntaxKind.ImportDeclaration:
4986+
var result: SymbolFlags = 0;
49804987
var target = resolveImport(getSymbolOfNode(d));
4981-
return target.flags & SymbolFlags.Export;
4988+
forEach(target.declarations, d => { result |= getDeclarationSpaces(d); } )
4989+
return result;
49824990
default:
49834991
return SymbolFlags.ExportValue;
49844992
}
@@ -5000,10 +5008,10 @@ module ts {
50005008
checkFunctionOrConstructorSymbol(localSymbol);
50015009
}
50025010

5003-
if (symbol !== localSymbol) {
5004-
// here we'll check exported side of the symbol
5005-
Debug.assert(symbol.parent);
5011+
if (symbol.parent) {
5012+
// run check once for the first declaration
50065013
if (getDeclarationOfKind(symbol, node.kind) === node) {
5014+
// run check on export symbol to check that modifiers agree across all exported declarations
50075015
checkFunctionOrConstructorSymbol(symbol);
50085016
}
50095017
}

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ module ts {
137137
A_signature_with_an_implementation_cannot_use_a_string_literal_type: { code: 2163, category: DiagnosticCategory.Error, key: "A signature with an implementation cannot use a string literal type." },
138138
Interface_0_cannot_simultaneously_extend_types_1_and_2_Colon: { code: 2189, category: DiagnosticCategory.Error, key: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}':" },
139139
Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: { code: 2190, category: DiagnosticCategory.Error, key: "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it." },
140-
All_declarations_of_merged_declaration_0_must_be_exported_or_not_exported: { code: 2192, category: DiagnosticCategory.Error, key: "All declarations of merged declaration '{0}' must be exported or not exported." },
140+
Individual_declarations_in_a_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2192, category: DiagnosticCategory.Error, key: "Individual declarations in a merged declaration {0} must be all exported or all local." },
141141
super_cannot_be_referenced_in_constructor_arguments: { code: 2193, category: DiagnosticCategory.Error, key: "'super' cannot be referenced in constructor arguments." },
142142
Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: { code: 2194, category: DiagnosticCategory.Error, key: "Return type of constructor signature must be assignable to the instance type of the class" },
143143
Ambient_external_module_declaration_cannot_specify_relative_module_name: { code: 2196, category: DiagnosticCategory.Error, key: "Ambient external module declaration cannot specify relative module name." },

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@
540540
"category": "Error",
541541
"code": 2190
542542
},
543-
"All declarations of merged declaration '{0}' must be exported or not exported.": {
543+
"Individual declarations in a merged declaration {0} must be all exported or all local.": {
544544
"category": "Error",
545545
"code": 2192
546546
},

tests/baselines/reference/anonymousModules.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
==== tests/cases/compiler/anonymousModules.ts (12 errors) ====
1+
==== tests/cases/compiler/anonymousModules.ts (13 errors) ====
22
module {
33
~
44
!!! ';' expected.
@@ -18,13 +18,15 @@
1818
export var bar = 1;
1919
~~~~~~
2020
!!! Statement expected.
21+
~~~
22+
!!! Individual declarations in a merged declaration bar must be all exported or all local.
2123
}
2224
~
2325
!!! Declaration or statement expected.
2426

2527
var bar = 2;
2628
~~~
27-
!!! All declarations of merged declaration 'bar' must be exported or not exported.
29+
!!! Individual declarations in a merged declaration bar must be all exported or all local.
2830

2931
module {
3032
~

tests/baselines/reference/duplicateSymbolsExportMatching.errors.txt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
==== tests/cases/compiler/duplicateSymbolsExportMatching.ts (9 errors) ====
1+
==== tests/cases/compiler/duplicateSymbolsExportMatching.ts (18 errors) ====
22
module M {
33
export interface E { }
44
interface I { }
@@ -23,62 +23,80 @@
2323

2424
module N2 {
2525
interface I { }
26+
~
27+
!!! Individual declarations in a merged declaration I must be all exported or all local.
2628
export interface I { } // error
2729
~
28-
!!! All declarations of merged declaration 'I' must be exported or not exported.
30+
!!! Individual declarations in a merged declaration I must be all exported or all local.
2931
export interface E { }
32+
~
33+
!!! Individual declarations in a merged declaration E must be all exported or all local.
3034
interface E { } // error
3135
~
32-
!!! All declarations of merged declaration 'E' must be exported or not exported.
36+
!!! Individual declarations in a merged declaration E must be all exported or all local.
3337
}
3438

3539
// Should report error only once for instantiated module
3640
module M {
3741
module inst {
42+
~~~~
43+
!!! Individual declarations in a merged declaration inst must be all exported or all local.
3844
var t;
3945
}
4046
export module inst { // one error
4147
~~~~
42-
!!! All declarations of merged declaration 'inst' must be exported or not exported.
48+
!!! Individual declarations in a merged declaration inst must be all exported or all local.
4349
var t;
4450
}
4551
}
4652

4753
// Variables of the same / different type
4854
module M2 {
4955
var v: string;
56+
~
57+
!!! Individual declarations in a merged declaration v must be all exported or all local.
5058
export var v: string; // one error (visibility)
5159
~
52-
!!! All declarations of merged declaration 'v' must be exported or not exported.
60+
!!! Individual declarations in a merged declaration v must be all exported or all local.
5361
var w: number;
62+
~
63+
!!! Individual declarations in a merged declaration w must be all exported or all local.
5464
export var w: string; // two errors (visibility and type mismatch)
5565
~
56-
!!! All declarations of merged declaration 'w' must be exported or not exported.
66+
!!! Individual declarations in a merged declaration w must be all exported or all local.
5767
}
5868

5969
module M {
6070
module F {
6171
~
6272
!!! A module declaration cannot be located prior to a class or function with which it is merged
73+
~
74+
!!! Individual declarations in a merged declaration F must be all exported or all local.
6375
var t;
6476
}
6577
export function F() { } // Only one error for duplicate identifier (don't consider visibility)
6678
~
67-
!!! All declarations of merged declaration 'F' must be exported or not exported.
79+
!!! Individual declarations in a merged declaration F must be all exported or all local.
6880
}
6981

7082
module M {
7183
class C { }
84+
~
85+
!!! Individual declarations in a merged declaration C must be all exported or all local.
7286
module C { }
87+
~
88+
!!! Individual declarations in a merged declaration C must be all exported or all local.
7389
export module C { // Two visibility errors (one for the clodule symbol, and one for the merged container symbol)
7490
~
75-
!!! All declarations of merged declaration 'C' must be exported or not exported.
91+
!!! Individual declarations in a merged declaration C must be all exported or all local.
7692
var t;
7793
}
7894
}
7995

8096
// Top level
8197
interface D { }
98+
~
99+
!!! Individual declarations in a merged declaration D must be all exported or all local.
82100
export interface D { }
83101
~
84-
!!! All declarations of merged declaration 'D' must be exported or not exported.
102+
!!! Individual declarations in a merged declaration D must be all exported or all local.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [mixedExports.ts]
2+
declare module M {
3+
function foo();
4+
export function foo();
5+
function foo();
6+
}
7+
8+
module A {
9+
interface X {x}
10+
export module X {}
11+
interface X {y}
12+
}
13+
14+
//// [mixedExports.js]

tests/baselines/reference/multivar.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
==== tests/cases/compiler/multivar.ts (1 errors) ====
1+
==== tests/cases/compiler/multivar.ts (2 errors) ====
22
var a,b,c;
33
var x=1,y=2,z=3;
44

55
module m2 {
66

77
export var a, b2: number = 10, b;
8+
~~
9+
!!! Individual declarations in a merged declaration b2 must be all exported or all local.
810
var m1;
911
var a2, b22: number = 10, b222;
1012
var m3;
@@ -22,7 +24,7 @@
2224
declare var d1, d2;
2325
var b2;
2426
~~
25-
!!! All declarations of merged declaration 'b2' must be exported or not exported.
27+
!!! Individual declarations in a merged declaration b2 must be all exported or all local.
2628

2729
declare var v1;
2830
}

tests/cases/compiler/mixedExports.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare module M {
2+
function foo();
3+
export function foo();
4+
function foo();
5+
}
6+
7+
module A {
8+
interface X {x}
9+
export module X {}
10+
interface X {y}
11+
}

0 commit comments

Comments
 (0)