Skip to content

Commit cc3f604

Browse files
weswighamAndy Hanson
authored and
Andy Hanson
committed
Add related span pointing to this-shadowing location for implicitly-any this (#28299)
* Add diagnostic pointing to this-shadowing location * Fix almost-top-level-this case * Change message on span
1 parent 45db51b commit cc3f604

8 files changed

+106
-1
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16310,11 +16310,17 @@ namespace ts {
1631016310
const type = tryGetThisTypeAt(node, container);
1631116311
if (!type && noImplicitThis) {
1631216312
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
16313-
error(
16313+
const diag = error(
1631416314
node,
1631516315
capturedByArrowFunction && container.kind === SyntaxKind.SourceFile ?
1631616316
Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this_which_implicitly_has_type_any :
1631716317
Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
16318+
if (!isSourceFile(container)) {
16319+
const outsideThis = tryGetThisTypeAt(container);
16320+
if (outsideThis) {
16321+
addRelatedInfo(diag, createDiagnosticForNode(container, Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container));
16322+
}
16323+
}
1631816324
}
1631916325
return type || anyType;
1632016326
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,6 +2509,10 @@
25092509
"category": "Error",
25102510
"code": 2737
25112511
},
2512+
"An outer value of 'this' is shadowed by this container.": {
2513+
"category": "Message",
2514+
"code": 2738
2515+
},
25122516

25132517
"Import declaration '{0}' is using private name '{1}'.": {
25142518
"category": "Error",

tests/baselines/reference/thisBinding2.errors.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ tests/cases/compiler/thisBinding2.ts(10,11): error TS2683: 'this' implicitly has
1414
return this.x;
1515
~~~~
1616
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
17+
!!! related TS2738 tests/cases/compiler/thisBinding2.ts:8:12: An outer value of 'this' is shadowed by this container.
1718
}();
1819
}
1920
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
tests/cases/compiler/thisShadowingErrorSpans.ts(5,13): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
2+
3+
4+
==== tests/cases/compiler/thisShadowingErrorSpans.ts (1 errors) ====
5+
class C {
6+
m() {
7+
this.m();
8+
function f() {
9+
this.m();
10+
~~~~
11+
!!! error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
12+
!!! related TS2738 tests/cases/compiler/thisShadowingErrorSpans.ts:4:18: An outer value of 'this' is shadowed by this container.
13+
}
14+
}
15+
}
16+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [thisShadowingErrorSpans.ts]
2+
class C {
3+
m() {
4+
this.m();
5+
function f() {
6+
this.m();
7+
}
8+
}
9+
}
10+
11+
12+
//// [thisShadowingErrorSpans.js]
13+
"use strict";
14+
var C = /** @class */ (function () {
15+
function C() {
16+
}
17+
C.prototype.m = function () {
18+
this.m();
19+
function f() {
20+
this.m();
21+
}
22+
};
23+
return C;
24+
}());
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/thisShadowingErrorSpans.ts ===
2+
class C {
3+
>C : Symbol(C, Decl(thisShadowingErrorSpans.ts, 0, 0))
4+
5+
m() {
6+
>m : Symbol(C.m, Decl(thisShadowingErrorSpans.ts, 0, 9))
7+
8+
this.m();
9+
>this.m : Symbol(C.m, Decl(thisShadowingErrorSpans.ts, 0, 9))
10+
>this : Symbol(C, Decl(thisShadowingErrorSpans.ts, 0, 0))
11+
>m : Symbol(C.m, Decl(thisShadowingErrorSpans.ts, 0, 9))
12+
13+
function f() {
14+
>f : Symbol(f, Decl(thisShadowingErrorSpans.ts, 2, 17))
15+
16+
this.m();
17+
}
18+
}
19+
}
20+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/thisShadowingErrorSpans.ts ===
2+
class C {
3+
>C : C
4+
5+
m() {
6+
>m : () => void
7+
8+
this.m();
9+
>this.m() : void
10+
>this.m : () => void
11+
>this : this
12+
>m : () => void
13+
14+
function f() {
15+
>f : () => void
16+
17+
this.m();
18+
>this.m() : any
19+
>this.m : any
20+
>this : any
21+
>m : any
22+
}
23+
}
24+
}
25+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @strict: true
2+
class C {
3+
m() {
4+
this.m();
5+
function f() {
6+
this.m();
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)