@@ -915,6 +915,9 @@ namespace ts {
915
915
function isNarrowingBinaryExpression ( expr : BinaryExpression ) {
916
916
switch ( expr . operatorToken . kind ) {
917
917
case SyntaxKind . EqualsToken :
918
+ case SyntaxKind . BarBarEqualsToken :
919
+ case SyntaxKind . AmpersandAmpersandEqualsToken :
920
+ case SyntaxKind . QuestionQuestionEqualsToken :
918
921
return containsNarrowableReference ( expr . left ) ;
919
922
case SyntaxKind . EqualsEqualsToken :
920
923
case SyntaxKind . ExclamationEqualsToken :
@@ -1062,6 +1065,15 @@ namespace ts {
1062
1065
}
1063
1066
}
1064
1067
1068
+ function isTopLevelLogicalAssignmentExpression ( node : Node ) : boolean {
1069
+ while ( isParenthesizedExpression ( node . parent ) ) {
1070
+ node = node . parent ;
1071
+ }
1072
+ return ! isStatementCondition ( node ) &&
1073
+ ! isLogicalAssignmentExpressioin ( node . parent ) &&
1074
+ ! ( isOptionalChain ( node . parent ) && node . parent . expression === node ) ;
1075
+ }
1076
+
1065
1077
function isTopLevelLogicalExpression ( node : Node ) : boolean {
1066
1078
while ( isParenthesizedExpression ( node . parent ) ||
1067
1079
isPrefixUnaryExpression ( node . parent ) && node . parent . operator === SyntaxKind . ExclamationToken ) {
@@ -1184,23 +1196,19 @@ namespace ts {
1184
1196
currentFlow = finishFlowLabel ( postIfLabel ) ;
1185
1197
}
1186
1198
1187
- function bindLogicalAssignmentExpression ( node : BinaryExpression ) {
1199
+ function bindLogicalAssignmentExpression ( node : BinaryExpression , trueTarget : FlowLabel , falseTarget : FlowLabel ) {
1188
1200
const preRightLabel = createBranchLabel ( ) ;
1189
- const postExpressionLabel = createBranchLabel ( ) ;
1190
-
1191
1201
if ( node . operatorToken . kind === SyntaxKind . AmpersandAmpersandEqualsToken ) {
1192
- bindCondition ( node . left , preRightLabel , postExpressionLabel ) ;
1202
+ bindCondition ( node . left , preRightLabel , falseTarget ) ;
1193
1203
}
1194
1204
else {
1195
- bindCondition ( node . left , postExpressionLabel , preRightLabel ) ;
1205
+ bindCondition ( node . left , trueTarget , preRightLabel ) ;
1196
1206
}
1197
1207
1198
1208
currentFlow = finishFlowLabel ( preRightLabel ) ;
1199
1209
bind ( node . operatorToken ) ;
1200
- bind ( node . right ) ;
1210
+ doWithConditionalBranches ( bind , node . right , trueTarget , falseTarget ) ;
1201
1211
bindAssignmentTargetFlow ( node . left ) ;
1202
-
1203
- currentFlow = finishFlowLabel ( postExpressionLabel ) ;
1204
1212
}
1205
1213
1206
1214
function bindReturnOrThrow ( node : ReturnStatement | ThrowStatement ) : void {
@@ -1556,7 +1564,14 @@ namespace ts {
1556
1564
completeNode ( ) ;
1557
1565
}
1558
1566
else if ( isLogicalAssignmentOperator ( operator ) ) {
1559
- bindLogicalAssignmentExpression ( node ) ;
1567
+ if ( isTopLevelLogicalAssignmentExpression ( node ) ) {
1568
+ const postExpressionLabel = createBranchLabel ( ) ;
1569
+ bindLogicalAssignmentExpression ( node , postExpressionLabel , postExpressionLabel ) ;
1570
+ currentFlow = finishFlowLabel ( postExpressionLabel ) ;
1571
+ }
1572
+ else {
1573
+ bindLogicalAssignmentExpression ( node , currentTrueTarget ! , currentFalseTarget ! ) ;
1574
+ }
1560
1575
completeNode ( ) ;
1561
1576
}
1562
1577
else {
0 commit comments