Skip to content

Commit

Permalink
Don't try to fold Array.join() when the array has a SPREAD node
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171068301
  • Loading branch information
tbreisacher authored and dimvar committed Oct 5, 2017
1 parent bc9cf44 commit b0763d2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
16 changes: 11 additions & 5 deletions src/com/google/javascript/jscomp/PeepholeReplaceKnownMethods.java
Expand Up @@ -18,6 +18,7 @@


import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;


import com.google.javascript.rhino.IR; import com.google.javascript.rhino.IR;
Expand Down Expand Up @@ -106,6 +107,7 @@ private Node tryFoldKnownStringMethods(Node subtree, Node callTarget) {
return tryFoldStringToLowerCase(subtree, stringNode); return tryFoldStringToLowerCase(subtree, stringNode);
case "toUpperCase": case "toUpperCase":
return tryFoldStringToUpperCase(subtree, stringNode); return tryFoldStringToUpperCase(subtree, stringNode);
default: // fall out
} }
} else { } else {
if (NodeUtil.isImmutableValue(firstArg)) { if (NodeUtil.isImmutableValue(firstArg)) {
Expand All @@ -122,6 +124,7 @@ private Node tryFoldKnownStringMethods(Node subtree, Node callTarget) {
return tryFoldStringCharAt(subtree, stringNode, firstArg); return tryFoldStringCharAt(subtree, stringNode, firstArg);
case "charCodeAt": case "charCodeAt":
return tryFoldStringCharCodeAt(subtree, stringNode, firstArg); return tryFoldStringCharCodeAt(subtree, stringNode, firstArg);
default: // fall out
} }
} }
} }
Expand Down Expand Up @@ -150,6 +153,8 @@ private Node tryFoldKnownStringMethods(Node subtree, Node callTarget) {
if (end - start == 1) { if (end - start == 1) {
return replaceWithCharAt(subtree, callTarget, firstArg); return replaceWithCharAt(subtree, callTarget, firstArg);
} }
break;
default: // fall out
} }
} }
} }
Expand Down Expand Up @@ -407,6 +412,7 @@ private Node tryFoldStringIndexOf(
* Try to fold an array join: ['a', 'b', 'c'].join('') -> 'abc'; * Try to fold an array join: ['a', 'b', 'c'].join('') -> 'abc';
*/ */
private Node tryFoldArrayJoin(Node n) { private Node tryFoldArrayJoin(Node n) {
checkState(n.isCall(), n);
Node callTarget = n.getFirstChild(); Node callTarget = n.getFirstChild();


if (callTarget == null || !callTarget.isGetProp()) { if (callTarget == null || !callTarget.isGetProp()) {
Expand All @@ -423,13 +429,11 @@ private Node tryFoldArrayJoin(Node n) {
Node arrayNode = callTarget.getFirstChild(); Node arrayNode = callTarget.getFirstChild();
Node functionName = arrayNode.getNext(); Node functionName = arrayNode.getNext();


if (!arrayNode.isArrayLit() || if (!arrayNode.isArrayLit() || !functionName.getString().equals("join")) {
!functionName.getString().equals("join")) {
return n; return n;
} }


if (right != null && right.isString() if (right != null && right.isString() && ",".equals(right.getString())) {
&& ",".equals(right.getString())) {
// "," is the default, it doesn't need to be explicit // "," is the default, it doesn't need to be explicit
n.removeChild(right); n.removeChild(right);
compiler.reportChangeToEnclosingScope(n); compiler.reportChangeToEnclosingScope(n);
Expand Down Expand Up @@ -485,7 +489,9 @@ private Node tryFoldArrayJoin(Node n) {
return emptyStringNode; return emptyStringNode;
case 1: case 1:
Node foldedStringNode = arrayFoldedChildren.remove(0); Node foldedStringNode = arrayFoldedChildren.remove(0);
if (foldedSize > originalSize) { // The spread isn't valid outside any array literal (or would change meaning)
// so don't try to fold it.
if (foldedStringNode.isSpread() || foldedSize > originalSize) {
return n; return n;
} }
arrayNode.detachChildren(); arrayNode.detachChildren();
Expand Down
Expand Up @@ -304,13 +304,24 @@ public void testJoinBug() {
" ].join()")); " ].join()"));
} }


// Fails with: public void testJoinSpread1() {
// java.lang.IllegalStateException: SPREAD node should not be the child of a ADD node.
// TODO(b/67381773): Fix and enable this test.
public void disabled_testJoinSpread() {
foldSame("var x = [...foo].join(',');");
foldSame("var x = [...foo].join('');"); foldSame("var x = [...foo].join('');");
foldSame("var x = [...someMap.keys()].join('');"); foldSame("var x = [...someMap.keys()].join('');");
foldSame("var x = [foo, ...bar].join('');");
foldSame("var x = [...foo, bar].join('');");
foldSame("var x = [...foo, 'bar'].join('');");
foldSame("var x = ['1', ...'2', '3'].join('');");
foldSame("var x = ['1', ...['2'], '3'].join('');");
}

public void testJoinSpread2() {
fold("var x = [...foo].join(',');", "var x = [...foo].join();");
fold("var x = [...someMap.keys()].join(',');", "var x = [...someMap.keys()].join();");
fold("var x = [foo, ...bar].join(',');", "var x = [foo, ...bar].join();");
fold("var x = [...foo, bar].join(',');", "var x = [...foo, bar].join();");
fold("var x = [...foo, 'bar'].join(',');", "var x = [...foo, 'bar'].join();");
fold("var x = ['1', ...'2', '3'].join(',');", "var x = ['1', ...'2', '3'].join();");
fold("var x = ['1', ...['2'], '3'].join(',');", "var x = ['1', ...['2'], '3'].join();");
} }


public void testToUpper() { public void testToUpper() {
Expand Down

0 comments on commit b0763d2

Please sign in to comment.