Merge pull request #13796 from Microsoft/fix-duplicate-identifier-reporting

Fix duplicate identifier reporting in classes
This commit is contained in:
Nathan Shively-Sanders 2017-02-14 11:42:48 -08:00 committed by GitHub
commit 477d9f2e48
4 changed files with 95 additions and 9 deletions

View File

@ -15933,19 +15933,20 @@ namespace ts {
}
function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) {
const enum Accessor {
const enum Declaration {
Getter = 1,
Setter = 2,
Method = 4,
Property = Getter | Setter
}
const instanceNames = createMap<Accessor>();
const staticNames = createMap<Accessor>();
const instanceNames = createMap<Declaration>();
const staticNames = createMap<Declaration>();
for (const member of node.members) {
if (member.kind === SyntaxKind.Constructor) {
for (const param of (member as ConstructorDeclaration).parameters) {
if (isParameterPropertyDeclaration(param)) {
addName(instanceNames, param.name, (param.name as Identifier).text, Accessor.Property);
addName(instanceNames, param.name, (param.name as Identifier).text, Declaration.Property);
}
}
}
@ -15957,25 +15958,34 @@ namespace ts {
if (memberName) {
switch (member.kind) {
case SyntaxKind.GetAccessor:
addName(names, member.name, memberName, Accessor.Getter);
addName(names, member.name, memberName, Declaration.Getter);
break;
case SyntaxKind.SetAccessor:
addName(names, member.name, memberName, Accessor.Setter);
addName(names, member.name, memberName, Declaration.Setter);
break;
case SyntaxKind.PropertyDeclaration:
addName(names, member.name, memberName, Accessor.Property);
addName(names, member.name, memberName, Declaration.Property);
break;
case SyntaxKind.MethodDeclaration:
addName(names, member.name, memberName, Declaration.Method);
break;
}
}
}
}
function addName(names: Map<Accessor>, location: Node, name: string, meaning: Accessor) {
function addName(names: Map<Declaration>, location: Node, name: string, meaning: Declaration) {
const prev = names.get(name);
if (prev) {
if (prev & meaning) {
if (prev & Declaration.Method) {
if (meaning !== Declaration.Method) {
error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location));
}
}
else if (prev & meaning) {
error(location, Diagnostics.Duplicate_identifier_0, getTextOfNode(location));
}
else {

View File

@ -0,0 +1,31 @@
tests/cases/compiler/classWithDuplicateIdentifier.ts(3,5): error TS2300: Duplicate identifier 'a'.
tests/cases/compiler/classWithDuplicateIdentifier.ts(6,5): error TS2300: Duplicate identifier 'b'.
tests/cases/compiler/classWithDuplicateIdentifier.ts(7,5): error TS2300: Duplicate identifier 'b'.
tests/cases/compiler/classWithDuplicateIdentifier.ts(11,5): error TS2300: Duplicate identifier 'c'.
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'.
==== tests/cases/compiler/classWithDuplicateIdentifier.ts (5 errors) ====
class C {
a(): number { return 0; } // error: duplicate identifier
a: number;
~
!!! error TS2300: Duplicate identifier 'a'.
}
class K {
b: number; // error: duplicate identifier
~
!!! error TS2300: Duplicate identifier 'b'.
b(): number { return 0; }
~
!!! error TS2300: Duplicate identifier 'b'.
}
class D {
c: number;
c: string;
~
!!! error TS2300: Duplicate identifier 'c'.
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'number', but here has type 'string'.
}

View File

@ -0,0 +1,33 @@
//// [classWithDuplicateIdentifier.ts]
class C {
a(): number { return 0; } // error: duplicate identifier
a: number;
}
class K {
b: number; // error: duplicate identifier
b(): number { return 0; }
}
class D {
c: number;
c: string;
}
//// [classWithDuplicateIdentifier.js]
var C = (function () {
function C() {
}
C.prototype.a = function () { return 0; }; // error: duplicate identifier
return C;
}());
var K = (function () {
function K() {
}
K.prototype.b = function () { return 0; };
return K;
}());
var D = (function () {
function D() {
}
return D;
}());

View File

@ -0,0 +1,12 @@
class C {
a(): number { return 0; } // error: duplicate identifier
a: number;
}
class K {
b: number; // error: duplicate identifier
b(): number { return 0; }
}
class D {
c: number;
c: string;
}