Skip to content

Commit 2f6dfd7

Browse files
committed
Fix cfa
1 parent 0a68f37 commit 2f6dfd7

14 files changed

+126
-120
lines changed

src/compiler/binder.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,9 @@ namespace ts {
942942
case SyntaxKind.BinaryExpression:
943943
switch ((<BinaryExpression>expr).operatorToken.kind) {
944944
case SyntaxKind.EqualsToken:
945+
case SyntaxKind.BarBarEqualsToken:
946+
case SyntaxKind.AmpersandAmpersandEqualsToken:
947+
case SyntaxKind.QuestionQuestionEqualsToken:
945948
return isNarrowableOperand((<BinaryExpression>expr).left);
946949
case SyntaxKind.CommaToken:
947950
return isNarrowableOperand((<BinaryExpression>expr).right);
@@ -1202,13 +1205,16 @@ namespace ts {
12021205
bindCondition(node.left, preRightLabel, falseTarget);
12031206
}
12041207
else {
1205-
bindCondition(node.left, trueTarget, preRightLabel);
1208+
bindCondition(node.left, trueTarget, preRightLabel)
12061209
}
1207-
12081210
currentFlow = finishFlowLabel(preRightLabel);
12091211
bind(node.operatorToken);
1212+
12101213
doWithConditionalBranches(bind, node.right, trueTarget, falseTarget);
12111214
bindAssignmentTargetFlow(node.left);
1215+
1216+
addAntecedent(trueTarget, createFlowCondition(FlowFlags.TrueCondition, currentFlow, node));
1217+
addAntecedent(falseTarget, createFlowCondition(FlowFlags.FalseCondition, currentFlow, node));
12121218
}
12131219

12141220
function bindReturnOrThrow(node: ReturnStatement | ThrowStatement): void {

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,7 @@ namespace ts {
25562556
switch (parent.kind) {
25572557
case SyntaxKind.BinaryExpression:
25582558
const binaryOperator = (<BinaryExpression>parent).operatorToken.kind;
2559-
return isAssignmentOperator(binaryOperator) && (<BinaryExpression>parent).left === node ?
2559+
return isAssignmentOperator(binaryOperator) && !isLogicalAssignmentOperator(binaryOperator) && (<BinaryExpression>parent).left === node ?
25602560
binaryOperator === SyntaxKind.EqualsToken ? AssignmentKind.Definite : AssignmentKind.Compound :
25612561
AssignmentKind.None;
25622562
case SyntaxKind.PrefixUnaryExpression:

tests/baselines/reference/logicalAssignment1(target=es2015).types

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ f ??= 42
6060

6161
g &&= 42
6262
>g &&= 42 : 0 | 42
63-
>g : number
63+
>g : 0 | 1 | 42
6464
>42 : 42
6565

6666
h ||= 42
67-
>h ||= 42 : number
68-
>h : number
67+
>h ||= 42 : 1 | 42
68+
>h : 0 | 1 | 42
6969
>42 : 42
7070

7171
i ??= 42
72-
>i ??= 42 : number
73-
>i : number
72+
>i ??= 42 : 0 | 1 | 42
73+
>i : 0 | 1 | 42
7474
>42 : 42
7575

tests/baselines/reference/logicalAssignment1(target=es2020).types

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ f ??= 42
6060

6161
g &&= 42
6262
>g &&= 42 : 0 | 42
63-
>g : number
63+
>g : 0 | 1 | 42
6464
>42 : 42
6565

6666
h ||= 42
67-
>h ||= 42 : number
68-
>h : number
67+
>h ||= 42 : 1 | 42
68+
>h : 0 | 1 | 42
6969
>42 : 42
7070

7171
i ??= 42
72-
>i ??= 42 : number
73-
>i : number
72+
>i ??= 42 : 0 | 1 | 42
73+
>i : 0 | 1 | 42
7474
>42 : 42
7575

tests/baselines/reference/logicalAssignment1(target=esnext).types

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ f ??= 42
6060

6161
g &&= 42
6262
>g &&= 42 : 0 | 42
63-
>g : number
63+
>g : 0 | 1 | 42
6464
>42 : 42
6565

6666
h ||= 42
67-
>h ||= 42 : number
68-
>h : number
67+
>h ||= 42 : 1 | 42
68+
>h : 0 | 1 | 42
6969
>42 : 42
7070

7171
i ??= 42
72-
>i ??= 42 : number
73-
>i : number
72+
>i ??= 42 : 0 | 1 | 42
73+
>i : 0 | 1 | 42
7474
>42 : 42
7575

tests/baselines/reference/logicalAssignment2(target=es2015).types

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,34 +30,34 @@ declare const c: A
3030

3131
a.baz &&= result.baz
3232
>a.baz &&= result.baz : "" | 0 | 1 | 42 | undefined
33-
>a.baz : string | number | undefined
33+
>a.baz : "" | 0 | 1 | 42 | undefined
3434
>a : A
35-
>baz : string | number | undefined
35+
>baz : "" | 0 | 1 | 42 | undefined
3636
>result.baz : "" | 0 | 1 | 42 | undefined
3737
>result : A
3838
>baz : "" | 0 | 1 | 42 | undefined
3939

4040
b.baz ||= result.baz
41-
>b.baz ||= result.baz : string | number | undefined
42-
>b.baz : string | number | undefined
41+
>b.baz ||= result.baz : "" | 0 | 1 | 42 | undefined
42+
>b.baz : "" | 0 | 1 | 42 | undefined
4343
>b : A
44-
>baz : string | number | undefined
44+
>baz : "" | 0 | 1 | 42 | undefined
4545
>result.baz : "" | 0 | 1 | 42 | undefined
4646
>result : A
4747
>baz : "" | 0 | 1 | 42 | undefined
4848

4949
c.baz ??= result.baz
50-
>c.baz ??= result.baz : string | number | undefined
51-
>c.baz : string | number | undefined
50+
>c.baz ??= result.baz : "" | 0 | 1 | 42 | undefined
51+
>c.baz : "" | 0 | 1 | 42 | undefined
5252
>c : A
53-
>baz : string | number | undefined
53+
>baz : "" | 0 | 1 | 42 | undefined
5454
>result.baz : "" | 0 | 1 | 42 | undefined
5555
>result : A
5656
>baz : "" | 0 | 1 | 42 | undefined
5757

5858
a.foo["baz"] &&= result.foo.baz
5959
>a.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
60-
>a.foo["baz"] : string | number | undefined
60+
>a.foo["baz"] : "" | 0 | 1 | 42 | undefined
6161
>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
6262
>a : A
6363
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -70,7 +70,7 @@ a.foo["baz"] &&= result.foo.baz
7070

7171
b.foo["baz"] &&= result.foo.baz
7272
>b.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
73-
>b.foo["baz"] : string | number | undefined
73+
>b.foo["baz"] : "" | 0 | 1 | 42 | undefined
7474
>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
7575
>b : A
7676
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -83,7 +83,7 @@ b.foo["baz"] &&= result.foo.baz
8383

8484
c.foo["baz"] &&= result.foo.baz
8585
>c.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
86-
>c.foo["baz"] : string | number | undefined
86+
>c.foo["baz"] : "" | 0 | 1 | 42 | undefined
8787
>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
8888
>c : A
8989
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -96,14 +96,14 @@ c.foo["baz"] &&= result.foo.baz
9696

9797
a.foo.bar().baz &&= result.foo.bar().baz
9898
>a.foo.bar().baz &&= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
99-
>a.foo.bar().baz : string | number | undefined
99+
>a.foo.bar().baz : "" | 0 | 1 | 42 | undefined
100100
>a.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
101101
>a.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
102102
>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
103103
>a : A
104104
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
105105
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
106-
>baz : string | number | undefined
106+
>baz : "" | 0 | 1 | 42 | undefined
107107
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
108108
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
109109
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
@@ -114,15 +114,15 @@ a.foo.bar().baz &&= result.foo.bar().baz
114114
>baz : "" | 0 | 1 | 42 | undefined
115115

116116
b.foo.bar().baz ||= result.foo.bar().baz
117-
>b.foo.bar().baz ||= result.foo.bar().baz : string | number | undefined
118-
>b.foo.bar().baz : string | number | undefined
117+
>b.foo.bar().baz ||= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
118+
>b.foo.bar().baz : "" | 0 | 1 | 42 | undefined
119119
>b.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
120120
>b.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
121121
>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
122122
>b : A
123123
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
124124
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
125-
>baz : string | number | undefined
125+
>baz : "" | 0 | 1 | 42 | undefined
126126
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
127127
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
128128
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
@@ -133,15 +133,15 @@ b.foo.bar().baz ||= result.foo.bar().baz
133133
>baz : "" | 0 | 1 | 42 | undefined
134134

135135
c.foo.bar().baz ??= result.foo.bar().baz
136-
>c.foo.bar().baz ??= result.foo.bar().baz : string | number | undefined
137-
>c.foo.bar().baz : string | number | undefined
136+
>c.foo.bar().baz ??= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
137+
>c.foo.bar().baz : "" | 0 | 1 | 42 | undefined
138138
>c.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
139139
>c.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
140140
>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
141141
>c : A
142142
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
143143
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
144-
>baz : string | number | undefined
144+
>baz : "" | 0 | 1 | 42 | undefined
145145
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
146146
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
147147
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }

tests/baselines/reference/logicalAssignment2(target=es2020).types

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,34 +30,34 @@ declare const c: A
3030

3131
a.baz &&= result.baz
3232
>a.baz &&= result.baz : "" | 0 | 1 | 42 | undefined
33-
>a.baz : string | number | undefined
33+
>a.baz : "" | 0 | 1 | 42 | undefined
3434
>a : A
35-
>baz : string | number | undefined
35+
>baz : "" | 0 | 1 | 42 | undefined
3636
>result.baz : "" | 0 | 1 | 42 | undefined
3737
>result : A
3838
>baz : "" | 0 | 1 | 42 | undefined
3939

4040
b.baz ||= result.baz
41-
>b.baz ||= result.baz : string | number | undefined
42-
>b.baz : string | number | undefined
41+
>b.baz ||= result.baz : "" | 0 | 1 | 42 | undefined
42+
>b.baz : "" | 0 | 1 | 42 | undefined
4343
>b : A
44-
>baz : string | number | undefined
44+
>baz : "" | 0 | 1 | 42 | undefined
4545
>result.baz : "" | 0 | 1 | 42 | undefined
4646
>result : A
4747
>baz : "" | 0 | 1 | 42 | undefined
4848

4949
c.baz ??= result.baz
50-
>c.baz ??= result.baz : string | number | undefined
51-
>c.baz : string | number | undefined
50+
>c.baz ??= result.baz : "" | 0 | 1 | 42 | undefined
51+
>c.baz : "" | 0 | 1 | 42 | undefined
5252
>c : A
53-
>baz : string | number | undefined
53+
>baz : "" | 0 | 1 | 42 | undefined
5454
>result.baz : "" | 0 | 1 | 42 | undefined
5555
>result : A
5656
>baz : "" | 0 | 1 | 42 | undefined
5757

5858
a.foo["baz"] &&= result.foo.baz
5959
>a.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
60-
>a.foo["baz"] : string | number | undefined
60+
>a.foo["baz"] : "" | 0 | 1 | 42 | undefined
6161
>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
6262
>a : A
6363
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -70,7 +70,7 @@ a.foo["baz"] &&= result.foo.baz
7070

7171
b.foo["baz"] &&= result.foo.baz
7272
>b.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
73-
>b.foo["baz"] : string | number | undefined
73+
>b.foo["baz"] : "" | 0 | 1 | 42 | undefined
7474
>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
7575
>b : A
7676
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -83,7 +83,7 @@ b.foo["baz"] &&= result.foo.baz
8383

8484
c.foo["baz"] &&= result.foo.baz
8585
>c.foo["baz"] &&= result.foo.baz : "" | 0 | 1 | 42 | undefined
86-
>c.foo["baz"] : string | number | undefined
86+
>c.foo["baz"] : "" | 0 | 1 | 42 | undefined
8787
>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
8888
>c : A
8989
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
@@ -96,14 +96,14 @@ c.foo["baz"] &&= result.foo.baz
9696

9797
a.foo.bar().baz &&= result.foo.bar().baz
9898
>a.foo.bar().baz &&= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
99-
>a.foo.bar().baz : string | number | undefined
99+
>a.foo.bar().baz : "" | 0 | 1 | 42 | undefined
100100
>a.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
101101
>a.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
102102
>a.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
103103
>a : A
104104
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
105105
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
106-
>baz : string | number | undefined
106+
>baz : "" | 0 | 1 | 42 | undefined
107107
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
108108
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
109109
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
@@ -114,15 +114,15 @@ a.foo.bar().baz &&= result.foo.bar().baz
114114
>baz : "" | 0 | 1 | 42 | undefined
115115

116116
b.foo.bar().baz ||= result.foo.bar().baz
117-
>b.foo.bar().baz ||= result.foo.bar().baz : string | number | undefined
118-
>b.foo.bar().baz : string | number | undefined
117+
>b.foo.bar().baz ||= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
118+
>b.foo.bar().baz : "" | 0 | 1 | 42 | undefined
119119
>b.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
120120
>b.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
121121
>b.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
122122
>b : A
123123
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
124124
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
125-
>baz : string | number | undefined
125+
>baz : "" | 0 | 1 | 42 | undefined
126126
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
127127
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
128128
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
@@ -133,15 +133,15 @@ b.foo.bar().baz ||= result.foo.bar().baz
133133
>baz : "" | 0 | 1 | 42 | undefined
134134

135135
c.foo.bar().baz ??= result.foo.bar().baz
136-
>c.foo.bar().baz ??= result.foo.bar().baz : string | number | undefined
137-
>c.foo.bar().baz : string | number | undefined
136+
>c.foo.bar().baz ??= result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
137+
>c.foo.bar().baz : "" | 0 | 1 | 42 | undefined
138138
>c.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
139139
>c.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
140140
>c.foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
141141
>c : A
142142
>foo : { bar(): { baz: "" | 0 | 1 | 42 | undefined; }; baz: "" | 0 | 1 | 42 | undefined; }
143143
>bar : () => { baz: "" | 0 | 1 | 42 | undefined; }
144-
>baz : string | number | undefined
144+
>baz : "" | 0 | 1 | 42 | undefined
145145
>result.foo.bar().baz : "" | 0 | 1 | 42 | undefined
146146
>result.foo.bar() : { baz: "" | 0 | 1 | 42 | undefined; }
147147
>result.foo.bar : () => { baz: "" | 0 | 1 | 42 | undefined; }

0 commit comments

Comments
 (0)