188 lines
6.3 KiB
Java
188 lines
6.3 KiB
Java
|
/*
|
||
|
* Copyright 2008 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;
|
||
|
|
||
|
/**
|
||
|
* Tests for {@link AliasKeywords}.
|
||
|
*
|
||
|
*/
|
||
|
public class AliasKeywordsTest extends CompilerTestCase {
|
||
|
private static final int ENOUGH_TO_ALIAS_LITERAL
|
||
|
= AliasKeywords.MIN_OCCURRENCES_REQUIRED_TO_ALIAS_LITERAL;
|
||
|
private static final int TOO_FEW_TO_ALIAS_LITERAL
|
||
|
= ENOUGH_TO_ALIAS_LITERAL - 1;
|
||
|
|
||
|
private static final int ENOUGH_TO_ALIAS_THROW
|
||
|
= AliasKeywords.MIN_OCCURRENCES_REQUIRED_TO_ALIAS_THROW;
|
||
|
private static final int TOO_FEW_TO_ALIAS_THROW
|
||
|
= ENOUGH_TO_ALIAS_THROW - 1;
|
||
|
|
||
|
@Override
|
||
|
public void setUp() {
|
||
|
super.enableLineNumberCheck(false);
|
||
|
super.enableNormalize();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public CompilerPass getProcessor(Compiler compiler) {
|
||
|
return new AliasKeywords(compiler);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected int getNumRepetitions() {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate code of the form 'if (<keyword>);' repeated numReps
|
||
|
* times, with prepend prepended.
|
||
|
*
|
||
|
* For example, generateCode("true", 2, "var a=b;") generates
|
||
|
* <code>var a=b;if (true);if (true);</code>
|
||
|
*/
|
||
|
private static String generateCode(
|
||
|
String keyword, int numReps, String prepend) {
|
||
|
StringBuilder sb = new StringBuilder(prepend);
|
||
|
for (int i = 0; i < numReps; i++) {
|
||
|
sb.append("if (");
|
||
|
sb.append(keyword);
|
||
|
sb.append(");");
|
||
|
}
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
private static String generateCode(String keyword, int numReps) {
|
||
|
return generateCode(keyword, numReps, "");
|
||
|
}
|
||
|
|
||
|
private static String generatePreProcessThrowCode(int repititions,
|
||
|
String whatToThrow) {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
for (int i = 0; i < repititions; i++) {
|
||
|
sb.append("throw ");
|
||
|
sb.append(whatToThrow);
|
||
|
sb.append(";");
|
||
|
}
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
private static String generatePostProcessThrowCode(
|
||
|
int repetitions, String code, String whatToThrow) {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.append("function ");
|
||
|
sb.append(AliasKeywords.ALIAS_THROW);
|
||
|
sb.append("(jscomp_throw_param){throw jscomp_throw_param;}");
|
||
|
sb.append(code);
|
||
|
for (int i = 0; i < repetitions; i++) {
|
||
|
sb.append(AliasKeywords.ALIAS_THROW);
|
||
|
sb.append("(");
|
||
|
sb.append(whatToThrow);
|
||
|
sb.append(");");
|
||
|
}
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Don't generate aliases if the keyword is not referenced enough.
|
||
|
*/
|
||
|
public void testDontAlias() {
|
||
|
testSame(generateCode("true", TOO_FEW_TO_ALIAS_LITERAL));
|
||
|
testSame(generateCode("false", TOO_FEW_TO_ALIAS_LITERAL));
|
||
|
testSame(generateCode("null", TOO_FEW_TO_ALIAS_LITERAL));
|
||
|
testSame(generateCode("void 0", TOO_FEW_TO_ALIAS_LITERAL));
|
||
|
testSame(generatePreProcessThrowCode(TOO_FEW_TO_ALIAS_THROW, "1"));
|
||
|
|
||
|
// Don't alias void nodes other than "void 0".
|
||
|
testSame(generateCode("void 1", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
testSame(generateCode("void x", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
testSame(generateCode("void f()", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate aliases if the keyword is referenced >= ENOUGH_TO_ALIAS
|
||
|
* times.
|
||
|
*/
|
||
|
public void testAlias() {
|
||
|
test(generateCode("true", ENOUGH_TO_ALIAS_LITERAL),
|
||
|
generateCode(AliasKeywords.ALIAS_TRUE, ENOUGH_TO_ALIAS_LITERAL,
|
||
|
"var JSCompiler_alias_TRUE=true;"));
|
||
|
|
||
|
test(generateCode("false", ENOUGH_TO_ALIAS_LITERAL),
|
||
|
generateCode(AliasKeywords.ALIAS_FALSE, ENOUGH_TO_ALIAS_LITERAL,
|
||
|
"var JSCompiler_alias_FALSE=false;"));
|
||
|
|
||
|
test(generateCode("null", ENOUGH_TO_ALIAS_LITERAL),
|
||
|
generateCode(AliasKeywords.ALIAS_NULL, ENOUGH_TO_ALIAS_LITERAL,
|
||
|
"var JSCompiler_alias_NULL=null;"));
|
||
|
|
||
|
test(generateCode("void 0", ENOUGH_TO_ALIAS_LITERAL),
|
||
|
generateCode(AliasKeywords.ALIAS_VOID, ENOUGH_TO_ALIAS_LITERAL,
|
||
|
"var JSCompiler_alias_VOID=void 0;"));
|
||
|
|
||
|
test(generatePreProcessThrowCode(ENOUGH_TO_ALIAS_THROW, "1"),
|
||
|
generatePostProcessThrowCode(ENOUGH_TO_ALIAS_THROW, "", "1"));
|
||
|
}
|
||
|
|
||
|
public void testAliasTrueFalseNull() {
|
||
|
StringBuilder actual = new StringBuilder();
|
||
|
actual.append(generateCode("true", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
actual.append(generateCode("false", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
actual.append(generateCode("null", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
actual.append(generateCode("void 0", ENOUGH_TO_ALIAS_LITERAL));
|
||
|
|
||
|
StringBuilder expected = new StringBuilder();
|
||
|
expected.append(
|
||
|
"var JSCompiler_alias_VOID=void 0;" +
|
||
|
"var JSCompiler_alias_TRUE=true;" +
|
||
|
"var JSCompiler_alias_NULL=null;" +
|
||
|
"var JSCompiler_alias_FALSE=false;");
|
||
|
expected.append(
|
||
|
generateCode(AliasKeywords.ALIAS_TRUE, ENOUGH_TO_ALIAS_LITERAL));
|
||
|
expected.append(
|
||
|
generateCode(AliasKeywords.ALIAS_FALSE, ENOUGH_TO_ALIAS_LITERAL));
|
||
|
expected.append(
|
||
|
generateCode(AliasKeywords.ALIAS_NULL, ENOUGH_TO_ALIAS_LITERAL));
|
||
|
expected.append(
|
||
|
generateCode(AliasKeywords.ALIAS_VOID, ENOUGH_TO_ALIAS_LITERAL));
|
||
|
|
||
|
test(actual.toString(), expected.toString());
|
||
|
}
|
||
|
|
||
|
public void testAliasThrowKeywordLiteral() {
|
||
|
int repitions = Math.max(ENOUGH_TO_ALIAS_THROW, ENOUGH_TO_ALIAS_LITERAL);
|
||
|
String afterCode = generatePostProcessThrowCode(
|
||
|
repitions, "var JSCompiler_alias_TRUE=true;",
|
||
|
AliasKeywords.ALIAS_TRUE);
|
||
|
test(generatePreProcessThrowCode(repitions, "true"), afterCode);
|
||
|
}
|
||
|
|
||
|
public void testExistingAliasDefinitionFails() {
|
||
|
try {
|
||
|
testSame("var JSCompiler_alias_TRUE='foo';");
|
||
|
fail();
|
||
|
} catch (RuntimeException expected) {
|
||
|
// expected exception
|
||
|
assertTrue(-1 != expected.getMessage().indexOf(
|
||
|
"Existing alias definition"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void testWithNoInputs() {
|
||
|
testSame(new String[] {});
|
||
|
}
|
||
|
}
|