mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
graph inference: infer from non-eq type bound
This commit is contained in:
@@ -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) {
|
||||
|
||||
+68
@@ -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> {}
|
||||
}
|
||||
+4
@@ -64,6 +64,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInferenceFromNotEqualTypeParamsBounds() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSOEDuringInferenceFromParamBounds() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user