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/PeepholeReplaceKnownMethodsTest.java

322 lines
11 KiB
Java
Raw Permalink Normal View History

2023-04-25 11:33:41 +00:00
/*
* Copyright 2011 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;
/**
* Unit tests for {#link {@link PeepholeReplaceKnownMethods}
*
*/
public class PeepholeReplaceKnownMethodsTest extends CompilerTestCase {
private boolean late = true;
public PeepholeReplaceKnownMethodsTest() {
super("");
}
@Override
public void setUp() {
enableLineNumberCheck(true);
}
@Override
public CompilerPass getProcessor(final Compiler compiler) {
CompilerPass peepholePass = new PeepholeOptimizationsPass(compiler,
new PeepholeReplaceKnownMethods(late));
return peepholePass;
}
public void testStringIndexOf() {
fold("x = 'abcdef'.indexOf('b')", "x = 1");
fold("x = 'abcdefbe'.indexOf('b', 2)", "x = 6");
fold("x = 'abcdef'.indexOf('bcd')", "x = 1");
fold("x = 'abcdefsdfasdfbcdassd'.indexOf('bcd', 4)", "x = 13");
fold("x = 'abcdef'.lastIndexOf('b')", "x = 1");
fold("x = 'abcdefbe'.lastIndexOf('b')", "x = 6");
fold("x = 'abcdefbe'.lastIndexOf('b', 5)", "x = 1");
// Both elements must be strings. Don't do anything if either one is not
// string.
fold("x = 'abc1def'.indexOf(1)", "x = 3");
fold("x = 'abcNaNdef'.indexOf(NaN)", "x = 3");
fold("x = 'abcundefineddef'.indexOf(undefined)", "x = 3");
fold("x = 'abcnulldef'.indexOf(null)", "x = 3");
fold("x = 'abctruedef'.indexOf(true)", "x = 3");
// The following test case fails with JSC_PARSE_ERROR. Hence omitted.
// foldSame("x = 1.indexOf('bcd');");
foldSame("x = NaN.indexOf('bcd')");
foldSame("x = undefined.indexOf('bcd')");
foldSame("x = null.indexOf('bcd')");
foldSame("x = true.indexOf('bcd')");
foldSame("x = false.indexOf('bcd')");
// Avoid dealing with regex or other types.
foldSame("x = 'abcdef'.indexOf(/b./)");
foldSame("x = 'abcdef'.indexOf({a:2})");
foldSame("x = 'abcdef'.indexOf([1,2])");
}
public void testStringJoinAddSparse() {
fold("x = [,,'a'].join(',')", "x = ',,a'");
}
public void testNoStringJoin() {
foldSame("x = [].join(',',2)");
foldSame("x = [].join(f)");
}
public void testStringJoinAdd() {
fold("x = ['a', 'b', 'c'].join('')", "x = \"abc\"");
fold("x = [].join(',')", "x = \"\"");
fold("x = ['a'].join(',')", "x = \"a\"");
fold("x = ['a', 'b', 'c'].join(',')", "x = \"a,b,c\"");
fold("x = ['a', foo, 'b', 'c'].join(',')",
"x = [\"a\",foo,\"b,c\"].join()");
fold("x = [foo, 'a', 'b', 'c'].join(',')",
"x = [foo,\"a,b,c\"].join()");
fold("x = ['a', 'b', 'c', foo].join(',')",
"x = [\"a,b,c\",foo].join()");
// Works with numbers
fold("x = ['a=', 5].join('')", "x = \"a=5\"");
fold("x = ['a', '5'].join(7)", "x = \"a75\"");
// Works on boolean
fold("x = ['a=', false].join('')", "x = \"a=false\"");
fold("x = ['a', '5'].join(true)", "x = \"atrue5\"");
fold("x = ['a', '5'].join(false)", "x = \"afalse5\"");
// Only optimize if it's a size win.
fold("x = ['a', '5', 'c'].join('a very very very long chain')",
"x = [\"a\",\"5\",\"c\"].join(\"a very very very long chain\")");
// TODO(user): Its possible to fold this better.
foldSame("x = ['', foo].join('-')");
foldSame("x = ['', foo, ''].join()");
fold("x = ['', '', foo, ''].join(',')",
"x = [',', foo, ''].join()");
fold("x = ['', '', foo, '', ''].join(',')",
"x = [',', foo, ','].join()");
fold("x = ['', '', foo, '', '', bar].join(',')",
"x = [',', foo, ',', bar].join()");
fold("x = [1,2,3].join('abcdef')",
"x = '1abcdef2abcdef3'");
fold("x = [1,2].join()", "x = '1,2'");
fold("x = [null,undefined,''].join(',')", "x = ',,'");
fold("x = [null,undefined,0].join(',')", "x = ',,0'");
// This can be folded but we don't currently.
foldSame("x = [[1,2],[3,4]].join()"); // would like: "x = '1,2,3,4'"
}
public void testStringJoinAdd_b1992789() {
fold("x = ['a'].join('')", "x = \"a\"");
fold("x = [foo()].join('')", "x = '' + foo()");
fold("[foo()].join('')", "'' + foo()");
}
public void testFoldStringSubstr() {
fold("x = 'abcde'.substr(0,2)", "x = 'ab'");
fold("x = 'abcde'.substr(1,2)", "x = 'bc'");
fold("x = 'abcde'['substr'](1,3)", "x = 'bcd'");
fold("x = 'abcde'.substr(2)", "x = 'cde'");
// we should be leaving negative indexes alone for now
foldSame("x = 'abcde'.substr(-1)");
foldSame("x = 'abcde'.substr(1, -2)");
foldSame("x = 'abcde'.substr(1, 2, 3)");
foldSame("x = 'a'.substr(0, 2)");
}
public void testFoldStringSubstring() {
fold("x = 'abcde'.substring(0,2)", "x = 'ab'");
fold("x = 'abcde'.substring(1,2)", "x = 'b'");
fold("x = 'abcde'['substring'](1,3)", "x = 'bc'");
fold("x = 'abcde'.substring(2)", "x = 'cde'");
// we should be leaving negative indexes alone for now
foldSame("x = 'abcde'.substring(-1)");
foldSame("x = 'abcde'.substring(1, -2)");
foldSame("x = 'abcde'.substring(1, 2, 3)");
foldSame("x = 'a'.substring(0, 2)");
}
public void testFoldStringCharAt() {
fold("x = 'abcde'.charAt(0)", "x = 'a'");
fold("x = 'abcde'.charAt(1)", "x = 'b'");
fold("x = 'abcde'.charAt(2)", "x = 'c'");
fold("x = 'abcde'.charAt(3)", "x = 'd'");
fold("x = 'abcde'.charAt(4)", "x = 'e'");
foldSame("x = 'abcde'.charAt(5)"); // or x = ''
foldSame("x = 'abcde'.charAt(-1)"); // or x = ''
foldSame("x = 'abcde'.charAt(y)");
foldSame("x = 'abcde'.charAt()"); // or x = 'a'
foldSame("x = 'abcde'.charAt(0, ++z)"); // or (++z, 'a')
foldSame("x = 'abcde'.charAt(null)"); // or x = 'a'
foldSame("x = 'abcde'.charAt(true)"); // or x = 'b'
fold("x = '\\ud834\udd1e'.charAt(0)", "x = '\\ud834'");
fold("x = '\\ud834\udd1e'.charAt(1)", "x = '\\udd1e'");
}
public void testFoldStringCharCodeAt() {
fold("x = 'abcde'.charCodeAt(0)", "x = 97");
fold("x = 'abcde'.charCodeAt(1)", "x = 98");
fold("x = 'abcde'.charCodeAt(2)", "x = 99");
fold("x = 'abcde'.charCodeAt(3)", "x = 100");
fold("x = 'abcde'.charCodeAt(4)", "x = 101");
foldSame("x = 'abcde'.charCodeAt(5)"); // or x = (0/0)
foldSame("x = 'abcde'.charCodeAt(-1)"); // or x = (0/0)
foldSame("x = 'abcde'.charCodeAt(y)");
foldSame("x = 'abcde'.charCodeAt()"); // or x = 97
foldSame("x = 'abcde'.charCodeAt(0, ++z)"); // or (++z, 97)
foldSame("x = 'abcde'.charCodeAt(null)"); // or x = 97
foldSame("x = 'abcde'.charCodeAt(true)"); // or x = 98
fold("x = '\\ud834\udd1e'.charCodeAt(0)", "x = 55348");
fold("x = '\\ud834\udd1e'.charCodeAt(1)", "x = 56606");
}
public void testFoldStringSplit() {
late = false;
fold("x = 'abcde'.split('foo')", "x = ['abcde']");
fold("x = 'abcde'.split()", "x = ['abcde']");
fold("x = 'abcde'.split(null)", "x = ['abcde']");
fold("x = 'a b c d e'.split(' ')", "x = ['a','b','c','d','e']");
fold("x = 'a b c d e'.split(' ', 0)", "x = []");
fold("x = 'abcde'.split('cd')", "x = ['ab','e']");
fold("x = 'a b c d e'.split(' ', 1)", "x = ['a']");
fold("x = 'a b c d e'.split(' ', 3)", "x = ['a','b','c']");
fold("x = 'a b c d e'.split(null, 1)", "x = ['a b c d e']");
fold("x = 'aaaaa'.split('a')", "x = ['', '', '', '', '', '']");
fold("x = 'xyx'.split('x')", "x = ['', 'y', '']");
// Empty separator
fold("x = 'abcde'.split('')", "x = ['a','b','c','d','e']");
fold("x = 'abcde'.split('', 3)", "x = ['a','b','c']");
// Empty separator AND empty string
fold("x = ''.split('')", "x = []");
// Separator equals string
fold("x = 'aaa'.split('aaa')", "x = ['','']");
fold("x = ' '.split(' ')", "x = ['','']");
foldSame("x = 'abcde'.split(/ /)");
foldSame("x = 'abcde'.split(' ', -1)");
late = true;
foldSame("x = 'a b c d e'.split(' ')");
}
public void testJoinBug() {
fold("var x = [].join();", "var x = '';");
fold("var x = [x].join();", "var x = '' + x;");
foldSame("var x = [x,y].join();");
foldSame("var x = [x,y,z].join();");
foldSame("shape['matrix'] = [\n" +
" Number(headingCos2).toFixed(4),\n" +
" Number(-headingSin2).toFixed(4),\n" +
" Number(headingSin2 * yScale).toFixed(4),\n" +
" Number(headingCos2 * yScale).toFixed(4),\n" +
" 0,\n" +
" 0\n" +
" ].join()");
}
public void testToUpper() {
fold("'a'.toUpperCase()", "'A'");
fold("'A'.toUpperCase()", "'A'");
fold("'aBcDe'.toUpperCase()", "'ABCDE'");
}
public void testToLower() {
fold("'A'.toLowerCase()", "'a'");
fold("'a'.toLowerCase()", "'a'");
fold("'aBcDe'.toLowerCase()", "'abcde'");
}
public void testFoldParseNumbers() {
enableNormalize();
enableEcmaScript5(true);
fold("x = parseInt('123')", "x = 123");
fold("x = parseInt(' 123')", "x = 123");
fold("x = parseInt('123', 10)", "x = 123");
fold("x = parseInt('0xA')", "x = 10");
fold("x = parseInt('0xA', 16)", "x = 10");
fold("x = parseInt('07', 8)", "x = 7");
fold("x = parseInt('08')", "x = 8");
fold("x = parseInt('0')", "x = 0");
fold("x = parseFloat('0')", "x = 0");
fold("x = parseFloat('1.23')", "x = 1.23");
fold("x = parseFloat('1.2300')", "x = 1.23");
fold("x = parseFloat(' 0.3333')", "x = 0.3333");
fold("x = parseFloat('0100')", "x = 100");
fold("x = parseFloat('0100.000')", "x = 100");
//Mozilla Dev Center test cases
fold("x = parseInt(' 0xF', 16)", "x = 15");
fold("x = parseInt(' F', 16)", "x = 15");
fold("x = parseInt('17', 8)", "x = 15");
fold("x = parseInt('015', 10)", "x = 15");
fold("x = parseInt('1111', 2)", "x = 15");
fold("x = parseInt('12', 13)", "x = 15");
fold("x = parseInt(021, 8)", "x = 15");
fold("x = parseInt(15.99, 10)", "x = 15");
fold("x = parseFloat('3.14')", "x = 3.14");
fold("x = parseFloat(3.14)", "x = 3.14");
//Valid calls - unable to fold
foldSame("x = parseInt('FXX123', 16)");
foldSame("x = parseInt('15*3', 10)");
foldSame("x = parseInt('15e2', 10)");
foldSame("x = parseInt('15px', 10)");
foldSame("x = parseInt('-0x08')");
foldSame("x = parseInt('1', -1)");
foldSame("x = parseFloat('3.14more non-digit characters')");
foldSame("x = parseFloat('314e-2')");
foldSame("x = parseFloat('0.0314E+2')");
foldSame("x = parseFloat('3.333333333333333333333333')");
//Invalid calls
foldSame("x = parseInt('0xa', 10)");
foldSame("x = parseInt('')");
enableEcmaScript5(false);
foldSame("x = parseInt('08')");
}
@Override
protected int getNumRepetitions() {
// Reduce this to 2 if we get better expression evaluators.
return 2;
}
private void foldSame(String js) {
testSame(js);
}
private void fold(String js, String expected) {
test(js, expected);
}
}