blob: 8afb3047a9f7fbbe061f74b426081d2107689ff7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import junit.framework.Test;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression;
import org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral;
import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
/**
* A tests series especially meant to validate the internals of our AST
* implementation.
*/
public class ASTImplTests extends AbstractRegressionTest {
public ASTImplTests(String name) {
super(name);
}
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which does not belong to the class are skipped...
// Only the highest compliance level is run; add the VM argument
// -Dcompliance=1.4 (for example) to lower it if needed
static {
// TESTS_NAMES = new String[] { "test2050" };
// TESTS_NUMBERS = new int[] { 3 };
// TESTS_NUMBERS = new int[] { 2999 };
// TESTS_RANGE = new int[] { 2050, -1 };
}
public static Test suite() {
return buildAllCompliancesTestSuite(testClass());
}
public static Class testClass() {
return ASTImplTests.class;
}
// Helper methods
static Parser defaultParser = new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
new CompilerOptions(),
new DefaultProblemFactory()), false);
public void runConformTest(String fileName, String fileContents,
Parser parser, ASTCollector visitor, String expected) {
CompilationUnit source =
new CompilationUnit(fileContents.toCharArray(), fileName, null);
CompilationResult compilationResult =
new CompilationResult(source, 1, 1, 10);
CompilationUnitDeclaration unit = parser.parse(source, compilationResult);
assertEquals(0, compilationResult.problemCount);
unit.traverse(visitor, unit.scope);
String result = visitor.result();
if (! expected.equals(result)) {
System.out.println(getClass().getName() + '#' + getName());
System.out.println("Expected:");
System.out.println(expected);
System.out.println("But was:");
System.out.println(result);
System.out.println("Cut and paste:");
System.out.println(Util.displayString(result, INDENT, SHIFT));
}
assertEquals(expected, result);
}
// AST implementation - visiting binary expressions
public void test0001_regular_binary_expression() {
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + \"l3\" + s4);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector(),
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v SL \"s3\"]\n" +
"[ev SL \"s3\"]\n" +
"[v SL \"s4\"]\n" +
"[ev SL \"s4\"]\n" +
"[v BE ((((((s1 + \"l1\") + s...) + s4)]\n" +
"[v BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v BE ((s1 + \"l1\") + s2)]\n" +
"[v BE (s1 + \"l1\")]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[v SL \"l1\"]\n" +
"[ev SL \"l1\"]\n" +
"[ev BE (s1 + \"l1\")]\n" +
"[v SNR s2]\n" +
"[ev SNR s2]\n" +
"[ev BE ((s1 + \"l1\") + s2)]\n" +
"[v SL \"l2\"]\n" +
"[ev SL \"l2\"]\n" +
"[ev BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v SNR s3]\n" +
"[ev SNR s3]\n" +
"[ev BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v SL \"l3\"]\n" +
"[ev SL \"l3\"]\n" +
"[ev BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v SNR s4]\n" +
"[ev SNR s4]\n" +
"[ev BE ((((((s1 + \"l1\") + s...) + s4)]\n");
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions
public void test0002_combined_binary_expression() {
CombinedBinaryExpression.defaultArityMaxStartingValue = 3;
// one CBE each fourth BE
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + \"l3\" + s4);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector() {
public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
if (binaryExpression instanceof CombinedBinaryExpression &&
((CombinedBinaryExpression) binaryExpression).
referencesTable != null) {
this.collector.append("[ev CBE " +
cut(binaryExpression.toString()) + "]\n");
} else {
super.endVisit(binaryExpression, scope);
}
}
},
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v SL \"s3\"]\n" +
"[ev SL \"s3\"]\n" +
"[v SL \"s4\"]\n" +
"[ev SL \"s4\"]\n" +
"[v BE ((((((s1 + \"l1\") + s...) + s4)]\n" +
"[v BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v BE ((s1 + \"l1\") + s2)]\n" +
"[v BE (s1 + \"l1\")]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[v SL \"l1\"]\n" +
"[ev SL \"l1\"]\n" +
"[ev BE (s1 + \"l1\")]\n" +
"[v SNR s2]\n" +
"[ev SNR s2]\n" +
"[ev BE ((s1 + \"l1\") + s2)]\n" +
"[v SL \"l2\"]\n" +
"[ev SL \"l2\"]\n" +
"[ev BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v SNR s3]\n" +
"[ev SNR s3]\n" +
"[ev CBE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v SL \"l3\"]\n" +
"[ev SL \"l3\"]\n" +
"[ev BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v SNR s4]\n" +
"[ev SNR s4]\n" +
"[ev BE ((((((s1 + \"l1\") + s...) + s4)]\n");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions
public void test0003_combined_binary_expression() {
Parser parser = new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
new CompilerOptions(),
new DefaultProblemFactory()), true); // optimize string literals
CombinedBinaryExpression.defaultArityMaxStartingValue = 2;
// one CBE each third BE - except the top one, which is degenerate (no
// references table)
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + \"l3\" + s4);\n" +
" }\n" +
"}\n",
parser,
new ASTBinaryExpressionCollector() {
public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
if (binaryExpression instanceof CombinedBinaryExpression &&
((CombinedBinaryExpression) binaryExpression).
referencesTable != null) {
this.collector.append("[ev CBE " +
cut(binaryExpression.toString()) + "]\n");
} else {
super.endVisit(binaryExpression, scope);
}
}
},
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v SL \"s3\"]\n" +
"[ev SL \"s3\"]\n" +
"[v SL \"s4\"]\n" +
"[ev SL \"s4\"]\n" +
"[v BE ((((((s1 + \"l1\") + s...) + s4)]\n" +
"[v BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v BE ((s1 + \"l1\") + s2)]\n" +
"[v BE (s1 + \"l1\")]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[v SL \"l1\"]\n" +
"[ev SL \"l1\"]\n" +
"[ev BE (s1 + \"l1\")]\n" +
"[v SNR s2]\n" +
"[ev SNR s2]\n" +
"[ev BE ((s1 + \"l1\") + s2)]\n" +
"[v SL \"l2\"]\n" +
"[ev SL \"l2\"]\n" +
"[ev CBE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v SNR s3]\n" +
"[ev SNR s3]\n" +
"[ev BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v SL \"l3\"]\n" +
"[ev SL \"l3\"]\n" +
"[ev BE (((((s1 + \"l1\") + s2...+ \"l3\")]\n" +
"[v SNR s4]\n" +
"[ev SNR s4]\n" +
"[ev BE ((((((s1 + \"l1\") + s...) + s4)]\n");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - effect of a literal at the start with
// string literal optimization
public void test0004_combined_binary_expression() {
Parser parser = new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
new CompilerOptions(),
new DefaultProblemFactory()), true); // optimize string literals
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" System.out.println(\"l\" + \"1\" + s1);\n" +
// "l" + "1" is collapsed into "l1" without affecting binary
// expressions: only one BE
" }\n" +
"}\n",
parser,
new ASTBinaryExpressionCollector(),
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v BE (ExtendedStringLiter...} + s1)]\n" +
"[v ESL ExtendedStringLiteral{l1}]\n" +
"[ev ESL ExtendedStringLiteral{l1}]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[ev BE (ExtendedStringLiter...} + s1)]\n");
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - effect of a literal at the start without
// string literals optimization
public void test0005_combined_binary_expression() {
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" System.out.println(\"l\" + \"1\" + s1);\n" +
// "l" + "1" is handled by a string literal concatenation without
// affecting binary expressions: only one BE
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector(),
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v BE (StringLiteralConcat...} + s1)]\n" +
"[v SLC StringLiteralConcate...\n" +
"\"1\"+\n" +
"}]\n" +
"[v SL \"l\"]\n" +
"[ev SL \"l\"]\n" +
"[v SL \"1\"]\n" +
"[ev SL \"1\"]\n" +
"[ev SLC StringLiteralConcate...\n" +
"\"1\"+\n" +
"}]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[ev BE (StringLiteralConcat...} + s1)]\n");
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - cutting the traversal half-way down
public void test0006_combined_binary_expression() {
CombinedBinaryExpression.defaultArityMaxStartingValue = 1;
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + s1 + s4);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector() {
public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
super.visit(binaryExpression, scope);
if (binaryExpression.right instanceof StringLiteral) {
return false;
}
return true;
}
},
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v SL \"s3\"]\n" +
"[ev SL \"s3\"]\n" +
"[v SL \"s4\"]\n" +
"[ev SL \"s4\"]\n" +
"[v BE ((((((s1 + \"l1\") + s...) + s4)]\n" +
"[v BE (((((s1 + \"l1\") + s2...) + s1)]\n" +
"[v BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[ev BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v SNR s3]\n" +
"[ev SNR s3]\n" +
"[ev BE ((((s1 + \"l1\") + s2)...) + s3)]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[ev BE (((((s1 + \"l1\") + s2...) + s1)]\n" +
"[v SNR s4]\n" +
"[ev SNR s4]\n" +
"[ev BE ((((((s1 + \"l1\") + s...) + s4)]\n");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - cutting the traversal right away
public void test0007_combined_binary_expression() {
CombinedBinaryExpression.defaultArityMaxStartingValue = 4;
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + \"l3\" + s4);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector() {
public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
super.visit(binaryExpression, scope);
return false;
}
},
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v SL \"s3\"]\n" +
"[ev SL \"s3\"]\n" +
"[v SL \"s4\"]\n" +
"[ev SL \"s4\"]\n" +
"[v BE ((((((s1 + \"l1\") + s...) + s4)]\n" +
"[ev BE ((((((s1 + \"l1\") + s...) + s4)]\n");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - case of one-deep expression
public void test0008_combined_binary_expression() {
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\");\n" +
" System.out.println(s1 + s2);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTBinaryExpressionCollector() {
public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
if (binaryExpression instanceof CombinedBinaryExpression) {
this.collector.append("[ev CBE " +
cut(binaryExpression.toString()) + "]\n");
} else {
super.endVisit(binaryExpression, scope);
}
}
},
"[v SL \"s1\"]\n" +
"[ev SL \"s1\"]\n" +
"[v SL \"s2\"]\n" +
"[ev SL \"s2\"]\n" +
"[v BE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v BE ((s1 + \"l1\") + s2)]\n" +
"[v BE (s1 + \"l1\")]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[v SL \"l1\"]\n" +
"[ev SL \"l1\"]\n" +
"[ev BE (s1 + \"l1\")]\n" +
"[v SNR s2]\n" +
"[ev SNR s2]\n" +
"[ev BE ((s1 + \"l1\") + s2)]\n" +
"[v SL \"l2\"]\n" +
"[ev SL \"l2\"]\n" +
"[ev CBE (((s1 + \"l1\") + s2) + \"l2\")]\n" +
"[v BE (s1 + s2)]\n" +
"[v SNR s1]\n" +
"[ev SNR s1]\n" +
"[v SNR s2]\n" +
"[ev SNR s2]\n" +
"[ev BE (s1 + s2)]\n");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
public void test0009_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" System.out.println(\n" +
" s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + \n" +
" s[7] + s[8] + s[9] + s[10] + s[11] + s[12] + s[13] +\n" +
" s[14] + s[15] + s[16] + s[17] + s[18] + s[19] + \n" +
" s[20] + s[21] + s[22] + s[23] + s[24] + s[25] + \n" +
" s[26] + s[27] + s[28] + s[29]\n" +
" );\n" +
"}\n" +
"}"},
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
// variant involving constant binary expressions deep in the tree
public void test0010_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" final String c = \"a\";" +
" System.out.println(\n" +
" c + c + c + c + s[4] + s[5] + s[6] + s[7] + s[8] + \n" +
" s[9] + s[10] + s[11] + s[12] + s[13] + s[14] + \n" +
" s[15] + s[16] + s[17] + s[18] + s[19] + s[20] + \n" +
" s[21] + s[22] + s[23] + s[24] + s[25] + s[26] + \n" +
" s[27] + s[28] + s[29]\n" +
" );\n" +
"}\n" +
"}"
},
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
// variant involving a constant combined binary expression
public void test0011_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" final String c = \"a\";" +
" System.out.println(\n" +
" c + c + c + c + c + c + c + c + c + c + \n" +
" c + c + c + c + c + c + c + c + c + c + \n" +
" c + c + s[22] + s[23] + s[24] + s[25] + s[26] + \n" +
" s[27] + s[28] + s[29]\n" +
" );\n" +
"}\n" +
"}"
},
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
// AST implementation - visiting binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - checking recursive print
public void test0012_combined_binary_expression() {
CombinedBinaryExpression.defaultArityMaxStartingValue = 2;
runConformTest(
"X.java",
"public class X {\n" +
" void foo() {\n" +
" String s1 = \"s1\";\n" +
" String s2 = \"s2\";\n" +
" String s3 = \"s3\";\n" +
" String s4 = \"s4\";\n" +
" System.out.println(s1 + \"l1\" + s2 + \"l2\" +\n" +
" s3 + s1 + s4);\n" +
" }\n" +
"}\n",
defaultParser,
new ASTCollector() {
public boolean visit(BinaryExpression binaryExpression,
BlockScope scope) {
super.visit(binaryExpression, scope);
this.collector.append(binaryExpression);
return true;
}
},
"((((((s1 + \"l1\") + s2) + \"l2\") + s3) + s1) + s4)(((((s1 + \"l1\")" +
" + s2) + \"l2\") + s3) + s1)((((s1 + \"l1\") + s2) + \"l2\") + s3)" +
"(((s1 + \"l1\") + s2) + \"l2\")((s1 + \"l1\") + s2)(s1 + \"l1\")");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
// variant involving a left-deep right expression at the topmost level
public void test0013_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" System.out.println(\n" +
" \"b\" + (s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + \n" +
" s[7] + s[8] + s[9] + s[10] + s[11] + s[12] + s[13] +\n" +
" s[14] + s[15] + s[16] + s[17] + s[18] + s[19] + \n" +
" s[20] + s[21] + s[22] + s[23] + s[24] + s[25] + \n" +
" s[26] + s[27] + s[28] + s[29])\n" +
" );\n" +
"}\n" +
"}"
},
"baaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
// variant involving a left-deep right expression at the topmost level, with
// a constant high in tree
public void test0014_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" final String c = \"c\";\n" +
" System.out.println(\n" +
" \"b\" + \n" +
" (c + c + c + c + c + c + c + c + c + c + \n" +
" c + c + c + c + c + c + c + c + c + c + \n" +
" c + c + s[0])\n" +
" );\n" +
"}\n" +
"}"
},
"bcccccccccccccccccccccca");
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// check if the generated code is OK when leveraging CombinedBinaryExpression
// variant involving a left-deep right expression at the topmost level, with
// a constant low in tree
public void test0015_combined_binary_expression() {
assertEquals(20, CombinedBinaryExpression.ARITY_MAX_MIN);
this.runConformTest(
new String[] {
"X.java",
"public class X {\n" +
"public static void main(String args[]) {\n" +
" final int max = 30; \n" +
" String s[] = new String[max];\n" +
" for (int i = 0; i < max; i++) {\n" +
" s[i] = \"a\";\n" +
" }\n" +
" foo(s);\n" +
"}\n" +
"static void foo (String s[]) {\n" +
" final String c = \"c\";\n" +
" System.out.println(\n" +
" \"b\" + \n" +
" (c + c + c + c + c + c + c + c + c + c + \n" +
" c + c + c + c + c + c + c + c + c + c + \n" +
" s[0] + s[1] + s[2])\n" +
" );\n" +
"}\n" +
"}"
},
"bccccccccccccccccccccaaa");
}
// AST implementation - binary expressions
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102728
// Adding combined binary expressions - alternate operands
public void test0016_combined_binary_expression() {
CombinedBinaryExpression.defaultArityMaxStartingValue = 2;
this.runConformTest(
"X.java",
"public class X {\n" +
"void foo(int i1, int i2, int i3, int i4) {\n" +
" System.out.println(i1 - i2 + 0 + i3 + 0 + i4);\n" +
"}\n" +
"}\n",
defaultParser,
new ASTCollector() {
public boolean visit(BinaryExpression binaryExpression,
BlockScope scope) {
super.visit(binaryExpression, scope);
this.collector.append(binaryExpression);
return true;
}
},
"(((((i1 - i2) + 0) + i3) + 0) + i4)((((i1 - i2) + 0) + i3) + 0)" +
"(((i1 - i2) + 0) + i3)((i1 - i2) + 0)(i1 - i2)");
CombinedBinaryExpression.defaultArityMaxStartingValue =
CombinedBinaryExpression.ARITY_MAX_MIN;
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=157170
public void test0017() {
CompilerOptions options = new CompilerOptions();
options.complianceLevel = ClassFileConstants.JDK1_5;
options.sourceLevel = ClassFileConstants.JDK1_5;
options.targetJDK = ClassFileConstants.JDK1_5;
this.runConformTest(
"X.java",
"@interface Annot {\n" +
" int value() default 0;\n" +
"}\n" +
"@Annot\n" +
"@Annot(3)\n" +
"@Annot(value=4)\n" +
"public class X {\n" +
"}\n",
new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
options,
new DefaultProblemFactory()), false),
new AnnotationCollector(),
"marker annotation start visit\n" +
"marker annotation end visit\n" +
"single member annotation start visit\n" +
"3\n" +
"single member annotation end visit\n" +
"normal annotation start visit\n" +
"member value pair start visit\n" +
"value, 4\n" +
"member value pair end visit\n" +
"normal annotation end visit\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=157170
public void test0018() {
CompilerOptions options = new CompilerOptions();
options.complianceLevel = ClassFileConstants.JDK1_5;
options.sourceLevel = ClassFileConstants.JDK1_5;
options.targetJDK = ClassFileConstants.JDK1_5;
options.docCommentSupport = true;
this.runConformTest(
"X.java",
"@interface Annot {\n" +
" int value() default 0;\n" +
"}\n" +
"/**\n" +
" * @see Annot\n" +
" */\n" +
"@Annot\n" +
"@Annot(3)\n" +
"@Annot(value=4)\n" +
"public class X {\n" +
" /**\n" +
" * @see Annot\n" +
" */\n" +
" public void foo() {}\n" +
"}\n",
new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
options,
new DefaultProblemFactory()), false),
new AnnotationCollector(),
"java doc single type reference start visit\n" +
"java doc single type reference end visit\n" +
"marker annotation start visit\n" +
"marker annotation end visit\n" +
"single member annotation start visit\n" +
"3\n" +
"single member annotation end visit\n" +
"normal annotation start visit\n" +
"member value pair start visit\n" +
"value, 4\n" +
"member value pair end visit\n" +
"normal annotation end visit\n" +
"java doc single type reference start visit\n" +
"java doc single type reference end visit\n");
}
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=157170
public void test0019() {
CompilerOptions options = new CompilerOptions();
options.complianceLevel = ClassFileConstants.JDK1_5;
options.sourceLevel = ClassFileConstants.JDK1_5;
options.targetJDK = ClassFileConstants.JDK1_5;
options.docCommentSupport = true;
this.runConformTest(
"X.java",
"@interface Annot {\n" +
" int value() default 0;\n" +
"}\n" +
"/**\n" +
" * @see Annot\n" +
" */\n" +
"@Annot\n" +
"@Annot(3)\n" +
"@Annot(value=4)\n" +
"public class X {\n" +
" /**\n" +
" * @see Annot\n" +
" */\n" +
" public void foo(@Annot int i) {\n" +
" @Annot int j = 0;" +
" }\n" +
"}\n",
new Parser(
new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(),
options,
new DefaultProblemFactory()), false),
new AnnotationCollector(),
"java doc single type reference start visit\n" +
"java doc single type reference end visit\n" +
"marker annotation start visit\n" +
"marker annotation end visit\n" +
"single member annotation start visit\n" +
"3\n" +
"single member annotation end visit\n" +
"normal annotation start visit\n" +
"member value pair start visit\n" +
"value, 4\n" +
"member value pair end visit\n" +
"normal annotation end visit\n" +
"java doc single type reference start visit\n" +
"java doc single type reference end visit\n" +
"start argument\n" +
"marker annotation start visit\n" +
"marker annotation end visit\n" +
"exit argument\n" +
"start local declaration\n" +
"marker annotation start visit\n" +
"marker annotation end visit\n" +
"exit local declaration\n");
}
}
// Helper classes: define visitors leveraged by some tests
class ASTCollector extends ASTVisitor {
StringBuffer collector = new StringBuffer();
public String result() {
return this.collector.toString();
}
}
class ASTBinaryExpressionCollector extends ASTCollector {
static final int LIMIT = 30;
// help limit the output in length by suppressing the middle
// part of strings which length exceeds LIMIT
String cut(String source) {
int length;
if ((length = source.length()) > LIMIT) {
StringBuffer result = new StringBuffer(length);
result.append(source.substring(0, LIMIT - 10));
result.append("...");
result.append(source.substring(length - 7, length));
return result.toString();
} else {
return source;
}
}
public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
this.collector.append("[ev BE " + cut(binaryExpression.toString()) + "]\n");
super.endVisit(binaryExpression, scope);
}
public void endVisit(CharLiteral charLiteral, BlockScope scope) {
this.collector.append("[ev CL " + cut(charLiteral.toString()) + "]\n");
super.endVisit(charLiteral, scope);
}
public void endVisit(ExtendedStringLiteral literal, BlockScope scope) {
this.collector.append("[ev ESL " + cut(literal.toString()) + "]\n");
super.endVisit(literal, scope);
}
public void endVisit(SingleNameReference singleNameReference,
BlockScope scope) {
this.collector.append("[ev SNR " + cut(singleNameReference.toString()) +
"]\n");
super.endVisit(singleNameReference, scope);
}
public void endVisit(StringLiteral stringLiteral, BlockScope scope) {
this.collector.append("[ev SL " + cut(stringLiteral.toString()) + "]\n");
super.endVisit(stringLiteral, scope);
}
public void endVisit(StringLiteralConcatenation literal, BlockScope scope) {
this.collector.append("[ev SLC " + cut(literal.toString()) + "]\n");
super.endVisit(literal, scope);
}
public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
this.collector.append("[v BE " + cut(binaryExpression.toString()) + "]\n");
return super.visit(binaryExpression, scope);
}
public boolean visit(CharLiteral charLiteral, BlockScope scope) {
this.collector.append("[v CL " + cut(charLiteral.toString()) + "]\n");
return super.visit(charLiteral, scope);
}
public boolean visit(ExtendedStringLiteral literal, BlockScope scope) {
this.collector.append("[v ESL " + cut(literal.toString()) + "]\n");
return super.visit(literal, scope);
}
public boolean visit(SingleNameReference singleNameReference,
BlockScope scope) {
this.collector.append("[v SNR " + cut(singleNameReference.toString()) +
"]\n");
return super.visit(singleNameReference, scope);
}
public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
this.collector.append("[v SL " + cut(stringLiteral.toString()) + "]\n");
return super.visit(stringLiteral, scope);
}
public boolean visit(StringLiteralConcatenation literal, BlockScope scope) {
this.collector.append("[v SLC " + cut(literal.toString()) + "]\n");
return super.visit(literal, scope);
}
}
class AnnotationCollector extends ASTCollector {
public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
this.collector.append("marker annotation start visit\n");
return true;
}
public void endVisit(MarkerAnnotation annotation, BlockScope scope) {
this.collector.append("marker annotation end visit\n");
}
public boolean visit(NormalAnnotation annotation, BlockScope scope) {
this.collector.append("normal annotation start visit\n");
return true;
}
public void endVisit(NormalAnnotation annotation, BlockScope scope) {
this.collector.append("normal annotation end visit\n");
}
public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
this.collector.append("single member annotation start visit\n");
this.collector.append(annotation.memberValue.toString());
this.collector.append("\n");
return true;
}
public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) {
this.collector.append("single member annotation end visit\n");
}
public void endVisit(JavadocSingleTypeReference typeRef, BlockScope scope) {
this.collector.append("java doc single type reference end visit\n");
}
public void endVisit(JavadocSingleTypeReference typeRef, ClassScope scope) {
this.collector.append("java doc single type reference end visit\n");
}
public boolean visit(JavadocSingleTypeReference typeRef, BlockScope scope) {
this.collector.append("java doc single type reference start visit\n");
return true;
}
public boolean visit(JavadocSingleTypeReference typeRef, ClassScope scope) {
this.collector.append("java doc single type reference start visit\n");
return true;
}
public boolean visit(MemberValuePair pair, BlockScope scope) {
this.collector.append("member value pair start visit\n");
this.collector.append(pair.name);
this.collector.append(", ");
this.collector.append(pair.value.toString());
this.collector.append("\n");
return true;
}
public void endVisit(MemberValuePair pair, BlockScope scope) {
this.collector.append("member value pair end visit\n");
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#endVisit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
*/
public void endVisit(Argument argument, BlockScope scope) {
this.collector.append("exit argument\n");
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#endVisit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
*/
public void endVisit(Argument argument, ClassScope scope) {
this.collector.append("exit argument\n");
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#endVisit(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
*/
public void endVisit(LocalDeclaration localDeclaration, BlockScope scope) {
this.collector.append("exit local declaration\n");
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
*/
public boolean visit(Argument argument, BlockScope scope) {
this.collector.append("start argument\n");
return true;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
*/
public boolean visit(Argument argument, ClassScope scope) {
this.collector.append("start argument\n");
return true;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
*/
public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
this.collector.append("start local declaration\n");
return true;
}
}