diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2013-02-08 15:14:04 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2013-02-08 15:14:04 -0800 |
commit | 9edc8f6b58f71ec510ba36b838f115718d9a174d (patch) | |
tree | 06f6df92024fa534ff27e1c0b5fc8b2002848093 /java/java-psi-api/src/com | |
parent | b56ea2a18f232d79481e778085fd64e8ae486fc3 (diff) | |
download | idea-9edc8f6b58f71ec510ba36b838f115718d9a174d.tar.gz |
Snapshot of commit 84dc01e773388c2c72a1fc437f313dd5747e7809
from branch master of git://git.jetbrains.org/idea/community.git
Diffstat (limited to 'java/java-psi-api/src/com')
14 files changed, 229 insertions, 170 deletions
diff --git a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java index dd339ffc4cef..8ca2c256b23b 100644 --- a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java +++ b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,8 @@ public interface CommonClassNames { @NonNls String JAVA_UTIL_DICTIONARY = "java.util.Dictionary"; @NonNls String JAVA_UTIL_COMPARATOR = "java.util.Comparator"; - @NonNls String JAVA_SQL_DATE = "java.sql.Date"; + /** @deprecated not that common (to remove in IDEA 13) */ + @SuppressWarnings("UnusedDeclaration") @NonNls String JAVA_SQL_DATE = "java.sql.Date"; @NonNls String JAVA_IO_SERIALIZABLE = "java.io.Serializable"; @NonNls String JAVA_IO_EXTERNALIZABLE = "java.io.Externalizable"; @@ -87,10 +88,11 @@ public interface CommonClassNames { @NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList"; @NonNls String JAVA_LANG_INVOKE_MH_POLYMORPHIC = "java.lang.invoke.MethodHandle.PolymorphicSignature"; - String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; + @NonNls String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; @NonNls String JAVA_LANG_RUNNABLE = "java.lang.Runnable"; @NonNls String JAVA_IO_FILE = "java.io.File"; - String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError"; + @NonNls String JAVA_LANG_ASSERTION_ERROR = "java.lang.AssertionError"; @NonNls String JAVA_UTIL_CONCURRENT_CALLABLE = "java.util.concurrent.Callable"; @NonNls String JAVA_UTIL_MAP_ENTRY = "java.util.Map.Entry"; + @NonNls String JAVA_UTIL_HASH_MAP = "java.util.HashMap"; } diff --git a/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java b/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java index 397fdf5f958e..320a69c19f25 100644 --- a/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java +++ b/java/java-psi-api/src/com/intellij/psi/JavaResolveResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package com.intellij.psi; /** * JavaResolveResult holds additional information that is obtained - * when Java references are being resolved + * when Java references are being resolved. * * @author ik, dsl * @see com.intellij.psi.PsiCall#resolveMethodGenerics() @@ -26,8 +26,7 @@ public interface JavaResolveResult extends ResolveResult { JavaResolveResult[] EMPTY_ARRAY = new JavaResolveResult[0]; /** - * Substitutor providing values of type parameters occuring - * in {@link #getElement()}. + * Substitutor providing values of type parameters occurring in {@link #getElement()}. */ PsiSubstitutor getSubstitutor(); @@ -35,34 +34,24 @@ public interface JavaResolveResult extends ResolveResult { /** * @return true if {@link #getElement()} is accessible from reference. - * */ boolean isAccessible(); boolean isStaticsScopeCorrect(); /** - * @return scope in the reference's file where the reference has been resolved - * null for qualified and local references + * @return scope in the reference's file where the reference has been resolved, + * {@code null} for qualified and local references. */ PsiElement getCurrentFileResolveScope(); - - JavaResolveResult EMPTY = new JavaResolveResult(){ - @Override - public PsiElement getElement(){return null;} - @Override - public PsiSubstitutor getSubstitutor(){return PsiSubstitutor.EMPTY;} - @Override - public boolean isValidResult(){return false;} - @Override - public boolean isAccessible(){return false;} - @Override - public boolean isStaticsScopeCorrect(){return false;} - @Override - public PsiElement getCurrentFileResolveScope() { return null; } - - @Override - public boolean isPackagePrefixPackageReference() { return false; } + JavaResolveResult EMPTY = new JavaResolveResult() { + @Override public PsiElement getElement() { return null; } + @Override public PsiSubstitutor getSubstitutor() { return PsiSubstitutor.EMPTY; } + @Override public boolean isValidResult() { return false; } + @Override public boolean isAccessible() { return false; } + @Override public boolean isStaticsScopeCorrect() { return false; } + @Override public PsiElement getCurrentFileResolveScope() { return null; } + @Override public boolean isPackagePrefixPackageReference() { return false; } }; }
\ No newline at end of file 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 9a5303ed4417..5214e3eb0cfa 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -17,12 +17,15 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,6 +38,7 @@ import java.util.*; public class LambdaUtil { private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName()); public static ThreadLocal<Set<PsiParameterList>> ourParams = new ThreadLocal<Set<PsiParameterList>>(); + @NonNls public static final String JAVA_LANG_FUNCTIONAL_INTERFACE = "java.lang.FunctionalInterface"; @Nullable public static PsiType getFunctionalInterfaceReturnType(PsiLambdaExpression expr) { @@ -109,13 +113,29 @@ public class LambdaUtil { while (parent instanceof PsiParenthesizedExpression) { parent = parent.getParent(); } - if (parent instanceof PsiExpressionList && functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){ - return false; + if (parent instanceof PsiExpressionList) { + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiMethodCallExpression) { + final PsiExpression qualifierExpression = ((PsiMethodCallExpression)gParent).getMethodExpression().getQualifierExpression(); + final PsiType type = qualifierExpression != null ? qualifierExpression.getType() : null; + if (type instanceof PsiClassType && ((PsiClassType)type).isRaw()) { + return true; + } + } + if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){ + return false; + } } return true; } public static boolean isAcceptable(PsiLambdaExpression lambdaExpression, final PsiType leftType, boolean checkReturnType) { + if (leftType instanceof PsiIntersectionType) { + for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) { + if (isAcceptable(lambdaExpression, conjunctType, checkReturnType)) return true; + } + return false; + } final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType); final PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass) { @@ -462,17 +482,16 @@ public class LambdaUtil { if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); } - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type); - if (resolveResult != null) { - final PsiMethod method = getFunctionalInterfaceMethod(type); - if (method != null) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameterIndex < parameters.length) { - final PsiType psiType = getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType()); - if (!dependsOnTypeParams(psiType, type, lambdaExpression, null)) { - return GenericsUtil.eliminateWildcards(psiType); - } - } + if (type instanceof PsiIntersectionType) { + final PsiType[] conjuncts = ((PsiIntersectionType)type).getConjuncts(); + for (PsiType conjunct : conjuncts) { + final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct); + if (lambdaParameterFromType != null) return lambdaParameterFromType; + } + } else { + final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type); + if (lambdaParameterFromType != null) { + return lambdaParameterFromType; } } } @@ -485,6 +504,23 @@ public class LambdaUtil { return new PsiLambdaParameterType(param); } + private static PsiType getLambdaParameterFromType(int parameterIndex, PsiLambdaExpression lambdaExpression, PsiType conjunct) { + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(conjunct); + if (resolveResult != null) { + final PsiMethod method = getFunctionalInterfaceMethod(conjunct); + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameterIndex < parameters.length) { + final PsiType psiType = getSubstitutor(method, resolveResult).substitute(parameters[parameterIndex].getType()); + if (!dependsOnTypeParams(psiType, conjunct, lambdaExpression, null)) { + return GenericsUtil.eliminateWildcards(psiType); + } + } + } + } + return null; + } + public static PsiSubstitutor inferFromReturnType(final PsiTypeParameter[] typeParameters, final PsiType returnType, @Nullable final PsiType interfaceMethodReturnType, @@ -557,6 +593,104 @@ public class LambdaUtil { return result; } + public static void checkMoreSpecificReturnType(List<CandidateInfo> conflicts, int functionalInterfaceIdx) { + final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]); + for (int i = 1; i < newConflictsArray.length; i++) { + final CandidateInfo method = newConflictsArray[i]; + final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method); + for (int j = 0; j < i; j++) { + final CandidateInfo conflict = newConflictsArray[j]; + assert conflict != method; + final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict); + if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) { + int moreSpecific = isMoreSpecific(interfaceReturnType, interfaceReturnType1); + if (moreSpecific > 0) { + conflicts.remove(method); + break; + } + else if (moreSpecific < 0) { + conflicts.remove(conflict); + } + } + } + } + } + + private static int isMoreSpecific(PsiType returnType, PsiType returnType1) { + if (returnType == PsiType.VOID || returnType1 == PsiType.VOID) return 0; + if (returnType instanceof PsiPrimitiveType) { + if (!(returnType1 instanceof PsiPrimitiveType)) { + return -1; + } else { + return TypeConversionUtil.areTypesConvertible(returnType, returnType1) ? 1 : -1; + } + } + if (returnType1 instanceof PsiPrimitiveType) { + return 1; + } + + final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType); + final PsiClass rClass = r.getElement(); + final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1); + final PsiClass rClass1 = r1.getElement(); + if (rClass != null && rClass1 != null) { + if (rClass == rClass1) { + int moreSpecific = 0; + for (PsiTypeParameter parameter : rClass.getTypeParameters()) { + final PsiType t = r.getSubstitutor().substituteWithBoundsPromotion(parameter); + final PsiType t1 = r1.getSubstitutor().substituteWithBoundsPromotion(parameter); + if (t == null || t1 == null) continue; + if (t1.isAssignableFrom(t) && !GenericsUtil.eliminateWildcards(t1).equals(t)) { + if (moreSpecific == 1) { + return 0; + } + moreSpecific = -1; + } + else if (t.isAssignableFrom(t1) && !GenericsUtil.eliminateWildcards(t).equals(t1)) { + if (moreSpecific == -1) { + return 0; + } + moreSpecific = 1; + } + else { + return 0; + } + } + return moreSpecific; + } + else if (rClass1.isInheritor(rClass, true)) { + return 1; + } + else if (rClass.isInheritor(rClass1, true)) { + return -1; + } + } + return 0; + } + + @Nullable + private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) { + final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters(); + if (methodParameters.length == 0) return null; + final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1]; + final PsiType functionalInterfaceType = method.getSubstitutor().substitute(param.getType()); + return getFunctionalInterfaceReturnType(functionalInterfaceType); + } + + @Nullable + public static String checkFunctionalInterface(PsiAnnotation annotation) { + if (PsiUtil.isLanguageLevel8OrHigher(annotation) && Comparing.strEqual(annotation.getQualifiedName(), JAVA_LANG_FUNCTIONAL_INTERFACE)) { + final PsiAnnotationOwner owner = annotation.getOwner(); + if (owner instanceof PsiModifierList) { + final PsiElement parent = ((PsiModifierList)owner).getParent(); + if (parent instanceof PsiClass) { + return LambdaHighlightingUtil.checkInterfaceFunctional((PsiClass)parent); + } + } + } + return null; + } + static class TypeParamsChecker extends PsiTypeVisitor<Boolean> { private PsiMethod myMethod; private final PsiClass myClass; diff --git a/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java b/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java index 7638a64265cd..41bb666bf429 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiElementFinder.java @@ -99,6 +99,9 @@ public abstract class PsiElementFinder { return PsiClass.EMPTY_ARRAY; } + /** + * A method to optimize resolve (to only search classes in a package which might be there) + */ @NotNull public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { return getClassNames(getClasses(psiPackage, scope)); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java index c2c69e9f25b8..c6e92a3c3727 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,5 +45,4 @@ public interface PsiJavaReference extends PsiPolyVariantReference { @Override @NotNull JavaResolveResult[] multiResolve(boolean incompleteCode); - } 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 1d01037048bb..635f4ce4539a 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -16,9 +16,7 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Comparing; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.MethodSignature; import com.intellij.psi.util.PsiUtil; @@ -26,7 +24,6 @@ import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.Nullable; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -116,6 +113,12 @@ public class PsiMethodReferenceUtil { public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) { if (methodReferenceExpression == null) return false; + if (left instanceof PsiIntersectionType) { + for (PsiType conjunct : ((PsiIntersectionType)left).getConjuncts()) { + if (isAcceptable(methodReferenceExpression, conjunct)) return true; + } + return false; + } Map<PsiMethodReferenceExpression, PsiType> map = ourRefs.get(); if (map == null) { map = new HashMap<PsiMethodReferenceExpression, PsiType>(); @@ -240,7 +243,7 @@ public class PsiMethodReferenceUtil { final int min = Math.min(signatureParameterTypes2.length, signatureParameterTypes1.length); for (int i = 0; i < min; i++) { - final PsiType type1 = psiSubstitutor.substitute(GenericsUtil.eliminateWildcards(signatureParameterTypes1[offset + i])); + final PsiType type1 = GenericsUtil.eliminateWildcards(psiSubstitutor.substitute(signatureParameterTypes1[offset + i])); if (isVarargs && i == min - 1) { if (!TypeConversionUtil.isAssignable(((PsiArrayType)signatureParameterTypes2[i]).getComponentType(), type1) && !TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) { @@ -248,7 +251,7 @@ public class PsiMethodReferenceUtil { } } else { - if (!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], psiSubstitutor.substitute(GenericsUtil.eliminateWildcards(type1)))) { + if (!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) { return false; } } @@ -266,76 +269,4 @@ public class PsiMethodReferenceUtil { methodReferenceExpression); return (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0]; } - - public static void processMethodReferenceReturnType(List<CandidateInfo> conflicts, int functionalInterfaceIdx) { - final CandidateInfo[] newConflictsArray = conflicts.toArray(new CandidateInfo[conflicts.size()]); - for (int i = 1; i < newConflictsArray.length; i++) { - final CandidateInfo method = newConflictsArray[i]; - final PsiType interfaceReturnType = getReturnType(functionalInterfaceIdx, method); - for (int j = 0; j < i; j++) { - final CandidateInfo conflict = newConflictsArray[j]; - assert conflict != method; - final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict); - if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) { - int moreSpecific = isMoreSpecific(interfaceReturnType, interfaceReturnType1); - if (moreSpecific > 0) { - conflicts.remove(method); - break; - } - else if (moreSpecific < 0) { - conflicts.remove(conflict); - } - } - } - } - } - - private static int isMoreSpecific(PsiType returnType, PsiType returnType1) { - final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType); - final PsiClass rClass = r.getElement(); - final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1); - final PsiClass rClass1 = r1.getElement(); - if (rClass != null && rClass1 != null) { - if (rClass == rClass1) { - int moreSpecific = 0; - for (PsiTypeParameter parameter : rClass.getTypeParameters()) { - final PsiType t = r.getSubstitutor().substituteWithBoundsPromotion(parameter); - final PsiType t1 = r1.getSubstitutor().substituteWithBoundsPromotion(parameter); - if (t == null || t1 == null) continue; - if (t1.isAssignableFrom(t) && !GenericsUtil.eliminateWildcards(t1).equals(t)) { - if (moreSpecific == 1) { - return 0; - } - moreSpecific = -1; - } - else if (t.isAssignableFrom(t1) && !GenericsUtil.eliminateWildcards(t).equals(t1)) { - if (moreSpecific == -1) { - return 0; - } - moreSpecific = 1; - } - else { - return 0; - } - } - return moreSpecific; - } - else if (rClass1.isInheritor(rClass, true)) { - return 1; - } - else if (rClass.isInheritor(rClass1, true)) { - return -1; - } - } - return 0; - } - - @Nullable - private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) { - final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters(); - if (methodParameters.length == 0) return null; - final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1]; - final PsiType functionalInterfaceType = method.getSubstitutor().substitute(param.getType()); - return LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); - } } diff --git a/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java b/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java index 23d4d4fa25f6..a105f446f288 100644 --- a/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java +++ b/java/java-psi-api/src/com/intellij/psi/augment/PsiAugmentProvider.java @@ -17,7 +17,6 @@ package com.intellij.psi.augment; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; @@ -35,11 +34,8 @@ public abstract class PsiAugmentProvider { public static <Psi extends PsiElement> List<Psi> collectAugments(@NotNull final PsiElement element, @NotNull final Class<Psi> type) { final List<Psi> augments = new ArrayList<Psi>(); for (PsiAugmentProvider provider : Extensions.getExtensions(EP_NAME)) { - try { - final List<Psi> list = provider.getAugments(element, type); - augments.addAll(list); - } - catch (ProcessCanceledException ignore) { } + final List<Psi> list = provider.getAugments(element, type); + augments.addAll(list); } return augments; diff --git a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java index c964036edfaf..aeb83e4f4cd4 100644 --- a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java +++ b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/DefaultParameterTypeInferencePolicy.java @@ -27,7 +27,7 @@ public class DefaultParameterTypeInferencePolicy extends ParameterTypeInferenceP @Nullable @Override - public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall, + public Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList parent, PsiCallExpression contextCall, PsiTypeParameter typeParameter) { diff --git a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java index e50133b99fb8..780232a4e59f 100644 --- a/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java +++ b/java/java-psi-api/src/com/intellij/psi/impl/source/resolve/ParameterTypeInferencePolicy.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable; */ public abstract class ParameterTypeInferencePolicy { @Nullable - public abstract Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiCallExpression innerMethodCall, + public abstract Pair<PsiType, ConstraintType> inferTypeConstraintFromCallContext(PsiExpression innerMethodCall, PsiExpressionList parent, PsiCallExpression contextCall, PsiTypeParameter typeParameter); diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index 8126582654f0..8c6f4c4ed477 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -41,7 +41,6 @@ public class MethodCandidateInfo extends CandidateInfo{ private final PsiType[] myTypeArguments; private PsiSubstitutor myCalcedSubstitutor = null; private final LanguageLevel myLanguageLevel; - private static final Object LOCK = new Object(); public MethodCandidateInfo(PsiElement candidate, PsiSubstitutor substitutor, @@ -99,27 +98,11 @@ public class MethodCandidateInfo extends CandidateInfo{ PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); PsiMethod method = getElement(); if (myTypeArguments == null) { - Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map; - synchronized (LOCK) { - map = CURRENT_CANDIDATE.get(); - if (map == null) { - map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>(); - CURRENT_CANDIDATE.set(map); - } - } - map.put(myArgumentList, Pair.create(getElement(), incompleteSubstitutor)); - try { - - final Set<PsiParameterList> lists = LambdaUtil.ourParams.get(); - if (lists != null && !lists.isEmpty()) { + final Set<PsiParameterList> lists = LambdaUtil.ourParams.get(); + if (lists != null && !lists.isEmpty()) { return inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); - } - - myCalcedSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); - } - finally { - map.remove(myArgumentList); - } + } + myCalcedSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE); } else { PsiTypeParameter[] typeParams = method.getTypeParameters(); @@ -165,21 +148,32 @@ public class MethodCandidateInfo extends CandidateInfo{ } public PsiSubstitutor inferTypeArguments(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) { - PsiMethod method = getElement(); - PsiTypeParameter[] typeParameters = method.getTypeParameters(); - - JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); - if (!method.hasModifierProperty(PsiModifier.STATIC)) { - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) { - return javaPsiFacade.getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters); - } + Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map = CURRENT_CANDIDATE.get(); + if (map == null) { + map = new ConcurrentWeakHashMap<PsiElement, Pair<PsiMethod, PsiSubstitutor>>(); + CURRENT_CANDIDATE.set(map); } + final PsiMethod method = getElement(); + final Pair<PsiMethod, PsiSubstitutor> alreadyThere = map.put(myArgumentList, Pair.create(method, super.getSubstitutor())); + try { + PsiTypeParameter[] typeParameters = method.getTypeParameters(); + + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(method.getProject()); + if (!method.hasModifierProperty(PsiModifier.STATIC)) { + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && PsiUtil.isRawSubstitutor(containingClass, mySubstitutor)) { + return javaPsiFacade.getElementFactory().createRawSubstitutor(mySubstitutor, typeParameters); + } + } - final PsiElement parent = getParent(); - if (parent == null) return PsiSubstitutor.EMPTY; - return javaPsiFacade.getResolveHelper() - .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy); + final PsiElement parent = getParent(); + if (parent == null) return PsiSubstitutor.EMPTY; + return javaPsiFacade.getResolveHelper() + .inferTypeArguments(typeParameters, method.getParameterList().getParameters(), arguments, mySubstitutor, parent, policy); + } + finally { + if (alreadyThere == null) map.remove(myArgumentList); + } } public boolean isInferencePossible() { diff --git a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java index d7f8aa2a27c2..158e7dd81a16 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/ClassUtil.java @@ -244,7 +244,7 @@ public class ClassUtil { } @Nullable - public static String getJVMClassName(PsiClass aClass) { + public static String getJVMClassName(@NotNull PsiClass aClass) { final PsiClass containingClass = aClass.getContainingClass(); if (containingClass != null) { String parentName = getJVMClassName(containingClass); diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java index 72c373ec94a5..f97ff1736c8d 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java @@ -202,7 +202,7 @@ public class MethodSignatureUtil { if (checkDeep) { final PsiClass clazz = superClass.getSuperClass(); - if (clazz != null) { + if (clazz != null && clazz != superClass) { PsiSubstitutor substitutor1 = TypeConversionUtil.getSuperClassSubstitutor(clazz, superClass, superSubstitutor); return doFindMethodInSuperClassBySignatureInDerived(clazz, substitutor1, signature, true); } diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java index 08b8deb0f0e4..3d6f4c7f5be5 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java @@ -431,6 +431,20 @@ public class PsiFormatUtil extends PsiFormatUtilBase { } public static String getPackageDisplayName(@NotNull final PsiClass psiClass) { + if (psiClass instanceof PsiTypeParameter) { + PsiTypeParameterListOwner owner = ((PsiTypeParameter)psiClass).getOwner(); + String ownerName = null; + if (owner instanceof PsiClass) { + ownerName = ((PsiClass)owner).getQualifiedName(); + if (ownerName == null) { + ownerName = owner.getName(); + } + } else if (owner instanceof PsiMethod) { + ownerName = owner.getName(); + } + return ownerName == null ? "type parameter" : "type parameter of " + ownerName; + } + @NonNls String packageName = psiClass.getQualifiedName(); packageName = packageName == null || packageName.lastIndexOf('.') <= 0 ? "" : packageName.substring(0, packageName.lastIndexOf('.')); if (packageName.isEmpty()) { diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index c0d120fcf0d1..a206a642e396 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -667,9 +667,7 @@ public class TypeConversionUtil { if (right instanceof PsiMethodReferenceType) { final PsiMethodReferenceExpression methodReferenceExpression = ((PsiMethodReferenceType)right).getExpression(); - if (left instanceof PsiClassType) { - return PsiMethodReferenceUtil.isAcceptable(methodReferenceExpression, (PsiClassType)left); - } else if (left instanceof PsiLambdaExpressionType) { + if (left instanceof PsiLambdaExpressionType) { final PsiType rType = methodReferenceExpression.getFunctionalInterfaceType(); final PsiType lType = ((PsiLambdaExpressionType)left).getExpression().getFunctionalInterfaceType(); return Comparing.equal(rType, lType); @@ -678,18 +676,17 @@ public class TypeConversionUtil { final PsiType lType = ((PsiMethodReferenceType)left).getExpression().getFunctionalInterfaceType(); return Comparing.equal(rType, lType); } + return PsiMethodReferenceUtil.isAcceptable(methodReferenceExpression, left); } if (right instanceof PsiLambdaExpressionType) { final PsiLambdaExpression rLambdaExpression = ((PsiLambdaExpressionType)right).getExpression(); - if (left instanceof PsiClassType) { - return LambdaUtil.isAcceptable(rLambdaExpression, left, false); - } if (left instanceof PsiLambdaExpressionType) { final PsiLambdaExpression lLambdaExpression = ((PsiLambdaExpressionType)left).getExpression(); final PsiType rType = rLambdaExpression.getFunctionalInterfaceType(); final PsiType lType = lLambdaExpression.getFunctionalInterfaceType(); return Comparing.equal(rType, lType); } + return LambdaUtil.isAcceptable(rLambdaExpression, left, false); } if (left instanceof PsiIntersectionType) { |