Skip to content

Commit 477d9f2

Browse files
authored
Merge pull request #13796 from Microsoft/fix-duplicate-identifier-reporting
Fix duplicate identifier reporting in classes
2 parents c57fc1f + ce629f0 commit 477d9f2

File tree

4 files changed

+95
-9
lines changed

4 files changed

+95
-9
lines changed

src/compiler/checker.ts

+19-9
Original file line numberDiff line numberDiff line change
@@ -15933,19 +15933,20 @@ namespace ts {
1593315933
}
1593415934

1593515935
function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) {
15936-
const enum Accessor {
15936+
const enum Declaration {
1593715937
Getter = 1,
1593815938
Setter = 2,
15939+
Method = 4,
1593915940
Property = Getter | Setter
1594015941
}
1594115942

15942-
const instanceNames = createMap<Accessor>();
15943-
const staticNames = createMap<Accessor>();
15943+
const instanceNames = createMap<Declaration>();
15944+
const staticNames = createMap<Declaration>();
1594415945
for (const member of node.members) {
1594515946
if (member.kind === SyntaxKind.Constructor) {
1594615947
for (const param of (member as ConstructorDeclaration).parameters) {
1594715948
if (isParameterPropertyDeclaration(param)) {
15948-
addName(instanceNames, param.name, (param.name as Identifier).text, Accessor.Property);
15949+
addName(instanceNames, param.name, (param.name as Identifier).text, Declaration.Property);
1594915950
}
1595015951
}
1595115952
}
@@ -15957,25 +15958,34 @@ namespace ts {
1595715958
if (memberName) {
1595815959
switch (member.kind) {
1595915960
case SyntaxKind.GetAccessor:
15960-
addName(names, member.name, memberName, Accessor.Getter);
15961+
addName(names, member.name, memberName, Declaration.Getter);
1596115962
break;
1596215963

1596315964
case SyntaxKind.SetAccessor:
15964-
addName(names, member.name, memberName, Accessor.Setter);
15965+
addName(names, member.name, memberName, Declaration.Setter);
1596515966
break;
1596615967

1596715968
case SyntaxKind.PropertyDeclaration:
15968-
addName(names, member.name, memberName, Accessor.Property);
15969+
addName(names, member.name, memberName, Declaration.Property);
15970+
break;
15971+
15972+
case SyntaxKind.MethodDeclaration:
15973+
addName(names, member.name, memberName, Declaration.Method);
1596915974
break;
1597015975
}
1597115976
}
1597215977
}
1597315978
}
1597415979

15975-
function addName(names: Map<Accessor>, location: Node, name: string, meaning: Accessor) {
15980+
function addName(names: Map<Declaration>, location: Node, name: string, meaning: Declaration) {
1597615981
const prev = names.get(name);
1597715982
if (prev) {
15978-
if (prev & meaning) {
15983+
if (prev & Declaration.Method) {
15984+
if (meaning !== Declaration.Method) {
15985+
error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location));
15986+
}
15987+
}
15988+
else if (prev & meaning) {
1597915989
error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location));
1598015990
}
1598115991
else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
tests/cases/compiler/classWithDuplicateIdentifier.ts(3,5): error TS2300: Duplicate identifier 'a'.
2+
tests/cases/compiler/classWithDuplicateIdentifier.ts(6,5): error TS2300: Duplicate identifier 'b'.
3+
tests/cases/compiler/classWithDuplicateIdentifier.ts(7,5): error TS2300: Duplicate identifier 'b'.
4+
tests/cases/compiler/classWithDuplicateIdentifier.ts(11,5): error TS2300: Duplicate identifier 'c'.
5+
tests/cases/compiler/classWithDuplicateIdentifier.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'number', but here has type 'string'.
6+
7+
8+
==== tests/cases/compiler/classWithDuplicateIdentifier.ts (5 errors) ====
9+
class C {
10+
a(): number { return 0; } // error: duplicate identifier
11+
a: number;
12+
~
13+
!!! error TS2300: Duplicate identifier 'a'.
14+
}
15+
class K {
16+
b: number; // error: duplicate identifier
17+
~
18+
!!! error TS2300: Duplicate identifier 'b'.
19+
b(): number { return 0; }
20+
~
21+
!!! error TS2300: Duplicate identifier 'b'.
22+
}
23+
class D {
24+
c: number;
25+
c: string;
26+
~
27+
!!! error TS2300: Duplicate identifier 'c'.
28+
~
29+
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'number', but here has type 'string'.
30+
}
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//// [classWithDuplicateIdentifier.ts]
2+
class C {
3+
a(): number { return 0; } // error: duplicate identifier
4+
a: number;
5+
}
6+
class K {
7+
b: number; // error: duplicate identifier
8+
b(): number { return 0; }
9+
}
10+
class D {
11+
c: number;
12+
c: string;
13+
}
14+
15+
16+
//// [classWithDuplicateIdentifier.js]
17+
var C = (function () {
18+
function C() {
19+
}
20+
C.prototype.a = function () { return 0; }; // error: duplicate identifier
21+
return C;
22+
}());
23+
var K = (function () {
24+
function K() {
25+
}
26+
K.prototype.b = function () { return 0; };
27+
return K;
28+
}());
29+
var D = (function () {
30+
function D() {
31+
}
32+
return D;
33+
}());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class C {
2+
a(): number { return 0; } // error: duplicate identifier
3+
a: number;
4+
}
5+
class K {
6+
b: number; // error: duplicate identifier
7+
b(): number { return 0; }
8+
}
9+
class D {
10+
c: number;
11+
c: string;
12+
}

0 commit comments

Comments
 (0)