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

1946 lines
55 KiB
Java

/*
* Copyright 2006 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.rhino.Node;
/**
* Tests for {@link NameAnalyzer}
*
*/
public class NameAnalyzerTest extends CompilerTestCase {
private static String kExterns =
"var window, top;" +
"var document;" +
"var Function;" +
"var Array;" +
"var externfoo; methods.externfoo;";
public NameAnalyzerTest() {
super(kExterns);
}
@Override
protected void setUp() {
super.enableNormalize();
super.enableLineNumberCheck(true);
}
@Override
protected int getNumRepetitions() {
// pass reaches steady state after 1 iteration.
return 1;
}
public void testRemoveVarDeclaration1() {
test("var foo = 3;", "");
}
public void testRemoveVarDeclaration2() {
test("var foo = 3, bar = 4; externfoo = foo;",
"var foo = 3; externfoo = foo;");
}
public void testRemoveVarDeclaration3() {
test("var a = f(), b = 1, c = 2; b; c", "f();var b = 1, c = 2; b; c");
}
public void testRemoveVarDeclaration4() {
test("var a = 0, b = f(), c = 2; a; c", "var a = 0;f();var c = 2; a; c");
}
public void testRemoveVarDeclaration5() {
test("var a = 0, b = 1, c = f(); a; b", "var a = 0, b = 1; f(); a; b");
}
public void testRemoveVarDeclaration6() {
test("var a = 0, b = a = 1; a", "var a = 0; a = 1; a");
}
public void testRemoveVarDeclaration7() {
test("var a = 0, b = a = 1", "");
}
public void testRemoveVarDeclaration8() {
test("var a;var b = 0, c = a = b = 1", "");
}
public void testRemoveDeclaration1() {
test("var a;var b = 0, c = a = b = 1", "");
}
public void testRemoveDeclaration2() {
test("var a,b,c; c = a = b = 1", "");
}
public void testRemoveDeclaration3() {
test("var a,b,c; c = a = b = {}; a.x = 1;", "");
}
public void testRemoveDeclaration4() {
testSame("var a,b,c; c = a = b = {}; a.x = 1;alert(c.x);");
}
public void testRemoveDeclaration5() {
test("var a,b,c; c = a = b = null; use(b)", "var b;b=null;use(b)");
}
public void testRemoveDeclaration6() {
test("var a,b,c; c = a = b = 'str';use(b)", "var b;b='str';use(b)");
}
public void testRemoveDeclaration7() {
test("var a,b,c; c = a = b = true;use(b)", "var b;b=true;use(b)");
}
public void testRemoveFunction1() {
test("var foo = function(){};", "");
}
public void testRemoveFunction2() {
test("var foo; foo = function(){};", "");
}
public void testRemoveFunction3() {
test("var foo = {}; foo.bar = function() {};", "");
}
public void testRemoveFunction4() {
test("var a = {}; a.b = {}; a.b.c = function() {};", "");
}
public void testReferredToByWindow() {
testSame("var foo = {}; foo.bar = function() {}; window['fooz'] = foo.bar");
}
public void testExtern() {
testSame("externfoo = 5");
}
public void testRemoveNamedFunction() {
test("function foo(){}", "");
}
public void testRemoveRecursiveFunction1() {
test("function f(){f()}", "");
}
public void testRemoveRecursiveFunction2() {
test("var f = function (){f()}", "");
}
public void testRemoveRecursiveFunction2a() {
test("var f = function g(){g()}", "");
}
public void testRemoveRecursiveFunction3() {
test("var f;f = function (){f()}", "");
}
public void testRemoveRecursiveFunction4() {
// don't removed if name definition doesn't exist.
testSame("f = function (){f()}");
}
public void testRemoveRecursiveFunction5() {
test("function g(){f()}function f(){g()}", "");
}
public void testRemoveRecursiveFunction6() {
test("var f=function(){g()};function g(){f()}", "");
}
public void testRemoveRecursiveFunction7() {
test("var g = function(){f()};var f = function(){g()}", "");
}
public void testRemoveRecursiveFunction8() {
test("var o = {};o.f = function(){o.f()}", "");
}
public void testRemoveRecursiveFunction9() {
testSame("var o = {};o.f = function(){o.f()};o.f()");
}
public void testSideEffectClassification1() {
test("foo();", "foo();");
}
public void testSideEffectClassification2() {
test("var a = foo();", "foo();");
}
public void testSideEffectClassification3() {
testSame("var a = foo();window['b']=a;");
}
public void testSideEffectClassification4() {
testSame("function sef(){} sef();");
}
public void testSideEffectClassification5() {
testSame("function nsef(){} var a = nsef();window['b']=a;");
}
public void testSideEffectClassification6() {
test("function sef(){} sef();", "function sef(){} sef();");
}
public void testSideEffectClassification7() {
testSame("function sef(){} var a = sef();window['b']=a;");
}
public void testNoSideEffectAnnotation1() {
test("function f(){} var a = f();",
"function f(){} f()");
}
public void testNoSideEffectAnnotation2() {
test("/**@nosideeffects*/function f(){}", "var a = f();",
"", null, null);
}
public void testNoSideEffectAnnotation3() {
test("var f = function(){}; var a = f();",
"var f = function(){}; f();");
}
public void testNoSideEffectAnnotation4() {
test("var f = /**@nosideeffects*/function(){};", "var a = f();",
"", null, null);
}
public void testNoSideEffectAnnotation5() {
test("var f; f = function(){}; var a = f();",
"var f; f = function(){}; f();");
}
public void testNoSideEffectAnnotation6() {
test("var f; f = /**@nosideeffects*/function(){};", "var a = f();",
"", null, null);
}
public void testNoSideEffectAnnotation7() {
test("var f;" +
"f = /**@nosideeffects*/function(){};",
"f = function(){};" +
"var a = f();",
"f = function(){}; f();", null, null);
}
public void testNoSideEffectAnnotation8() {
test("var f;" +
"f = function(){};" +
"f = /**@nosideeffects*/function(){};",
"var a = f();",
"f();", null, null);
}
public void testNoSideEffectAnnotation9() {
test("var f;" +
"f = /**@nosideeffects*/function(){};" +
"f = /**@nosideeffects*/function(){};",
"var a = f();",
"", null, null);
test("var f; f = /**@nosideeffects*/function(){};", "var a = f();",
"", null, null);
}
public void testNoSideEffectAnnotation10() {
test("var o = {}; o.f = function(){}; var a = o.f();",
"var o = {}; o.f = function(){}; o.f();");
}
public void testNoSideEffectAnnotation11() {
test("var o = {}; o.f = /**@nosideeffects*/function(){};",
"var a = o.f();", "", null, null);
}
public void testNoSideEffectAnnotation12() {
test("function c(){} var a = new c",
"function c(){} new c");
}
public void testNoSideEffectAnnotation13() {
test("/**@nosideeffects*/function c(){}", "var a = new c",
"", null, null);
}
public void testNoSideEffectAnnotation14() {
String common = "function c(){};" +
"c.prototype.f = /**@nosideeffects*/function(){};";
test(common, "var o = new c; var a = o.f()", "new c", null, null);
}
public void testNoSideEffectAnnotation15() {
test("function c(){}; c.prototype.f = function(){}; var a = (new c).f()",
"function c(){}; c.prototype.f = function(){}; (new c).f()");
}
public void testNoSideEffectAnnotation16() {
test("/**@nosideeffects*/function c(){}" +
"c.prototype.f = /**@nosideeffects*/function(){};",
"var a = (new c).f()",
"",
null, null);
}
public void testFunctionPrototype() {
testSame("var a = 5; Function.prototype.foo = function() {return a;}");
}
public void testTopLevelClass1() {
test("var Point = function() {}; Point.prototype.foo = function() {}", "");
}
public void testTopLevelClass2() {
testSame("var Point = {}; Point.prototype.foo = function() {};" +
"externfoo = new Point()");
}
public void testTopLevelClass3() {
test("function Point() {this.me_ = Point}", "");
}
public void testTopLevelClass4() {
test("function f(){} function A(){} A.prototype = {x: function() {}}; f();",
"function f(){} f();");
}
public void testTopLevelClass5() {
testSame("function f(){} function A(){}" +
"A.prototype = {x: function() { f(); }}; new A();");
}
public void testTopLevelClass6() {
testSame("function f(){} function A(){}" +
"A.prototype = {x: function() { f(); }}; new A().x();");
}
public void testTopLevelClass7() {
test("A.prototype.foo = function(){}; function A() {}", "");
}
public void testNamespacedClass1() {
test("var foo = {};foo.bar = {};foo.bar.prototype.baz = {}", "");
}
public void testNamespacedClass2() {
testSame("var foo = {};foo.bar = {};foo.bar.prototype.baz = {};" +
"window.z = new foo.bar()");
}
public void testNamespacedClass3() {
test("var a = {}; a.b = function() {}; a.b.prototype = {x: function() {}};",
"");
}
public void testNamespacedClass4() {
testSame("function f(){} var a = {}; a.b = function() {};" +
"a.b.prototype = {x: function() { f(); }}; new a.b();");
}
public void testNamespacedClass5() {
testSame("function f(){} var a = {}; a.b = function() {};" +
"a.b.prototype = {x: function() { f(); }}; new a.b().x();");
}
public void testAssignmentToThisPrototype() {
testSame("Function.prototype.inherits = function(parentCtor) {" +
" function tempCtor() {};" +
" tempCtor.prototype = parentCtor.prototype;" +
" this.superClass_ = parentCtor.prototype;" +
" this.prototype = new tempCtor();" +
" this.prototype.constructor = this;" +
"};");
}
public void testAssignmentToCallResultPrototype() {
testSame("function f() { return function(){}; } f().prototype = {};");
}
public void testAssignmentToExternPrototype() {
testSame("externfoo.prototype = {};");
}
public void testAssignmentToUnknownPrototype() {
testSame(
"/** @suppress {duplicate} */ var window;" +
"window['a'].prototype = {};");
}
public void testBug2099540() {
testSame(
"/** @suppress {duplicate} */ var document;\n" +
"/** @suppress {duplicate} */ var window;\n" +
"var klass;\n" +
"window[klass].prototype = " +
"document.createElement(tagName)['__proto__'];");
}
public void testOtherGlobal() {
testSame("goog.global.foo = bar(); function bar(){}");
}
public void testExternName1() {
testSame("top.z = bar(); function bar(){}");
}
public void testExternName2() {
testSame("top['z'] = bar(); function bar(){}");
}
public void testInherits1() {
test("var a = {}; var b = {}; b.inherits(a)", "");
}
public void testInherits2() {
test("var a = {}; var b = {}; var goog = {}; goog.inherits(b, a)", "");
}
public void testInherits3() {
testSame("var a = {}; this.b = {}; b.inherits(a);");
}
public void testInherits4() {
testSame("var a = {}; this.b = {}; var goog = {}; goog.inherits(b, a);");
}
public void testInherits5() {
test("this.a = {}; var b = {}; b.inherits(a);",
"this.a = {}");
}
public void testInherits6() {
test("this.a = {}; var b = {}; var goog = {}; goog.inherits(b, a);",
"this.a = {}");
}
public void testInherits7() {
testSame("var a = {}; this.b = {}; var goog = {};" +
" goog.inherits = function() {}; goog.inherits(b, a);");
}
public void testInherits8() {
// Make sure that exceptions aren't thrown if inherits() is used as
// an R-value
test("this.a = {}; var b = {}; var c = b.inherits(a);", "this.a = {};");
}
public void testMixin1() {
testSame("var goog = {}; goog.mixin = function() {};" +
"Function.prototype.mixin = function(base) {" +
" goog.mixin(this.prototype, base); " +
"};");
}
public void testMixin2() {
testSame("var a = {}; this.b = {}; var goog = {};" +
" goog.mixin = function() {}; goog.mixin(b.prototype, a.prototype);");
}
public void testMixin3() {
test("this.a = {}; var b = {}; var goog = {};" +
" goog.mixin = function() {}; goog.mixin(b.prototype, a.prototype);",
"this.a = {};");
}
public void testMixin4() {
testSame("this.a = {}; var b = {}; var goog = {};" +
"goog.mixin = function() {};" +
"goog.mixin(b.prototype, a.prototype);" +
"new b()");
}
public void testMixin5() {
test("this.a = {}; var b = {}; var c = {}; var goog = {};" +
"goog.mixin = function() {};" +
"goog.mixin(b.prototype, a.prototype);" +
"goog.mixin(c.prototype, a.prototype);" +
"new b()",
"this.a = {}; var b = {}; var goog = {};" +
"goog.mixin = function() {};" +
"goog.mixin(b.prototype, a.prototype);" +
"new b()");
}
public void testMixin6() {
testSame("this.a = {}; var b = {}; var c = {}; var goog = {};" +
"goog.mixin = function() {};" +
"goog.mixin(c.prototype, a.prototype) + " +
"goog.mixin(b.prototype, a.prototype);" +
"new b()");
}
public void testMixin7() {
test("this.a = {}; var b = {}; var c = {}; var goog = {};" +
"goog.mixin = function() {};" +
"var d = goog.mixin(c.prototype, a.prototype) + " +
"goog.mixin(b.prototype, a.prototype);" +
"new b()",
"this.a = {}; var b = {}; var goog = {};" +
"goog.mixin = function() {};" +
"goog.mixin(b.prototype, a.prototype);" +
"new b()");
}
public void testConstants1() {
testSame("var bar = function(){}; var EXP_FOO = true; if (EXP_FOO) bar();");
}
public void testConstants2() {
test("var bar = function(){}; var EXP_FOO = true; var EXP_BAR = true;" +
"if (EXP_FOO) bar();",
"var bar = function(){}; var EXP_FOO = true; if (EXP_FOO) bar();");
}
public void testExpressions1() {
test("var foo={}; foo.A='A'; foo.AB=foo.A+'B'; foo.ABC=foo.AB+'C'",
"");
}
public void testExpressions2() {
testSame("var foo={}; foo.A='A'; foo.AB=foo.A+'B'; this.ABC=foo.AB+'C'");
}
public void testExpressions3() {
testSame("var foo = 2; window.bar(foo + 3)");
}
public void testSetCreatingReference() {
testSame("var foo; var bar = function(){foo=6;}; bar();");
}
public void testAnonymous1() {
testSame("function foo() {}; function bar() {}; foo(function() {bar()})");
}
public void testAnonymous2() {
test("var foo;(function(){foo=6;})()", "(function(){})()");
}
public void testAnonymous3() {
testSame("var foo; (function(){ if(!foo)foo=6; })()");
}
public void testAnonymous4() {
testSame("var foo; (function(){ foo=6; })(); externfoo=foo;");
}
public void testAnonymous5() {
testSame("var foo;" +
"(function(){ foo=function(){ bar() }; function bar(){} })();" +
"foo();");
}
public void testAnonymous6() {
testSame("function foo(){}" +
"function bar(){}" +
"foo(function(){externfoo = bar});");
}
public void testAnonymous7() {
testSame("var foo;" +
"(function (){ function bar(){ externfoo = foo; } bar(); })();");
}
public void testAnonymous8() {
testSame("var foo;" +
"(function (){ var g=function(){ externfoo = foo; }; g(); })();");
}
public void testAnonymous9() {
testSame("function foo(){}" +
"function bar(){}" +
"foo(function(){ function baz(){ externfoo = bar; } baz(); });");
}
public void testFunctions1() {
testSame("var foo = null; function baz() {}" +
"function bar() {foo=baz();} bar();");
}
public void testFunctions2() {
testSame("var foo; foo = function() {var a = bar()};" +
"var bar = function(){}; foo();");
}
public void testGetElem1() {
testSame("var foo = {}; foo.bar = {}; foo.bar.baz = {a: 5, b: 10};" +
"var fn = function() {window[foo.bar.baz.a] = 5;}; fn()");
}
public void testGetElem2() {
testSame("var foo = {}; foo.bar = {}; foo.bar.baz = {a: 5, b: 10};" +
"var fn = function() {this[foo.bar.baz.a] = 5;}; fn()");
}
public void testGetElem3() {
testSame("var foo = {'i': 0, 'j': 1}; foo['k'] = 2; top.foo = foo;");
}
public void testIf1() {
test("var foo = {};if(e)foo.bar=function(){};", "if(e);");
}
public void testIf2() {
test("var e = false;var foo = {};if(e)foo.bar=function(){};",
"var e = false;if(e);");
}
public void testIf3() {
test("var e = false;var foo = {};if(e + 1)foo.bar=function(){};",
"var e = false;if(e + 1);");
}
public void testIf4() {
test("var e = false, f;var foo = {};if(f=e)foo.bar=function(){};",
"var e = false;if(e);");
}
public void testIf4a() {
// TODO(johnlenz): fix this.
testSame("var e = [], f;if(f=e);f[0] = 1;");
}
public void testIf4b() {
// TODO(johnlenz): fix this.
test("var e = [], f;if(e=f);f[0] = 1;",
"var f;if(f);f[0] = 1;");
}
public void testIf4c() {
test("var e = [], f;if(f=e);e[0] = 1;",
"var e = [];if(e);e[0] = 1;");
}
public void testIf5() {
test("var e = false, f;var foo = {};if(f = e + 1)foo.bar=function(){};",
"var e = false;if(e + 1);");
}
public void testIfElse() {
test("var foo = {};if(e)foo.bar=function(){};else foo.bar=function(){};",
"if(e);else;");
}
public void testWhile() {
test("var foo = {};while(e)foo.bar=function(){};", "while(e);");
}
public void testFor() {
test("var foo = {};for(e in x)foo.bar=function(){};", "for(e in x);");
}
public void testDo() {
test("var cond = false;do {var a = 1} while (cond)",
"var cond = false;do {} while (cond)");
}
public void testSetterInForStruct1() {
test("var j = 0; for (var i = 1; i = 0; j++);",
"var j = 0; for (; 0; j++);");
}
public void testSetterInForStruct2() {
test("var Class = function() {}; " +
"for (var i = 1; Class.prototype.property_ = 0; i++);",
"for (var i = 1; 0; i++);");
}
public void testSetterInForStruct3() {
test("var j = 0; for (var i = 1 + f() + g() + h(); i = 0; j++);",
"var j = 0; f(); g(); h(); for (; 0; j++);");
}
public void testSetterInForStruct4() {
test("var i = 0;var j = 0; for (i = 1 + f() + g() + h(); i = 0; j++);",
"var j = 0; f(); g(); h(); for (; 0; j++);");
}
public void testSetterInForStruct5() {
test("var i = 0, j = 0; for (i = f(), j = g(); 0;);",
"for (f(), g(); 0;);");
}
public void testSetterInForStruct6() {
test("var i = 0, j = 0, k = 0; for (i = f(), j = g(), k = h(); i = 0;);",
"for (f(), g(), h(); 0;);");
}
public void testSetterInForStruct7() {
test("var i = 0, j = 0, k = 0; for (i = 1, j = 2, k = 3; i = 0;);",
"for (1, 2, 3; 0;);");
}
public void testSetterInForStruct8() {
test("var i = 0, j = 0, k = 0; for (i = 1, j = i, k = 2; i = 0;);",
"var i = 0; for(i = 1, i , 2; i = 0;);");
}
public void testSetterInForStruct9() {
test("var Class = function() {}; " +
"for (var i = 1; Class.property_ = 0; i++);",
"for (var i = 1; 0; i++);");
}
public void testSetterInForStruct10() {
test("var Class = function() {}; " +
"for (var i = 1; Class.property_ = 0; i = 2);",
"for (; 0;);");
}
public void testSetterInForStruct11() {
test("var Class = function() {}; " +
"for (;Class.property_ = 0;);",
"for (;0;);");
}
public void testSetterInForStruct12() {
test("var a = 1; var Class = function() {}; " +
"for (;Class.property_ = a;);",
"var a = 1; for (; a;);");
}
public void testSetterInForStruct13() {
test("var a = 1; var Class = function() {}; " +
"for (Class.property_ = a; 0 ;);",
"for (; 0;);");
}
public void testSetterInForStruct14() {
test("var a = 1; var Class = function() {}; " +
"for (; 0; Class.property_ = a);",
"for (; 0;);");
}
public void testSetterInForStruct15() {
test("var Class = function() {}; " +
"for (var i = 1; 0; Class.prototype.property_ = 0);",
"for (; 0; 0);");
}
public void testSetterInForStruct16() {
test("var Class = function() {}; " +
"for (var i = 1; i = 0; Class.prototype.property_ = 0);",
"for (; 0; 0);");
}
public void testSetterInForIn1() {
test("var foo = {}; var bar; for(e in bar = foo.a);",
"var foo = {}; for(e in foo.a);");
}
public void testSetterInForIn2() {
testSame("var foo = {}; var bar; for(e in bar = foo.a); bar");
}
public void testSetterInForIn3() {
testSame("var foo = {}; var bar; for(e in bar = foo.a); bar.b = 3");
}
public void testSetterInForIn4() {
testSame("var foo = {}; var bar; for (e in bar = foo.a); bar.b = 3; foo.a");
}
public void testSetterInForIn5() {
// TODO(user) Fix issue similar to b/2316773: bar should be preserved
// but isn't due to missing references between e and foo.a
test("var foo = {}; var bar; for (e in foo.a) { bar = e } bar.b = 3; foo.a",
"var foo={};for(e in foo.a);foo.a");
}
public void testSetterInForIn6() {
testSame("var foo = {};for(e in foo);");
}
public void testSetterInIfPredicate() {
// TODO(user) Make NameAnalyzer smarter so it can remove "Class".
testSame("var a = 1;" +
"var Class = function() {}; " +
"if (Class.property_ = a);");
}
public void testSetterInWhilePredicate() {
test("var a = 1;" +
"var Class = function() {}; " +
"while (Class.property_ = a);",
"var a = 1; for (;a;) {}");
}
public void testSetterInDoWhilePredicate() {
// TODO(user) Make NameAnalyzer smarter so it can remove "Class".
testSame("var a = 1;" +
"var Class = function() {}; " +
"do {} while(Class.property_ = a);");
}
public void testSetterInSwitchInput() {
// TODO(user) Make NameAnalyzer smarter so it can remove "Class".
testSame("var a = 1;" +
"var Class = function() {}; " +
"switch (Class.property_ = a) {" +
" default:" +
"}");
}
public void testComplexAssigns() {
// Complex assigns are not removed by the current pass.
testSame("var x = 0; x += 3; x *= 5;");
}
public void testNestedAssigns1() {
test("var x = 0; var y = x = 3; window.alert(y);",
"var y = 3; window.alert(y);");
}
public void testNestedAssigns2() {
testSame("var x = 0; var y = x = {}; x.b = 3; window.alert(y);");
}
public void testComplexNestedAssigns1() {
// TODO(nicksantos): Make NameAnalyzer smarter, so that we can eliminate y.
testSame("var x = 0; var y = 2; y += x = 3; window.alert(x);");
}
public void testComplexNestedAssigns2() {
test("var x = 0; var y = 2; y += x = 3; window.alert(y);",
"var y = 2; y += 3; window.alert(y);");
}
public void testComplexNestedAssigns3() {
test("var x = 0; var y = x += 3; window.alert(x);",
"var x = 0; x += 3; window.alert(x);");
}
public void testComplexNestedAssigns4() {
testSame("var x = 0; var y = x += 3; window.alert(y);");
}
public void testUnintendedUseOfInheritsInLocalScope1() {
testSame("goog.mixin = function() {}; " +
"(function() { var x = {}; var y = {}; goog.mixin(x, y); })();");
}
public void testUnintendedUseOfInheritsInLocalScope2() {
testSame("goog.mixin = function() {}; " +
"var x = {}; var y = {}; (function() { goog.mixin(x, y); })();");
}
public void testUnintendedUseOfInheritsInLocalScope3() {
testSame("goog.mixin = function() {}; " +
"var x = {}; var y = {}; (function() { goog.mixin(x, y); })(); " +
"window.alert(x);");
}
public void testUnintendedUseOfInheritsInLocalScope4() {
// Ensures that the "goog$mixin" variable doesn't get stripped out,
// even when it's only used in a local scope.
testSame("var goog$mixin = function() {}; " +
"(function() { var x = {}; var y = {}; goog$mixin(x, y); })();");
}
public void testPrototypePropertySetInLocalScope1() {
testSame("(function() { var x = function(){}; x.prototype.bar = 3; })();");
}
public void testPrototypePropertySetInLocalScope2() {
testSame("var x = function(){}; (function() { x.prototype.bar = 3; })();");
}
public void testPrototypePropertySetInLocalScope3() {
test("var x = function(){ x.prototype.bar = 3; };", "");
}
public void testPrototypePropertySetInLocalScope4() {
test("var x = {}; x.foo = function(){ x.foo.prototype.bar = 3; };", "");
}
public void testPrototypePropertySetInLocalScope5() {
test("var x = {}; x.prototype.foo = 3;", "");
}
public void testPrototypePropertySetInLocalScope6() {
testSame("var x = {}; x.prototype.foo = 3; bar(x.prototype.foo)");
}
public void testPrototypePropertySetInLocalScope7() {
testSame("var x = {}; x.foo = 3; bar(x.foo)");
}
public void testRValueReference1() {
testSame("var a = 1; a");
}
public void testRValueReference2() {
testSame("var a = 1; 1+a");
}
public void testRValueReference3() {
testSame("var x = {}; x.prototype.foo = 3; var a = x.prototype.foo; 1+a");
}
public void testRValueReference4() {
testSame("var x = {}; x.prototype.foo = 3; x.prototype.foo");
}
public void testRValueReference5() {
testSame("var x = {}; x.prototype.foo = 3; 1+x.prototype.foo");
}
public void testRValueReference6() {
testSame("var x = {}; var idx = 2; x[idx]");
}
public void testUnhandledTopNode() {
testSame("function Foo() {}; Foo.prototype.isBar = function() {};" +
"function Bar() {}; Bar.prototype.isFoo = function() {};" +
"var foo = new Foo(); var bar = new Bar();" +
// The boolean AND here is currently unhandled by this pass, but
// it should not cause it to blow up.
"var cond = foo.isBar() && bar.isFoo();" +
"if (cond) {window.alert('hello');}");
}
public void testPropertyDefinedInGlobalScope() {
testSame("function Foo() {}; var x = new Foo(); x.cssClass = 'bar';" +
"window.alert(x);");
}
public void testConditionallyDefinedFunction1() {
testSame("var g; externfoo.x || (externfoo.x = function() { g; })");
}
public void testConditionallyDefinedFunction2() {
testSame("var g; 1 || (externfoo.x = function() { g; })");
}
public void testConditionallyDefinedFunction3() {
testSame("var a = {};" +
"rand() % 2 || (a.f = function() { externfoo = 1; } || alert());");
}
public void testGetElemOnThis() {
testSame("var a = 3; this['foo'] = a;");
testSame("this['foo'] = 3;");
}
public void testRemoveInstanceOfOnly() {
test("function Foo() {}; Foo.prototype.isBar = function() {};" +
"var x; if (x instanceof Foo) { window.alert(x); }",
";var x; if (false) { window.alert(x); }");
}
public void testRemoveLocalScopedInstanceOfOnly() {
test("function Foo() {}; function Bar(x) { this.z = x instanceof Foo; };" +
"externfoo.x = new Bar({});",
";function Bar(x) { this.z = false }; externfoo.x = new Bar({});");
}
public void testRemoveInstanceOfWithReferencedMethod() {
test("function Foo() {}; Foo.prototype.isBar = function() {};" +
"var x; if (x instanceof Foo) { window.alert(x.isBar()); }",
";var x; if (false) { window.alert(x.isBar()); }");
}
public void testDoNotChangeReferencedInstanceOf() {
testSame("function Foo() {}; Foo.prototype.isBar = function() {};" +
"var x = new Foo(); if (x instanceof Foo) { window.alert(x); }");
}
public void testDoNotChangeReferencedLocalScopedInstanceOf() {
testSame("function Foo() {}; externfoo.x = new Foo();" +
"function Bar() { if (x instanceof Foo) { window.alert(x); } };" +
"externfoo.y = new Bar();");
}
public void testDoNotChangeLocalScopeReferencedInstanceOf() {
testSame("function Foo() {}; Foo.prototype.isBar = function() {};" +
"function Bar() { this.z = new Foo(); }; externfoo.x = new Bar();" +
"if (x instanceof Foo) { window.alert(x); }");
}
public void testDoNotChangeLocalScopeReferencedLocalScopedInstanceOf() {
testSame("function Foo() {}; Foo.prototype.isBar = function() {};" +
"function Bar() { this.z = new Foo(); };" +
"Bar.prototype.func = function(x) {" +
"if (x instanceof Foo) { window.alert(x); }" +
"}; new Bar().func();");
}
public void testDoNotChangeLocalScopeReferencedLocalScopedInstanceOf2() {
test(
"function Foo() {}" +
"var createAxis = function(f) { return window.passThru(f); };" +
"var axis = createAxis(function(test) {" +
" return test instanceof Foo;" +
"});",
"var createAxis = function(f) { return window.passThru(f); };" +
"createAxis(function(test) {" +
" return false;" +
"});");
}
public void testDoNotChangeInstanceOfGetElem() {
testSame("var goog = {};" +
"function f(obj, name) {" +
" if (obj instanceof goog[name]) {" +
" return name;" +
" }" +
"}" +
"window['f'] = f;");
}
public void testWeirdnessOnLeftSideOfPrototype() {
// This checks a bug where 'x' was removed, but the function referencing
// it was not, causing problems.
testSame("var x = 3; " +
"(function() { this.bar = 3; }).z = function() {" +
" return x;" +
"};");
}
public void testShortCircuit1() {
test("var a = b() || 1", "b()");
}
public void testShortCircuit2() {
test("var a = 1 || c()", "1 || c()");
}
public void testShortCircuit3() {
test("var a = b() || c()", "b() || c()");
}
public void testShortCircuit4() {
test("var a = b() || 3 || c()", "b() || 3 || c()");
}
public void testShortCircuit5() {
test("var a = b() && 1", "b()");
}
public void testShortCircuit6() {
test("var a = 1 && c()", "1 && c()");
}
public void testShortCircuit7() {
test("var a = b() && c()", "b() && c()");
}
public void testShortCircuit8() {
test("var a = b() && 3 && c()", "b() && 3 && c()");
}
public void testRhsReference1() {
testSame("var a = 1; a");
}
public void testRhsReference2() {
testSame("var a = 1; a || b()");
}
public void testRhsReference3() {
testSame("var a = 1; 1 || a");
}
public void testRhsReference4() {
test("var a = 1; var b = a || foo()", "var a = 1; a || foo()");
}
public void testRhsReference5() {
test("var a = 1, b = 5; a; foo(b)", "var a = 1, b = 5; a; foo(b)");
}
public void testRhsAssign1() {
test("var foo, bar; foo || (bar = 1)",
"var foo; foo || 1");
}
public void testRhsAssign2() {
test("var foo, bar, baz; foo || (baz = bar = 1)",
"var foo; foo || 1");
}
public void testRhsAssign3() {
testSame("var foo = null; foo || (foo = 1)");
}
public void testRhsAssign4() {
test("var foo = null; foo = (foo || 1)", "");
}
public void testRhsAssign5() {
test("var a = 3, foo, bar; foo || (bar = a)", "var a = 3, foo; foo || a");
}
public void testRhsAssign6() {
test("function Foo(){} var foo = null;" +
"var f = function () {foo || (foo = new Foo()); return foo}",
"");
}
public void testRhsAssign7() {
testSame("function Foo(){} var foo = null;" +
"var f = function () {foo || (foo = new Foo())}; f()");
}
public void testRhsAssign8() {
testSame("function Foo(){} var foo = null;" +
"var f = function () {(foo = new Foo()) || g()}; f()");
}
public void testRhsAssign9() {
test("function Foo(){} var foo = null;" +
"var f = function () {1 + (foo = new Foo()); return foo}",
"");
}
public void testAssignWithOr1() {
testSame("var foo = null;" +
"var f = window.a || function () {return foo}; f()");
}
public void testAssignWithOr2() {
test("var foo = null;" +
"var f = window.a || function () {return foo};",
"var foo = null"); // why is this left?
}
public void testAssignWithAnd1() {
testSame("var foo = null;" +
"var f = window.a && function () {return foo}; f()");
}
public void testAssignWithAnd2() {
test("var foo = null;" +
"var f = window.a && function () {return foo};",
"var foo = null;"); // why is this left?
}
public void testAssignWithHook1() {
testSame("function Foo(){} var foo = null;" +
"var f = window.a ? " +
" function () {return new Foo()} : function () {return foo}; f()");
}
public void testAssignWithHook2() {
test("function Foo(){} var foo = null;" +
"var f = window.a ? " +
" function () {return new Foo()} : function () {return foo};",
"");
}
public void testAssignWithHook2a() {
test("function Foo(){} var foo = null;" +
"var f; f = window.a ? " +
" function () {return new Foo()} : function () {return foo};",
"");
}
public void testAssignWithHook3() {
testSame("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a ? " +
" function () {return new Foo()} : function () {return foo}; f.b()");
}
public void testAssignWithHook4() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a ? " +
" function () {return new Foo()} : function () {return foo};",
"");
}
public void testAssignWithHook5() {
testSame("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a ? function () {return new Foo()} :" +
" window.b ? function () {return foo} :" +
" function() { return Foo }; f.b()");
}
public void testAssignWithHook6() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a ? function () {return new Foo()} :" +
" window.b ? function () {return foo} :" +
" function() { return Foo };",
"");
}
public void testAssignWithHook7() {
testSame("function Foo(){} var foo = null;" +
"var f = window.a ? new Foo() : foo;" +
"f()");
}
public void testAssignWithHook8() {
test("function Foo(){} var foo = null;" +
"var f = window.a ? new Foo() : foo;",
"function Foo(){}" +
"window.a && new Foo()");
}
public void testAssignWithHook9() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a ? new Foo() : foo;",
"function Foo(){} window.a && new Foo()");
}
public void testAssign1() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = window.a;",
"");
}
public void testAssign2() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = window;",
"");
}
public void testAssign3() {
test("var f = {};" +
"f.b = window;",
"");
}
public void testAssign4() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = new Foo();",
"function Foo(){} new Foo()");
}
public void testAssign5() {
test("function Foo(){} var foo = null; var f = {};" +
"f.b = foo;",
"");
}
public void testNestedAssign1() {
test("var a, b = a = 1, c = 2", "");
}
public void testNestedAssign2() {
test("var a, b = a = 1; foo(b)",
"var b = 1; foo(b)");
}
public void testNestedAssign3() {
test("var a, b = a = 1; a = b = 2; foo(b)",
"var b = 1; b = 2; foo(b)");
}
public void testNestedAssign4() {
test("var a, b = a = 1; b = a = 2; foo(b)",
"var b = 1; b = 2; foo(b)");
}
public void testNestedAssign5() {
test("var a, b = a = 1; b = a = 2", "");
}
public void testNestedAssign15() {
test("var a, b, c; c = b = a = 2", "");
}
public void testNestedAssign6() {
testSame("var a, b, c; a = b = c = 1; foo(a, b, c)");
}
public void testNestedAssign7() {
testSame("var a = 0; a = i[j] = 1; b(a, i[j])");
}
public void testNestedAssign8() {
testSame("function f(){" +
"this.lockedToken_ = this.lastToken_ = " +
"SETPROP_value(this.hiddenInput_, a)}f()");
}
public void testRefChain1() {
test("var a = 1; var b = a; var c = b; var d = c", "");
}
public void testRefChain2() {
test("var a = 1; var b = a; var c = b; var d = c || f()",
"var a = 1; var b = a; var c = b; c || f()");
}
public void testRefChain3() {
test("var a = 1; var b = a; var c = b; var d = c + f()", "f()");
}
public void testRefChain4() {
test("var a = 1; var b = a; var c = b; var d = f() || c",
"f()");
}
public void testRefChain5() {
test("var a = 1; var b = a; var c = b; var d = f() ? g() : c",
"f() && g()");
}
public void testRefChain6() {
test("var a = 1; var b = a; var c = b; var d = c ? f() : g()",
"var a = 1; var b = a; var c = b; c ? f() : g()");
}
public void testRefChain7() {
test("var a = 1; var b = a; var c = b; var d = (b + f()) ? g() : c",
"var a = 1; var b = a; (b+f()) && g()");
}
public void testRefChain8() {
test("var a = 1; var b = a; var c = b; var d = f()[b] ? g() : 0",
"var a = 1; var b = a; f()[b] && g()");
}
public void testRefChain9() {
test("var a = 1; var b = a; var c = 5; var d = f()[b+c] ? g() : 0",
"var a = 1; var b = a; var c = 5; f()[b+c] && g()");
}
public void testRefChain10() {
test("var a = 1; var b = a; var c = b; var d = f()[b] ? g() : 0",
"var a = 1; var b = a; f()[b] && g()");
}
public void testRefChain11() {
test("var a = 1; var b = a; var d = f()[b] ? g() : 0",
"var a = 1; var b = a; f()[b] && g()");
}
public void testRefChain12() {
testSame("var a = 1; var b = a; f()[b] ? g() : 0");
}
public void testRefChain13() {
test("function f(){}var a = 1; var b = a; var d = f()[b] ? g() : 0",
"function f(){}var a = 1; var b = a; f()[b] && g()");
}
public void testRefChain14() {
testSame("function f(){}var a = 1; var b = a; f()[b] ? g() : 0");
}
public void testRefChain15() {
test("function f(){}var a = 1, b = a; var c = f(); var d = c[b] ? g() : 0",
"function f(){}var a = 1, b = a; var c = f(); c[b] && g()");
}
public void testRefChain16() {
testSame("function f(){}var a = 1; var b = a; var c = f(); c[b] ? g() : 0");
}
public void testRefChain17() {
test("function f(){}var a = 1; var b = a; var c = f(); var d = c[b]",
"function f(){} f()");
}
public void testRefChain18() {
testSame("var a = 1; f()[a] && g()");
}
public void testRefChain19() {
test("var a = 1; var b = [a]; var c = b; b[f()] ? g() : 0",
"var a=1; var b=[a]; b[f()] ? g() : 0");
}
public void testRefChain20() {
test("var a = 1; var b = [a]; var c = b; var d = b[f()] ? g() : 0",
"var a=1; var b=[a]; b[f()]&&g()");
}
public void testRefChain21() {
testSame("var a = 1; var b = 2; var c = a + b; f(c)");
}
public void testRefChain22() {
test("var a = 2; var b = a = 4; f(a)", "var a = 2; a = 4; f(a)");
}
public void testRefChain23() {
test("var a = {}; var b = a[1] || f()", "var a = {}; a[1] || f()");
}
/**
* Expressions that cannot be attributed to any enclosing dependency
* scope should be treated as global references.
* @bug 1739062
*/
public void testAssignmentWithComplexLhs() {
testSame("function f() { return this; }" +
"var o = {'key': 'val'};" +
"f().x_ = o['key'];");
}
public void testAssignmentWithComplexLhs2() {
testSame("function f() { return this; }" +
"var o = {'key': 'val'};" +
"f().foo = function() {" +
" o" +
"};");
}
public void testAssignmentWithComplexLhs3() {
String source =
"var o = {'key': 'val'};" +
"function init_() {" +
" this.x = o['key']" +
"}";
test(source, "");
testSame(source + ";init_()");
}
public void testAssignmentWithComplexLhs4() {
testSame("function f() { return this; }" +
"var o = {'key': 'val'};" +
"f().foo = function() {" +
" this.x = o['key']" +
"};");
}
/**
* Do not "prototype" property of variables that are not being
* tracked (because they are local).
* @bug 1809442
*/
public void testNoRemovePrototypeDefinitionsOutsideGlobalScope1() {
testSame("function f(arg){}" +
"" +
"(function(){" +
" var O = {};" +
" O.prototype = 'foo';" +
" f(O);" +
"})()");
}
public void testNoRemovePrototypeDefinitionsOutsideGlobalScope2() {
testSame("function f(arg){}" +
"(function h(){" +
" var L = {};" +
" L.prototype = 'foo';" +
" f(L);" +
"})()");
}
public void testNoRemovePrototypeDefinitionsOutsideGlobalScope4() {
testSame("function f(arg){}" +
"function g(){" +
" var N = {};" +
" N.prototype = 'foo';" +
" f(N);" +
"}" +
"g()");
}
public void testNoRemovePrototypeDefinitionsOutsideGlobalScope5() {
// function body not removed due to @bug 1898561
testSame("function g(){ var R = {}; R.prototype = 'foo' } g()");
}
public void testRemovePrototypeDefinitionsInGlobalScope1() {
testSame("function f(arg){}" +
"var M = {};" +
"M.prototype = 'foo';" +
"f(M);");
}
public void testRemovePrototypeDefinitionsInGlobalScope2() {
test("var Q = {}; Q.prototype = 'foo'", "");
}
public void testRemoveLabeledStatment() {
test("LBL: var x = 1;", "LBL: {}");
}
public void testRemoveLabeledStatment2() {
test("var x; LBL: x = f() + g()", "LBL: { f() ; g()}");
}
public void testRemoveLabeledStatment3() {
test("var x; LBL: x = 1;", "LBL: {}");
}
public void testRemoveLabeledStatment4() {
test("var a; LBL: a = f()", "LBL: f()");
}
public void testPreservePropertyMutationsToAlias1() {
// Test for issue b/2316773 - property get case
// Since a is referenced, property mutations via a's alias b must
// be preserved.
testSame("var a = {}; var b = a; b.x = 1; a");
}
public void testPreservePropertyMutationsToAlias2() {
// Test for issue b/2316773 - property get case, don't keep 'c'
test("var a = {}; var b = a; var c = a; b.x = 1; a",
"var a = {}; var b = a; b.x = 1; a");
}
public void testPreservePropertyMutationsToAlias3() {
// Test for issue b/2316773 - property get case, chain
testSame("var a = {}; var b = a; var c = b; c.x = 1; a");
}
public void testPreservePropertyMutationsToAlias4() {
// Test for issue b/2316773 - element get case
testSame("var a = {}; var b = a; b['x'] = 1; a");
}
public void testPreservePropertyMutationsToAlias5() {
// From issue b/2316773 description
testSame("function testCall(o){}" +
"var DATA = {'prop': 'foo','attr': {}};" +
"var SUBDATA = DATA['attr'];" +
"SUBDATA['subprop'] = 'bar';" +
"testCall(DATA);");
}
public void testPreservePropertyMutationsToAlias6() {
// Longer GETELEM chain
testSame("function testCall(o){}" +
"var DATA = {'prop': 'foo','attr': {}};" +
"var SUBDATA = DATA['attr'];" +
"var SUBSUBDATA = SUBDATA['subprop'];" +
"SUBSUBDATA['subsubprop'] = 'bar';" +
"testCall(DATA);");
}
public void testPreservePropertyMutationsToAlias7() {
// Make sure that the base class does not depend on the derived class.
test("var a = {}; var b = {}; b.x = 0;" +
"var goog = {}; goog.inherits(b, a); a",
"var a = {}; a");
}
public void testPreservePropertyMutationsToAlias8() {
// Make sure that the derived classes don't end up depending on each other.
test("var a = {};" +
"var b = {}; b.x = 0;" +
"var c = {}; c.y = 0;" +
"var goog = {}; goog.inherits(b, a); goog.inherits(c, a); c",
"var a = {}; var c = {}; c.y = 0;" +
"var goog = {}; goog.inherits(c, a); c");
}
public void testPreservePropertyMutationsToAlias9() {
testSame("var a = {b: {}};" +
"var c = a.b; c.d = 3;" +
"a.d = 3; a.d;");
}
public void testRemoveAlias() {
test("var a = {b: {}};" +
"var c = a.b;" +
"a.d = 3; a.d;",
"var a = {b: {}}; a.d = 3; a.d;");
}
public void testSingletonGetter1() {
test("function Foo() {} goog.addSingletonGetter(Foo);", "");
}
public void testSingletonGetter2() {
test("function Foo() {} goog$addSingletonGetter(Foo);", "");
}
public void testSingletonGetter3() {
// addSingletonGetter adds a getInstance method to a class.
testSame("function Foo() {} goog$addSingletonGetter(Foo);" +
"this.x = Foo.getInstance();");
}
public void testNoRemoveWindowPropertyAlias1() {
testSame(
"var self_ = window.gbar;\n" +
"self_.qs = function() {};");
}
public void testNoRemoveWindowPropertyAlias2() {
testSame(
"var self_ = window;\n" +
"self_.qs = function() {};");
}
public void testNoRemoveWindowPropertyAlias3() {
testSame(
"var self_ = window;\n" +
"self_['qs'] = function() {};");
}
public void testNoRemoveWindowPropertyAlias4() {
// TODO(johnlenz): fix this. "self_" should remain.
test(
"var self_ = window['gbar'] || {};\n" +
"self_.qs = function() {};",
"");
}
public void testNoRemoveWindowPropertyAlias4a() {
// TODO(johnlenz): fix this. "self_" should remain.
test(
"var self_; self_ = window.gbar || {};\n" +
"self_.qs = function() {};",
"");
}
public void testNoRemoveWindowPropertyAlias5() {
// TODO(johnlenz): fix this. "self_" should remain.
test(
"var self_ = window || {};\n" +
"self_['qs'] = function() {};",
"");
}
public void testNoRemoveWindowPropertyAlias5a() {
// TODO(johnlenz): fix this.
test(
"var self_; self_ = window || {};\n" +
"self_['qs'] = function() {};",
"");
}
public void testNoRemoveWindowPropertyAlias6() {
testSame(
"var self_ = (window.gbar = window.gbar || {});\n" +
"self_.qs = function() {};");
}
public void testNoRemoveWindowPropertyAlias6a() {
testSame(
"var self_; self_ = (window.gbar = window.gbar || {});\n" +
"self_.qs = function() {};");
}
public void testNoRemoveWindowPropertyAlias7() {
testSame(
"var self_ = (window = window || {});\n" +
"self_['qs'] = function() {};");
}
public void testNoRemoveWindowPropertyAlias7a() {
testSame(
"var self_; self_ = (window = window || {});\n" +
"self_['qs'] = function() {};");
}
public void testNoRemoveAlias0() {
testSame(
"var x = {}; function f() { return x; }; " +
"f().style.display = 'block';" +
"alert(x.style)");
}
public void testNoRemoveAlias1() {
testSame(
"var x = {}; function f() { return x; };" +
"var map = f();\n" +
"map.style.display = 'block';" +
"alert(x.style)");
}
public void testNoRemoveAlias2() {
testSame(
"var x = {};" +
"var map = (function () { return x; })();\n" +
"map.style = 'block';" +
"alert(x.style)");
}
public void testNoRemoveAlias3() {
testSame(
"var x = {}; function f() { return x; };" +
"var map = {}\n" +
"map[1] = f();\n" +
"map[1].style.display = 'block';");
}
public void testNoRemoveAliasOfExternal0() {
testSame(
"document.getElementById('foo').style.display = 'block';");
}
public void testNoRemoveAliasOfExternal1() {
testSame(
"var map = document.getElementById('foo');\n" +
"map.style.display = 'block';");
}
public void testNoRemoveAliasOfExternal2() {
testSame(
"var map = {}\n" +
"map[1] = document.getElementById('foo');\n" +
"map[1].style.display = 'block';");
}
public void testNoRemoveThrowReference1() {
testSame(
"var e = {}\n" +
"throw e;");
}
public void testNoRemoveThrowReference2() {
testSame(
"function e() {}\n" +
"throw new e();");
}
public void testClassDefinedInObjectLit1() {
test(
"var data = {Foo: function() {}};" +
"data.Foo.prototype.toString = function() {};",
"");
}
public void testClassDefinedInObjectLit2() {
test(
"var data = {}; data.bar = {Foo: function() {}};" +
"data.bar.Foo.prototype.toString = function() {};",
"");
}
public void testClassDefinedInObjectLit3() {
test(
"var data = {bar: {Foo: function() {}}};" +
"data.bar.Foo.prototype.toString = function() {};",
"");
}
public void testClassDefinedInObjectLit4() {
test(
"var data = {};" +
"data.baz = {bar: {Foo: function() {}}};" +
"data.baz.bar.Foo.prototype.toString = function() {};",
"");
}
public void testVarReferencedInClassDefinedInObjectLit1() {
testSame(
"var ref = 3;" +
"var data = {Foo: function() { this.x = ref; }};" +
"window.Foo = data.Foo;");
}
public void testVarReferencedInClassDefinedInObjectLit2() {
testSame(
"var ref = 3;" +
"var data = {Foo: function() { this.x = ref; }," +
" Bar: function() {}};" +
"window.Bar = data.Bar;");
}
public void testArrayExt() {
testSame(
"Array.prototype.foo = function() { return 1 };" +
"var y = [];" +
"switch (y.foo()) {" +
"}");
}
public void testArrayAliasExt() {
testSame(
"Array$X = Array;" +
"Array$X.prototype.foo = function() { return 1 };" +
"function Array$X() {}" +
"var y = [];" +
"switch (y.foo()) {" +
"}");
}
public void testExternalAliasInstanceof1() {
test(
"Array$X = Array;" +
"function Array$X() {}" +
"var y = [];" +
"if (y instanceof Array) {}",
"var y = [];" +
"if (y instanceof Array) {}"
);
}
public void testExternalAliasInstanceof2() {
testSame(
"Array$X = Array;" +
"function Array$X() {}" +
"var y = [];" +
"if (y instanceof Array$X) {}");
}
public void testExternalAliasInstanceof3() {
testSame(
"var b = Array;" +
"var y = [];" +
"if (y instanceof b) {}");
}
public void testAliasInstanceof4() {
testSame(
"function Foo() {};" +
"var b = Foo;" +
"var y = new Foo();" +
"if (y instanceof b) {}");
}
public void testAliasInstanceof5() {
// TODO(johnlenz): fix this. "b" should remain.
test(
"function Foo() {}" +
"function Bar() {}" +
"var b = x ? Foo : Bar;" +
"var y = new Foo();" +
"if (y instanceof b) {}",
"function Foo() {}" +
"var y = new Foo;" +
"if (false){}");
}
// We cannot leave x.a.prototype there because it will
// fail sanity var check.
public void testBrokenNamespaceWithPrototypeAssignment() {
test("var x = {}; x.a.prototype = 1", "");
}
public void testRemovePrototypeAliases() {
test(
"function g() {}" +
"function F() {} F.prototype.bar = g;" +
"window.g = g;",
"function g() {}" +
"window.g = g;");
}
public void testIssue284() {
test(
"var goog = {};" +
"goog.inherits = function(x, y) {};" +
"var ns = {};" +
"/** @constructor */" +
"ns.PageSelectionModel = function() {};" +
"/** @constructor */" +
"ns.PageSelectionModel.FooEvent = function() {};" +
"/** @constructor */" +
"ns.PageSelectionModel.SelectEvent = function() {};" +
"goog.inherits(ns.PageSelectionModel.ChangeEvent," +
" ns.PageSelectionModel.FooEvent);",
"");
}
public void testIssue838a() {
testSame("var z = window['z'] || (window['z'] = {});\n" +
"z['hello'] = 'Hello';\n" +
"z['world'] = 'World';");
}
public void testIssue838b() {
testSame(
"var z;" +
"window['z'] = z || (z = {});\n" +
"z['hello'] = 'Hello';\n" +
"z['world'] = 'World';");
}
public void testIssue874a() {
testSame(
"var a = a || {};\n" +
"var b = a;\n" +
"b.View = b.View || {}\n" +
"var c = b.View;\n" +
"c.Editor = function f(d, e) {\n" +
" return d + e\n" +
"};\n" +
"window.ImageEditor.View.Editor = a.View.Editor;");
}
public void testIssue874b() {
testSame(
"var b;\n" +
"var c = b = {};\n" +
"c.Editor = function f(d, e) {\n" +
" return d + e\n" +
"};\n" +
"window['Editor'] = b.Editor;");
}
public void testIssue874c() {
testSame(
"var b, c;\n" +
"c = b = {};\n" +
"c.Editor = function f(d, e) {\n" +
" return d + e\n" +
"};\n" +
"window['Editor'] = b.Editor;");
}
public void testIssue874d() {
testSame(
"var b = {}, c;\n" +
"c = b;\n" +
"c.Editor = function f(d, e) {\n" +
" return d + e\n" +
"};\n" +
"window['Editor'] = b.Editor;");
}
public void testIssue874e() {
testSame(
"var a;\n" +
"var b = a || (a = {});\n" +
"var c = b.View || (b.View = {});\n" +
"c.Editor = function f(d, e) {\n" +
" return d + e\n" +
"};\n" +
"window.ImageEditor.View.Editor = a.View.Editor;");
}
public void testBug6575051() {
testSame(
"var hackhack = window['__o_o_o__'] = window['__o_o_o__'] || {};\n" +
"window['__o_o_o__']['va'] = 1;\n" +
"hackhack['Vb'] = 1;");
}
@Override
protected CompilerPass getProcessor(Compiler compiler) {
return new MarkNoSideEffectCallsAndNameAnalyzerRunner(compiler);
}
private class MarkNoSideEffectCallsAndNameAnalyzerRunner
implements CompilerPass {
MarkNoSideEffectCalls markNoSideEffectCalls;
NameAnalyzer analyzer;
MarkNoSideEffectCallsAndNameAnalyzerRunner(Compiler compiler) {
this.markNoSideEffectCalls = new MarkNoSideEffectCalls(compiler);
this.analyzer = new NameAnalyzer(compiler, true);
}
@Override
public void process(Node externs, Node root) {
markNoSideEffectCalls.process(externs, root);
analyzer.process(externs, root);
}
}
}