/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.typeresolution;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.io.IOUtils;
import org.jaxen.JaxenException;
import org.junit.Assert;
import org.junit.Test;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.JavaLanguageModule;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
import net.sourceforge.pmd.lang.java.ast.ASTStatementExpression;
import net.sourceforge.pmd.lang.java.ast.ASTType;
import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.ast.TypeNode;
import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
import net.sourceforge.pmd.lang.java.typeresolution.ClassTypeResolver;
import net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass;
import net.sourceforge.pmd.typeresolution.testdata.ArrayListFound;
import net.sourceforge.pmd.typeresolution.testdata.DefaultJavaLangImport;
import net.sourceforge.pmd.typeresolution.testdata.EnumWithAnonymousInnerClass;
import net.sourceforge.pmd.typeresolution.testdata.ExtraTopLevelClass;
import net.sourceforge.pmd.typeresolution.testdata.InnerClass;
import net.sourceforge.pmd.typeresolution.testdata.Literals;
import net.sourceforge.pmd.typeresolution.testdata.Operators;
import net.sourceforge.pmd.typeresolution.testdata.Promotion;
public class ClassTypeResolverTest {
@Test
public void testClassNameExists() {
ClassTypeResolver classTypeResolver = new ClassTypeResolver();
assertEquals(true, classTypeResolver.classNameExists("java.lang.System"));
assertEquals(false, classTypeResolver.classNameExists("im.sure.that.this.does.not.Exist"));
assertEquals(true, classTypeResolver.classNameExists("java.awt.List"));
}
@Test
public void acceptanceTest() {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(ArrayListFound.class);
assertEquals(ArrayListFound.class, acu.getFirstDescendantOfType(ASTTypeDeclaration.class).getType());
assertEquals(ArrayListFound.class,
acu.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
ASTImportDeclaration id = acu.getFirstDescendantOfType(ASTImportDeclaration.class);
assertEquals("java.util", id.getPackage().getName());
assertEquals(ArrayList.class, id.getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTReferenceType.class).getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTType.class).getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclaratorId.class).getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTVariableDeclarator.class).getType());
assertEquals(ArrayList.class, acu.getFirstDescendantOfType(ASTFieldDeclaration.class).getType());
acu = parseAndTypeResolveForClass15(DefaultJavaLangImport.class);
assertEquals(String.class, acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType());
assertEquals(Override.class, acu.findDescendantsOfType(ASTName.class).get(1).getType());
}
/**
* See bug #1138 Anonymous inner class in enum causes NPE
*/
@Test
public void testEnumAnonymousInnerClass() {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(EnumWithAnonymousInnerClass.class);
Class<?> inner = acu.getFirstDescendantOfType(ASTAllocationExpression.class)
.getFirstDescendantOfType(ASTClassOrInterfaceType.class).getType();
assertEquals("net.sourceforge.pmd.typeresolution.testdata.EnumWithAnonymousInnerClass$1", inner.getName());
}
@Test
public void testExtraTopLevelClass() throws ClassNotFoundException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(ExtraTopLevelClass.class);
Class<?> theExtraTopLevelClass = Class
.forName("net.sourceforge.pmd.typeresolution.testdata.TheExtraTopLevelClass");
// First class
ASTTypeDeclaration typeDeclaration = (ASTTypeDeclaration) acu.jjtGetChild(1);
assertEquals(ExtraTopLevelClass.class, typeDeclaration.getType());
assertEquals(ExtraTopLevelClass.class,
typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
// Second class
typeDeclaration = (ASTTypeDeclaration) acu.jjtGetChild(2);
assertEquals(theExtraTopLevelClass, typeDeclaration.getType());
assertEquals(theExtraTopLevelClass,
typeDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
}
@Test
public void testInnerClass() throws ClassNotFoundException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(InnerClass.class);
Class<?> theInnerClass = Class.forName("net.sourceforge.pmd.typeresolution.testdata.InnerClass$TheInnerClass");
// Outer class
ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
assertEquals(InnerClass.class, typeDeclaration.getType());
ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration
.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
assertEquals(InnerClass.class, outerClassDeclaration.getType());
// Inner class
assertEquals(theInnerClass,
outerClassDeclaration.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getType());
// Method parameter as inner class
ASTFormalParameter formalParameter = typeDeclaration.getFirstDescendantOfType(ASTFormalParameter.class);
assertEquals(theInnerClass, formalParameter.getTypeNode().getType());
}
/**
* If we don't have the auxclasspath, we might not find the inner class. In
* that case, we'll need to search by name for a match.
*
* @throws Exception
*/
@Test
public void testInnerClassNotCompiled() throws Exception {
Node acu = parseAndTypeResolveForString("public class TestInnerClass {\n" + " public void foo() {\n"
+ " Statement statement = new Statement();\n" + " }\n" + " static class Statement {\n"
+ " }\n" + "}", "1.8");
ASTClassOrInterfaceType statement = acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
Assert.assertTrue(statement.isReferenceToClassSameCompilationUnit());
}
@Test
public void testAnonymousInnerClass() throws ClassNotFoundException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(AnonymousInnerClass.class);
Class<?> theAnonymousInnerClass = Class
.forName("net.sourceforge.pmd.typeresolution.testdata.AnonymousInnerClass$1");
// Outer class
ASTTypeDeclaration typeDeclaration = acu.getFirstDescendantOfType(ASTTypeDeclaration.class);
assertEquals(AnonymousInnerClass.class, typeDeclaration.getType());
ASTClassOrInterfaceDeclaration outerClassDeclaration = typeDeclaration
.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class);
assertEquals(AnonymousInnerClass.class, outerClassDeclaration.getType());
// Anonymous Inner class
assertEquals(theAnonymousInnerClass,
outerClassDeclaration.getFirstDescendantOfType(ASTAllocationExpression.class).getType());
}
@Test
public void testLiterals() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Literals.class);
List<ASTLiteral> literals = convertList(acu.findChildNodesWithXPath("//Literal"), ASTLiteral.class);
int index = 0;
// String s = "s";
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(String.class, literals.get(index++).getType());
// boolean boolean1 = false;
assertEquals(Boolean.TYPE, literals.get(index).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
assertEquals(Boolean.TYPE, literals.get(index++).getType());
// boolean boolean2 = true;
assertEquals(Boolean.TYPE, literals.get(index).getFirstDescendantOfType(ASTBooleanLiteral.class).getType());
assertEquals(Boolean.TYPE, literals.get(index++).getType());
// Object obj = null;
assertNull(literals.get(index).getFirstDescendantOfType(ASTNullLiteral.class).getType());
assertNull(literals.get(index++).getType());
// byte byte1 = 0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// byte byte2 = 0x0F;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// byte byte3 = -007;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// short short1 = 0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// short short2 = 0x0F;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// short short3 = -007;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// char char1 = 0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// char char2 = 0x0F;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// char char3 = 007;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// char char4 = 'a';
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Character.TYPE, literals.get(index++).getType());
// int int1 = 0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// int int2 = 0x0F;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// int int3 = -007;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// int int4 = 'a';
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Character.TYPE, literals.get(index++).getType());
// long long1 = 0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// long long2 = 0x0F;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// long long3 = -007;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// long long4 = 0L;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Long.TYPE, literals.get(index++).getType());
// long long5 = 0x0Fl;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Long.TYPE, literals.get(index++).getType());
// long long6 = -007L;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Long.TYPE, literals.get(index++).getType());
// long long7 = 'a';
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Character.TYPE, literals.get(index++).getType());
// float float1 = 0.0f;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Float.TYPE, literals.get(index++).getType());
// float float2 = -10e+01f;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Float.TYPE, literals.get(index++).getType());
// float float3 = 0x08.08p3f;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Float.TYPE, literals.get(index++).getType());
// float float4 = 0xFF;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// float float5 = 'a';
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Character.TYPE, literals.get(index++).getType());
// double double1 = 0.0;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Double.TYPE, literals.get(index++).getType());
// double double2 = -10e+01;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Double.TYPE, literals.get(index++).getType());
// double double3 = 0x08.08p3;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Double.TYPE, literals.get(index++).getType());
// double double4 = 0xFF;
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Integer.TYPE, literals.get(index++).getType());
// double double5 = 'a';
assertEquals(0, literals.get(index).jjtGetNumChildren());
assertEquals(Character.TYPE, literals.get(index++).getType());
// Make sure we got them all.
assertEquals("All literals not tested", index, literals.size());
}
@Test
public void testUnaryNumericPromotion() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericPromotion']]//Expression[UnaryExpression]"),
ASTExpression.class);
int index = 0;
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testBinaryNumericPromotion() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericPromotion']]//Expression[AdditiveExpression]"),
ASTExpression.class);
int index = 0;
// LHS = byte
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = short
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = char
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = int
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = long
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = float
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Float.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// LHS = double
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testBinaryStringPromotion() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Promotion.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryStringPromotion']]//Expression"),
ASTExpression.class);
int index = 0;
assertEquals(String.class, expressions.get(index++).getType());
assertEquals(String.class, expressions.get(index++).getType());
assertEquals(String.class, expressions.get(index++).getType());
assertEquals(String.class, expressions.get(index++).getType());
assertEquals(String.class, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testUnaryLogicalOperators() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryLogicalOperators']]//Expression"),
ASTExpression.class);
int index = 0;
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testBinaryLogicalOperators() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryLogicalOperators']]//Expression"),
ASTExpression.class);
int index = 0;
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testUnaryNumericOperators() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
List<TypeNode> expressions = new ArrayList<>();
expressions.addAll(convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//Expression"),
TypeNode.class));
expressions.addAll(convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PostfixExpression"),
TypeNode.class));
expressions.addAll(convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreIncrementExpression"),
TypeNode.class));
expressions.addAll(convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'unaryNumericOperators']]//PreDecrementExpression"),
TypeNode.class));
int index = 0;
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
assertEquals(Double.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
private static <T> List<T> convertList(List<Node> nodes, Class<T> target) {
List<T> converted = new ArrayList<>();
for (Node n : nodes) {
converted.add(target.cast(n));
}
return converted;
}
@Test
public void testBinaryNumericOperators() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
List<ASTExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'binaryNumericOperators']]//Expression"),
ASTExpression.class);
int index = 0;
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
assertEquals(Integer.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
@Test
public void testAssignmentOperators() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(Operators.class);
List<ASTStatementExpression> expressions = convertList(
acu.findChildNodesWithXPath(
"//Block[preceding-sibling::MethodDeclarator[@Image = 'assignmentOperators']]//StatementExpression"),
ASTStatementExpression.class);
int index = 0;
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
assertEquals(Long.TYPE, expressions.get(index++).getType());
// Make sure we got them all.
assertEquals("All expressions not tested", index, expressions.size());
}
/**
* The type should be filled also on the ASTVariableDeclaratorId node, not
* only on the variable name declaration.
*/
@Test
public void testFullyQualifiedType() {
String source = "public class Foo {\n" + " public void bar() {\n"
+ " java.util.StringTokenizer st = new StringTokenizer(\"a.b.c.d\", \".\");\n"
+ " while (st.hasMoreTokens()) {\n" + " System.out.println(st.nextToken());\n"
+ " }\n" + " }\n" + "}";
ASTCompilationUnit acu = parseAndTypeResolveForString(source, "1.5");
List<ASTName> names = acu.findDescendantsOfType(ASTName.class);
ASTName theStringTokenizer = null;
for (ASTName name : names) {
if (name.hasImageEqualTo("st.hasMoreTokens")) {
theStringTokenizer = name;
break;
}
}
Assert.assertNotNull(theStringTokenizer);
VariableNameDeclaration declaration = (VariableNameDeclaration) theStringTokenizer.getNameDeclaration();
Assert.assertNotNull(declaration);
Assert.assertEquals("java.util.StringTokenizer", declaration.getTypeImage());
Assert.assertNotNull(declaration.getType());
Assert.assertSame(StringTokenizer.class, declaration.getType());
ASTVariableDeclaratorId id = (ASTVariableDeclaratorId) declaration.getNode();
Assert.assertNotNull(id.getType());
Assert.assertSame(StringTokenizer.class, id.getType());
}
private ASTCompilationUnit parseAndTypeResolveForClass15(Class<?> clazz) {
return parseAndTypeResolveForClass(clazz, "1.5");
}
// Note: If you're using Eclipse or some other IDE to run this test, you
// _must_ have the src/test/java folder in
// the classpath. Normally the IDE doesn't put source directories themselves
// directly in the classpath, only
// the output directories are in the classpath.
private ASTCompilationUnit parseAndTypeResolveForClass(Class<?> clazz, String version) {
String sourceFile = clazz.getName().replace('.', '/') + ".java";
InputStream is = ClassTypeResolverTest.class.getClassLoader().getResourceAsStream(sourceFile);
if (is == null) {
throw new IllegalArgumentException("Unable to find source file " + sourceFile + " for " + clazz);
}
String source;
try {
source = IOUtils.toString(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
return parseAndTypeResolveForString(source, version);
}
private ASTCompilationUnit parseAndTypeResolveForString(String source, String version) {
LanguageVersionHandler languageVersionHandler = LanguageRegistry.getLanguage(JavaLanguageModule.NAME)
.getVersion(version).getLanguageVersionHandler();
ASTCompilationUnit acu = (ASTCompilationUnit) languageVersionHandler
.getParser(languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(source));
languageVersionHandler.getSymbolFacade().start(acu);
languageVersionHandler.getTypeResolutionFacade(ClassTypeResolverTest.class.getClassLoader()).start(acu);
return acu;
}
}