mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
method refs: ambiguity with method refs inside
This commit is contained in:
@@ -32,6 +32,7 @@ import java.util.*;
|
||||
*/
|
||||
public class LambdaUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName());
|
||||
public static ThreadLocal<Map<PsiMethodReferenceExpression, PsiType>> ourRefs = new ThreadLocal<Map<PsiMethodReferenceExpression, PsiType>>();
|
||||
public static ThreadLocal<Set<PsiParameterList>> ourParams = new ThreadLocal<Set<PsiParameterList>>();
|
||||
|
||||
@Nullable
|
||||
@@ -561,9 +562,23 @@ public class LambdaUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isAcceptable(@Nullable PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
|
||||
public static boolean isAcceptable(@Nullable final PsiMethodReferenceExpression methodReferenceExpression, PsiType left) {
|
||||
if (methodReferenceExpression == null) return false;
|
||||
final JavaResolveResult result = methodReferenceExpression.advancedResolve(false);
|
||||
Map<PsiMethodReferenceExpression, PsiType> map = ourRefs.get();
|
||||
if (map == null) {
|
||||
map = new HashMap<PsiMethodReferenceExpression, PsiType>();
|
||||
ourRefs.set(map);
|
||||
}
|
||||
|
||||
final JavaResolveResult result;
|
||||
try {
|
||||
if (map.put(methodReferenceExpression, left) != null) return false;
|
||||
result = methodReferenceExpression.advancedResolve(false);
|
||||
}
|
||||
finally {
|
||||
map.remove(methodReferenceExpression);
|
||||
}
|
||||
|
||||
final PsiElement resolve = result.getElement();
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(left);
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression {
|
||||
private static Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
|
||||
@@ -107,7 +108,11 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
LOG.error("invalid!");
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
ResolveResult[] results = ResolveCache.getInstance(getProject()).resolveWithCaching(this, new MethodReferenceResolver(), true,
|
||||
final MethodReferenceResolver resolver = new MethodReferenceResolver();
|
||||
if (getFunctionalInterfaceType() == null) {
|
||||
return (JavaResolveResult[])resolver.resolve(this, incompleteCode);
|
||||
}
|
||||
ResolveResult[] results = ResolveCache.getInstance(getProject()).resolveWithCaching(this, resolver, true,
|
||||
incompleteCode);
|
||||
return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results;
|
||||
}
|
||||
@@ -224,7 +229,16 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
final PsiElement element = getReferenceNameElement();
|
||||
final boolean isConstructor = element instanceof PsiKeyword && PsiKeyword.NEW.equals(element.getText());
|
||||
if (element instanceof PsiIdentifier || isConstructor) {
|
||||
final PsiType functionalInterfaceType = getFunctionalInterfaceType();
|
||||
PsiType functionalInterfaceType = getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType == null) {
|
||||
final Map<PsiMethodReferenceExpression,PsiType> map = LambdaUtil.ourRefs.get();
|
||||
if (map != null) {
|
||||
functionalInterfaceType = map.get(PsiMethodReferenceExpressionImpl.this);
|
||||
}
|
||||
else {
|
||||
functionalInterfaceType = null;
|
||||
}
|
||||
}
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(resolveResult.getSubstitutor()) : null;
|
||||
|
||||
@@ -29,7 +29,7 @@ class MyTest {
|
||||
|
||||
{
|
||||
Bar1 b1 = MyTest :: foo;
|
||||
bar<error descr="Cannot resolve method 'bar(<method reference>)'">(MyTest :: foo)</error>;
|
||||
bar<error descr="Ambiguous method call: both 'MyTest.bar(Bar1)' and 'MyTest.bar(Bar2)' match">(MyTest :: foo)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,12 +55,12 @@ class StaticInner {
|
||||
|
||||
class StaticInner1 {
|
||||
static class Inner {
|
||||
Inner(StaticInner outer) {}
|
||||
Inner(StaticInner1 outer) {}
|
||||
Inner() {}
|
||||
}
|
||||
|
||||
interface I1 {
|
||||
Inner _(StaticInner rec);
|
||||
Inner _(StaticInner1 rec);
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
@@ -71,6 +71,6 @@ class StaticInner1 {
|
||||
static void call3(I2 s) {}
|
||||
|
||||
static {
|
||||
call3<error descr="Cannot resolve method 'call3(<method reference>)'">(StaticInner.Inner :: new)</error>;
|
||||
call3<error descr="Ambiguous method call: both 'StaticInner1.call3(I1)' and 'StaticInner1.call3(I2)' match">(StaticInner1.Inner :: new)</error>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user