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/InlineSimpleMethodsTest.java
github-classroom[bot] e42e547e48
Initial commit
2023-04-25 11:33:41 +00:00

304 lines
9.7 KiB
Java

/*
* Copyright 2007 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;
public class InlineSimpleMethodsTest extends CompilerTestCase {
public InlineSimpleMethodsTest() {
super("", false);
}
@Override
protected void setUp() throws Exception {
super.setUp();
super.enableLineNumberCheck(true);
}
@Override
protected CompilerPass getProcessor(Compiler compiler) {
return new InlineSimpleMethods(compiler);
}
/**
* Helper for tests that expects definitions to remain unchanged, such
* that {@code definitions+js} is converted to {@code definitions+expected}.
*/
private void testWithPrefix(String definitions, String js, String expected) {
test(definitions + js, definitions + expected);
}
public void testSimpleInline1() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};",
"var x=(new Foo).bar();var y=(new Foo).bar();",
"var x=(new Foo).baz;var y=(new Foo).baz");
}
public void testSimpleInline2() {
testWithPrefix("function Foo(){}" +
"Foo.prototype={bar:function(){return this.baz}};",
"var x=(new Foo).bar();var y=(new Foo).bar();",
"var x=(new Foo).baz;var y=(new Foo).baz");
}
public void testSimpleGetterInline1() {
// TODO(johnlenz): Support this case.
testSame("function Foo(){}" +
"Foo.prototype={get bar(){return this.baz}};" +
"var x=(new Foo).bar;var y=(new Foo).bar");
// Verify we are not confusing calling the result of an ES5 getter
// with call the getter.
testSame("function Foo(){}" +
"Foo.prototype={get bar(){return this.baz}};" +
"var x=(new Foo).bar();var y=(new Foo).bar()");
}
public void testSimpleSetterInline1() {
// Verify 'get' and 'set' are not confused.
testSame("function Foo(){}" +
"Foo.prototype={set bar(a){return this.baz}};" +
"var x=(new Foo).bar;var y=(new Foo).bar");
testSame("function Foo(){}" +
"Foo.prototype={set bar(a){return this.baz}};" +
"var x=(new Foo).bar();var y=(new Foo).bar()");
}
public void testSelfInline() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};",
"Foo.prototype.meth=function(){this.bar();}",
"Foo.prototype.meth=function(){this.baz}");
}
public void testCallWithArgs() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};",
"var x=(new Foo).bar(3,new Foo)",
"var x=(new Foo).bar(3,new Foo)");
}
public void testCallWithConstArgs() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(a){return this.baz};",
"var x=(new Foo).bar(3, 4)",
"var x=(new Foo).baz");
}
public void testNestedProperties() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz.ooka};",
"(new Foo).bar()",
"(new Foo).baz.ooka");
}
public void testSkipComplexMethods() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};" +
"Foo.prototype.condy=function(){return this.baz?this.baz:1};",
"var x=(new Foo).argy()",
"var x=(new Foo).argy()");
}
public void testSkipConflictingMethods() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};" +
"Foo.prototype.bar=function(){return this.bazz};",
"var x=(new Foo).bar()",
"var x=(new Foo).bar()");
}
public void testSameNamesDifferentDefinitions() {
testWithPrefix("function A(){}" +
"A.prototype.g=function(){return this.a};" +
"function B(){}" +
"B.prototype.g=function(){return this.b};",
"var x=(new A).g();" +
"var y=(new B).g();" +
"var a=new A;" +
"var ag=a.g();",
"var x=(new A).g();" +
"var y=(new B).g();" +
"var a=new A;" +
"var ag=a.g()");
}
public void testSameNamesSameDefinitions() {
testWithPrefix("function A(){}" +
"A.prototype.g=function(){return this.a};" +
"function B(){}" +
"B.prototype.g=function(){return this.a};",
"var x=(new A).g();" +
"var y=(new B).g();" +
"var a=new A;" +
"var ag=a.g();",
"var x=(new A).a;" +
"var y=(new B).a;" +
"var a=new A;" +
"var ag=a.a");
}
public void testConfusingNames() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return this.baz};",
"function bar(){var bar=function(){};bar()}",
"function bar(){var bar=function(){};bar()}");
}
public void testConstantInline() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return 3};",
"var f=new Foo;var x=f.bar()",
"var f=new Foo;var x=3");
}
public void testConstantArrayInline() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return[3,4]};",
"var f=new Foo;var x=f.bar()",
"var f=new Foo;var x=[3,4]");
}
public void testConstantInlineWithSideEffects() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){return 3};",
"var x=(new Foo).bar()",
"var x=(new Foo).bar()");
}
public void testEmptyMethodInline() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(a){};",
"var x=new Foo; x.bar();",
"var x=new Foo");
}
public void testEmptyMethodInlineWithSideEffects() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){};",
"(new Foo).bar();var y=new Foo;y.bar(new Foo)",
"(new Foo).bar();var y=new Foo;y.bar(new Foo)");
}
public void testEmptyMethodInlineInAssign1() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){};",
"var x=new Foo;var y=x.bar()",
"var x=new Foo;var y=void 0");
}
public void testEmptyMethodInlineInAssign2() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){};",
"var x=new Foo;var y=x.bar().toString()",
"var x=new Foo;var y=(void 0).toString()");
}
public void testNormalMethod() {
testWithPrefix("function Foo(){}" +
"Foo.prototype.bar=function(){var x=1};",
"var x=new Foo;x.bar()",
"var x=new Foo;x.bar()");
}
public void testNoInlineOfExternMethods1() {
testSame("var external={};external.charAt;",
"external.charAt()", (DiagnosticType) null);
}
public void testNoInlineOfExternMethods2() {
testSame("var external={};external.charAt=function(){};",
"external.charAt()", (DiagnosticType) null);
}
public void testNoInlineOfExternMethods3() {
testSame("var external={};external.bar=function(){};",
"function Foo(){}Foo.prototype.bar=function(){};(new Foo).bar()",
(DiagnosticType) null);
}
public void testNoInlineOfDangerousProperty() {
testSame("function Foo(){this.bar=3}" +
"Foo.prototype.bar=function(){};" +
"var x=new Foo;var y=x.bar()");
}
// Don't warn about argument naming conventions (this is done in another pass)
// opt_ parameters must not be followed by non-optional parameters.
// var_args must be last
public void testNoWarn() {
testSame("function Foo(){}" +
"Foo.prototype.bar=function(opt_a,b){var x=1};" +
"var x=new Foo;x.bar()");
testSame("function Foo(){}" +
"Foo.prototype.bar=function(var_args,b){var x=1};" +
"var x=new Foo;x.bar()");
}
public void testObjectLit() {
testSame("Foo.prototype.bar=function(){return this.baz_};" +
"var blah={bar:function(){}};" +
"(new Foo).bar()");
}
public void testObjectLit2() {
testSame("var blah={bar:function(){}};" +
"(new Foo).bar()");
}
public void testObjectLitExtern() {
String externs = "window.bridge={_sip:function(){}};";
testSame(externs, "window.bridge._sip()", null);
}
public void testExternFunction() {
String externs = "function emptyFunction() {}";
testSame(externs,
"function Foo(){this.empty=emptyFunction}" +
"(new Foo).empty()", null);
}
public void testIssue2508576_1() {
// Method defined by an extern should be left alone.
String externs = "function alert(a) {}";
testSame(externs, "({a:alert,b:alert}).a(\"a\")", null);
}
public void testIssue2508576_2() {
// Anonymous object definition with a side-effect should be left alone.
testSame("({a:function(){},b:x()}).a(\"a\")");
}
public void testIssue2508576_3() {
// Anonymous object definition without side-effect should be removed.
test("({a:function(){},b:alert}).a(\"a\")", "");
}
public void testAnonymousGet() {
// Anonymous object definition without side-effect should be removed.
testSame("({get a(){return function(){}},b:alert}).a(\"a\")");
testSame("({get a(){},b:alert}).a(\"a\")");
testSame("({get a(){},b:alert}).a");
}
public void testAnonymousSet() {
// Anonymous object definition without side-effect should be removed.
testSame("({set a(b){return function(){}},b:alert}).a(\"a\")");
testSame("({set a(b){},b:alert}).a(\"a\")");
testSame("({set a(b){},b:alert}).a");
}
}