Skip to content

Commit

Permalink
Make UnreachableCodeElimination understand ES6 features.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=158748650
  • Loading branch information
lillymliu authored and Tyler Breisacher committed Jun 13, 2017
1 parent b76e7c8 commit 6c0a5fc
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 24 deletions.
19 changes: 11 additions & 8 deletions src/com/google/javascript/jscomp/DefaultPassConfig.java
Expand Up @@ -2443,16 +2443,19 @@ protected CompilerPass create(AbstractCompiler compiler) {
}
};

/**
* Use data flow analysis to remove dead branches.
*/
/** Use data flow analysis to remove dead branches. */
private final PassFactory removeUnreachableCode =
new PassFactory(Compiler.UNREACHABLE_CODE_ELIM_NAME, false) {
@Override
protected CompilerPass create(AbstractCompiler compiler) {
return new UnreachableCodeElimination(compiler, true);
}
};
@Override
protected CompilerPass create(AbstractCompiler compiler) {
return new UnreachableCodeElimination(compiler, true);
}

@Override
protected FeatureSet featureSet() {
return ES8;
}
};

/**
* Use data flow analysis to remove dead branches.
Expand Down
4 changes: 4 additions & 0 deletions src/com/google/javascript/jscomp/PureFunctionIdentifier.java
Expand Up @@ -510,6 +510,10 @@ public void updateSideEffectsForNode(
if (node.hasChildren() && !NodeUtil.evaluatesToLocalValue(node.getFirstChild())) {
sideEffectInfo.setTaintsReturn();
}
} else if (node.isYield()) {
if (node.hasChildren() && !NodeUtil.evaluatesToLocalValue(node.getFirstChild())) {
sideEffectInfo.setTaintsReturn();
}
} else {
throw new IllegalArgumentException("Unhandled side effect node type " + node.getToken());
}
Expand Down
Expand Up @@ -202,8 +202,8 @@ private void removeDeadExprStatementSafely(Node n) {
}

// TODO(user): This is a problem with removeNoOpStatements.
// Every expression in a FOR-IN header looks side effect free on its own.
if (parent.isForIn()) {
// Every expression in a FOR-IN or FOR-OF header looks side effect free on its own.
if (NodeUtil.isEnhancedFor(parent)) {
return;
}

Expand Down
43 changes: 29 additions & 14 deletions test/com/google/javascript/jscomp/PureFunctionIdentifierTest.java
Expand Up @@ -20,7 +20,6 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.javascript.jscomp.CompilerOptions.LanguageMode;
import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.rhino.Node;
import java.util.ArrayList;
Expand Down Expand Up @@ -1608,6 +1607,34 @@ public void testMutatesArgumentsArray3() throws Exception {
assertNoPureCalls(source);
}

public void testCallGenerator1() {
this.mode = TypeInferenceMode.NEITHER; // type check for yield not yet implemented
String source =
LINE_JOINER.join(
"var x = 0;",
"function* f() {",
" x = 2",
" while (true) {",
" yield x;",
" }",
"}",
"var g = f();");
assertNoPureCalls(source);
Node lastRoot = getLastCompiler().getRoot().getLastChild();
Node call = findQualifiedNameNode("f", lastRoot).getParent();
assertThat(call.isNoSideEffectsCall()).isFalse();
assertEquals(
new Node.SideEffectFlags().setReturnsTainted().valueOf(), call.getSideEffectFlags());
}

public void testCallGenerator2() {
this.mode = TypeInferenceMode.NEITHER; // type check for yield not yet implemented
String source =
LINE_JOINER.join(
"function* f() {", " while (true) {", " yield 1;", " }", "}", "var g = f()");
assertPureCallsMarked(source, ImmutableList.of("f"));
}

public void testCallFunctionFOrG() throws Exception {
String source = LINE_JOINER.join(
"function f(){}",
Expand Down Expand Up @@ -1839,13 +1866,6 @@ void assertPureCallsMarked(String source, List<String> expected) {
}

void assertPureCallsMarked(String source, List<String> expected, DiagnosticType warning) {
assertPureCallsMarked(source, expected, warning, LanguageMode.ECMASCRIPT_2015);
assertPureCallsMarked(source, expected, warning, LanguageMode.ECMASCRIPT5);
}

void assertPureCallsMarked(
String source, List<String> expected, DiagnosticType warning, LanguageMode mode) {
setAcceptedLanguage(mode);
if (warning != null) {
testSame(source, warning);
} else {
Expand All @@ -1854,13 +1874,8 @@ void assertPureCallsMarked(
assertEquals(expected, noSideEffectCalls);
}

void checkLocalityOfMarkedCalls(String source, List<String> expected) {
checkLocalityOfMarkedCalls(source, expected, LanguageMode.ECMASCRIPT_2015);
checkLocalityOfMarkedCalls(source, expected, LanguageMode.ECMASCRIPT5);
}

void checkLocalityOfMarkedCalls(String source, List<String> expected, LanguageMode mode) {
setAcceptedLanguage(mode);
void checkLocalityOfMarkedCalls(String source, List<String> expected) {
testSame(source);
assertEquals(expected, localResultCalls);
}
Expand Down
Expand Up @@ -428,4 +428,55 @@ public void testIssue1001() throws Exception {
test("function f(x) { x.property = 3; } new f({})",
"function f(x) { x.property = 3; }");
}

public void testLetConstBlocks() {
test("function f() {return 1; let a; }", "function f() {return 1;}");

test("function f() {return 1; const a = 1; }", "function f() {return 1;}");

test(
"function f() { x = 1; {let g; return x} let y}",
"function f() { x = 1; {let g; return x;}} ");
}

public void testArrowFunctions() {
test("f(x => {return x; j = 1})", "f(x => {return x;})");

testSame("f( () => {return 1;})");
}

public void testGenerators() {
test(
LINE_JOINER.join(
"function* f() {", " while(true) {", " yield 1;", " }", " x = 1;", "}"),
LINE_JOINER.join("function* f() {", " while(true) {", " yield 1;", " }", "}"));

testSame(LINE_JOINER.join("function* f() {", " while(true) {", " yield 1;", " }", "}"));

testSame(
LINE_JOINER.join(
"function* f() {",
" let i = 0;",
" while (true) {",
" if (i < 10) {",
" yield i;",
" } else {",
" break;",
" }",
" }",
" let x = 1;",
"}"));
}

public void testForOf() {
test("for(x of i){ 1; }", "for(x of i) {}");

testSame("for(x of i){}");
}

public void testRemoveUselessTemplateStrings() {
test("`hi`", "");

testSame("`hello visitor # ${i++}`");
}
}

0 comments on commit 6c0a5fc

Please sign in to comment.