Skip to content

Commit 11eabc0

Browse files
authored
Skip parens and non-null assertions when looking for this-context (microsoft#23097)
* Skip parens and ! for getting this-context of call * Add test and improve code a bit * Use skipOuterExpressions instead
1 parent a2c11bb commit 11eabc0

6 files changed

Lines changed: 165 additions & 7 deletions

File tree

src/compiler/checker.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17269,12 +17269,9 @@ namespace ts {
1726917269
*/
1727017270
function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression {
1727117271
if (node.kind === SyntaxKind.CallExpression) {
17272-
const callee = node.expression;
17273-
if (callee.kind === SyntaxKind.PropertyAccessExpression) {
17274-
return (callee as PropertyAccessExpression).expression;
17275-
}
17276-
else if (callee.kind === SyntaxKind.ElementAccessExpression) {
17277-
return (callee as ElementAccessExpression).expression;
17272+
const callee = skipOuterExpressions(node.expression);
17273+
if (callee.kind === SyntaxKind.PropertyAccessExpression || callee.kind === SyntaxKind.ElementAccessExpression) {
17274+
return (callee as PropertyAccessExpression | ElementAccessExpression).expression;
1727817275
}
1727917276
}
1728017277
}

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2022,7 +2022,7 @@ namespace ts {
20222022
export function skipParentheses(node: Node): Node;
20232023
export function skipParentheses(node: Node): Node {
20242024
while (node.kind === SyntaxKind.ParenthesizedExpression) {
2025-
node = (<ParenthesizedExpression>node).expression;
2025+
node = (node as ParenthesizedExpression).expression;
20262026
}
20272027

20282028
return node;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [thisTypeSyntacticContext.ts]
2+
function f(this: { n: number }) {
3+
}
4+
5+
const o: { n: number, test?: (this: { n: number }) => void } = { n: 1 }
6+
o.test = f
7+
8+
o.test();
9+
o!.test();
10+
o.test!();
11+
o.test!!!();
12+
(o.test!)();
13+
(o.test)();
14+
15+
16+
17+
//// [thisTypeSyntacticContext.js]
18+
function f() {
19+
}
20+
var o = { n: 1 };
21+
o.test = f;
22+
o.test();
23+
o.test();
24+
o.test();
25+
o.test();
26+
(o.test)();
27+
(o.test)();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeSyntacticContext.ts ===
2+
function f(this: { n: number }) {
3+
>f : Symbol(f, Decl(thisTypeSyntacticContext.ts, 0, 0))
4+
>this : Symbol(this, Decl(thisTypeSyntacticContext.ts, 0, 11))
5+
>n : Symbol(n, Decl(thisTypeSyntacticContext.ts, 0, 18))
6+
}
7+
8+
const o: { n: number, test?: (this: { n: number }) => void } = { n: 1 }
9+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
10+
>n : Symbol(n, Decl(thisTypeSyntacticContext.ts, 3, 10))
11+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
12+
>this : Symbol(this, Decl(thisTypeSyntacticContext.ts, 3, 30))
13+
>n : Symbol(n, Decl(thisTypeSyntacticContext.ts, 3, 37))
14+
>n : Symbol(n, Decl(thisTypeSyntacticContext.ts, 3, 64))
15+
16+
o.test = f
17+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
18+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
19+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
20+
>f : Symbol(f, Decl(thisTypeSyntacticContext.ts, 0, 0))
21+
22+
o.test();
23+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
24+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
25+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
26+
27+
o!.test();
28+
>o!.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
29+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
30+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
31+
32+
o.test!();
33+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
34+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
35+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
36+
37+
o.test!!!();
38+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
39+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
40+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
41+
42+
(o.test!)();
43+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
44+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
45+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
46+
47+
(o.test)();
48+
>o.test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
49+
>o : Symbol(o, Decl(thisTypeSyntacticContext.ts, 3, 5))
50+
>test : Symbol(test, Decl(thisTypeSyntacticContext.ts, 3, 21))
51+
52+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeSyntacticContext.ts ===
2+
function f(this: { n: number }) {
3+
>f : (this: { n: number; }) => void
4+
>this : { n: number; }
5+
>n : number
6+
}
7+
8+
const o: { n: number, test?: (this: { n: number }) => void } = { n: 1 }
9+
>o : { n: number; test?: (this: { n: number; }) => void; }
10+
>n : number
11+
>test : (this: { n: number; }) => void
12+
>this : { n: number; }
13+
>n : number
14+
>{ n: 1 } : { n: number; }
15+
>n : number
16+
>1 : 1
17+
18+
o.test = f
19+
>o.test = f : (this: { n: number; }) => void
20+
>o.test : (this: { n: number; }) => void
21+
>o : { n: number; test?: (this: { n: number; }) => void; }
22+
>test : (this: { n: number; }) => void
23+
>f : (this: { n: number; }) => void
24+
25+
o.test();
26+
>o.test() : void
27+
>o.test : (this: { n: number; }) => void
28+
>o : { n: number; test?: (this: { n: number; }) => void; }
29+
>test : (this: { n: number; }) => void
30+
31+
o!.test();
32+
>o!.test() : void
33+
>o!.test : (this: { n: number; }) => void
34+
>o! : { n: number; test?: (this: { n: number; }) => void; }
35+
>o : { n: number; test?: (this: { n: number; }) => void; }
36+
>test : (this: { n: number; }) => void
37+
38+
o.test!();
39+
>o.test!() : void
40+
>o.test! : (this: { n: number; }) => void
41+
>o.test : (this: { n: number; }) => void
42+
>o : { n: number; test?: (this: { n: number; }) => void; }
43+
>test : (this: { n: number; }) => void
44+
45+
o.test!!!();
46+
>o.test!!!() : void
47+
>o.test!!! : (this: { n: number; }) => void
48+
>o.test!! : (this: { n: number; }) => void
49+
>o.test! : (this: { n: number; }) => void
50+
>o.test : (this: { n: number; }) => void
51+
>o : { n: number; test?: (this: { n: number; }) => void; }
52+
>test : (this: { n: number; }) => void
53+
54+
(o.test!)();
55+
>(o.test!)() : void
56+
>(o.test!) : (this: { n: number; }) => void
57+
>o.test! : (this: { n: number; }) => void
58+
>o.test : (this: { n: number; }) => void
59+
>o : { n: number; test?: (this: { n: number; }) => void; }
60+
>test : (this: { n: number; }) => void
61+
62+
(o.test)();
63+
>(o.test)() : void
64+
>(o.test) : (this: { n: number; }) => void
65+
>o.test : (this: { n: number; }) => void
66+
>o : { n: number; test?: (this: { n: number; }) => void; }
67+
>test : (this: { n: number; }) => void
68+
69+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function f(this: { n: number }) {
2+
}
3+
4+
const o: { n: number, test?: (this: { n: number }) => void } = { n: 1 }
5+
o.test = f
6+
7+
o.test();
8+
o!.test();
9+
o.test!();
10+
o.test!!!();
11+
(o.test!)();
12+
(o.test)();
13+

0 commit comments

Comments
 (0)