Skip to content

Commit 8298766

Browse files
committed
PropagatesThisKeyword
1 parent 9579094 commit 8298766

5 files changed

Lines changed: 64 additions & 67 deletions

File tree

src/compiler/binder.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ export const enum ContainerFlags {
488488
HasLocals = 1 << 5,
489489
IsInterface = 1 << 6,
490490
IsObjectLiteralOrClassExpressionMethodOrAccessor = 1 << 7,
491+
PropagatesThisKeyword = 1 << 8,
491492
}
492493

493494
/** @internal */
@@ -1055,7 +1056,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
10551056
currentExceptionTarget = saveExceptionTarget;
10561057
activeLabelList = saveActiveLabelList;
10571058
hasExplicitReturn = saveHasExplicitReturn;
1058-
seenThisKeyword = node.kind === SyntaxKind.ArrowFunction ? saveSeenThisKeyword || seenThisKeyword : saveSeenThisKeyword;
1059+
seenThisKeyword = containerFlags & ContainerFlags.PropagatesThisKeyword ? saveSeenThisKeyword || seenThisKeyword : saveSeenThisKeyword;
10591060
}
10601061
else if (containerFlags & ContainerFlags.IsInterface) {
10611062
const saveSeenThisKeyword = seenThisKeyword;
@@ -3843,28 +3844,30 @@ export function getContainerFlags(node: Node): ContainerFlags {
38433844
// falls through
38443845
case SyntaxKind.Constructor:
38453846
case SyntaxKind.FunctionDeclaration:
3847+
case SyntaxKind.ClassStaticBlockDeclaration:
3848+
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike;
3849+
38463850
case SyntaxKind.MethodSignature:
38473851
case SyntaxKind.CallSignature:
38483852
case SyntaxKind.JSDocSignature:
38493853
case SyntaxKind.JSDocFunctionType:
38503854
case SyntaxKind.FunctionType:
38513855
case SyntaxKind.ConstructSignature:
38523856
case SyntaxKind.ConstructorType:
3853-
case SyntaxKind.ClassStaticBlockDeclaration:
3854-
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike;
3857+
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.PropagatesThisKeyword;
38553858

38563859
case SyntaxKind.JSDocImportTag:
38573860
// treat as a container to prevent using an enclosing effective host, ensuring import bindings are scoped correctly
3858-
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
3861+
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.PropagatesThisKeyword;
38593862

38603863
case SyntaxKind.FunctionExpression:
3861-
case SyntaxKind.ArrowFunction:
38623864
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsFunctionExpression;
38633865

3866+
case SyntaxKind.ArrowFunction:
3867+
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike | ContainerFlags.IsFunctionExpression | ContainerFlags.PropagatesThisKeyword;
3868+
38643869
case SyntaxKind.ModuleBlock:
38653870
return ContainerFlags.IsControlFlowContainer;
3866-
case SyntaxKind.PropertyDeclaration:
3867-
return (node as PropertyDeclaration).initializer ? ContainerFlags.IsControlFlowContainer : 0;
38683871

38693872
case SyntaxKind.CatchClause:
38703873
case SyntaxKind.ForStatement:

tests/baselines/reference/controlFlowForFunctionLike1.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
controlFlowForFunctionLike1.ts(10,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
2-
controlFlowForFunctionLike1.ts(21,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
32
controlFlowForFunctionLike1.ts(31,10): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
43

54

6-
==== controlFlowForFunctionLike1.ts (3 errors) ====
5+
==== controlFlowForFunctionLike1.ts (2 errors) ====
76
function test1(a: number | string) {
87
if (typeof a === "number") {
98
const fn = (arg: typeof a) => true;
@@ -27,8 +26,6 @@ controlFlowForFunctionLike1.ts(31,10): error TS2345: Argument of type 'string' i
2726

2827
test2(0)?.(100);
2928
test2(0)?.("");
30-
~~
31-
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
3229

3330
function test3(a: number | string) {
3431
if (typeof a === "number") {

tests/baselines/reference/controlFlowForFunctionLike1.types

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ function test2(a: number | string) {
7979
const fn: { (arg: typeof a): boolean; } = () => true;
8080
>fn : (arg: typeof a) => boolean
8181
> : ^ ^^ ^^^^^
82-
>arg : number
83-
> : ^^^^^^
84-
>a : number
85-
> : ^^^^^^
82+
>arg : string | number
83+
> : ^^^^^^^^^^^^^^^
84+
>a : string | number
85+
> : ^^^^^^^^^^^^^^^
8686
>() => true : () => true
8787
> : ^^^^^^^^^^
8888
>true : true
@@ -98,8 +98,8 @@ function test2(a: number | string) {
9898
test2(0)?.(100);
9999
>test2(0)?.(100) : boolean | undefined
100100
> : ^^^^^^^^^^^^^^^^^^^
101-
>test2(0) : ((arg: number) => boolean) | undefined
102-
> : ^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
101+
>test2(0) : ((arg: string | number) => boolean) | undefined
102+
> : ^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
103103
>test2 : (a: number | string) => ((arg: typeof a) => boolean) | undefined
104104
> : ^ ^^ ^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^
105105
>0 : 0
@@ -110,8 +110,8 @@ test2(0)?.(100);
110110
test2(0)?.("");
111111
>test2(0)?.("") : boolean | undefined
112112
> : ^^^^^^^^^^^^^^^^^^^
113-
>test2(0) : ((arg: number) => boolean) | undefined
114-
> : ^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
113+
>test2(0) : ((arg: string | number) => boolean) | undefined
114+
> : ^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
115115
>test2 : (a: number | string) => ((arg: typeof a) => boolean) | undefined
116116
> : ^ ^^ ^^^^^^^ ^^ ^^^^^ ^^^^^^^^^^^^^
117117
>0 : 0

tests/baselines/reference/controlFlowFunctionLikeCircular1.errors.txt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ controlFlowFunctionLikeCircular_8.ts(3,5): error TS2554: Expected 1 arguments, b
3434
controlFlowFunctionLikeCircular_9.ts(1,10): error TS2393: Duplicate function implementation.
3535
controlFlowFunctionLikeCircular_9.ts(3,5): error TS2448: Block-scoped variable 'o' used before its declaration.
3636
controlFlowFunctionLikeCircular_9.ts(3,5): error TS2454: Variable 'o' is used before being assigned.
37-
controlFlowFunctionLikeCircular_9.ts(4,47): error TS2411: Property 'x' of type '(() => any) | (() => void)' is not assignable to 'string' index type '() => string'.
38-
controlFlowFunctionLikeCircular_9.ts(4,57): error TS2577: Return type annotation circularly references itself.
37+
controlFlowFunctionLikeCircular_9.ts(4,47): error TS2411: Property 'x' of type '(() => DateConstructor) | (() => void)' is not assignable to 'string' index type '() => string | number'.
3938

4039

4140
==== controlFlowFunctionLikeCircular_1.ts (5 errors) ====
@@ -170,7 +169,7 @@ controlFlowFunctionLikeCircular_9.ts(4,57): error TS2577: Return type annotation
170169
return undefined;
171170
}
172171

173-
==== controlFlowFunctionLikeCircular_9.ts (5 errors) ====
172+
==== controlFlowFunctionLikeCircular_9.ts (4 errors) ====
174173
function test(arg: string | number, whatever: any) {
175174
~~~~
176175
!!! error TS2393: Duplicate function implementation.
@@ -183,9 +182,7 @@ controlFlowFunctionLikeCircular_9.ts(4,57): error TS2577: Return type annotation
183182
!!! error TS2454: Variable 'o' is used before being assigned.
184183
const o: { [k: string]: () => typeof arg; x: (() => typeof Date) | (() => void) } = whatever
185184
~
186-
!!! error TS2411: Property 'x' of type '(() => any) | (() => void)' is not assignable to 'string' index type '() => string'.
187-
~~~~~~~~~~~
188-
!!! error TS2577: Return type annotation circularly references itself.
185+
!!! error TS2411: Property 'x' of type '(() => DateConstructor) | (() => void)' is not assignable to 'string' index type '() => string | number'.
189186
return o.x;
190187
}
191188
return undefined;

0 commit comments

Comments
 (0)