mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
method refs: collect substitution from type parameter's extends list (IDEA-104314)
This commit is contained in:
+16
-2
@@ -359,9 +359,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
|
||||
final PsiType[] rightTypes = signature.getParameterTypes();
|
||||
if (types.length < rightTypes.length) {
|
||||
return PsiUtil.resolveGenericsClassInType(rightTypes[0]).getSubstitutor();
|
||||
return getSubstitutor(rightTypes[0]);
|
||||
} else if (types.length > rightTypes.length) {
|
||||
return PsiUtil.resolveGenericsClassInType(types[0]).getSubstitutor();
|
||||
return getSubstitutor(types[0]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < rightTypes.length; i++) {
|
||||
@@ -381,6 +381,20 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
languageLevel, PsiMethodReferenceExpressionImpl.this.getProject());
|
||||
}
|
||||
|
||||
private PsiSubstitutor getSubstitutor(PsiType type) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type);
|
||||
PsiSubstitutor psiSubstitutor = resolveResult.getSubstitutor();
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
for (PsiClass aClass : psiClass.getSupers()) {
|
||||
psiSubstitutor = psiSubstitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(aClass, (PsiClassType)type));
|
||||
}
|
||||
}
|
||||
}
|
||||
return psiSubstitutor;
|
||||
}
|
||||
|
||||
private class MethodReferenceConflictResolver implements PsiConflictResolver {
|
||||
private final PsiClass myContainingClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
interface AdditiveGroupValue<A> {
|
||||
A negative();
|
||||
}
|
||||
|
||||
interface Vector<S extends AdditiveGroupValue<S>> {
|
||||
default void foo() {
|
||||
Foo<S> negative = AdditiveGroupValue::negative;
|
||||
}
|
||||
}
|
||||
|
||||
interface Foo<T> {
|
||||
T bar(T t);
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
interface AdditiveGroupValue<V extends AdditiveGroupValue<V>> {
|
||||
|
||||
V plus(V other);
|
||||
|
||||
V negative();
|
||||
|
||||
default V minus(V other) {
|
||||
return self().plus(other.negative());
|
||||
}
|
||||
|
||||
V self();
|
||||
|
||||
Class<?> valueClass();
|
||||
|
||||
}
|
||||
|
||||
interface Vector<S extends AdditiveGroupValue<S>, V extends Vector<S, V>> extends AdditiveGroupValue<V> {
|
||||
|
||||
S get(int i);
|
||||
|
||||
int size();
|
||||
|
||||
@Override
|
||||
default V plus(V other) {
|
||||
return Vectors.binaryComponentOp(self(), other, AdditiveGroupValue::plus);
|
||||
}
|
||||
|
||||
@Override
|
||||
default V minus(V other) {
|
||||
return Vectors.binaryComponentOp(self(), other, AdditiveGroupValue::minus);
|
||||
}
|
||||
|
||||
@Override
|
||||
default V negative() {
|
||||
return Vectors.unaryComponentOp(self(), AdditiveGroupValue::negative);
|
||||
}
|
||||
|
||||
V valueOf(S[] components);
|
||||
|
||||
}
|
||||
|
||||
interface UnaryOperator<T> {
|
||||
T apply(T r);
|
||||
}
|
||||
|
||||
interface BinaryOperator<T> {
|
||||
T apply(T r, T t);
|
||||
}
|
||||
static class Vectors {
|
||||
|
||||
public static <S extends AdditiveGroupValue<S>, V extends Vector<S, V>> V unaryComponentOp(V v1, UnaryOperator<S> op) {
|
||||
int size = v1.size();
|
||||
S[] components = newComponentArray(v1.valueClass(), size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
components[i] = op.apply(v1.get(i));
|
||||
}
|
||||
return v1.valueOf(components);
|
||||
}
|
||||
|
||||
public static <S extends AdditiveGroupValue<S>, V extends Vector<S, V>> V binaryComponentOp(V v1, V v2, BinaryOperator<S> op) {
|
||||
int size = v1.size();
|
||||
S[] components = newComponentArray(v1.valueClass(), size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
components[i] = op.apply(v1.get(i), v2.get(i));
|
||||
}
|
||||
return v1.valueOf(components);
|
||||
}
|
||||
|
||||
protected static <S extends AdditiveGroupValue<S>> S[] newComponentArray(Class<?> componentClass, int size) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+4
@@ -79,6 +79,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testAbstractMethod() { doTest(); }
|
||||
public void testMethodRefAcceptance() { doTest(); }
|
||||
|
||||
public void testTypeParameterWithExtendsList() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user