use of net.sourceforge.pmd.lang.java.typeresolution.typeinference.Variable in project pmd by pmd.
the class TypeInferenceTest method testResolution.
@Test
public void testResolution() {
List<Bound> bounds = new ArrayList<>();
bounds.add(new Bound(JavaTypeDefinition.forClass(SuperClassA.class), alpha, SUBTYPE));
bounds.add(new Bound(JavaTypeDefinition.forClass(SuperClassAOther.class), alpha, SUBTYPE));
Map<Variable, JavaTypeDefinition> result = TypeInferenceResolver.resolveVariables(bounds);
assertEquals(1, result.size());
assertEquals(JavaTypeDefinition.forClass(SuperClassA2.class), result.get(alpha));
}
use of net.sourceforge.pmd.lang.java.typeresolution.typeinference.Variable in project pmd by pmd.
the class MethodTypeResolution method produceInitialBounds.
public static void produceInitialBounds(Method method, JavaTypeDefinition context, List<Variable> variables, List<Bound> initialBounds) {
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-18.html#jls-18.1.3
// When inference begins, a bound set is typically generated from a list of type parameter declarations P1,
// ..., Pp and associated inference variables α1, ..., αp. Such a bound set is constructed as follows. For
// each l (1 ≤ l ≤ p):
TypeVariable<Method>[] typeVariables = method.getTypeParameters();
variables.clear();
for (int i = 0; i < typeVariables.length; ++i) {
variables.add(new Variable());
}
for (int currVarIndex = 0; currVarIndex < typeVariables.length; ++currVarIndex) {
Type[] bounds = typeVariables[currVarIndex].getBounds();
boolean currVarHasNoProperUpperBound = true;
for (Type bound : bounds) {
// Otherwise, for each type T delimited by & in the TypeBound, the bound αl <: T[P1:=α1, ..., Pp:=αp]
// appears in the set; if this results in no proper upper bounds for αl (only dependencies), then the
// bound α <: Object also appears in the set.
int boundVarIndex = -1;
if (bound instanceof TypeVariable) {
boundVarIndex = JavaTypeDefinition.getGenericTypeIndex(typeVariables, ((TypeVariable<?>) bound).getName());
}
if (boundVarIndex != -1) {
initialBounds.add(new Bound(variables.get(currVarIndex), variables.get(boundVarIndex), SUBTYPE));
} else {
currVarHasNoProperUpperBound = false;
initialBounds.add(new Bound(variables.get(currVarIndex), context.resolveTypeDefinition(bound), SUBTYPE));
}
}
// If Pl has no TypeBound, the bound αl <: Object appears in the set.
if (currVarHasNoProperUpperBound) {
initialBounds.add(new Bound(variables.get(currVarIndex), JavaTypeDefinition.forClass(Object.class), SUBTYPE));
}
}
}
use of net.sourceforge.pmd.lang.java.typeresolution.typeinference.Variable in project pmd by pmd.
the class ClassTypeResolverTest method testMethodInitialBounds.
@Test
public void testMethodInitialBounds() throws NoSuchMethodException {
JavaTypeDefinition context = forClass(GenericMethodsImplicit.class, forClass(Thread.class));
List<Variable> variables = new ArrayList<>();
List<Bound> initialBounds = new ArrayList<>();
Method method = GenericMethodsImplicit.class.getMethod("foo");
MethodTypeResolution.produceInitialBounds(method, context, variables, initialBounds);
assertEquals(initialBounds.size(), 6);
// A
assertTrue(initialBounds.contains(new Bound(variables.get(0), forClass(Object.class), SUBTYPE)));
// B
assertTrue(initialBounds.contains(new Bound(variables.get(1), forClass(Number.class), SUBTYPE)));
assertTrue(initialBounds.contains(new Bound(variables.get(1), forClass(Runnable.class), SUBTYPE)));
// C
assertTrue(initialBounds.contains(new Bound(variables.get(2), variables.get(3), SUBTYPE)));
assertTrue(initialBounds.contains(new Bound(variables.get(2), forClass(Object.class), SUBTYPE)));
// D
assertTrue(initialBounds.contains(new Bound(variables.get(3), forClass(Thread.class), SUBTYPE)));
}
use of net.sourceforge.pmd.lang.java.typeresolution.typeinference.Variable in project pmd by pmd.
the class ClassTypeResolverTest method testMethodInitialConstraints.
@Test
public void testMethodInitialConstraints() throws NoSuchMethodException, JaxenException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(GenericMethodsImplicit.class);
List<AbstractJavaNode> expressions = convertList(acu.findChildNodesWithXPath("//ArgumentList"), AbstractJavaNode.class);
List<Variable> variables = new ArrayList<>();
for (int i = 0; i < 2; ++i) {
variables.add(new Variable());
}
Method method = GenericMethodsImplicit.class.getMethod("bar", Object.class, Object.class, Integer.class, Object.class);
ASTArgumentList argList = (ASTArgumentList) expressions.get(0);
List<Constraint> constraints = MethodTypeResolution.produceInitialConstraints(method, argList, variables);
assertEquals(constraints.size(), 3);
// A
assertTrue(constraints.contains(new Constraint(forClass(SuperClassA.class), variables.get(0), LOOSE_INVOCATION)));
assertTrue(constraints.contains(new Constraint(forClass(SuperClassAOther.class), variables.get(0), LOOSE_INVOCATION)));
// B
assertTrue(constraints.contains(new Constraint(forClass(SuperClassAOther2.class), variables.get(1), LOOSE_INVOCATION)));
}
Aggregations