forked from phoedos/pmd
Java, typeres: add erased candidate set and minimal erased candidate set methods
This commit is contained in:
@ -484,6 +484,10 @@ public final class MethodTypeResolution {
|
||||
return isSubtypeable(parameter, argument.getTypeDefinition());
|
||||
}
|
||||
|
||||
public static boolean isSubtypeable(Class<?> parameter, Class<?> argument) {
|
||||
return isSubtypeable(JavaTypeDefinition.forClass(parameter), JavaTypeDefinition.forClass(argument));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtypeability rules.
|
||||
* https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.10
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.typeresolution.typeinference;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.MethodTypeResolution;
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.typedefinition.JavaTypeDefinition;
|
||||
|
||||
import static net.sourceforge.pmd.lang.java.typeresolution.typeinference.InferenceRuleType.EQUALITY;
|
||||
@ -26,6 +27,38 @@ public final class TypeInferenceResolver {
|
||||
|
||||
}
|
||||
|
||||
public static Set<Class<?>> getErasedCandidateSet(List<Set<Class<?>>> erasedSuperTypeSets) {
|
||||
Set<Class<?>> result = new HashSet<>();
|
||||
|
||||
if (!erasedSuperTypeSets.isEmpty()) {
|
||||
result.addAll(erasedSuperTypeSets.get(0));
|
||||
}
|
||||
|
||||
for (Set<Class<?>> superTypeSet : erasedSuperTypeSets) {
|
||||
result.retainAll(superTypeSet);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set<Class<?>> getMinimalErasedCandidateSet(Set<Class<?>> erasedSet) {
|
||||
Set<Class<?>> result = new HashSet<>();
|
||||
|
||||
outter:
|
||||
for (Class<?> candidate : erasedSet) {
|
||||
for (Class<?> erasedSetMember : erasedSet) {
|
||||
if (candidate != erasedSetMember
|
||||
&& MethodTypeResolution.isSubtypeable(candidate, erasedSetMember)) {
|
||||
continue outter; // skip candidate from result set
|
||||
}
|
||||
}
|
||||
|
||||
result.add(candidate);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve unresolved variables in a list of bounds.
|
||||
*/
|
||||
|
@ -12,8 +12,10 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
@ -278,7 +280,7 @@ public class TypeInferenceTest {
|
||||
@Test
|
||||
public void testIncorporationSubtypeAndSubtype() {
|
||||
List<Constraint> result;
|
||||
|
||||
|
||||
// ### Original rule 4. : S <: α and α <: T imply ‹S <: T›
|
||||
result = incorporationResult(new Bound(s, alpha, EQUALITY), new Bound(alpha, t, SUBTYPE));
|
||||
assertEquals(result.size(), 1);
|
||||
@ -291,6 +293,29 @@ public class TypeInferenceTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErasedCandidateSet() {
|
||||
List<Set<Class<?>>> superTypeSets = new ArrayList<>();
|
||||
superTypeSets.add(JavaTypeDefinition.forClass(List.class).getErasedSuperTypeSet());
|
||||
superTypeSets.add(JavaTypeDefinition.forClass(Set.class).getErasedSuperTypeSet());
|
||||
|
||||
Set<Class<?>> erasedCandidate = TypeInferenceResolver.getErasedCandidateSet(superTypeSets);
|
||||
|
||||
assertEquals(erasedCandidate.size(), 3);
|
||||
assertTrue(erasedCandidate.contains(Object.class));
|
||||
assertTrue(erasedCandidate.contains(Collection.class));
|
||||
assertTrue(erasedCandidate.contains(Iterable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinimalErasedCandidateSet() {
|
||||
Set<Class<?>> minimalSet = TypeInferenceResolver.getMinimalErasedCandidateSet(
|
||||
JavaTypeDefinition.forClass(List.class).getErasedSuperTypeSet());
|
||||
|
||||
assertEquals(minimalSet.size(), 1);
|
||||
assertTrue(minimalSet.contains(List.class));
|
||||
}
|
||||
|
||||
private List<Constraint> incorporationResult(Bound firstBound, Bound secondBound) {
|
||||
List<Bound> current = new ArrayList<>();
|
||||
List<Bound> newBounds = new ArrayList<>();
|
||||
|
Reference in New Issue
Block a user