Skip to content

Commit 1868caa

Browse files
Merge pull request microsoft#6469 from ShyykoSerhiy/fix-528
Fixes issue microsoft#528 (Show better error message for unresolved references due to missing prefix)
2 parents 3b9c20e + 21baedf commit 1868caa

11 files changed

Lines changed: 79 additions & 35 deletions

src/compiler/checker.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,9 @@ namespace ts {
741741

742742
if (!result) {
743743
if (nameNotFoundMessage) {
744-
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
744+
if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg)) {
745+
error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
746+
}
745747
}
746748
return undefined;
747749
}
@@ -778,6 +780,40 @@ namespace ts {
778780
return result;
779781
}
780782

783+
function checkAndReportErrorForMissingPrefix(errorLocation: Node, name: string, nameArg: string | Identifier): boolean {
784+
if (!errorLocation || (errorLocation.kind === SyntaxKind.Identifier && (isTypeReferenceIdentifier(<Identifier>errorLocation)) || isInTypeQuery(errorLocation))) {
785+
return false;
786+
}
787+
788+
const container = getThisContainer(errorLocation, /* includeArrowFunctions */ true);
789+
let location = container;
790+
while (location) {
791+
if (isClassLike(location.parent)) {
792+
const symbol = getSymbolOfNode(location.parent);
793+
let classType: Type;
794+
if (location.flags & NodeFlags.Static) {
795+
classType = getTypeOfSymbol(symbol);
796+
if (getPropertyOfType(classType, name)) {
797+
error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg), symbolToString(symbol));
798+
return true;
799+
}
800+
}
801+
else {
802+
if (location === container) {
803+
classType = (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
804+
if (getPropertyOfType(classType, name)) {
805+
error(errorLocation, Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
806+
return true;
807+
}
808+
}
809+
}
810+
}
811+
812+
location = location.parent;
813+
}
814+
return false;
815+
}
816+
781817
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
782818
Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0);
783819
// Block-scoped variables cannot be used before their definition

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,14 @@
17671767
"category": "Error",
17681768
"code": 2661
17691769
},
1770+
"Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?": {
1771+
"category": "Error",
1772+
"code": 2662
1773+
},
1774+
"Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?": {
1775+
"category": "Error",
1776+
"code": 2663
1777+
},
17701778
"Import declaration '{0}' is using private name '{1}'.": {
17711779
"category": "Error",
17721780
"code": 4000
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/es6/yieldExpressions/YieldExpression11_es6.ts(2,3): error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
2-
tests/cases/conformance/es6/yieldExpressions/YieldExpression11_es6.ts(3,11): error TS2304: Cannot find name 'foo'.
2+
tests/cases/conformance/es6/yieldExpressions/YieldExpression11_es6.ts(3,11): error TS2663: Cannot find name 'foo'. Did you mean the instance member 'this.foo'?
33

44

55
==== tests/cases/conformance/es6/yieldExpressions/YieldExpression11_es6.ts (2 errors) ====
@@ -9,6 +9,6 @@ tests/cases/conformance/es6/yieldExpressions/YieldExpression11_es6.ts(3,11): err
99
!!! error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
1010
yield(foo);
1111
~~~
12-
!!! error TS2304: Cannot find name 'foo'.
12+
!!! error TS2663: Cannot find name 'foo'. Did you mean the instance member 'this.foo'?
1313
}
1414
}

tests/baselines/reference/initializerReferencingConstructorParameters.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(4,9): error TS2304: Cannot find name 'x'.
22
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(5,15): error TS2304: Cannot find name 'x'.
3-
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(10,9): error TS2304: Cannot find name 'x'.
3+
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(10,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
44
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(11,15): error TS2304: Cannot find name 'x'.
55
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(17,15): error TS1003: Identifier expected.
6-
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(23,9): error TS2304: Cannot find name 'x'.
6+
tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts(23,9): error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
77

88

99
==== tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencingConstructorParameters.ts (6 errors) ====
@@ -22,7 +22,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
2222
class D {
2323
a = x; // error
2424
~
25-
!!! error TS2304: Cannot find name 'x'.
25+
!!! error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
2626
b: typeof x; // error
2727
~
2828
!!! error TS2304: Cannot find name 'x'.
@@ -41,6 +41,6 @@ tests/cases/conformance/classes/propertyMemberDeclarations/initializerReferencin
4141
a = this.x; // ok
4242
b = x; // error
4343
~
44-
!!! error TS2304: Cannot find name 'x'.
44+
!!! error TS2663: Cannot find name 'x'. Did you mean the instance member 'this.x'?
4545
constructor(public x: T) { }
4646
}

tests/baselines/reference/parserharness.errors.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(25,17): er
77
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(41,12): error TS2304: Cannot find name 'ActiveXObject'.
88
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(43,19): error TS2304: Cannot find name 'require'.
99
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(44,14): error TS2304: Cannot find name 'require'.
10-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(341,13): error TS2304: Cannot find name 'errorHandlerStack'.
11-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(347,13): error TS2304: Cannot find name 'errorHandlerStack'.
12-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(351,17): error TS2304: Cannot find name 'errorHandlerStack'.
13-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(354,17): error TS2304: Cannot find name 'errorHandlerStack'.
14-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(354,35): error TS2304: Cannot find name 'errorHandlerStack'.
10+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(341,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
11+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(347,13): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
12+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(351,17): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
13+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(354,17): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
14+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(354,35): error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
1515
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(691,50): error TS2304: Cannot find name 'ITextWriter'.
1616
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(716,47): error TS2503: Cannot find namespace 'TypeScript'.
1717
tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(721,62): error TS2304: Cannot find name 'ITextWriter'.
@@ -471,28 +471,28 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32):
471471
static pushGlobalErrorHandler(done: IDone) {
472472
errorHandlerStack.push(function (e) {
473473
~~~~~~~~~~~~~~~~~
474-
!!! error TS2304: Cannot find name 'errorHandlerStack'.
474+
!!! error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
475475
done(e);
476476
});
477477
}
478478

479479
static popGlobalErrorHandler() {
480480
errorHandlerStack.pop();
481481
~~~~~~~~~~~~~~~~~
482-
!!! error TS2304: Cannot find name 'errorHandlerStack'.
482+
!!! error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
483483
}
484484

485485
static handleError(e: Error) {
486486
if (errorHandlerStack.length === 0) {
487487
~~~~~~~~~~~~~~~~~
488-
!!! error TS2304: Cannot find name 'errorHandlerStack'.
488+
!!! error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
489489
IO.printLine('Global error: ' + e);
490490
} else {
491491
errorHandlerStack[errorHandlerStack.length - 1](e);
492492
~~~~~~~~~~~~~~~~~
493-
!!! error TS2304: Cannot find name 'errorHandlerStack'.
493+
!!! error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
494494
~~~~~~~~~~~~~~~~~
495-
!!! error TS2304: Cannot find name 'errorHandlerStack'.
495+
!!! error TS2662: Cannot find name 'errorHandlerStack'. Did you mean the static member 'Runnable.errorHandlerStack'?
496496
}
497497
}
498498
}

tests/baselines/reference/parserindenter.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(152,63):
2828
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(153,30): error TS2304: Cannot find name 'List_TextEditInfo'.
2929
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(155,32): error TS2304: Cannot find name 'AuthorTokenKind'.
3030
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(182,79): error TS2503: Cannot find namespace 'Services'.
31-
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(183,20): error TS2304: Cannot find name 'GetIndentSizeFromText'.
31+
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(183,20): error TS2662: Cannot find name 'GetIndentSizeFromText'. Did you mean the static member 'Indenter.GetIndentSizeFromText'?
3232
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(186,67): error TS2503: Cannot find namespace 'Services'.
3333
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(207,50): error TS2304: Cannot find name 'TokenSpan'.
3434
tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(207,67): error TS2304: Cannot find name 'ParseNode'.
@@ -373,7 +373,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserindenter.ts(736,38):
373373
!!! error TS2503: Cannot find namespace 'Services'.
374374
return GetIndentSizeFromText(indentText, editorOptions, /*includeNonIndentChars:*/ false);
375375
~~~~~~~~~~~~~~~~~~~~~
376-
!!! error TS2304: Cannot find name 'GetIndentSizeFromText'.
376+
!!! error TS2662: Cannot find name 'GetIndentSizeFromText'. Did you mean the static member 'Indenter.GetIndentSizeFromText'?
377377
}
378378

379379
static GetIndentSizeFromText(text: string, editorOptions: Services.EditorOptions, includeNonIndentChars: boolean): number {

tests/baselines/reference/recursiveClassReferenceTest.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/recursiveClassReferenceTest.ts(16,19): error TS2304: Cannot find name 'Element'.
2-
tests/cases/compiler/recursiveClassReferenceTest.ts(56,11): error TS2304: Cannot find name 'domNode'.
3-
tests/cases/compiler/recursiveClassReferenceTest.ts(88,36): error TS2304: Cannot find name 'mode'.
2+
tests/cases/compiler/recursiveClassReferenceTest.ts(56,11): error TS2663: Cannot find name 'domNode'. Did you mean the instance member 'this.domNode'?
3+
tests/cases/compiler/recursiveClassReferenceTest.ts(88,36): error TS2663: Cannot find name 'mode'. Did you mean the instance member 'this.mode'?
44
tests/cases/compiler/recursiveClassReferenceTest.ts(95,21): error TS2345: Argument of type 'Window' is not assignable to parameter of type 'IMode'.
55
Property 'getInitialState' is missing in type 'Window'.
66

@@ -65,7 +65,7 @@ tests/cases/compiler/recursiveClassReferenceTest.ts(95,21): error TS2345: Argume
6565
public getDomNode() {
6666
return domNode;
6767
~~~~~~~
68-
!!! error TS2304: Cannot find name 'domNode'.
68+
!!! error TS2663: Cannot find name 'domNode'. Did you mean the instance member 'this.domNode'?
6969
}
7070

7171
public destroy() {
@@ -99,7 +99,7 @@ tests/cases/compiler/recursiveClassReferenceTest.ts(95,21): error TS2345: Argume
9999

100100
public getMode(): IMode { return mode; }
101101
~~~~
102-
!!! error TS2304: Cannot find name 'mode'.
102+
!!! error TS2663: Cannot find name 'mode'. Did you mean the instance member 'this.mode'?
103103
}
104104

105105
export class Mode extends AbstractMode {

tests/baselines/reference/scannertest1.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(1,1): error TS6053: File 'tests/cases/conformance/scanner/ecmascript5/References.ts' not found.
22
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(5,21): error TS2304: Cannot find name 'CharacterCodes'.
33
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(5,47): error TS2304: Cannot find name 'CharacterCodes'.
4-
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(9,16): error TS2304: Cannot find name 'isDecimalDigit'.
4+
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(9,16): error TS2662: Cannot find name 'isDecimalDigit'. Did you mean the static member 'CharacterInfo.isDecimalDigit'?
55
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(10,22): error TS2304: Cannot find name 'CharacterCodes'.
66
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(10,47): error TS2304: Cannot find name 'CharacterCodes'.
77
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(11,22): error TS2304: Cannot find name 'CharacterCodes'.
88
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(11,47): error TS2304: Cannot find name 'CharacterCodes'.
99
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(15,9): error TS2304: Cannot find name 'Debug'.
10-
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(15,22): error TS2304: Cannot find name 'isHexDigit'.
11-
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(16,16): error TS2304: Cannot find name 'isDecimalDigit'.
10+
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(15,22): error TS2662: Cannot find name 'isHexDigit'. Did you mean the static member 'CharacterInfo.isHexDigit'?
11+
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(16,16): error TS2662: Cannot find name 'isDecimalDigit'. Did you mean the static member 'CharacterInfo.isDecimalDigit'?
1212
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(17,20): error TS2304: Cannot find name 'CharacterCodes'.
1313
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(18,21): error TS2304: Cannot find name 'CharacterCodes'.
1414
tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(18,46): error TS2304: Cannot find name 'CharacterCodes'.
@@ -33,7 +33,7 @@ tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(20,23): error TS2304
3333
public static isHexDigit(c: number): boolean {
3434
return isDecimalDigit(c) ||
3535
~~~~~~~~~~~~~~
36-
!!! error TS2304: Cannot find name 'isDecimalDigit'.
36+
!!! error TS2662: Cannot find name 'isDecimalDigit'. Did you mean the static member 'CharacterInfo.isDecimalDigit'?
3737
(c >= CharacterCodes.A && c <= CharacterCodes.F) ||
3838
~~~~~~~~~~~~~~
3939
!!! error TS2304: Cannot find name 'CharacterCodes'.
@@ -51,10 +51,10 @@ tests/cases/conformance/scanner/ecmascript5/scannertest1.ts(20,23): error TS2304
5151
~~~~~
5252
!!! error TS2304: Cannot find name 'Debug'.
5353
~~~~~~~~~~
54-
!!! error TS2304: Cannot find name 'isHexDigit'.
54+
!!! error TS2662: Cannot find name 'isHexDigit'. Did you mean the static member 'CharacterInfo.isHexDigit'?
5555
return isDecimalDigit(c)
5656
~~~~~~~~~~~~~~
57-
!!! error TS2304: Cannot find name 'isDecimalDigit'.
57+
!!! error TS2662: Cannot find name 'isDecimalDigit'. Did you mean the static member 'CharacterInfo.isDecimalDigit'?
5858
? (c - CharacterCodes._0)
5959
~~~~~~~~~~~~~~
6060
!!! error TS2304: Cannot find name 'CharacterCodes'.

tests/baselines/reference/scopeCheckExtendedClassInsidePublicMethod2.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/scopeCheckExtendedClassInsidePublicMethod2.ts(4,7): error TS2304: Cannot find name 'v'.
1+
tests/cases/compiler/scopeCheckExtendedClassInsidePublicMethod2.ts(4,7): error TS2663: Cannot find name 'v'. Did you mean the instance member 'this.v'?
22
tests/cases/compiler/scopeCheckExtendedClassInsidePublicMethod2.ts(6,7): error TS2304: Cannot find name 's'.
33

44

@@ -8,7 +8,7 @@ tests/cases/compiler/scopeCheckExtendedClassInsidePublicMethod2.ts(6,7): error T
88
public c() {
99
v = 1;
1010
~
11-
!!! error TS2304: Cannot find name 'v'.
11+
!!! error TS2663: Cannot find name 'v'. Did you mean the instance member 'this.v'?
1212
this.p = 1;
1313
s = 1;
1414
~

tests/baselines/reference/scopeCheckExtendedClassInsideStaticMethod1.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts(4,7): error TS2304: Cannot find name 'v'.
22
tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts(5,12): error TS2339: Property 'p' does not exist on type 'typeof D'.
3-
tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts(6,7): error TS2304: Cannot find name 's'.
3+
tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts(6,7): error TS2662: Cannot find name 's'. Did you mean the static member 'D.s'?
44

55

66
==== tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts (3 errors) ====
@@ -15,6 +15,6 @@ tests/cases/compiler/scopeCheckExtendedClassInsideStaticMethod1.ts(6,7): error T
1515
!!! error TS2339: Property 'p' does not exist on type 'typeof D'.
1616
s = 1;
1717
~
18-
!!! error TS2304: Cannot find name 's'.
18+
!!! error TS2662: Cannot find name 's'. Did you mean the static member 'D.s'?
1919
}
2020
}

0 commit comments

Comments
 (0)