@@ -8424,6 +8424,14 @@ namespace ts {
8424
8424
return node;
8425
8425
}
8426
8426
8427
+ function getReferenceParent(node: Node): Node {
8428
+ const parent = node.parent;
8429
+ return parent.kind === SyntaxKind.ParenthesizedExpression ||
8430
+ parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.EqualsToken && (<BinaryExpression>parent).left === node ||
8431
+ parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).operatorToken.kind === SyntaxKind.CommaToken && (<BinaryExpression>parent).right === node ?
8432
+ getReferenceParent(parent) : parent;
8433
+ }
8434
+
8427
8435
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
8428
8436
if (clause.kind === SyntaxKind.CaseClause) {
8429
8437
const caseType = getRegularTypeOfLiteralType(checkExpression((<CaseClause>clause).expression));
@@ -8556,15 +8564,16 @@ namespace ts {
8556
8564
8557
8565
// Return true if the given node is 'x' in an 'x.push(value)' operation.
8558
8566
function isPushCallTarget(node: Node) {
8559
- return node.parent.kind === SyntaxKind.PropertyAccessExpression &&
8560
- (<PropertyAccessExpression>node.parent).name.text === "push" &&
8561
- node.parent.parent.kind === SyntaxKind.CallExpression;
8567
+ const parent = getReferenceParent(node);
8568
+ return parent.kind === SyntaxKind.PropertyAccessExpression &&
8569
+ (<PropertyAccessExpression>parent).name.text === "push" &&
8570
+ parent.parent.kind === SyntaxKind.CallExpression;
8562
8571
}
8563
8572
8564
8573
// Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an
8565
8574
// expression of type any, undefined, or a number-like type.
8566
8575
function isElementAssignmentTarget(node: Node) {
8567
- const parent = node.parent ;
8576
+ const parent = getReferenceParent( node) ;
8568
8577
return parent.kind === SyntaxKind.ElementAccessExpression &&
8569
8578
(<ElementAccessExpression>parent).expression === node &&
8570
8579
parent.parent.kind === SyntaxKind.BinaryExpression &&
@@ -8696,19 +8705,24 @@ namespace ts {
8696
8705
8697
8706
function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType {
8698
8707
const node = flow.node;
8699
- if (isMatchingReference(reference, node)) {
8708
+ const expr = node.kind === SyntaxKind.CallExpression ?
8709
+ (<PropertyAccessExpression>(<CallExpression>node).expression).expression :
8710
+ (<ElementAccessExpression>(<BinaryExpression>node).left).expression;
8711
+ if (isMatchingReference(reference, getReferenceCandidate(expr))) {
8700
8712
const flowType = getTypeAtFlowNode(flow.antecedent);
8701
8713
const type = getTypeFromFlowType(flowType);
8702
8714
if (isEvolvingArrayType(type)) {
8703
- const parent = node.parent;
8704
8715
let evolvedType = <AnonymousType>type;
8705
- if (parent .kind === SyntaxKind.PropertyAccessExpression ) {
8706
- for (const arg of (<CallExpression>parent.parent ).arguments) {
8716
+ if (node .kind === SyntaxKind.CallExpression ) {
8717
+ for (const arg of (<CallExpression>node ).arguments) {
8707
8718
evolvedType = addEvolvingArrayElementType(evolvedType, arg);
8708
8719
}
8709
8720
}
8710
- else if (isTypeAnyOrAllConstituentTypesHaveKind(checkExpression((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike)) {
8711
- evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>parent.parent).right);
8721
+ else {
8722
+ const indexType = checkExpression((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
8723
+ if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) {
8724
+ evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
8725
+ }
8712
8726
}
8713
8727
return evolvedType === type ? flowType : createFlowType(evolvedType, isIncomplete(flowType));
8714
8728
}
0 commit comments