/* * Copyright 2004 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; /** * Ensures that the InlineVariables pass in constants-only mode * is functionally equivalent to the old InlineVariablesConstants pass. */ public class InlineVariablesConstantsTest extends CompilerTestCase { private boolean inlineAllStrings = false; public InlineVariablesConstantsTest() { enableNormalize(); } @Override protected CompilerPass getProcessor(final Compiler compiler) { return new InlineVariables( compiler, InlineVariables.Mode.CONSTANTS_ONLY, inlineAllStrings); } @Override public void tearDown() { inlineAllStrings = false; } public void testInlineVariablesConstants() { test("var ABC=2; var x = ABC;", "var x=2"); test("var AA = 'aa'; AA;", "'aa'"); test("var A_A=10; A_A + A_A;", "10+10"); test("var AA=1", ""); test("var AA; AA=1", "1"); test("var AA; if (false) AA=1; AA;", "if (false) 1; 1;"); testSame("var AA; if (false) AA=1; else AA=2; AA;"); test("var AA;(function () {AA=1})()", "(function () {1})()"); // Make sure that nothing explodes if there are undeclared variables. testSame("var x = AA;"); // Don't inline if it will make the output larger. testSame("var AA = '1234567890'; foo(AA); foo(AA); foo(AA);"); test("var AA = '123456789012345';AA;", "'123456789012345'"); } public void testNoInlineArraysOrRegexps() { testSame("var AA = [10,20]; AA[0]"); testSame("var AA = [10,20]; AA.push(1); AA[0]"); testSame("var AA = /x/; AA.test('1')"); testSame("/** @const */ var aa = /x/; aa.test('1')"); } public void testInlineVariablesConstantsJsDocStyle() { test("/** @const */var abc=2; var x = abc;", "var x=2"); test("/** @const */var aa = 'aa'; aa;", "'aa'"); test("/** @const */var a_a=10; a_a + a_a;", "10+10"); test("/** @const */var aa=1;", ""); test("/** @const */var aa; aa=1;", "1"); test("/** @const */var aa;(function () {aa=1})()", "(function () {1})()"); test("/** @const */var aa;(function () {aa=1})(); var z=aa", "(function () {1})(); var z=1"); testSame("/** @const */var aa;(function () {var y; aa=y})(); var z=aa"); // Don't inline if it will make the output larger. testSame("/** @const */var aa = '1234567890'; foo(aa); foo(aa); foo(aa);"); test("/** @const */var aa = '123456789012345';aa;", "'123456789012345'"); } public void testInlineConditionallyDefinedConstant1() { // Note that inlining conditionally defined constants can change the // run-time behavior of code (e.g. when y is true and x is false in the // example below). We inline them anyway because if the code author didn't // want one inlined, he/she could define it as a non-const variable instead. test("if (x) var ABC = 2; if (y) f(ABC);", "if (x); if (y) f(2);"); } public void testInlineConditionallyDefinedConstant2() { test("if (x); else var ABC = 2; if (y) f(ABC);", "if (x); else; if (y) f(2);"); } public void testInlineConditionallyDefinedConstant3() { test("if (x) { var ABC = 2; } if (y) { f(ABC); }", "if (x) {} if (y) { f(2); }"); } public void testInlineDefinedConstant() { test( "/**\n" + " * @define {string}\n" + " */\n" + "var aa = '1234567890';\n" + "foo(aa); foo(aa); foo(aa);", "foo('1234567890');foo('1234567890');foo('1234567890')"); test( "/**\n" + " * @define {string}\n" + " */\n" + "var ABC = '1234567890';\n" + "foo(ABC); foo(ABC); foo(ABC);", "foo('1234567890');foo('1234567890');foo('1234567890')"); } public void testInlineVariablesConstantsWithInlineAllStringsOn() { inlineAllStrings = true; test("var AA = '1234567890'; foo(AA); foo(AA); foo(AA);", "foo('1234567890'); foo('1234567890'); foo('1234567890')"); } public void testNoInlineWithoutConstDeclaration() { testSame("var abc = 2; var x = abc;"); } // TODO(nicksantos): enable this again once we allow constant aliasing. // public void testInlineConstantAlias() { // test("var XXX = new Foo(); var YYY = XXX; bar(YYY)", // "var XXX = new Foo(); bar(XXX)"); // } public void testNoInlineAliases() { testSame("var XXX = new Foo(); var yyy = XXX; bar(yyy)"); testSame("var xxx = new Foo(); var YYY = xxx; bar(YYY)"); } }