Merge branch 'master' into metrics

This commit is contained in:
oowekyala
2017-06-02 23:20:28 +02:00
11 changed files with 309 additions and 17 deletions

View File

@ -5,7 +5,7 @@
package net.sourceforge.pmd.lang.java.ast;
public class ASTPrimarySuffix extends AbstractJavaNode {
public class ASTPrimarySuffix extends AbstractJavaTypeNode {
private boolean isArguments;
private boolean isArrayDereference;

View File

@ -61,6 +61,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpressionNotPlusMinus;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.ast.AbstractJavaTypeNode;
import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.lang.java.ast.TypeNode;
@ -442,34 +443,65 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter {
}
@Override
public Object visit(ASTPrimaryExpression node, Object data) {
super.visit(node, data);
if (node.jjtGetNumChildren() == 1) {
rollupTypeUnary(node);
} else {
// TODO OMG, this is complicated. PrimaryExpression, PrimaryPrefix
// and PrimarySuffix are all related.
public Object visit(ASTPrimaryExpression primaryNode, Object data) {
super.visit(primaryNode, data);
Class<?> primaryNodeType = null;
AbstractJavaTypeNode previousChild = null;
for (int childIndex = 0; childIndex < primaryNode.jjtGetNumChildren(); ++childIndex) {
AbstractJavaTypeNode currentChild = (AbstractJavaTypeNode) primaryNode.jjtGetChild(childIndex);
// skip children which already have their type assigned
if (currentChild.getType() == null) {
// Last token, because if 'this' is a Suffix, it'll have tokens '.' and 'this'
if (currentChild.jjtGetLastToken().toString().equals("this")) {
if (previousChild != null) { // Qualified 'this' expression
currentChild.setType(previousChild.getType());
} else { // simple 'this' expression
ASTClassOrInterfaceDeclaration typeDeclaration
= currentChild.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
if (typeDeclaration != null) {
currentChild.setType(typeDeclaration.getType());
}
}
// Last token, because if 'super' is a Suffix, it'll have tokens '.' and 'super'
} else if (currentChild.jjtGetLastToken().toString().equals("super")) {
if (previousChild != null) { // Qualified 'super' expression
currentChild.setType(previousChild.getType().getSuperclass());
} else { // simple 'super' expression
ASTClassOrInterfaceDeclaration typeDeclaration
= currentChild.getFirstParentOfType(ASTClassOrInterfaceDeclaration.class);
if (typeDeclaration != null && typeDeclaration.getType() != null) {
currentChild.setType(typeDeclaration.getType().getSuperclass());
}
}
}
}
//if (currentChild.getType() != null)
primaryNodeType = currentChild.getType();
previousChild = currentChild;
}
primaryNode.setType(primaryNodeType);
return data;
}
@Override
public Object visit(ASTPrimaryPrefix node, Object data) {
super.visit(node, data);
if (node.getImage() == null) {
rollupTypeUnary(node);
} else {
// TODO OMG, this is complicated. PrimaryExpression, PrimaryPrefix
// and PrimarySuffix are all related.
}
rollupTypeUnary(node);
return data;
}
@Override
public Object visit(ASTPrimarySuffix node, Object data) {
super.visit(node, data);
// TODO OMG, this is complicated. PrimaryExpression, PrimaryPrefix and
// PrimarySuffix are all related.
return data;
}

View File

@ -14,11 +14,13 @@ 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;
@ -35,13 +37,17 @@ 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.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
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.AbstractJavaTypeNode;
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;
@ -53,6 +59,10 @@ 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;
import net.sourceforge.pmd.typeresolution.testdata.SuperClass;
import net.sourceforge.pmd.typeresolution.testdata.SuperExpression;
import net.sourceforge.pmd.typeresolution.testdata.ThisExpression;
public class ClassTypeResolverTest {
@ -134,7 +144,7 @@ public class ClassTypeResolverTest {
/**
* 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
@ -584,6 +594,73 @@ public class ClassTypeResolverTest {
Assert.assertSame(StringTokenizer.class, id.getType());
}
@Test
public void testThisExpression() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(ThisExpression.class);
List<ASTPrimaryExpression> expressions = convertList(
acu.findChildNodesWithXPath("//PrimaryExpression"),
ASTPrimaryExpression.class);
List<ASTPrimaryPrefix> prefixes = convertList(
acu.findChildNodesWithXPath("//PrimaryPrefix"),
ASTPrimaryPrefix.class);
int index = 0;
assertEquals(ThisExpression.class, expressions.get(index).getType());
assertEquals(ThisExpression.class, prefixes.get(index++).getType());
assertEquals(ThisExpression.class, expressions.get(index).getType());
assertEquals(ThisExpression.class, prefixes.get(index++).getType());
assertEquals(ThisExpression.class, expressions.get(index).getType());
assertEquals(ThisExpression.class, prefixes.get(index++).getType());
assertEquals(ThisExpression.class, expressions.get(index).getType());
assertEquals(ThisExpression.class, prefixes.get(index++).getType());
assertEquals(ThisExpression.ThisExprNested.class, expressions.get(index).getType());
assertEquals(ThisExpression.ThisExprNested.class, prefixes.get(index++).getType());
// Qualified this
assertEquals(ThisExpression.class, expressions.get(index).getType());
assertEquals(ThisExpression.class, prefixes.get(index).getType());
assertEquals(ThisExpression.class, ((TypeNode) expressions.get(index++).jjtGetChild(1)).getType());
assertEquals(ThisExpression.ThisExprStaticNested.class, expressions.get(index).getType());
assertEquals(ThisExpression.ThisExprStaticNested.class, prefixes.get(index++).getType());
// Make sure we got them all
assertEquals("All expressions not tested", index, expressions.size());
assertEquals("All expressions not tested", index, prefixes.size());
}
@Test
public void testSuperExpression() throws JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(SuperExpression.class);
List<AbstractJavaTypeNode> expressions = convertList(
acu.findChildNodesWithXPath("//VariableInitializer/Expression/PrimaryExpression/PrimaryPrefix"),
AbstractJavaTypeNode.class);
int index = 0;
assertEquals(SuperClass.class, expressions.get(index++).getType());
assertEquals(SuperClass.class, expressions.get(index++).getType());
assertEquals(SuperClass.class, expressions.get(index++).getType());
assertEquals(SuperClass.class, expressions.get(index++).getType());
assertEquals(SuperExpression.class, ((TypeNode) expressions.get(index).jjtGetParent().jjtGetChild(0)).getType());
assertEquals(SuperClass.class, ((TypeNode) expressions.get(index++).jjtGetParent().jjtGetChild(1)).getType());
assertEquals(SuperExpression.class, expressions.get(index++).getType());
assertEquals(SuperExpression.class, expressions.get(index++).getType());
// Make sure we got them all
assertEquals("All expressions not tested", index, expressions.size());
}
private ASTCompilationUnit parseAndTypeResolveForClass15(Class<?> clazz) {
return parseAndTypeResolveForClass(clazz, "1.5");
}

View File

@ -0,0 +1,10 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.typeresolution.testdata;
public class SuperClass {
protected SuperClass s;
}

View File

@ -0,0 +1,32 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.typeresolution.testdata;
public class SuperExpression extends SuperClass {
public SuperExpression() {
SuperClass a = super.s;
}
protected SuperExpression b;
{ SuperClass s = super.s; }
public void foo() {
SuperClass a = super.s;
}
SuperClass a = super.s;
public class SuperExprNested extends SuperExpression {
SuperClass a = SuperExpression.super.s;
SuperExpression b = super.b;
}
public static class ThisExprStaticNested extends SuperExpression {
SuperExpression a = super.b;
}
}

View File

@ -0,0 +1,32 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.typeresolution.testdata;
public class ThisExpression {
public ThisExpression() {
ThisExpression a = this;
}
{
ThisExpression a = this;
}
public void foo() {
ThisExpression a = this;
}
ThisExpression a = this;
public class ThisExprNested {
ThisExprNested a = this;
ThisExpression b = ThisExpression.this;
}
public static class ThisExprStaticNested {
ThisExprStaticNested a = this;
}
}