method refs: missed applicable member/containing class substitutor for exact refs (IDEA-126613)

This commit is contained in:
Anna Kozlova
2014-06-26 17:35:20 +02:00
parent 6f5d5f7900
commit 5650b7331e
3 changed files with 70 additions and 3 deletions

View File

@@ -23,6 +23,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import java.util.List;
@@ -66,10 +67,18 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
}
} else {
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember();
LOG.assertTrue(applicableMember != null);
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass();
final PsiClass containingClass = qualifierResolveResult.getContainingClass();
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
psiSubstitutor = applicableMemberContainingClass == null || containingClass == null || myExpression.isConstructor()
? psiSubstitutor
: TypeConversionUtil.getSuperClassSubstitutor(applicableMemberContainingClass, containingClass, psiSubstitutor);
PsiType applicableMethodReturnType = applicableMember instanceof PsiMethod ? ((PsiMethod)applicableMember).getReturnType() : null;
int idx = 0;
for (PsiTypeParameter param : ((PsiTypeParameterListOwner)applicableMember).getTypeParameters()) {
@@ -99,7 +108,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
constraints.add(new TypeCompatibilityConstraint(returnType, psiSubstitutor.substitute(applicableMethodReturnType)));
} else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod)applicableMember).isConstructor()) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject());
final PsiClass containingClass = qualifierResolveResult.getContainingClass();
if (containingClass != null) {
final PsiClassType classType = elementFactory.createType(containingClass, psiSubstitutor);
constraints.add(new TypeCompatibilityConstraint(returnType, classType));

View File

@@ -0,0 +1,54 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
class TestA {
public static class Entity<K> {
K id;
public K getId() {
return id;
}
}
public static class EntityVo {}
public static class Area extends Entity<Integer> {
}
public static class AreaVo {
public AreaVo(Area area, String lang) {
}
}
public static void main(String[] args) {
String language = "da";
List<Area> areas = new ArrayList<>();
Map<Integer, AreaVo> areaLookup = areas.stream()
.collect(Collectors.toMap(Area::getId, area -> new AreaVo(area, language)));
}
}
class TestSimple {
public static class Entity<K> {
K id;
public K getId() {
return id;
}
}
public static class Area extends Entity<Integer> {
}
public static <M> Set<M> toMap(Function<Area, M> keyMapper) {
return null;
}
{
Set<Integer> tMapCollector = toMap(Area::getId);
}
}

View File

@@ -269,6 +269,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testMissedApplicableMemberContainingClassSubstitution() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}