mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
method refs: when no acceptable methods found force conflicts to be empty; raw refs corrected; check for static should be performed over inner class in case of constructors
This commit is contained in:
@@ -220,7 +220,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
public ResolveResult[] resolve(@NotNull PsiJavaReference reference, boolean incompleteCode) {
|
||||
final Ref<PsiClass> classRef = new Ref<PsiClass>();
|
||||
final Ref<PsiSubstitutor> substRef = new Ref<PsiSubstitutor>();
|
||||
boolean checkStatic = process(classRef, substRef);
|
||||
final boolean beginsWithReferenceType = process(classRef, substRef);
|
||||
|
||||
final PsiClass containingClass = classRef.get();
|
||||
final PsiSubstitutor substitutor = substRef.get();
|
||||
@@ -242,15 +242,14 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(resolveResult.getSubstitutor()) : null;
|
||||
final MethodReferenceConflictResolver conflictResolver = new MethodReferenceConflictResolver(containingClass, substitutor,
|
||||
signature);
|
||||
final MethodReferenceConflictResolver conflictResolver = new MethodReferenceConflictResolver(containingClass, substitutor, signature, beginsWithReferenceType);
|
||||
final MethodCandidatesProcessor processor = new MethodCandidatesProcessor(PsiMethodReferenceExpressionImpl.this,
|
||||
new PsiConflictResolver[]{conflictResolver},
|
||||
new SmartList<CandidateInfo>());
|
||||
processor.setIsConstructor(isConstructor);
|
||||
processor.setName(isConstructor ? containingClass.getName() : element.getText());
|
||||
|
||||
if (checkStatic) {
|
||||
if (beginsWithReferenceType) {
|
||||
if (containingClass.getContainingClass() == null || !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass aClass = null;
|
||||
if (PsiTreeUtil.isAncestor(containingClass, PsiMethodReferenceExpressionImpl.this, false)) {
|
||||
@@ -275,13 +274,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
private final PsiClass myContainingClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
private final MethodSignature mySignature;
|
||||
private final boolean myBeginsWithReferenceType;
|
||||
|
||||
private MethodReferenceConflictResolver(PsiClass containingClass,
|
||||
PsiSubstitutor psiSubstitutor,
|
||||
@Nullable MethodSignature signature) {
|
||||
@Nullable MethodSignature signature, boolean beginsWithReferenceType) {
|
||||
myContainingClass = containingClass;
|
||||
mySubstitutor = psiSubstitutor;
|
||||
mySignature = signature;
|
||||
myBeginsWithReferenceType = beginsWithReferenceType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -293,7 +294,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiType[] parameterTypes = mySignature.getParameterTypes();
|
||||
if (parameterTypes.length > 0) {
|
||||
final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(parameterTypes[0]);
|
||||
if (LambdaUtil.isReceiverType(parameterTypes[0], myContainingClass) && classResolveResult.getSubstitutor().equals(mySubstitutor)) {
|
||||
if (LambdaUtil.isReceiverType(parameterTypes[0], myContainingClass) &&
|
||||
((parameterTypes[0] instanceof PsiClassType && ((PsiClassType)parameterTypes[0]).isRaw()) || classResolveResult.getSubstitutor().equals(mySubstitutor))) {
|
||||
hasReceiver = true;
|
||||
}
|
||||
}
|
||||
@@ -305,6 +307,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiMethod psiMethod = ((MethodCandidateInfo)conflict).getElement();
|
||||
if (psiMethod == null) continue;
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
subst = subst.putAll(conflict.getSubstitutor());
|
||||
subst = subst.putAll(mySubstitutor);
|
||||
final PsiType[] signatureParameterTypes2 = psiMethod.getSignature(subst).getParameterTypes();
|
||||
|
||||
@@ -312,7 +315,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC);
|
||||
|
||||
if ((parameterTypes.length == signatureParameterTypes2.length || varArgs && parameterTypes.length >= signatureParameterTypes2.length) &&
|
||||
(isStatic || (psiMethod.isConstructor() && (conflict.isStaticsScopeCorrect() || myContainingClass.getContainingClass() == null) && !hasReceiver))) {
|
||||
(!myBeginsWithReferenceType || isStatic || (psiMethod.isConstructor() && (conflict.isStaticsScopeCorrect() || myContainingClass.getContainingClass() == null)))) {
|
||||
boolean correct = true;
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
final PsiType type1 = parameterTypes[i];
|
||||
@@ -326,7 +329,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
}
|
||||
}
|
||||
|
||||
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !isStatic && (!psiMethod.isConstructor() || myContainingClass.getContainingClass() != null)) {
|
||||
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !isStatic &&
|
||||
(!psiMethod.isConstructor() || (myContainingClass.getContainingClass() != null) && !myContainingClass.hasModifierProperty(PsiModifier.STATIC))) {
|
||||
boolean correct = true;
|
||||
for (int i = 0; i < signatureParameterTypes2.length; i++) {
|
||||
final PsiType type1 = parameterTypes[i + 1];
|
||||
@@ -339,7 +343,13 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
}
|
||||
}
|
||||
|
||||
if (secondCandidates.size() + firstCandidates.size() != 1) return null;
|
||||
final int acceptedCount = secondCandidates.size() + firstCandidates.size();
|
||||
if (acceptedCount != 1) {
|
||||
if (acceptedCount == 0) {
|
||||
conflicts.clear();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,4 +73,46 @@ class StaticInner1 {
|
||||
static {
|
||||
call3<error descr="Ambiguous method call: both 'StaticInner1.call3(I1)' and 'StaticInner1.call3(I2)' match">(StaticInner1.Inner :: new)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
class StaticInner2 {
|
||||
|
||||
static class Inner {
|
||||
Inner() {}
|
||||
}
|
||||
|
||||
|
||||
interface I1 {
|
||||
Inner m(StaticInner2 rec);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'StaticInner2.I1'">I1 i1 = StaticInner2.Inner :: new;</error>
|
||||
}
|
||||
|
||||
{
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'StaticInner2.I1'">I1 i1 = StaticInner2.Inner :: new;</error>
|
||||
}
|
||||
}
|
||||
|
||||
class NonStaticInner2 {
|
||||
|
||||
class Inner {
|
||||
Inner() {}
|
||||
}
|
||||
|
||||
|
||||
interface I1 {
|
||||
Inner m(NonStaticInner2 rec);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
I1 i1 = NonStaticInner2.Inner :: new;
|
||||
}
|
||||
|
||||
{
|
||||
I1 i1 = NonStaticInner2.Inner :: new;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user