fix: Duplicate function call in variable destructuring (#13711)
* Add test case demonstrating invalid behavior * Add conditional check for child properties so RHS is not duplicated * Add recursive check to find any nested non single-property case * Add case for array destructuring * Add test case for a nested rest element * More safely recurse through array destructuring * Traverse assignment and nested rest operations * Refactor to be more clear which case statement we are executing against * Update missed snapshots * Update packages/babel-plugin-proposal-object-rest-spread/src/index.js Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com> * Filter null array elements, add early return, remove optional chaining * Use stronger type assertions * Update fall through to be false; add early return to RestElement case * Move hasMoreThanOneBinding to its own file with distinct tests * Rename testing helper to more appropriately match business logic * Yarn Dedup & rename hasMoreThanOneBinding to shouldStoreRHSInTemporaryVariable Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com>
This commit is contained in:
committed by
GitHub
parent
d87a3d9e13
commit
40e43f5a14
@@ -0,0 +1,30 @@
|
||||
import { types as t } from "@babel/core";
|
||||
|
||||
/**
|
||||
* This is a helper function to determine if we should create an intermediate variable
|
||||
* such that the RHS of an assignment is not duplicated.
|
||||
*
|
||||
* See https://github.com/babel/babel/pull/13711#issuecomment-914388382 for discussion
|
||||
* on further optimizations.
|
||||
*/
|
||||
export default function shouldStoreRHSInTemporaryVariable(node) {
|
||||
if (t.isArrayPattern(node)) {
|
||||
const nonNullElements = node.elements.filter(element => element !== null);
|
||||
if (nonNullElements.length > 1) return true;
|
||||
else return shouldStoreRHSInTemporaryVariable(nonNullElements[0]);
|
||||
} else if (t.isObjectPattern(node)) {
|
||||
if (node.properties.length > 1) return true;
|
||||
else if (node.properties.length === 0) return false;
|
||||
else return shouldStoreRHSInTemporaryVariable(node.properties[0]);
|
||||
} else if (t.isObjectProperty(node)) {
|
||||
return shouldStoreRHSInTemporaryVariable(node.value);
|
||||
} else if (t.isAssignmentPattern(node)) {
|
||||
return shouldStoreRHSInTemporaryVariable(node.left);
|
||||
} else if (t.isRestElement(node)) {
|
||||
if (t.isIdentifier(node.argument)) return true;
|
||||
return shouldStoreRHSInTemporaryVariable(node.argument);
|
||||
} else {
|
||||
// node is Identifier or MemberExpression
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user