mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java overload resolution: reuse computed getSubstitutor(false); use cache for method references
GitOrigin-RevId: abd73c52013d4924fa66fabdfa67bcba597279f5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b6d5ec0315
commit
308e4f7daf
@@ -20,8 +20,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -107,9 +109,17 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
@ApplicabilityLevelConstant
|
||||
public int getPertinentApplicabilityLevel() {
|
||||
return getPertinentApplicabilityLevel(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param map reuse substitutor from conflict resolver cache when available
|
||||
*/
|
||||
@ApplicabilityLevelConstant
|
||||
public int getPertinentApplicabilityLevel(@Nullable Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
int result = myPertinentApplicabilityLevel;
|
||||
if (result == 0) {
|
||||
myPertinentApplicabilityLevel = result = getPertinentApplicabilityLevelInner();
|
||||
myPertinentApplicabilityLevel = result = getPertinentApplicabilityLevelInner(() -> map != null ? map.get(this) : getSubstitutor(false));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -118,7 +128,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
* 15.12.2.2 Identify Matching Arity Methods Applicable by Strict Invocation
|
||||
*/
|
||||
@ApplicabilityLevelConstant
|
||||
private int getPertinentApplicabilityLevelInner() {
|
||||
private int getPertinentApplicabilityLevelInner(Supplier<PsiSubstitutor> substitutorSupplier) {
|
||||
if (myArgumentList == null || !myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
return getApplicabilityLevel();
|
||||
}
|
||||
@@ -127,7 +137,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
if (isToInferApplicability()) {
|
||||
//ensure applicability check is performed
|
||||
getSubstitutor(false);
|
||||
substitutorSupplier.get();
|
||||
|
||||
//already performed checks, so if inference failed, error message should be saved
|
||||
if (myApplicabilityError || isPotentiallyCompatible() != ThreeState.YES) {
|
||||
@@ -136,7 +146,7 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return isVarargs() ? ApplicabilityLevel.VARARGS : ApplicabilityLevel.FIXED_ARITY;
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = getSubstitutor(false);
|
||||
final PsiSubstitutor substitutor = substitutorSupplier.get();
|
||||
final Computable<Integer> computable = () -> computeWithKnownTargetType(() -> {
|
||||
//arg types are calculated here without additional constraints:
|
||||
//non-pertinent to applicability arguments of arguments would be skipped
|
||||
|
||||
+14
-7
@@ -19,11 +19,13 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MethodReferenceResolver implements ResolveCache.PolyVariantContextResolver<PsiMethodReferenceExpressionImpl> {
|
||||
@@ -208,7 +210,8 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict) {
|
||||
protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict,
|
||||
Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
return conflict.isVarargs() ? MethodCandidateInfo.ApplicabilityLevel.VARARGS : MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY;
|
||||
}
|
||||
|
||||
@@ -219,8 +222,9 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
|
||||
if (conflicts.isEmpty()) return null;
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
final Map<MethodCandidateInfo, PsiSubstitutor> map = FactoryMap.create(key -> key.getSubstitutor(false));
|
||||
|
||||
checkSameSignatures(conflicts);
|
||||
checkSameSignatures(conflicts, map);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
checkAccessStaticLevels(conflicts, true);
|
||||
@@ -254,12 +258,12 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
}
|
||||
}
|
||||
|
||||
CandidateInfo candidateInfo = resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY);
|
||||
CandidateInfo candidateInfo = resolveConflicts(firstCandidates, secondCandidates, map, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY);
|
||||
if (candidateInfo != null) {
|
||||
return candidateInfo;
|
||||
}
|
||||
|
||||
candidateInfo = resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.VARARGS);
|
||||
candidateInfo = resolveConflicts(firstCandidates, secondCandidates, map, MethodCandidateInfo.ApplicabilityLevel.VARARGS);
|
||||
if (candidateInfo != null) {
|
||||
return candidateInfo;
|
||||
}
|
||||
@@ -346,12 +350,15 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
}
|
||||
}
|
||||
|
||||
private CandidateInfo resolveConflicts(@NotNull List<CandidateInfo> firstCandidates, @NotNull List<CandidateInfo> secondCandidates, int applicabilityLevel) {
|
||||
private CandidateInfo resolveConflicts(@NotNull List<CandidateInfo> firstCandidates,
|
||||
@NotNull List<CandidateInfo> secondCandidates,
|
||||
Map<MethodCandidateInfo, PsiSubstitutor> map,
|
||||
int applicabilityLevel) {
|
||||
int firstApplicability = checkApplicability(firstCandidates);
|
||||
checkSpecifics(firstCandidates, applicabilityLevel);
|
||||
checkSpecifics(firstCandidates, applicabilityLevel, map, 0);
|
||||
|
||||
int secondApplicability = checkApplicability(secondCandidates);
|
||||
checkSpecifics(secondCandidates, applicabilityLevel, null, 1);
|
||||
checkSpecifics(secondCandidates, applicabilityLevel, map, 1);
|
||||
|
||||
if (firstApplicability < secondApplicability) {
|
||||
return secondCandidates.size() == 1 ? secondCandidates.get(0) : null;
|
||||
|
||||
+13
-6
@@ -81,7 +81,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
}
|
||||
|
||||
final int applicabilityLevel = checkApplicability(conflicts);
|
||||
final int applicabilityLevel = checkApplicability(conflicts, map);
|
||||
if (conflicts.size() == 1) return conflicts.get(0);
|
||||
|
||||
// makes no sense to do further checks, because if no one candidate matches by parameters count
|
||||
@@ -186,7 +186,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
checkSameSignatures(conflicts, null);
|
||||
}
|
||||
|
||||
private void checkSameSignatures(@NotNull List<? extends CandidateInfo> conflicts, Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
protected void checkSameSignatures(@NotNull List<? extends CandidateInfo> conflicts, Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
// candidates should go in order of class hierarchy traversal
|
||||
// in order for this to work
|
||||
Map<MethodSignature, CandidateInfo> signatures = new THashMap<>(conflicts.size());
|
||||
@@ -364,11 +364,17 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant
|
||||
public int checkApplicability(@NotNull List<CandidateInfo> conflicts) {
|
||||
return checkApplicability(conflicts, null);
|
||||
}
|
||||
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant
|
||||
public int checkApplicability(@NotNull List<CandidateInfo> conflicts,
|
||||
Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant int maxApplicabilityLevel = 0;
|
||||
boolean toFilter = false;
|
||||
for (CandidateInfo conflict : conflicts) {
|
||||
ProgressManager.checkCanceled();
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant final int level = getPertinentApplicabilityLevel((MethodCandidateInfo)conflict);
|
||||
@MethodCandidateInfo.ApplicabilityLevelConstant final int level = getPertinentApplicabilityLevel((MethodCandidateInfo)conflict, map);
|
||||
if (maxApplicabilityLevel > 0 && maxApplicabilityLevel != level) {
|
||||
toFilter = true;
|
||||
}
|
||||
@@ -381,7 +387,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext();) {
|
||||
ProgressManager.checkCanceled();
|
||||
CandidateInfo info = iterator.next();
|
||||
final int level = getPertinentApplicabilityLevel((MethodCandidateInfo)info);
|
||||
final int level = getPertinentApplicabilityLevel((MethodCandidateInfo)info, map);
|
||||
if (level < maxApplicabilityLevel) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -391,8 +397,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return maxApplicabilityLevel;
|
||||
}
|
||||
|
||||
protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict) {
|
||||
return conflict.getPertinentApplicabilityLevel();
|
||||
protected int getPertinentApplicabilityLevel(@NotNull MethodCandidateInfo conflict,
|
||||
Map<MethodCandidateInfo, PsiSubstitutor> map) {
|
||||
return conflict.getPertinentApplicabilityLevel(map);
|
||||
}
|
||||
|
||||
private static int getCheckAccessLevel(@NotNull MethodCandidateInfo method){
|
||||
|
||||
Reference in New Issue
Block a user