diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2013-02-27 09:41:48 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2013-02-27 09:41:48 -0800 |
commit | 1d526b16d476792ca7ce47616d55833115e8d6ab (patch) | |
tree | 650fb03af01ff04097d1d59939518cc71be029cb /java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java | |
parent | 9edc8f6b58f71ec510ba36b838f115718d9a174d (diff) | |
download | idea-1d526b16d476792ca7ce47616d55833115e8d6ab.tar.gz |
Snapshot of commit 329607d9ebcedf2bb0ad81265354366db7dc3f9c
from branch master of git://git.jetbrains.org/idea/community.git
Change-Id: I3b27d82897504da1b66169b67c7771e0f551c973
Diffstat (limited to 'java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java')
-rw-r--r-- | java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java | 86 |
1 files changed, 55 insertions, 31 deletions
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java index 635f4ce4539a..1d0b2d750304 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -16,11 +16,10 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.MethodSignature; -import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.openapi.project.Project; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.util.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -77,12 +76,7 @@ public class PsiMethodReferenceUtil { PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final PsiExpression expression = methodReferenceExpression.getQualifierExpression(); if (expression != null) { - final PsiType expressionType = expression.getType(); - if (expressionType instanceof PsiArrayType) { - containingClass = JavaPsiFacade.getInstance(methodReferenceExpression.getProject()) - .findClass(CommonClassNames.JAVA_LANG_OBJECT, methodReferenceExpression.getResolveScope()); - return new QualifierResolveResult(containingClass, substitutor, false); - } + final PsiType expressionType = getExpandedType(expression.getType(), expression); PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType); containingClass = result.getElement(); if (containingClass != null) { @@ -101,7 +95,8 @@ public class PsiMethodReferenceUtil { else { final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType(); if (typeElement != null) { - PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(typeElement.getType()); + PsiType type = getExpandedType(typeElement.getType(), typeElement); + PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); containingClass = result.getElement(); if (containingClass != null) { substitutor = result.getSubstitutor(); @@ -142,14 +137,21 @@ public class PsiMethodReferenceUtil { final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodReferenceExpression); final PsiElement resolve = result.getElement(); if (resolve instanceof PsiMethod) { - final MethodSignature signature1 = method.getSignature(resolveResult.getSubstitutor()); + final MethodSignature signature1 = method.getSignature(LambdaUtil.getSubstitutor(method, resolveResult)); PsiSubstitutor subst = PsiSubstitutor.EMPTY; subst = subst.putAll(qualifierResolveResult.getSubstitutor()); subst = subst.putAll(result.getSubstitutor()); final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(subst); final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left); - PsiType methodReturnType = subst.substitute(((PsiMethod)resolve).getReturnType()); + + PsiType returnType = PsiTypesUtil.patchMethodGetClassReturnType(methodReferenceExpression, methodReferenceExpression, + (PsiMethod)resolve, null, + PsiUtil.getLanguageLevel(methodReferenceExpression)); + if (returnType == null) { + returnType = ((PsiMethod)resolve).getReturnType(); + } + PsiType methodReturnType = subst.substitute(returnType); if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) { if (methodReturnType == null) { methodReturnType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType(((PsiMethod)resolve).getContainingClass(), subst); @@ -161,9 +163,18 @@ public class PsiMethodReferenceUtil { final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left); if (interfaceReturnType != null) { if (interfaceReturnType == PsiType.VOID) return true; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (resolve == JavaPsiFacade.getElementFactory(resolve.getProject()).getArrayClass(PsiUtil.getLanguageLevel(resolve))) { + if (parameters.length != 1 || parameters[0].getType() != PsiType.INT) return false; + final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters(); + if (typeParameters.length == 1) { + final PsiType arrayComponentType = result.getSubstitutor().substitute(typeParameters[0]); + return arrayComponentType != null && TypeConversionUtil.isAssignable(interfaceReturnType, arrayComponentType.createArrayType(), true); + } + return false; + } final PsiClassType classType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType((PsiClass)resolve, result.getSubstitutor()); if (TypeConversionUtil.isAssignable(interfaceReturnType, classType, !((PsiClass)resolve).hasTypeParameters())) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length == 0) return true; if (parameters.length == 1) { if (isReceiverType(resolveResult.getSubstitutor().substitute(parameters[0].getType()), qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor())) return true; @@ -176,25 +187,29 @@ public class PsiMethodReferenceUtil { } private static boolean isReceiverType(@Nullable PsiClass aClass, @Nullable PsiClass containingClass) { - while (containingClass != null) { - if (InheritanceUtil.isInheritorOrSelf(aClass, containingClass, true)) return true; - containingClass = containingClass.getContainingClass(); - } - return false; + return InheritanceUtil.isInheritorOrSelf(aClass, containingClass, true); } public static boolean isReceiverType(PsiType receiverType, @Nullable PsiClass containingClass, PsiSubstitutor psiSubstitutor) { + if (containingClass != null) { + receiverType = getExpandedType(receiverType, containingClass); + } final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(receiverType)); final PsiClass receiverClass = resolveResult.getElement(); if (receiverClass != null && isReceiverType(receiverClass, containingClass)) { LOG.assertTrue(containingClass != null); return resolveResult.getSubstitutor().equals(psiSubstitutor) || - PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor) || - PsiUtil.isRawSubstitutor(receiverClass, resolveResult.getSubstitutor()); + emptyOrRaw(containingClass, psiSubstitutor) || + emptyOrRaw(receiverClass, resolveResult.getSubstitutor()); } return false; } + private static boolean emptyOrRaw(PsiClass containingClass, PsiSubstitutor psiSubstitutor) { + return PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor) || + (!containingClass.hasTypeParameters() && psiSubstitutor.getSubstitutionMap().isEmpty()); + } + public static boolean isReceiverType(PsiType functionalInterfaceType, PsiClass containingClass, @Nullable PsiMethod referencedMethod) { final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); final MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement()); @@ -259,14 +274,23 @@ public class PsiMethodReferenceUtil { return true; } - public static PsiLocalVariable createMethodReferenceExpressionAccording2Type(PsiMethodReferenceExpression methodReferenceExpression, - PsiType leftType) { - final String uniqueVarName = - JavaCodeStyleManager.getInstance(methodReferenceExpression.getProject()) - .suggestUniqueVariableName("l", methodReferenceExpression, true); - final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()) - .createStatementFromText(leftType.getCanonicalText() + " " + uniqueVarName + " = " + methodReferenceExpression.getText(), - methodReferenceExpression); - return (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0]; + + public static boolean onArrayType(PsiClass containingClass, MethodSignature signature) { + if (signature.getParameterTypes().length == 1 && signature.getParameterTypes()[0] == PsiType.INT) { + if (containingClass != null) { + final Project project = containingClass.getProject(); + final LanguageLevel level = PsiUtil.getLanguageLevel(containingClass); + return containingClass == JavaPsiFacade.getElementFactory(project).getArrayClass(level); + } + } + return false; + } + + private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) { + if (type instanceof PsiArrayType) { + type = JavaPsiFacade.getElementFactory(typeElement.getProject()).getArrayClassType(((PsiArrayType)type).getComponentType(), + PsiUtil.getLanguageLevel(typeElement)); + } + return type; } } |