diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index 45f3e66fa98c..6a8f24e65ef8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -101,7 +101,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(callExpression.getProject()); final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)elementFactory.createExpressionFromText(methodReferenceText, callExpression); - final Map map = PsiMethodReferenceUtil.getFunctionalTypeMap(); + final Map map = LambdaUtil.getFunctionalTypeMap(); try { map.put(methodReferenceExpression, functionalInterfaceType); final JavaResolveResult result = methodReferenceExpression.advancedResolve(false); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java b/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java index 494ed110b254..4bf336995b1f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/MethodReferenceCompletionProvider.java @@ -50,9 +50,8 @@ public class MethodReferenceCompletionProvider extends CompletionProvider map = PsiMethodReferenceUtil.getFunctionalTypeMap(); + new ExpectedTypeInfoImpl(returnType, ExpectedTypeInfo.TYPE_OR_SUBTYPE, returnType, TailType.UNKNOWN, null, ExpectedTypeInfoImpl.NULL); + final Map map = LambdaUtil.getFunctionalTypeMap(); Consumer noTypeCheck = new Consumer() { @Override public void consume(final LookupElement lookupElement) { diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 7f707200d6c6..68e12a637ae1 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; +import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -286,6 +287,15 @@ public class LambdaUtil { element = parent; parent = parent.getParent(); } + + final Map map = ourFunctionTypes.get(); + if (map != null) { + final PsiType type = map.get(expression); + if (type != null) { + return type; + } + } + if (parent instanceof PsiArrayInitializerExpression) { final PsiType psiType = ((PsiArrayInitializerExpression)parent).getType(); if (psiType instanceof PsiArrayType) { @@ -327,13 +337,6 @@ public class LambdaUtil { return properties.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx])); } } - final Map map = ourFunctionTypes.get(); - if (map != null) { - final PsiType type = map.get(expression); - if (type != null) { - return type; - } - } final JavaResolveResult resolveResult = contextCall.resolveMethodGenerics(); final PsiElement resolve = resolveResult.getElement(); if (resolve instanceof PsiMethod) { @@ -518,7 +521,17 @@ public class LambdaUtil { } return false; } - + + @NotNull + public static Map getFunctionalTypeMap() { + Map map = ourFunctionTypes.get(); + if (map == null) { + map = new HashMap(); + ourFunctionTypes.set(map); + } + return map; + } + public static class TypeParamsChecker extends PsiTypeVisitor { private PsiMethod myMethod; private final PsiClass myClass; 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 3347d8319c53..6118e1b9bf89 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -27,8 +27,6 @@ import java.util.Map; * User: anna */ public class PsiMethodReferenceUtil { - public static ThreadLocal> ourRefs = new ThreadLocal>(); - public static final Logger LOG = Logger.getInstance("#" + PsiMethodReferenceUtil.class.getName()); public static boolean hasReceiver(PsiType[] parameterTypes, QualifierResolveResult qualifierResolveResult, PsiMethodReferenceExpression methodRef) { @@ -97,16 +95,6 @@ public class PsiMethodReferenceUtil { return !varargs || parameterTypes.length - 1 <= argTypes.length - offset; } - @NotNull - public static Map getFunctionalTypeMap() { - Map map = ourRefs.get(); - if (map == null) { - map = new HashMap(); - ourRefs.set(map); - } - return map; - } - public static class QualifierResolveResult { private final PsiClass myContainingClass; private final PsiSubstitutor mySubstitutor; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 344ac1627392..7641f629fa24 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -746,8 +746,8 @@ public class PsiImplUtil { return JavaResolveResult.EMPTY_ARRAY; } if (element instanceof PsiMethodReferenceExpression) { - // method refs: do not cache results during parent conflict resolving - final Map map = PsiMethodReferenceUtil.ourRefs.get(); + // method refs: do not cache results during parent conflict resolving, acceptable checks, etc + final Map map = LambdaUtil.ourFunctionTypes.get(); if (map != null && map.containsKey(element)) { return (JavaResolveResult[])resolver.resolve(element, psiFile, incompleteCode); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java index e5f5a8a8d483..8edb864a2391 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java @@ -112,12 +112,7 @@ public abstract class InputOutputConstraintFormula implements ConstraintFormula public void apply(PsiSubstitutor substitutor, boolean cache) { setT(substitutor.substitute(getT())); if (cache) { - Map map = LambdaUtil.ourFunctionTypes.get(); - if (map == null) { - map = new HashMap(); - LambdaUtil.ourFunctionTypes.set(map); - } - map.put(getExpression(), getT()); + LambdaUtil.getFunctionalTypeMap().put(getExpression(), getT()); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java index 45018296d888..ac79be8a50ac 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/PsiMethodReferenceCompatibilityConstraint.java @@ -21,7 +21,6 @@ import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfacePa import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil; import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; @@ -124,7 +123,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm return true; } - final Map map = PsiMethodReferenceUtil.getFunctionalTypeMap(); + final Map map = LambdaUtil.getFunctionalTypeMap(); final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType)); final JavaResolveResult resolve; try { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java index 7b17460255c5..703b1287a6c5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java @@ -174,17 +174,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR } protected PsiType getInterfaceType(PsiMethodReferenceExpression reference) { - PsiType functionalInterfaceType = null; - final Map map = PsiMethodReferenceUtil.ourRefs.get(); - if (map != null) { - functionalInterfaceType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(map.get(reference)); - } - - if (functionalInterfaceType == null) { - functionalInterfaceType = reference.getFunctionalInterfaceType(); - } - - return functionalInterfaceType; + return reference.getFunctionalInterfaceType(); } protected PsiConflictResolver createResolver(PsiMethodReferenceExpressionImpl referenceExpression, diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java index 364017055c98..8c738a70fea5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java @@ -181,11 +181,6 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this); final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType); - final PsiClass psiClass = resolveResult.getElement(); - if (psiClass instanceof PsiAnonymousClass) { - return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType()); - } - if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) { final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList); if (candidateProperties != null) { @@ -200,13 +195,6 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi } } - final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); - - if (interfaceMethod == null) return false; - - final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult); - - assert leftType != null; if (!isPotentiallyCompatible(leftType)) { return false; } @@ -215,7 +203,10 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi return true; } - + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); + if (interfaceMethod == null) return false; + + final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult); if (hasFormalParameterTypes()) { final PsiParameter[] lambdaParameters = getParameterList().getParameters(); @@ -235,11 +226,7 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi PsiType methodReturnType = interfaceMethod.getReturnType(); if (methodReturnType != null && methodReturnType != PsiType.VOID) { - Map map = LambdaUtil.ourFunctionTypes.get(); - if (map == null) { - map = new HashMap(); - LambdaUtil.ourFunctionTypes.set(map); - } + Map map = LambdaUtil.getFunctionalTypeMap(); try { if (map.put(this, leftType) != null) { return false; 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 32545c51df0d..ab331933b437 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 @@ -409,7 +409,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase // the result of applying capture conversion (5.1.10) to the return type of the invocation type (15.12.2.6) of the chosen declaration is R', // where R is the target type that may be used to infer R'; neither R nor R' is void; and R' is compatible with R in an assignment context. - Map map = PsiMethodReferenceUtil.getFunctionalTypeMap(); + Map map = LambdaUtil.getFunctionalTypeMap(); final JavaResolveResult result; try { if (map.put(this, left) != null) {