forked from phoedos/pmd
Merge branch 'pr-444'
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);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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();
|
||||
}
|
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;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.typeresolution.testdata.dummytypes;
|
||||
|
||||
public class GenericSuperClassB<T, S> {
|
||||
public S fieldB;
|
||||
}
|
@ -27,7 +27,7 @@ His progress so far has allowed to properly resolve, in addition to previously s
|
||||
- References to `this` and `super`, even when qualified
|
||||
- References to fields, even when chained (ie: `this.myObject.aField`), and properly handling inheritance / shadowing
|
||||
|
||||
Fields using generics are still Work in Progress, but we expect to fully support it soon enough.
|
||||
Lambda parameter types where these are infered rather than explicit are still not supported. Expect future releases to do so.
|
||||
|
||||
|
||||
#### Metrics Framework
|
||||
@ -120,5 +120,6 @@ by a new CyclomaticComplexity rule based on the metrics framework. See also [iss
|
||||
* [#436](https://github.com/pmd/pmd/pull/436): \[java] Metrics framework tests and various improvements
|
||||
* [#440](https://github.com/pmd/pmd/pull/440): \[core] Created ruleset schema 3.0.0 (to use metrics)
|
||||
* [#443](https://github.com/pmd/pmd/pull/443): \[java] Optimize typeresolution, by skipping package and import declarations in visit(ASTName)
|
||||
* [#444](https://github.com/pmd/pmd/pull/444): \[java] [typeresolution]: add support for generic fields
|
||||
* [#451](https://github.com/pmd/pmd/pull/451): \[java] Metrics framework: first metrics + first rule
|
||||
|
||||
|
Reference in New Issue
Block a user