From 497644d544fde6773f9e9df3c05f133176ed9a4a Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 1 Apr 2013 19:27:33 +0200 Subject: [PATCH] method refs: collect substitution from type parameter's extends list (IDEA-104314) --- .../PsiMethodReferenceExpressionImpl.java | 18 +++- .../TypeParameterWithExtendsList.java | 91 +++++++++++++++++++ .../lambda/MethodRefHighlightingTest.java | 4 + 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/TypeParameterWithExtendsList.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index b0d613746929..e092c9e3178e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -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; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/TypeParameterWithExtendsList.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/TypeParameterWithExtendsList.java new file mode 100644 index 000000000000..90734eee8474 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/TypeParameterWithExtendsList.java @@ -0,0 +1,91 @@ +interface AdditiveGroupValue { + A negative(); +} + +interface Vector> { + default void foo() { + Foo negative = AdditiveGroupValue::negative; + } +} + +interface Foo { + T bar(T t); +} + +class Test1 { + interface AdditiveGroupValue> { + + V plus(V other); + + V negative(); + + default V minus(V other) { + return self().plus(other.negative()); + } + + V self(); + + Class valueClass(); + + } + + interface Vector, V extends Vector> extends AdditiveGroupValue { + + 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 apply(T r); + } + + interface BinaryOperator { + T apply(T r, T t); + } + static class Vectors { + + public static , V extends Vector> V unaryComponentOp(V v1, UnaryOperator 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 , V extends Vector> V binaryComponentOp(V v1, V v2, BinaryOperator 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[] newComponentArray(Class componentClass, int size) { + return null; + } + + } + + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java index c43f639cc326..fb83e99ac190 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java @@ -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); }