Skip to content

Commit 1dedca7

Browse files
committed
Support 'unshift' and fix typo
1 parent 38278ee commit 1dedca7

File tree

4 files changed

+16
-10
lines changed

4 files changed

+16
-10
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ namespace ts {
12171217
}
12181218
if (node.expression.kind === SyntaxKind.PropertyAccessExpression) {
12191219
const propertyAccess = <PropertyAccessExpression>node.expression;
1220-
if (isNarrowableOperand(propertyAccess.expression) && propertyAccess.name.text === "push") {
1220+
if (isNarrowableOperand(propertyAccess.expression) && isPushOrUnshiftIdentifier(propertyAccess.name)) {
12211221
currentFlow = createFlowArrayMutation(currentFlow, node);
12221222
}
12231223
}

src/compiler/checker.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8405,8 +8405,10 @@ namespace ts {
84058405
}
84068406

84078407
function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) {
8408-
return node.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>node).initializer && isEmptyArrayLiteral((<VariableDeclaration>node).initializer) ||
8409-
node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression && isEmptyArrayLiteral((<BinaryExpression>node.parent).right);
8408+
return node.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>node).initializer &&
8409+
isEmptyArrayLiteral((<VariableDeclaration>node).initializer) ||
8410+
node.kind !== SyntaxKind.BindingElement && node.parent.kind === SyntaxKind.BinaryExpression &&
8411+
isEmptyArrayLiteral((<BinaryExpression>node.parent).right);
84108412
}
84118413

84128414
function getReferenceCandidate(node: Expression): Expression {
@@ -8562,12 +8564,12 @@ namespace ts {
85628564
getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
85638565
}
85648566

8565-
// Return true if the given node is 'x' in an 'x.push(value)' operation.
8566-
function isPushCallTarget(node: Node) {
8567+
// Return true if the given node is 'x' in an 'x.push(value)' or 'x.unshift(value)' operation.
8568+
function isPushOrUnshiftCallTarget(node: Node) {
85678569
const parent = getReferenceRoot(node).parent;
85688570
return parent.kind === SyntaxKind.PropertyAccessExpression &&
8569-
(<PropertyAccessExpression>parent).name.text === "push" &&
8570-
parent.parent.kind === SyntaxKind.CallExpression;
8571+
parent.parent.kind === SyntaxKind.CallExpression &&
8572+
isPushOrUnshiftIdentifier((<PropertyAccessExpression>parent).name);
85718573
}
85728574

85738575
// Return true if the given node is 'x' in an 'x[n] = value' operation, where 'n' is an
@@ -8596,9 +8598,9 @@ namespace ts {
85968598
const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
85978599
visitedFlowCount = visitedFlowStart;
85988600
// When the reference is 'x' in an 'x.push(value)' or 'x[n] = value' operation, we give type
8599-
// 'any[]' to 'x' instead of using the type determed by control flow analysis such that new
8601+
// 'any[]' to 'x' instead of using the type determined by control flow analysis such that new
86008602
// element types are not considered errors.
8601-
const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushCallTarget(reference) || isElementAssignmentTarget(reference));
8603+
const isEvolvingArrayInferenceTarget = isEvolvingArrayType(evolvedType) && (isPushOrUnshiftCallTarget(reference) || isElementAssignmentTarget(reference));
86028604
const resultType = isEvolvingArrayInferenceTarget ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
86038605
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
86048606
return declaredType;

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,7 @@ namespace ts {
19531953
}
19541954

19551955
// FlowArrayMutation represents a node potentially mutates an array, i.e. an
1956-
// operation of the form 'x.push(value)' or 'x[n] = value'.
1956+
// operation of the form 'x.push(value)', 'x.unshift(value)' or 'x[n] = value'.
19571957
export interface FlowArrayMutation extends FlowNode {
19581958
node: CallExpression | BinaryExpression;
19591959
antecedent: FlowNode;

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,10 @@ namespace ts {
18951895
return node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "Symbol";
18961896
}
18971897

1898+
export function isPushOrUnshiftIdentifier(node: Identifier) {
1899+
return node.text === "push" || node.text === "unshift";
1900+
}
1901+
18981902
export function isModifierKind(token: SyntaxKind): boolean {
18991903
switch (token) {
19001904
case SyntaxKind.AbstractKeyword:

0 commit comments

Comments
 (0)