This repository has been archived on 2023-06-18. You can view files and clone it, but cannot push or open issues or pull requests.
ima02/resources/defects4j-checkout-closure-1f/test/com/google/javascript/jscomp/UnreachableCodeEliminationTest.java
github-classroom[bot] e42e547e48
Initial commit
2023-04-25 11:33:41 +00:00

462 lines
15 KiB
Java

/*
* Copyright 2008 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.javascript.jscomp;
/**
* Test for {@link UnreachableCodeElimination}.
*
*/
public class UnreachableCodeEliminationTest extends CompilerTestCase {
private boolean removeNoOpStatements = true;
@Override
protected CompilerPass getProcessor(Compiler compiler) {
return new UnreachableCodeElimination(compiler, removeNoOpStatements);
}
@Override public void setUp() throws Exception {
super.setUp();
removeNoOpStatements = true;
}
public void testRemoveUnreachableCode() {
// switch statement with stuff after "return"
test("function foo(){switch(foo){case 1:x=1;return;break;" +
"case 2:{x=2;return;break}default:}}",
"function foo(){switch(foo){case 1:x=1;return;" +
"case 2:{x=2}default:}}");
// if/else statements with returns
test("function bar(){if(foo)x=1;else if(bar){return;x=2}" +
"else{x=3;return;x=4}return 5;x=5}",
"function bar(){if(foo)x=1;else if(bar){return}" +
"else{x=3;return}return 5}");
// if statements without blocks
test("function foo(){if(x==3)return;x=4;y++;while(y==4){return;x=3}}",
"function foo(){if(x==3)return;x=4;y++;while(y==4){return}}");
// for/do/while loops
test("function baz(){for(i=0;i<n;i++){x=3;break;x=4}" +
"do{x=2;break;x=4}while(x==4);" +
"while(i<4){x=3;return;x=6}}",
"function baz(){for(i=0;i<n;){x=3;break}" +
"do{x=2;break}while(x==4);" +
"while(i<4){x=3;return}}");
// return statements on the same level as conditionals
test("function foo(){if(x==3){return}return 5;while(y==4){x++;return;x=4}}",
"function foo(){if(x==3){return}return 5}");
// return statements on the same level as conditionals
test("function foo(){return 3;for(;y==4;){x++;return;x=4}}",
"function foo(){return 3}");
// try/catch statements
test("function foo(){try{x=3;return x+1;x=5}catch(e){x=4;return 5;x=5}}",
"function foo(){try{x=3;return x+1}catch(e){x=4;return 5}}");
// try/finally statements
test("function foo(){try{x=3;return x+1;x=5}finally{x=4;return 5;x=5}}",
"function foo(){try{x=3;return x+1}finally{x=4;return 5}}");
// try/catch/finally statements
test("function foo(){try{x=3;return x+1;x=5}catch(e){x=3;return;x=2}" +
"finally{x=4;return 5;x=5}}",
"function foo(){try{x=3;return x+1}catch(e){x=3;return}" +
"finally{x=4;return 5}}");
// test a combination of blocks
test("function foo(){x=3;if(x==4){x=5;return;x=6}else{x=7}return 5;x=3}",
"function foo(){x=3;if(x==4){x=5;return}else{x=7}return 5}");
// test removing multiple statements
test("function foo() { return 1; var x = 2; var y = 10; return 2;}",
"function foo() { var y; var x; return 1}");
test("function foo() { return 1; x = 2; y = 10; return 2;}",
"function foo(){ return 1}");
}
public void testRemoveUselessNameStatements() {
test("a;", "");
test("a.b;", "");
test("a.b.MyClass.prototype.memberName;", "");
}
public void testRemoveUselessStrings() {
test("'a';", "");
}
public void testNoRemoveUseStrict() {
test("'use strict';", "'use strict'");
}
public void testNoRemoveUselessNameStatements() {
removeNoOpStatements = false;
testSame("a;");
testSame("a.b;");
testSame("a.b.MyClass.prototype.memberName;");
}
public void testRemoveDo() {
test("do { print(1); break } while(1)", "do { print(1); break } while(1)");
test("while(1) { break; do { print(1); break } while(1) }",
"while(1) { break; do {} while(1) }");
}
public void testRemoveUselessLiteralValueStatements() {
test("true;", "");
test("'hi';", "");
test("if (x) 1;", "");
test("while (x) 1;", "while (x);");
test("do 1; while (x);", "do ; while (x);");
test("for (;;) 1;", "for (;;);");
test("switch(x){case 1:true;case 2:'hi';default:true}",
"switch(x){case 1:case 2:default:}");
}
public void testConditionalDeadCode() {
test("function f() { if (1) return 5; else return 5; x = 1}",
"function f() { if (1) return 5; else return 5; }");
}
public void testSwitchCase() {
test("function f() { switch(x) { default: return 5; foo()}}",
"function f() { switch(x) { default: return 5;}}");
test("function f() { switch(x) { default: return; case 1: foo(); bar()}}",
"function f() { switch(x) { default: return; case 1: foo(); bar()}}");
test("function f() { switch(x) { default: return; case 1: return 5;bar()}}",
"function f() { switch(x) { default: return; case 1: return 5;}}");
}
public void testTryCatchFinally() {
testSame("try {foo()} catch (e) {bar()}");
testSame("try { try {foo()} catch (e) {bar()}} catch (x) {bar()}");
test("try {var x = 1} catch (e) {e()}", "try {var x = 1} finally {}");
test("try {var x = 1} catch (e) {e()} finally {x()}",
" try {var x = 1} finally {x()}");
test("try {var x = 1} catch (e) {e()} finally {}",
"try {var x = 1} finally {}");
testSame("try {var x = 1} finally {x()}");
testSame("try {var x = 1} finally {}");
test("function f() {return; try{var x = 1}catch(e){} }",
"function f() {var x;}");
}
public void testRemovalRequiresRedeclaration() {
test("while(1) { break; var x = 1}", "var x; while(1) { break } ");
test("while(1) { break; var x=1; var y=1}",
"var y; var x; while(1) { break } ");
}
public void testAssignPropertyOnCreatedObject() {
testSame("this.foo = 3;");
testSame("a.foo = 3;");
testSame("bar().foo = 3;");
testSame("({}).foo = bar();");
testSame("(new X()).foo = 3;");
test("({}).foo = 3;", "");
test("(function() {}).prototype.toString = function(){};", "");
test("(function() {}).prototype['toString'] = function(){};", "");
test("(function() {}).prototype[f] = function(){};", "");
}
public void testUselessUnconditionalReturn() {
test("function foo() { return }", " function foo() { }");
test("function foo() { return; return; x=1 }", "function foo() { }");
test("function foo() { return; return; var x=1}", "function foo() {var x}");
test("function foo() { return; function bar() {} }",
"function foo() { function bar() {} }" );
testSame("function foo() { return 5 }");
test("function f() {switch (a) { case 'a': return}}",
"function f() {switch (a) { case 'a': }}");
testSame("function f() {switch (a) { case 'a': case foo(): }}");
testSame("function f() {switch (a) {" +
" default: return; case 'a': alert(1)}}");
testSame("function f() {switch (a) {" +
" case 'a': return; default: alert(1)}}");
}
public void testUnlessUnconditionalContinue() {
test("for(;1;) {continue}", " for(;1;) {}");
test("for(;0;) {continue}", " for(;0;) {}");
testSame("X: for(;1;) { for(;1;) { if (x()) {continue X} x = 1}}");
test("for(;1;) { X: for(;1;) { if (x()) {continue X} }}",
"for(;1;) { X: for(;1;) { if (x()) {}}}");
test("do { continue } while(1);", "do { } while(1);");
}
public void testUnlessUnconditonalBreak() {
test("switch (a) { case 'a': break }", "switch (a) { case 'a': }");
test("switch (a) { case 'a': break; case foo(): }",
"switch (a) { case 'a': case foo(): }");
test("switch (a) { default: break; case 'a': }",
"switch (a) { default: case 'a': }");
testSame("switch (a) { case 'a': alert(a); break; default: alert(a); }");
testSame("switch (a) { default: alert(a); break; case 'a': alert(a); }");
test("X: {switch (a) { case 'a': break X}}",
"X: {switch (a) { case 'a': }}");
testSame("X: {switch (a) { case 'a': if (a()) {break X} a = 1}}");
test("X: {switch (a) { case 'a': if (a()) {break X}}}",
"X: {switch (a) { case 'a': if (a()) {}}}");
test("X: {switch (a) { case 'a': if (a()) {break X}}}",
"X: {switch (a) { case 'a': if (a()) {}}}");
testSame("do { break } while(1);");
testSame("for(;1;) { break }");
}
public void testCascadedRemovalOfUnlessUnconditonalJumps() {
test("switch (a) { case 'a': break; case 'b': break; case 'c': break }",
"switch (a) { case 'a': break; case 'b': case 'c': }");
// Only one break removed per pass.
test("switch (a) { case 'a': break; case 'b': case 'c': }",
"switch (a) { case 'a': case 'b': case 'c': }");
test("function foo() {" +
" switch (a) { case 'a':return; case 'b':return; case 'c':return }}",
"function foo() { switch (a) { case 'a':return; case 'b': case 'c': }}");
test("function foo() {" +
" switch (a) { case 'a':return; case 'b': case 'c': }}",
"function foo() { switch (a) { case 'a': case 'b': case 'c': }}");
testSame("function foo() {" +
"switch (a) { case 'a':return 2; case 'b':return 1}}");
}
public void testIssue311() {
test("function a(b) {\n" +
" switch (b.v) {\n" +
" case 'SWITCH':\n" +
" if (b.i >= 0) {\n" +
" return b.o;\n" +
" } else {\n" +
" return;\n" +
" }\n" +
" break;\n" +
" }\n" +
"}",
"function a(b) {\n" +
" switch (b.v) {\n" +
" case 'SWITCH':\n" +
" if (b.i >= 0) {\n" +
" return b.o;\n" +
" } else {\n" +
" }\n" +
" }\n" +
"}");
}
public void testIssue4177428a() {
test(
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" break a\n" + // Remove this...
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};",
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};"
);
}
public void testIssue4177428b() {
test(
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" break a\n" + // Remove this...
" }\n" +
" } finally {\n" +
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};",
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" break a\n" + // Remove this...
" }\n" +
" } finally {\n" +
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};"
);
}
public void testIssue4177428c() {
test(
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" } finally {\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" break a\n" + // Remove this...
" }\n" +
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};",
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" } finally {\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" }\n" +
" }\n" +
" }\n" +
" alert(action)\n" + // but not this.
"};"
);
}
public void testIssue4177428_continue() {
test(
"f = function() {\n" +
" var action;\n" +
" a: do {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" continue a\n" + // Remove this...
" }\n" +
" } while(false)\n" +
" alert(action)\n" + // but not this.
"};",
"f = function() {\n" +
" var action;\n" +
" a: do {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" }\n" +
" } while (false)\n" +
" alert(action)\n" +
"};"
);
}
public void testIssue4177428_return() {
test(
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" return\n" + // Remove this...
" }\n" +
" }\n" +
" alert(action)\n" + // and this.
"};",
"f = function() {\n" +
" var action;\n" +
" a: {\n" +
" var proto = null;\n" +
" try {\n" +
" proto = new Proto\n" +
" } finally {\n" +
" action = proto;\n" +
" }\n" +
" }\n" +
"};"
);
}
public void testIssue4177428_multifinally() {
testSame(
"a: {\n" +
" try {\n" +
" try {\n" +
" } finally {\n" +
" break a;\n" +
" }\n" +
" } finally {\n" +
" x = 1;\n" +
" }\n" +
"}");
}
public void testIssue5215541_deadVarDeclar() {
testSame("throw 1; var x");
testSame("throw 1; function x() {}");
testSame("throw 1; var x; var y;");
test("throw 1; var x = foo", "var x; throw 1");
}
public void testForInLoop() {
testSame("for(var x in y) {}");
}
}