Merge branch 'master' of https://github.com/pmd/pmd into metrics
This commit is contained in:
@ -47,4 +47,8 @@ public class ASTClassOrInterfaceType extends AbstractJavaTypeNode {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAnonymousClass() {
|
||||
return jjtGetParent().hasDescendantOfType(ASTClassOrInterfaceBody.class);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public class ASTTypeArgument extends AbstractJavaNode {
|
||||
public class ASTTypeArgument extends AbstractJavaTypeNode {
|
||||
public ASTTypeArgument(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public class ASTTypeBound extends AbstractJavaNode {
|
||||
public class ASTTypeBound extends AbstractJavaTypeNode {
|
||||
public ASTTypeBound(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public class ASTTypeParameter extends AbstractJavaNode {
|
||||
public class ASTTypeParameter extends AbstractJavaTypeNode {
|
||||
public ASTTypeParameter(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -4,9 +4,10 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
public abstract class AbstractJavaAccessTypeNode extends AbstractJavaAccessNode implements TypeNode {
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
private Class<?> type;
|
||||
public abstract class AbstractJavaAccessTypeNode extends AbstractJavaAccessNode implements TypeNode {
|
||||
private JavaTypeDefinition typeDefinition;
|
||||
|
||||
public AbstractJavaAccessTypeNode(int i) {
|
||||
super(i);
|
||||
@ -18,11 +19,25 @@ public abstract class AbstractJavaAccessTypeNode extends AbstractJavaAccessNode
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
if (typeDefinition != null) {
|
||||
return typeDefinition.getType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Class<?> type) {
|
||||
this.type = type;
|
||||
typeDefinition = JavaTypeDefinition.build(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDefinition getTypeDefinition() {
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypeDefinition(JavaTypeDefinition typeDefinition) {
|
||||
this.typeDefinition = typeDefinition;
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,16 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
/**
|
||||
* An extension of the SimpleJavaNode which implements the TypeNode interface.
|
||||
*
|
||||
*
|
||||
* @see AbstractJavaNode
|
||||
* @see TypeNode
|
||||
*/
|
||||
public abstract class AbstractJavaTypeNode extends AbstractJavaNode implements TypeNode {
|
||||
|
||||
private Class<?> type;
|
||||
private JavaTypeDefinition typeDefinition;
|
||||
|
||||
public AbstractJavaTypeNode(int i) {
|
||||
super(i);
|
||||
@ -24,11 +25,25 @@ public abstract class AbstractJavaTypeNode extends AbstractJavaNode implements T
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
if (typeDefinition != null) {
|
||||
return typeDefinition.getType();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(Class<?> type) {
|
||||
this.type = type;
|
||||
typeDefinition = JavaTypeDefinition.build(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDefinition getTypeDefinition() {
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTypeDefinition(JavaTypeDefinition typeDefinition) {
|
||||
this.typeDefinition = typeDefinition;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
/**
|
||||
* This interface allows a Java Class to be associated with a node.
|
||||
@ -13,16 +14,31 @@ public interface TypeNode extends Node {
|
||||
|
||||
/**
|
||||
* Get the Java Class associated with this node.
|
||||
*
|
||||
*
|
||||
* @return The Java Class, may return <code>null</code>.
|
||||
*/
|
||||
Class<?> getType();
|
||||
|
||||
/**
|
||||
* Get the TypeDefinition associated with this node. The Class object
|
||||
* contained in the TypeDefinition will always be equal to that which
|
||||
* is returned by <code>getType()</code>.
|
||||
*
|
||||
* @return The TypeDefinition, may return <code>null</code>
|
||||
*/
|
||||
JavaTypeDefinition getTypeDefinition();
|
||||
|
||||
/**
|
||||
* Set the TypeDefinition associated with this node.
|
||||
*
|
||||
* @param type A TypeDefinition object
|
||||
*/
|
||||
void setTypeDefinition(JavaTypeDefinition type);
|
||||
|
||||
/**
|
||||
* Set the Java Class associated with this node.
|
||||
*
|
||||
* @param type
|
||||
* A Java Class
|
||||
*
|
||||
* @param type A Java Class
|
||||
*/
|
||||
void setType(Class<?> type);
|
||||
}
|
||||
|
@ -86,7 +86,14 @@ public class UnusedImportsRule extends AbstractJavaRule {
|
||||
if (s != null) {
|
||||
String[] params = s.split("\\s*,\\s*");
|
||||
for (String param : params) {
|
||||
imports.remove(new ImportWrapper(param, param, new DummyJavaNode(-1)));
|
||||
final int firstDot = param.indexOf('.');
|
||||
final String expectedImportName;
|
||||
if (firstDot == -1) {
|
||||
expectedImportName = param;
|
||||
} else {
|
||||
expectedImportName = param.substring(0, firstDot);
|
||||
}
|
||||
imports.remove(new ImportWrapper(param, expectedImportName, new DummyJavaNode(-1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
|
||||
@ -81,7 +80,7 @@ public class JUnitTestsShouldIncludeAssertRule extends AbstractJUnitRule {
|
||||
|
||||
for (NameDeclaration decl : decls.keySet()) {
|
||||
Node parent = decl.getNode().jjtGetParent().jjtGetParent().jjtGetParent();
|
||||
if (parent.hasDescendantOfType(ASTAnnotation.class)
|
||||
if (parent.hasDescendantOfType(ASTMarkerAnnotation.class)
|
||||
&& parent.getFirstChildOfType(ASTFieldDeclaration.class) != null) {
|
||||
String annot = parent.getFirstDescendantOfType(ASTMarkerAnnotation.class).jjtGetChild(0).getImage();
|
||||
if (!"Rule".equals(annot) && !"org.junit.Rule".equals(annot)) {
|
||||
|
@ -70,23 +70,9 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule {
|
||||
// find the arguments
|
||||
final List<ASTExpression> argumentList = parentNode.getFirstChildOfType(ASTPrimarySuffix.class)
|
||||
.getFirstDescendantOfType(ASTArgumentList.class).findChildrenOfType(ASTExpression.class);
|
||||
final List<ASTPrimaryExpression> params = new ArrayList<ASTPrimaryExpression>(argumentList.size());
|
||||
|
||||
for (final ASTExpression astExpression : argumentList) {
|
||||
ASTPrimaryExpression primaryExpression = astExpression.getFirstChildOfType(ASTPrimaryExpression.class);
|
||||
if (primaryExpression != null) {
|
||||
params.add(primaryExpression);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.isEmpty()) {
|
||||
// no params we could analyze
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
final ASTPrimaryExpression messageParam = params.get(0);
|
||||
// remove the message parameter
|
||||
params.remove(0);
|
||||
final ASTPrimaryExpression messageParam = argumentList.remove(0).getFirstDescendantOfType(ASTPrimaryExpression.class);
|
||||
final int expectedArguments = expectedArguments(messageParam);
|
||||
|
||||
if (expectedArguments == 0) {
|
||||
@ -97,14 +83,14 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule {
|
||||
|
||||
// Remove throwable param, since it is shown separately.
|
||||
// But only, if it is not used as a placeholder argument
|
||||
if (params.size() > expectedArguments) {
|
||||
removeThrowableParam(params);
|
||||
if (argumentList.size() > expectedArguments) {
|
||||
removeThrowableParam(argumentList);
|
||||
}
|
||||
|
||||
if (params.size() < expectedArguments) {
|
||||
addViolationWithMessage(data, node, "Missing arguments," + getExpectedMessage(params, expectedArguments));
|
||||
} else if (params.size() > expectedArguments) {
|
||||
addViolationWithMessage(data, node, "Too many arguments," + getExpectedMessage(params, expectedArguments));
|
||||
if (argumentList.size() < expectedArguments) {
|
||||
addViolationWithMessage(data, node, "Missing arguments," + getExpectedMessage(argumentList, expectedArguments));
|
||||
} else if (argumentList.size() > expectedArguments) {
|
||||
addViolationWithMessage(data, node, "Too many arguments," + getExpectedMessage(argumentList, expectedArguments));
|
||||
}
|
||||
|
||||
return super.visit(node, data);
|
||||
@ -146,21 +132,20 @@ public class InvalidSlf4jMessageFormatRule extends AbstractJavaRule {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void removeThrowableParam(final List<ASTPrimaryExpression> params) {
|
||||
private void removeThrowableParam(final List<ASTExpression> params) {
|
||||
// Throwable parameters are the last one in the list, if any.
|
||||
if (params.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int lastIndex = params.size() - 1;
|
||||
ASTPrimaryExpression last = params.get(lastIndex);
|
||||
ASTPrimaryExpression last = params.get(lastIndex).getFirstDescendantOfType(ASTPrimaryExpression.class);
|
||||
|
||||
if (isNewThrowable(last) || hasTypeThrowable(last) || isReferencingThrowable(last)) {
|
||||
params.remove(lastIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private String getExpectedMessage(final List<ASTPrimaryExpression> params, final int expectedArguments) {
|
||||
private String getExpectedMessage(final List<ASTExpression> params, final int expectedArguments) {
|
||||
return " expected " + expectedArguments + (expectedArguments > 1 ? " arguments " : " argument ") + "but have "
|
||||
+ params.size();
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
@ -51,6 +52,15 @@ public class SignatureDeclareThrowsExceptionRule extends AbstractJavaRule {
|
||||
if (methodDeclaration.getMethodName().startsWith("test")) {
|
||||
return super.visit(methodDeclaration, o);
|
||||
}
|
||||
|
||||
// Ignore overridden methods, the issue should be marked on the method definition
|
||||
final List<ASTAnnotation> methodAnnotations = methodDeclaration.jjtGetParent().findChildrenOfType(ASTAnnotation.class);
|
||||
for (final ASTAnnotation annotation : methodAnnotations) {
|
||||
final ASTName annotationName = annotation.getFirstDescendantOfType(ASTName.class);
|
||||
if (annotationName.hasImageEqualTo("Override") || annotationName.hasImageEqualTo("java.lang.Override")) {
|
||||
return super.visit(methodDeclaration, o);
|
||||
}
|
||||
}
|
||||
|
||||
List<ASTName> exceptionList = Collections.emptyList();
|
||||
ASTNameList nameList = methodDeclaration.getFirstChildOfType(ASTNameList.class);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.typeresolution.rules;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
|
||||
@ -113,6 +114,15 @@ public class SignatureDeclareThrowsException extends AbstractJavaRule {
|
||||
if (junitImported && isAllowedMethod(methodDeclaration)) {
|
||||
return super.visit(methodDeclaration, o);
|
||||
}
|
||||
|
||||
// Ignore overridden methods, the issue should be marked on the method definition
|
||||
final List<ASTAnnotation> methodAnnotations = methodDeclaration.jjtGetParent().findChildrenOfType(ASTAnnotation.class);
|
||||
for (final ASTAnnotation annotation : methodAnnotations) {
|
||||
final ASTName annotationName = annotation.getFirstDescendantOfType(ASTName.class);
|
||||
if (annotationName.hasImageEqualTo("Override") || annotationName.hasImageEqualTo("java.lang.Override")) {
|
||||
return super.visit(methodDeclaration, o);
|
||||
}
|
||||
}
|
||||
|
||||
checkExceptions(methodDeclaration, o);
|
||||
|
||||
|
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.typeresolution.typedefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class JavaTypeDefinition implements TypeDefinition {
|
||||
private final Class<?> clazz;
|
||||
private List<JavaTypeDefinition> genericArgs;
|
||||
// contains TypeDefs where only the clazz field is used
|
||||
private static Map<Class<?>, JavaTypeDefinition> onlyClassTypeDef = new HashMap<>();
|
||||
|
||||
public Class<?> getType() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public List<JavaTypeDefinition> getGenericArgs() {
|
||||
if (genericArgs == null) {
|
||||
genericArgs = Collections.unmodifiableList(new ArrayList<JavaTypeDefinition>());
|
||||
}
|
||||
|
||||
return genericArgs;
|
||||
}
|
||||
|
||||
private JavaTypeDefinition(Class<?> clazz, List<JavaTypeDefinition> genericArgs) {
|
||||
this.clazz = clazz;
|
||||
|
||||
if (genericArgs != null) {
|
||||
this.genericArgs = Collections.unmodifiableList(genericArgs);
|
||||
}
|
||||
}
|
||||
|
||||
// builder part of the class
|
||||
|
||||
public static JavaTypeDefinition build(Class<?> clazz) {
|
||||
if (onlyClassTypeDef.containsKey(clazz)) {
|
||||
return onlyClassTypeDef.get(clazz);
|
||||
}
|
||||
|
||||
JavaTypeDefinition typeDef = new JavaTypeDefinition(clazz, null);
|
||||
|
||||
onlyClassTypeDef.put(clazz, typeDef);
|
||||
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param genericArgs This package private method expects that the genericArgs list has not been leaked,
|
||||
* meaning the other references have been discarded to ensure immutability.
|
||||
*/
|
||||
/* default */ static JavaTypeDefinition build(Class<?> clazz, List<JavaTypeDefinition> genericArgs) {
|
||||
if (genericArgs == null) {
|
||||
return build(clazz);
|
||||
}
|
||||
|
||||
return new JavaTypeDefinition(clazz, genericArgs);
|
||||
}
|
||||
|
||||
public static JavaTypeDefinitionBuilder builder(Class<?> clazz) {
|
||||
return new JavaTypeDefinitionBuilder().setType(clazz);
|
||||
}
|
||||
|
||||
|
||||
public static JavaTypeDefinitionBuilder builder() {
|
||||
return new JavaTypeDefinitionBuilder();
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.typeresolution.typedefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaTypeDefinitionBuilder {
|
||||
private Class<?> clazz = null;
|
||||
private List<JavaTypeDefinition> genericArgs = new ArrayList<>();
|
||||
|
||||
/* default */ JavaTypeDefinitionBuilder() {}
|
||||
|
||||
public JavaTypeDefinitionBuilder addTypeArg(JavaTypeDefinition arg) {
|
||||
genericArgs.add(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<JavaTypeDefinition> getTypeArgs() {
|
||||
return Collections.unmodifiableList(genericArgs);
|
||||
}
|
||||
|
||||
public JavaTypeDefinitionBuilder getTypeArg(int index) {
|
||||
genericArgs.get(index);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaTypeDefinitionBuilder setType(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaTypeDefinition build() {
|
||||
return JavaTypeDefinition.build(clazz, genericArgs);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.typeresolution.typedefinition;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TypeDefinition {
|
||||
/**
|
||||
* Get the raw Class type of the definition.
|
||||
*
|
||||
* @return Raw Class type.
|
||||
*/
|
||||
Class<?> getType();
|
||||
|
||||
/**
|
||||
* Get the list of type arguments for this TypeDefinition.
|
||||
*
|
||||
* @return An ordered and immutable list of type arguments.
|
||||
*/
|
||||
List<? extends TypeDefinition> getGenericArgs();
|
||||
}
|
@ -148,7 +148,8 @@ public class Foo {
|
||||
since="1.03"
|
||||
message = "The {0} ''{1}'' has a Cyclomatic Complexity of {2}."
|
||||
class="net.sourceforge.pmd.lang.java.rule.codesize.CyclomaticComplexityRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#CyclomaticComplexity">
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#CyclomaticComplexity"
|
||||
deprecated="true">
|
||||
<description>
|
||||
<![CDATA[
|
||||
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
||||
@ -204,7 +205,8 @@ public class Foo { // This has a Cyclomatic Complexity = 12
|
||||
since="5.1.2"
|
||||
message = "The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
|
||||
class="net.sourceforge.pmd.lang.java.rule.codesize.StdCyclomaticComplexityRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#StdCyclomaticComplexity">
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#StdCyclomaticComplexity"
|
||||
deprecated="true">
|
||||
<description>
|
||||
<![CDATA[
|
||||
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
||||
@ -260,7 +262,8 @@ public class Foo { // This has a Cyclomatic Complexity = 12
|
||||
since="5.1.2"
|
||||
message = "The {0} ''{1}'' has a Modified Cyclomatic Complexity of {2}."
|
||||
class="net.sourceforge.pmd.lang.java.rule.codesize.ModifiedCyclomaticComplexityRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#ModifiedCyclomaticComplexity">
|
||||
externalInfoUrl="${pmd.website.baseurl}/rules/java/codesize.html#ModifiedCyclomaticComplexity"
|
||||
deprecated="true">
|
||||
<description>
|
||||
<![CDATA[
|
||||
Complexity directly affects maintenance costs is determined by the number of decision points in a method
|
||||
|
@ -30,10 +30,12 @@ or reported.
|
||||
[FormalParameter/Type/ReferenceType
|
||||
/ClassOrInterfaceType[@Image != 'InterruptedException' and @Image != 'CloneNotSupportedException']
|
||||
]
|
||||
[FormalParameter/VariableDeclaratorId[not(matches(@Image, $allowExceptionNameRegex))]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
<property name="allowCommentedBlocks" type="Boolean" description="Empty blocks containing comments will be skipped" value="false"/>
|
||||
<property name="allowExceptionNameRegex" type="String" description="Empty blocks catching exceptions with names matching this regular expression will be skipped" value="^$"/>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
@ -129,7 +131,7 @@ Avoid empty try blocks - what's the point?
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//TryStatement/Block[1][count(*) = 0]
|
||||
//TryStatement[not(ResourceSpecification)]/Block[1][count(*) = 0]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,13 @@ import net.sourceforge.pmd.typeresolution.testdata.dummytypes.SuperClassA;
|
||||
/*
|
||||
* Note: inherited fields of a nested class shadow outer scope variables
|
||||
* Note: only if they are accessible!
|
||||
*
|
||||
* TODO: test static field access, array types, anonymous class (super type access)
|
||||
*/
|
||||
public class FieldAccess extends SuperClassA {
|
||||
public int field;
|
||||
public FieldAccess f;
|
||||
public static FieldAccess staticF;
|
||||
|
||||
public void foo(FieldAccess param) {
|
||||
FieldAccess local = null;
|
||||
|
32
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericBounds.java
vendored
Normal file
32
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericBounds.java
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata;
|
||||
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericClass;
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericSuperClassA;
|
||||
|
||||
|
||||
public class FieldAccessGenericBounds extends GenericSuperClassA<Long> {
|
||||
GenericClass<? super String, ?> superGeneric;
|
||||
GenericClass<? extends Number, Object> upperBound;
|
||||
|
||||
public void astPrimaryNameCases() {
|
||||
// test ?, ? super Something, ? extends Something
|
||||
// Primary[Prefix[Name[superGeneric.first]]]
|
||||
superGeneric.first = ""; // Object
|
||||
superGeneric.second = null; // Object
|
||||
inheritedSuperGeneric.first = ""; // Object
|
||||
inheritedSuperGeneric.second = null; // Object
|
||||
|
||||
upperBound.first = null; // Number
|
||||
inheritedUpperBound.first = null; // String
|
||||
|
||||
// test static imports
|
||||
// Primary[Prefix[Name[instanceFields.generic.first]]]
|
||||
//instanceFields.generic.first = "";
|
||||
//staticGeneric.first = new Long(0);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata;
|
||||
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericClass;
|
||||
|
||||
public class FieldAccessGenericParameter<T extends GenericClass<String, GenericClass<String, Integer>>,
|
||||
S extends Double> {
|
||||
T parameterGeneric;
|
||||
S classGeneric;
|
||||
|
||||
<M extends Character> void foo() {
|
||||
M localGeneric = null;
|
||||
|
||||
// access type dependant on class/method type arguments
|
||||
// Primary[Prefix[Name[classGeneric]]]
|
||||
classGeneric = null; // Double
|
||||
localGeneric = null; // Character
|
||||
|
||||
|
||||
// test type parameters extending generic types
|
||||
// Primary[Prefix[Name[parameterGeneric.first]]]
|
||||
parameterGeneric.second.second = new Integer(0);
|
||||
}
|
||||
|
||||
<C extends Number> FieldAccessGenericParameter() {
|
||||
C constructorGeneric = null;
|
||||
|
||||
// access type dependant on constructor type arugments
|
||||
// Primary[Prefix[Name[localGeneric]]]
|
||||
constructorGeneric = null; // Number
|
||||
}
|
||||
}
|
37
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericRaw.java
vendored
Normal file
37
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericRaw.java
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata;
|
||||
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericClass2;
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericSuperClassA;
|
||||
|
||||
public class FieldAccessGenericRaw<T extends GenericClass2> extends GenericSuperClassA<Long> {
|
||||
GenericClass2 rawGeneric;
|
||||
T parameterRawGeneric;
|
||||
|
||||
void foo() {
|
||||
// test raw types
|
||||
// Primary[Prefix[Name[rawGeneric.first]]]
|
||||
rawGeneric.first = new Integer(0);
|
||||
rawGeneric.second = new Integer(0);
|
||||
rawGeneric.third = new Object();
|
||||
rawGeneric.fourth.second = "";
|
||||
rawGeneric.rawGeneric.second = new Integer(0);
|
||||
|
||||
// Primary[Prefix[Name[inheritedGeneric.first]]]
|
||||
inheritedRawGeneric.first = new Integer(0);
|
||||
inheritedRawGeneric.second = new Integer(0);
|
||||
inheritedRawGeneric.third = new Object();
|
||||
inheritedRawGeneric.fourth.second = "";
|
||||
inheritedRawGeneric.rawGeneric.second = new Integer(0);
|
||||
|
||||
// Primary[Prefix[Name[parameterRawGeneric.first]]]
|
||||
parameterRawGeneric.first = new Integer(0);
|
||||
parameterRawGeneric.second = new Integer(0);
|
||||
parameterRawGeneric.third = new Object();
|
||||
parameterRawGeneric.fourth.second = "";
|
||||
parameterRawGeneric.rawGeneric.second = new Integer(0);
|
||||
}
|
||||
}
|
60
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericSimple.java
vendored
Normal file
60
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/FieldAccessGenericSimple.java
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata;
|
||||
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericClass;
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericSuperClassA;
|
||||
|
||||
|
||||
/*
|
||||
* TODO: add anonymous class this (Allocation expression)
|
||||
* TODO: add primitives, parameterized arrays
|
||||
* TODO: diamond, type parmeter declarations can shadow Class declarations
|
||||
*/
|
||||
|
||||
public class FieldAccessGenericSimple extends GenericSuperClassA<Long> {
|
||||
GenericClass<String, Double> genericField;
|
||||
GenericClass<String, GenericClass<Number, Double>> genericTypeArg;
|
||||
FieldAccessGenericSimple fieldAcc;
|
||||
|
||||
void foo(GenericClass<Integer, Character> param) {
|
||||
GenericClass<Float, Long> local = null;
|
||||
|
||||
// access a generic field through member field
|
||||
// Primary[Prefix[Name[genericField.first]]]
|
||||
genericField.first = "";
|
||||
genericField.second = new Double(0);
|
||||
|
||||
// access a generic field whose type depends on a generic type argument
|
||||
// Primary[Prefix[Name[genericTypeArg.second.second]]]
|
||||
genericTypeArg.second.second = new Double(0);
|
||||
|
||||
// access a generic field through a local or a parameter
|
||||
// Primary[Prefix[Name[param.first]]]
|
||||
param.first = new Integer(0);
|
||||
local.second = new Long(0);
|
||||
|
||||
// access a generic field whose type depends on indirect type arguments
|
||||
// Primary[Prefix[Name[generic.generic.first]]]
|
||||
param.generic.first = new Character('c');
|
||||
local.generic.second = new Float(0);
|
||||
genericField.generic.generic.generic.first = new Double(0);
|
||||
|
||||
// test inherited generic
|
||||
// Primary[Prefix[Name[generic.first]]]
|
||||
fieldA = new Long(0);
|
||||
fieldB.generic.second = "";
|
||||
|
||||
// test inherited generic
|
||||
// Primary[Prefix[Name[fieldAcc.fieldA]]]
|
||||
fieldAcc.fieldA = new Long(0);
|
||||
}
|
||||
|
||||
public class Nested extends GenericSuperClassA<Long> {
|
||||
void foo() {
|
||||
fieldA = new Long(0);
|
||||
}
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ public class FieldAccessNested {
|
||||
a = new SuperClassA();
|
||||
|
||||
net.sourceforge.pmd.typeresolution.testdata.FieldAccessNested.Nested.this.a = new SuperClassA();
|
||||
FieldAccessNested.Nested.this.a = new SuperClassA();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata;
|
||||
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericClass;
|
||||
import net.sourceforge.pmd.typeresolution.testdata.dummytypes.GenericSuperClassA;
|
||||
|
||||
public class FieldAccessPrimaryGenericSimple extends GenericSuperClassA<Long> {
|
||||
GenericClass<String, Double> genericField;
|
||||
GenericClass<String, GenericClass<Number, Double>> genericTypeArg;
|
||||
|
||||
void foo(GenericClass<Integer, Character> param) {
|
||||
GenericClass<Float, Long> local = null;
|
||||
|
||||
// access a generic field through member field
|
||||
// Primary[Prefix[this], Suffix[genericField], Suffix[first]]
|
||||
this.genericField.first = "";
|
||||
(this).genericField.second = new Double(0);
|
||||
|
||||
// access a generic field whose type depends on a generic type argument
|
||||
// Primary[Prefix[this], Suffix[genericTypeArg], Suffix[second], Suffix[second]]
|
||||
this.genericTypeArg.second.second = new Double(0);
|
||||
|
||||
// access a generic field whose type depends on indirect type arguments
|
||||
// Primary[Prefix[this], Suffix[genericField], Suffix[generic], Suffix[generic]...]
|
||||
(this).genericField.generic.generic.generic.first = new Double(0);
|
||||
|
||||
// test inherited generic
|
||||
// Primary[Primary[Prefix[(this)]], Suffix[fieldA]]
|
||||
(this).fieldA = new Long(0);
|
||||
this.fieldB.generic.second = "";
|
||||
|
||||
// test inherited generic
|
||||
// Primary[Prefix[super], Suffix[fieldA]]
|
||||
super.fieldA = new Long(0);
|
||||
super.fieldB.generic.second = "";
|
||||
}
|
||||
|
||||
class Nested<T extends GenericClass<String, Number>> {
|
||||
T field;
|
||||
|
||||
void foo() {
|
||||
// Primary[Prefix[this], Suffix[field], Suffix[first]]
|
||||
this.field.first = "";
|
||||
}
|
||||
}
|
||||
}
|
@ -16,13 +16,8 @@ import net.sourceforge.pmd.typeresolution.testdata.dummytypes.SuperClassB2;
|
||||
*/
|
||||
public class FieldAccessShadow {
|
||||
Integer field;
|
||||
|
||||
String s2;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void foo() {
|
||||
String field;
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata.dummytypes;
|
||||
|
||||
public class GenericClass<T> {
|
||||
public T a;
|
||||
public class GenericClass<T, S> {
|
||||
public T first;
|
||||
public S second;
|
||||
public GenericClass<S, T> generic;
|
||||
}
|
||||
|
19
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/dummytypes/GenericClass2.java
vendored
Normal file
19
pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/testdata/dummytypes/GenericClass2.java
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata.dummytypes;
|
||||
|
||||
public class GenericClass2<A extends Integer, B extends A, C,
|
||||
S extends String,
|
||||
D extends GenericClass<A, S>,
|
||||
//, E extends GenericClass<E, E>,
|
||||
F extends GenericClass2> {
|
||||
public A first;
|
||||
public B second;
|
||||
public C third;
|
||||
public D fourth;
|
||||
//public E fifth; // recursion
|
||||
public F sixth; // recursion
|
||||
public GenericClass2 rawGeneric;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata.dummytypes;
|
||||
|
||||
public class GenericSuperClassA<T> extends GenericSuperClassB<T, GenericClass<String, T>> {
|
||||
public T fieldA;
|
||||
public GenericClass2 inheritedRawGeneric;
|
||||
public GenericClass<? super String, ?> inheritedSuperGeneric;
|
||||
public GenericClass<? extends String, Object> inheritedUpperBound;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user