graph inference: infer from non-eq type bound

This commit is contained in:
anna
2013-02-20 18:09:44 +01:00
parent 87464bfa04
commit 35c349430a
3 changed files with 85 additions and 0 deletions
@@ -969,6 +969,19 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
for (int i = 0; i < argExtendsListTypes.length; i++) {
PsiClassType argBoundType = argExtendsListTypes[i];
PsiClassType paramBoundType = paramExtendsListTypes[i];
final PsiClassType.ClassResolveResult argResolveResult = argBoundType.resolveGenerics();
final PsiClassType.ClassResolveResult paramResolveResult = paramBoundType.resolveGenerics();
final PsiClass paramBoundClass = paramResolveResult.getElement();
final PsiClass argBoundClass = argResolveResult.getElement();
if (argBoundClass != null && paramBoundClass != null && paramBoundClass != argBoundClass) {
if (argBoundClass.isInheritor(paramBoundClass, true)) {
final PsiSubstitutor superClassSubstitutor =
TypeConversionUtil.getSuperClassSubstitutor(paramBoundClass, argBoundClass, argResolveResult.getSubstitutor());
argBoundType = JavaPsiFacade.getElementFactory(argClass.getProject()).createType(paramBoundClass, superClassSubstitutor);
} else {
return null;
}
}
final Pair<PsiType, ConstraintType> constraint =
getSubstitutionForTypeParameterInner(paramBoundType, argBoundType, patternType, constraintType, depth);
if (constraint != null) {
@@ -0,0 +1,68 @@
import java.util.*;
public class ConcurrentCollectors {
static class Test1 {
static <T, K, D, M1 extends ConcurrentMap<K, D>> C<T, M1> groupingBy(F<M1> f,
C<T, D> c,
BiConsumer<M1, T> consumer) {
return new CImpl<>(f, consumer, arg(c.getOp()));
}
static <K, V, M2 extends Map<K, V>> BiOp<M2> arg(BiOp<V> op) {
return null;
}
}
static class Test2 {
static <T, K, D, M1 extends ConcurrentMap<K, D>> C<T, M1> groupingBy(F<M1> f,
C<T, D> c,
BiConsumer<M1, T> consumer) {
return new CImpl<>(f, consumer, arg(c.getOp()));
}
static <K, V, M2 extends ConcurrentMap<K, V>> BiOp<M2> arg(BiOp<V> op) {
return null;
}
}
static class Test3 {
static <T, K, D, M1 extends Map<K, D>> C<T, M1> groupingBy(F<M1> f,
C<T, D> c,
BiConsumer<M1, T> consumer) {
return new CImpl<>(f, consumer, <error descr="Inferred type 'M1' for type parameter 'M2' is not within its bound; should implement 'ConcurrentCollectors.ConcurrentMap<java.lang.Object,D>'">arg(c.getOp())</error>);
}
static <K, V, M2 extends ConcurrentMap<K, V>> BiOp<M2> arg(BiOp<V> op) {
return null;
}
}
interface C<T, R> {
BiOp<R> getOp();
}
interface F<T> {}
static class CImpl<T, R> implements C<T, R> {
CImpl(F<R> f,
BiConsumer<R, T> consumer,
BiOp<R> op) {
}
@Override
public BiOp<R> getOp() {
return null;
}
}
interface BiFun<T, U, R> { }
interface BiOp<T> extends BiFun<T, T, T> {
}
interface BiConsumer<T, U> {}
interface ConcurrentMap<A, B> extends Map<A, B> {}
}
@@ -64,6 +64,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
public void testInferenceFromNotEqualTypeParamsBounds() throws Exception {
doTest();
}
public void testSOEDuringInferenceFromParamBounds() throws Exception {
doTest();
}