@@ -905,6 +905,9 @@ namespace ts {
905
905
function isNarrowingBinaryExpression ( expr : BinaryExpression ) {
906
906
switch ( expr . operatorToken . kind ) {
907
907
case SyntaxKind . EqualsToken :
908
+ case SyntaxKind . BarBarEqualsToken :
909
+ case SyntaxKind . AmpersandAmpersandEqualsToken :
910
+ case SyntaxKind . QuestionQuestionEqualsToken :
908
911
return containsNarrowableReference ( expr . left ) ;
909
912
case SyntaxKind . EqualsEqualsToken :
910
913
case SyntaxKind . ExclamationEqualsToken :
@@ -1052,6 +1055,15 @@ namespace ts {
1052
1055
}
1053
1056
}
1054
1057
1058
+ function isTopLevelLogicalAssignmentExpression ( node : Node ) : boolean {
1059
+ while ( isParenthesizedExpression ( node . parent ) ) {
1060
+ node = node . parent ;
1061
+ }
1062
+ return ! isStatementCondition ( node ) &&
1063
+ ! isLogicalAssignmentExpressioin ( node . parent ) &&
1064
+ ! ( isOptionalChain ( node . parent ) && node . parent . expression === node ) ;
1065
+ }
1066
+
1055
1067
function isTopLevelLogicalExpression ( node : Node ) : boolean {
1056
1068
while ( isParenthesizedExpression ( node . parent ) ||
1057
1069
isPrefixUnaryExpression ( node . parent ) && node . parent . operator === SyntaxKind . ExclamationToken ) {
@@ -1174,23 +1186,19 @@ namespace ts {
1174
1186
currentFlow = finishFlowLabel ( postIfLabel ) ;
1175
1187
}
1176
1188
1177
- function bindLogicalAssignmentExpression ( node : BinaryExpression ) {
1189
+ function bindLogicalAssignmentExpression ( node : BinaryExpression , trueTarget : FlowLabel , falseTarget : FlowLabel ) {
1178
1190
const preRightLabel = createBranchLabel ( ) ;
1179
- const postExpressionLabel = createBranchLabel ( ) ;
1180
-
1181
1191
if ( node . operatorToken . kind === SyntaxKind . AmpersandAmpersandEqualsToken ) {
1182
- bindCondition ( node . left , preRightLabel , postExpressionLabel ) ;
1192
+ bindCondition ( node . left , preRightLabel , falseTarget ) ;
1183
1193
}
1184
1194
else {
1185
- bindCondition ( node . left , postExpressionLabel , preRightLabel ) ;
1195
+ bindCondition ( node . left , trueTarget , preRightLabel ) ;
1186
1196
}
1187
1197
1188
1198
currentFlow = finishFlowLabel ( preRightLabel ) ;
1189
1199
bind ( node . operatorToken ) ;
1190
- bind ( node . right ) ;
1200
+ doWithConditionalBranches ( bind , node . right , trueTarget , falseTarget ) ;
1191
1201
bindAssignmentTargetFlow ( node . left ) ;
1192
-
1193
- currentFlow = finishFlowLabel ( postExpressionLabel ) ;
1194
1202
}
1195
1203
1196
1204
function bindReturnOrThrow ( node : ReturnStatement | ThrowStatement ) : void {
@@ -1546,7 +1554,14 @@ namespace ts {
1546
1554
completeNode ( ) ;
1547
1555
}
1548
1556
else if ( isLogicalAssignmentOperator ( operator ) ) {
1549
- bindLogicalAssignmentExpression ( node ) ;
1557
+ if ( isTopLevelLogicalAssignmentExpression ( node ) ) {
1558
+ const postExpressionLabel = createBranchLabel ( ) ;
1559
+ bindLogicalAssignmentExpression ( node , postExpressionLabel , postExpressionLabel ) ;
1560
+ currentFlow = finishFlowLabel ( postExpressionLabel ) ;
1561
+ }
1562
+ else {
1563
+ bindLogicalAssignmentExpression ( node , currentTrueTarget ! , currentFalseTarget ! ) ;
1564
+ }
1550
1565
completeNode ( ) ;
1551
1566
}
1552
1567
else {
0 commit comments