/*
* Copyright 2016 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;
import com.google.javascript.jscomp.CompilerOptions.LanguageMode;
public class J2clClinitPrunerPassTest extends CompilerTestCase {
@Override
protected CompilerPass getProcessor(Compiler compiler) {
return new J2clClinitPrunerPass(compiler);
}
@Override
protected CompilerOptions getOptions() {
CompilerOptions options = super.getOptions();
options.setJ2clPass(CompilerOptions.J2clPassMode.ON);
return options;
}
public void testRemoveDuplicates() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" someClass.$clinit();",
" someClass.$clinit();",
"};"),
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" someClass.$clinit();",
" void 0;",
"};"));
}
public void testRemoveDuplicates_commaExpressions() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" (someClass.$clinit(), true);",
" (someClass.$clinit(), true);",
"};"),
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" (someClass.$clinit(), true);",
" (void 0, true);",
"};"));
}
public void testRemoveDuplicates_controlBlocks() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" someClass.$clinit();",
" if (true) {",
" someClass.$clinit();",
" while(true) {",
" someClass.$clinit();",
" }",
" } else {",
" someClass.$clinit();",
" }",
" var a = (someClass.$clinit(), true) ? (someClass.$clinit(), void 0) : void 0;",
" var b = function() { someClass.$clinit(); };",
" var c = function c() { someClass.$clinit(); };",
" [].forEach(function() { someClass.$clinit(); });",
" someClass.$clinit();",
"};"),
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" someClass.$clinit();",
" if (true) {",
" void 0;",
" while(true) {",
" void 0;",
" }",
" } else {",
" void 0;",
" }",
" var a = (void 0, true) ? (void 0, void 0) : void 0;",
" var b = function() { void 0; };",
" var c = function c() { void 0; };",
" [].forEach(function() { void 0; });",
" void 0;",
"};"));
}
public void testRemoveDuplicates_selfRemoval() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {",
" someClass.$clinit();",
"};"),
LINE_JOINER.join("var someClass = {};", "someClass.$clinit = function() {void 0;}"));
test(
LINE_JOINER.join(
"function someClass$$0clinit() {",
" someClass$$0clinit();",
"}"),
"function someClass$$0clinit() {void 0;}");
}
public void testRemoveDuplicates_jumpFunctionDeclarations() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" myFunc();",
" someClass.$clinit();",
" function myFunc() {",
" someClass.$clinit();",
" someClass.$clinit();",
" }",
"};"),
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.someOtherFunction = function() {",
" myFunc();",
" someClass.$clinit();",
" function myFunc() {",
" someClass.$clinit();",
" void 0;",
" }",
"};"));
}
public void testRemoveDuplicates_avoidControlBlocks() {
testSame(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {}",
"someClass.anotherMethod = function() {",
" (false && someClass.$clinit());",
" (true || someClass.$clinit());",
" if (true) {",
" someClass.$clinit();",
" } else {",
" someClass.$clinit();",
" }",
" while(false) {",
" someClass.$clinit();",
" }",
" for(;false;) {",
" someClass.$clinit();",
" }",
" try {",
" someClass.$clinit();",
" } catch(e) {",
" someClass.$clinit();",
" }",
" switch(2) {",
" case 1: someClass.$clinit(); break;",
" case 2: break;",
" default: someClass.$clinit();",
" }",
" var a = true ? (someClass.$clinit(), void 0) : void 0;",
" var b = function() { someClass.$clinit(); }",
" someClass.$clinit();",
"};"));
}
public void testRedundantClinit_returnCtor() {
test(
LINE_JOINER.join(
"var Foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return new Foo();",
"};"),
LINE_JOINER.join(
"var Foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" return new Foo();",
"};"));
}
public void testRedundantClinit_returnCall() {
test(
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return foo();",
"};"),
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" return foo();",
"};"));
}
public void testRedundantClinit_exprResult() {
test(
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" foo();",
"};"),
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" foo();",
"};"));
}
public void testRedundantClinit_var() {
test(
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" var x = foo();",
"};"),
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" var x = foo();",
"};"));
}
public void testRedundantClinit_let() {
setAcceptedLanguage(LanguageMode.ECMASCRIPT_2015);
test(
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" let x = foo();",
"};"),
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" let x = foo();",
"};"));
}
public void testRedundantClinit_const() {
setAcceptedLanguage(LanguageMode.ECMASCRIPT_2015);
test(
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" const x = foo();",
"};"),
LINE_JOINER.join(
"var foo = function() {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" const x = foo();",
"};"));
}
public void testRedundantClinit_literalArgs() {
test(
LINE_JOINER.join(
"var Foo = function(a) {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return new Foo(1);",
"};"),
LINE_JOINER.join(
"var Foo = function(a) {",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" return new Foo(1);",
"};"));
}
public void testRedundantClinit_paramArgs() {
test(
LINE_JOINER.join(
"var Foo = function(a, b) {",
" Foo.$clinit();",
"};",
"Foo.ctor = function(a) {",
" Foo.$clinit();",
" return new Foo(a, 1);",
"};"),
LINE_JOINER.join(
"var Foo = function(a, b) {",
" Foo.$clinit();",
"};",
"Foo.ctor = function(a) {",
" return new Foo(a, 1);",
"};"));
}
public void testRedundantClinit_unsafeArgs() {
testSame(
LINE_JOINER.join(
"var Foo = function(a) {",
" Foo.$clinit();",
"};",
"Foo.STATIC_VAR = null;",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return new Foo(Foo.STATIC_VAR);",
"};"));
}
public void testRedundantClinit_otherClinit() {
testSame(
LINE_JOINER.join(
"var Foo = function() {",
" Foo1.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return new Foo();",
"};"));
}
public void testRedundantClinit_clinitNotFirstStatement() {
testSame(
LINE_JOINER.join(
"var Foo = function() {",
" var x = 1;",
" Foo.$clinit();",
"};",
"Foo.ctor = function() {",
" Foo.$clinit();",
" return new Foo();",
"};"));
}
public void testRedundantClinit_recursiveCall() {
testSame(
LINE_JOINER.join(
"var foo = function() {",
" Foo1.$clinit();",
" foo();",
"};"));
}
public void testFoldClinit() {
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {",
" someClass.$clinit = function() {};",
"};"),
LINE_JOINER.join("var someClass = {};", "someClass.$clinit = function() {};"));
test(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$clinit = function() {",
" someClass.$clinit = function() {};",
"};"),
LINE_JOINER.join("var someClass = {};", "someClass.$clinit = function() {};"));
}
public void testFoldClinit_invalidCandidates() {
testSame(
LINE_JOINER.join(
"var someClass = /** @constructor */ function() {};",
"someClass.foo = function() {};",
"someClass.$clinit = function() {",
" someClass.$clinit = function() {};",
" someClass.foo();",
"};"));
testSame(
LINE_JOINER.join(
"var someClass = {}, otherClass = {};",
"someClass.$clinit = function() {",
" otherClass.$clinit = function() {};",
"};"));
testSame(
LINE_JOINER.join(
"var someClass = {};",
"someClass.$notClinit = function() {",
" someClass.$notClinit = function() {};",
"};"));
}
}