mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new overload resolution: remember candidate when argument type is to be calculated (IDEA-137921)
This commit is contained in:
@@ -115,34 +115,23 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
if (myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
|
||||
return getApplicabilityLevel();
|
||||
}
|
||||
@ApplicabilityLevelConstant int level;
|
||||
final PsiSubstitutor substitutor = getSubstitutor(false);
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = ContainerUtil.createConcurrentWeakMap();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final PsiMethod method = getElement();
|
||||
final CurrentCandidateProperties properties = new CurrentCandidateProperties(method, substitutor, isVarargs(), true);
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(), properties);
|
||||
try {
|
||||
PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
@ApplicabilityLevelConstant int level = computeForOverloadedCandidate(new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
PsiType[] argumentTypes = getArgumentTypes();
|
||||
if (argumentTypes == null) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
level = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
|
||||
if (!isVarargs() && level < ApplicabilityLevel.FIXED_ARITY) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
int level = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
|
||||
if (!isVarargs() && level < ApplicabilityLevel.FIXED_ARITY) {
|
||||
return ApplicabilityLevel.NOT_APPLICABLE;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) {
|
||||
map.remove(getMarkerList());
|
||||
} else {
|
||||
map.put(getMarkerList(), alreadyThere);
|
||||
}
|
||||
}
|
||||
}, substitutor);
|
||||
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
@@ -154,6 +143,34 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
return level;
|
||||
}
|
||||
|
||||
public PsiType[] getPertinentArgumentTypes() {
|
||||
return computeForOverloadedCandidate(new Computable<PsiType[]>() {
|
||||
public PsiType[] compute() {
|
||||
return getArgumentTypes();
|
||||
}
|
||||
}, getSubstitutor(false));
|
||||
}
|
||||
|
||||
private <T> T computeForOverloadedCandidate(final Computable<T> computable, final PsiSubstitutor substitutor) {
|
||||
Map<PsiElement, CurrentCandidateProperties> map = CURRENT_CANDIDATE.get();
|
||||
if (map == null) {
|
||||
map = ContainerUtil.createConcurrentWeakMap();
|
||||
CURRENT_CANDIDATE.set(map);
|
||||
}
|
||||
final CurrentCandidateProperties alreadyThere = map.put(getMarkerList(),
|
||||
new CurrentCandidateProperties(getElement(), substitutor, isVarargs(), true));
|
||||
try {
|
||||
return computable.compute();
|
||||
}
|
||||
finally {
|
||||
if (alreadyThere == null) {
|
||||
map.remove(getMarkerList());
|
||||
} else {
|
||||
map.put(getMarkerList(), alreadyThere);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiSubstitutor getSiteSubstitutor() {
|
||||
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
|
||||
|
||||
+6
-18
@@ -422,16 +422,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
(method.getCurrentFileResolveScope() instanceof PsiImportStaticStatement ? 0 : 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiType[] getActualParameterTypes() {
|
||||
PsiType[] types = myActualParameterTypes;
|
||||
if (types == null) {
|
||||
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
|
||||
myActualParameterTypes = types = getArgumentTypes();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private int getActualParametersLength() {
|
||||
if (myActualParameterTypes == null) {
|
||||
LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList);
|
||||
@@ -440,11 +430,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return myActualParameterTypes.length;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected PsiType[] getArgumentTypes() {
|
||||
return ((PsiExpressionList)myArgumentsList).getExpressionTypes();
|
||||
}
|
||||
|
||||
private enum Specifics {
|
||||
FIRST,
|
||||
SECOND,
|
||||
@@ -509,20 +494,23 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
boolean sameBoxing = true;
|
||||
int[] boxingHappened = new int[2];
|
||||
final PsiType[] argTypes1 = myActualParameterTypes != null ? myActualParameterTypes : info1.getPertinentArgumentTypes();
|
||||
final PsiType[] argTypes2 = myActualParameterTypes != null ? myActualParameterTypes : info2.getPertinentArgumentTypes();
|
||||
for (int i = 0; i < types1.length; i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
PsiType type1 = classSubstitutor1.substitute(types1[i]);
|
||||
PsiType type2 = classSubstitutor2.substitute(types2[i]);
|
||||
PsiType argType = i < getActualParameterTypes().length ? getActualParameterTypes()[i] : null;
|
||||
final PsiType argType1 = i < getActualParametersLength() ? argTypes1[i] : null;
|
||||
final PsiType argType2 = i < getActualParametersLength() ? argTypes2[i] : null;
|
||||
|
||||
boolean boxingInFirst = false;
|
||||
if (isBoxingHappened(argType, type1, languageLevel)) {
|
||||
if (isBoxingHappened(argType1, type1, languageLevel)) {
|
||||
boxingHappened[0] += 1;
|
||||
boxingInFirst = true;
|
||||
}
|
||||
|
||||
boolean boxingInSecond = false;
|
||||
if (isBoxingHappened(argType, type2, languageLevel)) {
|
||||
if (isBoxingHappened(argType2, type2, languageLevel)) {
|
||||
boxingHappened[1] += 1;
|
||||
boxingInSecond = true;
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import java.lang.String;
|
||||
|
||||
abstract class Test {
|
||||
abstract <T> T get();
|
||||
|
||||
void foo() {
|
||||
String.valueOf(get());
|
||||
}
|
||||
}
|
||||
+4
@@ -98,6 +98,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
}).assertTiming();
|
||||
}
|
||||
|
||||
public void testMultipleOverloadsWithNestedGeneric() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user