mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
overload resolution: encapsulate overload guard checks + eliminate additional applicability predicate
GitOrigin-RevId: 41c411466ef8def32fb15535dc639a7f7dc29285
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c4eb244441
commit
e26bb55130
+1
-1
@@ -1453,7 +1453,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
if (results.length == 0 || results[0] instanceof MethodCandidateInfo &&
|
||||
!((MethodCandidateInfo)results[0]).isApplicable() &&
|
||||
functionalInterfaceType != null) {
|
||||
functionalInterfaceType != null || results.length > 1) {
|
||||
String description = null;
|
||||
if (results.length == 1) {
|
||||
description = ((MethodCandidateInfo)results[0]).getInferenceErrorMessage();
|
||||
|
||||
@@ -591,6 +591,7 @@ public class ExpectedTypesProvider {
|
||||
|
||||
PsiExpression rExpr = assignment.getRExpression();
|
||||
if (rExpr != null) {
|
||||
//prevent using left expression to detect type of the right
|
||||
PsiType type = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(assignment, false, () -> rExpr.getType());
|
||||
if (type != null && type != PsiType.NULL) {
|
||||
if (type instanceof PsiClassType) {
|
||||
@@ -1063,13 +1064,11 @@ public class ExpectedTypesProvider {
|
||||
if (candidateInfo instanceof MethodCandidateInfo) {
|
||||
final MethodCandidateInfo info = (MethodCandidateInfo)candidateInfo;
|
||||
Computable<PsiSubstitutor> computable = () -> info.inferSubstitutorFromArgs(policy, args);
|
||||
substitutor = info.isInferencePossible() && targetMethod == method
|
||||
? computable.compute()
|
||||
: MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(argumentList, false, computable);
|
||||
substitutor = computable.compute();
|
||||
if (!info.isStaticsScopeCorrect() && !method.hasModifierProperty(PsiModifier.STATIC) || info.getInferenceErrorMessage() != null) continue;
|
||||
}
|
||||
else {
|
||||
substitutor = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(argumentList, false, candidateInfo::getSubstitutor);
|
||||
substitutor = candidateInfo.getSubstitutor();
|
||||
}
|
||||
if (substitutor == null) {
|
||||
return ExpectedTypeInfo.EMPTY_ARRAY;
|
||||
@@ -1079,9 +1078,7 @@ public class ExpectedTypesProvider {
|
||||
|
||||
if (leftArgs != null && candidateInfo instanceof MethodCandidateInfo) {
|
||||
Computable<PsiSubstitutor> computable = () -> ((MethodCandidateInfo)candidateInfo).inferSubstitutorFromArgs(policy, leftArgs);
|
||||
substitutor = ((MethodCandidateInfo)candidateInfo).isInferencePossible() && targetMethod == method
|
||||
? computable.compute()
|
||||
: MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(argumentList, false, computable);
|
||||
substitutor = computable.compute();
|
||||
if (substitutor != null) {
|
||||
inferMethodCallArgumentTypes(argument, forCompletion, leftArgs, index, method, substitutor, set);
|
||||
if (set.size() >= myMaxCandidates) break;
|
||||
|
||||
+6
-13
@@ -21,7 +21,6 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.UserDataHolder;
|
||||
@@ -42,7 +41,6 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -486,17 +484,12 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
}
|
||||
|
||||
private static PsiSubstitutor getCandidateInfoSubstitutor(PsiElement argList, CandidateInfo candidate, boolean resolveResult) {
|
||||
Computable<PsiSubstitutor> computeSubstitutor =
|
||||
() -> candidate instanceof MethodCandidateInfo && ((MethodCandidateInfo)candidate).isInferencePossible()
|
||||
? ((MethodCandidateInfo)candidate).inferTypeArguments(resolveResult ? DefaultParameterTypeInferencePolicy.INSTANCE
|
||||
: CompletionParameterTypeInferencePolicy.INSTANCE, true)
|
||||
: candidate.getSubstitutor();
|
||||
if (resolveResult && candidate instanceof MethodCandidateInfo && ((MethodCandidateInfo)candidate).isInferencePossible()) {
|
||||
return computeSubstitutor.compute();
|
||||
}
|
||||
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(ObjectUtils.notNull(argList, candidate.getElement()),
|
||||
false,
|
||||
computeSubstitutor);
|
||||
return candidate instanceof MethodCandidateInfo &&
|
||||
((MethodCandidateInfo)candidate).isInferencePossible()
|
||||
? ((MethodCandidateInfo)candidate)
|
||||
.inferTypeArguments(resolveResult ? DefaultParameterTypeInferencePolicy.INSTANCE
|
||||
: CompletionParameterTypeInferencePolicy.INSTANCE, true)
|
||||
: candidate.getSubstitutor();
|
||||
}
|
||||
|
||||
private static boolean isAssignableParametersBeforeGivenIndex(final PsiParameter[] parms,
|
||||
|
||||
@@ -775,9 +775,10 @@ public class LambdaUtil {
|
||||
if (psiCall == null) {
|
||||
break;
|
||||
}
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(psiCall.getArgumentList());
|
||||
PsiExpressionList argumentList = psiCall.getArgumentList();
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
if (properties != null) {
|
||||
if (properties.isApplicabilityCheck() || lambdaExpression != null) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(argumentList) || lambdaExpression != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,9 +272,11 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
final PsiElement argumentList = getMarkerList();
|
||||
final CurrentCandidateProperties alreadyThere =
|
||||
map.put(argumentList, new CurrentCandidateProperties(this, applicabilityCheck));
|
||||
map.put(argumentList, new CurrentCandidateProperties(this));
|
||||
try {
|
||||
return computable.compute();
|
||||
return applicabilityCheck
|
||||
? ourOverloadGuard.doPreventingRecursion(argumentList, false, computable)
|
||||
: computable.compute();
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) {
|
||||
@@ -316,16 +318,9 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
myApplicabilityError.remove();
|
||||
try {
|
||||
Computable<PsiSubstitutor> computeSubst = () -> inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
|
||||
final PsiElement markerList = getMarkerList();
|
||||
final PsiSubstitutor inferredSubstitutor = includeReturnConstraint || markerList == null || isOverloadCheck()
|
||||
? computeSubst.compute()
|
||||
: ourOverloadGuard.doPreventingRecursion(markerList, true, computeSubst);
|
||||
if (inferredSubstitutor == null) {
|
||||
//todo log error
|
||||
return mySubstitutor;
|
||||
}
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
if (!stackStamp.mayCacheNow() ||
|
||||
isOverloadCheck() ||
|
||||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
|
||||
@@ -369,6 +364,9 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return !ourOverloadGuard.currentStack().isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isOverloadCheck(PsiElement argumentList) {
|
||||
return ourOverloadGuard.currentStack().contains(argumentList);
|
||||
}
|
||||
|
||||
public boolean isTypeArgumentsApplicable() {
|
||||
return isTypeArgumentsApplicable(() -> getSubstitutor(false));
|
||||
@@ -494,16 +492,14 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
}
|
||||
|
||||
public CurrentCandidateProperties createProperties() {
|
||||
return new CurrentCandidateProperties(this, false);
|
||||
return new CurrentCandidateProperties(this);
|
||||
}
|
||||
|
||||
public static class CurrentCandidateProperties {
|
||||
private final MethodCandidateInfo myMethod;
|
||||
private final boolean myApplicabilityCheck;
|
||||
|
||||
private CurrentCandidateProperties(MethodCandidateInfo info, boolean applicabilityCheck) {
|
||||
private CurrentCandidateProperties(MethodCandidateInfo info) {
|
||||
myMethod = info;
|
||||
myApplicabilityCheck = applicabilityCheck;
|
||||
}
|
||||
|
||||
public PsiMethod getMethod() {
|
||||
@@ -513,11 +509,6 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
public MethodCandidateInfo getInfo() {
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
|
||||
public boolean isApplicabilityCheck() {
|
||||
return myApplicabilityCheck;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplicabilityLevel {
|
||||
|
||||
+14
-8
@@ -169,17 +169,22 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodCandidateInfo.CurrentCandidateProperties getCurrentProperties(PsiElement parent) {
|
||||
|
||||
private static PsiExpressionList getArgumentList(PsiElement parent) {
|
||||
if (parent instanceof PsiCall) {
|
||||
return MethodCandidateInfo.getCurrentMethod(((PsiCall)parent).getArgumentList());
|
||||
return ((PsiCall)parent).getArgumentList();
|
||||
}
|
||||
if (parent instanceof PsiAnonymousClass) {
|
||||
return getCurrentProperties(parent.getParent());
|
||||
return getArgumentList(parent.getParent());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MethodCandidateInfo.CurrentCandidateProperties getCurrentProperties(PsiElement parent) {
|
||||
PsiExpressionList argumentList = getArgumentList(parent);
|
||||
return argumentList != null ? MethodCandidateInfo.getCurrentMethod(argumentList) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition from 15.12.2.2 Phase 1: Identify Matching Arity Methods Applicable by Subtyping Strict Invocation
|
||||
* An argument expression is considered pertinent to applicability for a potentially-applicable method m unless it has one of the following forms:
|
||||
@@ -336,7 +341,8 @@ public class InferenceSession {
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties != null && !properties.isApplicabilityCheck()) {
|
||||
PsiExpressionList argumentList = getArgumentList(parent);
|
||||
if (properties != null && argumentList != null && !MethodCandidateInfo.isOverloadCheck(argumentList)) {
|
||||
String expectedActualErrorMessage = null;
|
||||
final PsiMethod method = properties.getMethod();
|
||||
if (parent instanceof PsiCallExpression && PsiPolyExpressionUtil.isMethodCallPolyExpression((PsiExpression)parent, method)) {
|
||||
@@ -365,7 +371,7 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
//proceed to B3 constraints
|
||||
else if (parameters != null && parameters.length > 0 && args != null && !isOverloadCheck()) {
|
||||
else if (parameters != null && parameters.length > 0 && args != null && !isOverloadCheck()) {//todo
|
||||
final Set<ConstraintFormula> additionalConstraints = new LinkedHashSet<>();
|
||||
final HashSet<ConstraintFormula> ignoredConstraints = new HashSet<>();
|
||||
collectAdditionalConstraints(parameters, args, properties.getMethod(), mySiteSubstitutor, additionalConstraints,
|
||||
@@ -830,7 +836,7 @@ public class InferenceSession {
|
||||
final PsiExpressionList argumentList = ((PsiCall)gParent).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
if (properties != null && properties.isApplicabilityCheck()) {
|
||||
if (properties != null && MethodCandidateInfo.isOverloadCheck(argumentList)) {
|
||||
return getTypeByMethod(context, argumentList, properties.getMethod(), properties.getInfo().isVarargs(), properties.getInfo().getSiteSubstitutor(), inferParent);
|
||||
}
|
||||
|
||||
@@ -1118,7 +1124,7 @@ public class InferenceSession {
|
||||
}
|
||||
|
||||
public void setUncheckedInContext() {
|
||||
if (myContext != null && !MethodCandidateInfo.isOverloadCheck()) {
|
||||
if (myContext != null && !MethodCandidateInfo.isOverloadCheck(getArgumentList(myContext))) {//todo
|
||||
myContext.putUserData(ERASED, myErased);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class InferenceSessionContainer {
|
||||
if (//in order to to avoid caching of candidates's errors on parent (!) , so check for overload resolution is left here
|
||||
//But overload resolution can depend on type of lambda parameter. As it can't depend on lambda body,
|
||||
//traversing down would stop at lambda level and won't take into account overloaded method
|
||||
!MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argumentList)) {
|
||||
!MethodCandidateInfo.isOverloadCheck(argumentList)) {
|
||||
final PsiCall topLevelCall = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, false,
|
||||
() -> {
|
||||
if (parent instanceof PsiExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)parent)) {
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public class PsiConditionalExpressionImpl extends ExpressionPsiElement implement
|
||||
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(this) &&
|
||||
PsiPolyExpressionUtil.isPolyExpression(this) &&
|
||||
!MethodCandidateInfo.ourOverloadGuard.currentStack().contains(PsiUtil.skipParenthesizedExprUp(this.getParent()))) {
|
||||
!MethodCandidateInfo.isOverloadCheck(PsiUtil.skipParenthesizedExprUp(this.getParent()))) {
|
||||
//15.25.3 Reference Conditional Expressions
|
||||
// The type of a poly reference conditional expression is the same as its target type.
|
||||
return InferenceSession.getTargetType(this);
|
||||
|
||||
+2
-2
@@ -176,7 +176,7 @@ public class PsiLambdaExpressionImpl extends JavaStubPsiElement<FunctionalExpres
|
||||
}
|
||||
final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(argsList)) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
|
||||
if (candidateProperties != null) {
|
||||
final PsiMethod method = candidateProperties.getMethod();
|
||||
@@ -195,7 +195,7 @@ public class PsiLambdaExpressionImpl extends JavaStubPsiElement<FunctionalExpres
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && !hasFormalParameterTypes()) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(argsList) && !hasFormalParameterTypes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -382,7 +382,7 @@ public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement<Functio
|
||||
|
||||
final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
|
||||
final boolean isExact = isExact();
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(argsList)) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
|
||||
if (candidateProperties != null) {
|
||||
final PsiMethod method = candidateProperties.getMethod();
|
||||
@@ -401,7 +401,7 @@ public class PsiMethodReferenceExpressionImpl extends JavaStubPsiElement<Functio
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(argsList)) {
|
||||
if (!isExact) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class PsiSwitchExpressionImpl extends PsiSwitchBlockImpl implements PsiSw
|
||||
@Override
|
||||
public PsiType getType() {
|
||||
if (PsiPolyExpressionUtil.isPolyExpression(this) &&
|
||||
!MethodCandidateInfo.ourOverloadGuard.currentStack().contains(PsiUtil.skipParenthesizedExprUp(getParent()))) {
|
||||
!MethodCandidateInfo.isOverloadCheck(PsiUtil.skipParenthesizedExprUp(getParent()))) {
|
||||
return InferenceSession.getTargetType(this);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -48,11 +48,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
@Override
|
||||
public final CandidateInfo resolveConflict(@NotNull final List<CandidateInfo> conflicts){
|
||||
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(myArgumentsList)) {
|
||||
if (MethodCandidateInfo.isOverloadCheck(myArgumentsList)) {
|
||||
LOG.error("Recursive conflict resolution for:" + myArgumentsList.getParent() + "; " +
|
||||
"file=" + myArgumentsList.getContainingFile());
|
||||
}
|
||||
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, false, () -> guardedOverloadResolution(conflicts));
|
||||
return guardedOverloadResolution(conflicts);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ class AlienTest {
|
||||
IInt i1 = MyTest::<error descr="Cannot resolve method 'abracadabra'">abracadabra</error>;
|
||||
IInt i2 = MyTest::<error descr="Incompatible types: int is not convertible to String">foo</error>;
|
||||
IInt i3 = MyTest::<error descr="Cannot resolve method 'bar'">bar</error>;
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'AlienTest.IIntInt'">IIntInt i4 = MyTest::bar;</error>
|
||||
IIntInt i4 = MyTest::<error descr="Cannot resolve method 'bar'">bar</error>;
|
||||
IInt i5 = <error descr="Non-static method cannot be referenced from a static context">MyTest::baz</error>;
|
||||
IInt i6 = <error descr="'foo(int)' is not public in 'MyTest.Foo'. Cannot be accessed from outside package">MyTest.foo::foo</error>;
|
||||
IInt i7 = MyTest.<error descr="'MyTest.Foo' has private access in 'MyTest'">Foo</error>::foo;
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class MyTest {
|
||||
|
||||
{
|
||||
Bar1 b1 = MyTest :: foo;
|
||||
bar<error descr="Ambiguous method call: both 'MyTest.bar(Bar1)' and 'MyTest.bar(Bar2)' match">(MyTest :: foo)</error>;
|
||||
bar(MyTest :: <error descr="Cannot resolve method 'foo'">foo</error>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ class StaticInner1 {
|
||||
static void call3(I2 s) {}
|
||||
|
||||
static {
|
||||
call3<error descr="Ambiguous method call: both 'StaticInner1.call3(I1)' and 'StaticInner1.call3(I2)' match">(StaticInner1.Inner :: new)</error>;
|
||||
call3(StaticInner1.Inner :: <error descr="Cannot resolve constructor 'Inner'">new</error>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ interface Func<TIn, TOut>{
|
||||
class Main {
|
||||
|
||||
public static void main(final String[] args) {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'Func<java.lang.Integer,java.lang.String>'">Func<Integer, String> func = Integer::toString;</error>
|
||||
Func<Integer, String> func = Integer::<error descr="Cannot resolve method 'toString'">toString</error>;
|
||||
System.out.println(func.run(6));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import java.util.*;
|
||||
|
||||
class LambdaTest {
|
||||
public void testR() {
|
||||
<error descr="Incompatible types. Found: 'java.lang.String', required: '<method reference>'">new ArrayList<String>() :: size = ""</error>;
|
||||
new ArrayList<String>() :: <error descr="Cannot resolve method 'size'">size</error> = "";
|
||||
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -57,10 +57,10 @@ class MyTest1 {
|
||||
I2 s2 = MyTest1 :: m2;
|
||||
call2(MyTest1::m2);
|
||||
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I2'">I2 s3 = MyTest1 :: m3;</error>
|
||||
call2<error descr="'call2(MyTest1.I2)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m3)</error>;
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest1.I2'">I2 s4 = MyTest1 ::m4;</error>
|
||||
call2<error descr="'call2(MyTest1.I2)' in 'MyTest1' cannot be applied to '(<method reference>)'">(MyTest1::m4)</error>;
|
||||
I2 s3 = MyTest1 :: <error descr="Cannot resolve method 'm3'">m3</error>;
|
||||
call2(MyTest1::<error descr="Cannot resolve method 'm3'">m3</error>);
|
||||
I2 s4 = MyTest1 ::<error descr="Cannot resolve method 'm4'">m4</error>;
|
||||
call2(MyTest1::<error descr="Cannot resolve method 'm4'">m4</error>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,19 +106,19 @@ class MyTest2 {
|
||||
I2 s2 = MyTest2 :: m2;
|
||||
call2(MyTest2::m2);
|
||||
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I2'">I2 s3 = MyTest2 :: m3;</error>
|
||||
call2<error descr="'call2(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m3)</error>;
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest2.I2'">I2 s4 = MyTest2 ::m4;</error>
|
||||
call2<error descr="'call2(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m4)</error>;
|
||||
I2 s3 = MyTest2 :: <error descr="Cannot resolve method 'm3'">m3</error>;
|
||||
call2(MyTest2::<error descr="Cannot resolve method 'm3'">m3</error>);
|
||||
I2 s4 = MyTest2 ::<error descr="Cannot resolve method 'm4'">m4</error>;
|
||||
call2(MyTest2::<error descr="Cannot resolve method 'm4'">m4</error>);
|
||||
}
|
||||
|
||||
static void call3(I1 s) {}
|
||||
static void call3(I2 s) {}
|
||||
static {
|
||||
call3(MyTest2::m1);
|
||||
call3<error descr="Ambiguous method call: both 'MyTest2.call3(I1)' and 'MyTest2.call3(I2)' match">(MyTest2::m2)</error>;
|
||||
call3(MyTest2::<error descr="Cannot resolve method 'm2'">m2</error>);
|
||||
call3(MyTest2::m3);
|
||||
call3<error descr="'call3(MyTest2.I2)' in 'MyTest2' cannot be applied to '(<method reference>)'">(MyTest2::m4)</error>;
|
||||
call3(MyTest2::<error descr="Cannot resolve method 'm4'">m4</error>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -31,8 +31,8 @@ class Test {
|
||||
String i1 = instanceCall(this::m0);
|
||||
String i2 = instanceCall(this::m1);
|
||||
String i3 = instanceCall(this::m2);
|
||||
String i4 = instanceCall<error descr="Ambiguous method call: both 'Test.instanceCall(I0)' and 'Test.instanceCall(I1<Object>)' match">(this::m01)</error>;
|
||||
String i5 = instanceCall<error descr="Ambiguous method call: both 'Test.instanceCall(I0)' and 'Test.instanceCall(I1<Object>)' match">(this::m012)</error>;
|
||||
String i4 = instanceCall(this::<error descr="Cannot resolve method 'm01'">m01</error>);
|
||||
String i5 = instanceCall(this::<error descr="Cannot resolve method 'm012'">m012</error>);
|
||||
}
|
||||
|
||||
void n0() { }
|
||||
@@ -53,7 +53,7 @@ class Test {
|
||||
Test s1 = staticCall(Test::n0);
|
||||
Test s2 = staticCall(Test::n1);
|
||||
Test s3 = staticCall<error descr="Cannot resolve method 'staticCall(<method reference>)'">(Test::n2)</error>;
|
||||
Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Object>)' and 'Test.staticCall(I2<Object, String>)' match">(Test::n01)</error>;
|
||||
Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Object>)' and 'Test.staticCall(I2<Object, String>)' match">(Test::n012)</error>;
|
||||
Test s4 = staticCall(Test::<error descr="Cannot resolve method 'n01'">n01</error>);
|
||||
Test s5 = staticCall(Test::<error descr="Cannot resolve method 'n012'">n012</error>);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Test {
|
||||
{
|
||||
Set<String> m = replyWith(this::query);
|
||||
System.out.println(m);
|
||||
Set<String> m1 = replyWith<error descr="Ambiguous method call: both 'Test.replyWith(Function<Object, List<Object>>)' and 'Test.replyWith(Callable<List<Object>>)' match">(this::query1)</error>;
|
||||
Set<String> m1 = replyWith(this::<error descr="Cannot resolve method 'query1'">query1</error>);
|
||||
System.out.println(m1);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@ class Test {
|
||||
static void m(Test t, Object s) {}
|
||||
|
||||
static void test() {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.I'">I i = Test::m;</error>
|
||||
I i = Test::<error descr="Cannot resolve method 'm'">m</error>;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -84,10 +84,7 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doHighlighting()
|
||||
.stream()
|
||||
.filter(info -> info.type == HighlightInfoType.ERROR)
|
||||
.forEach(info -> Assert.assertEquals("<html><body>Incompatible types." +
|
||||
"<table><tr><td>Required:</td><td><font color='red'><b>Test.I</b></font></td></tr><tr><td>" +
|
||||
"Found:</td><td><font color='red'><b><method reference></b></font></td></tr></table><br/>" +
|
||||
"reason: method reference is ambiguous: both 'Test.m(Test, String)' and 'Test.m(String)' match</body></html>",
|
||||
.forEach(info -> Assert.assertEquals("<html>Cannot resolve method 'm'</html>",
|
||||
info.getToolTip()));
|
||||
}
|
||||
public void testSuperClassPotentiallyApplicableMembers() { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user