return getApplicabilityLevel();
}
@ApplicabilityLevelConstant int level;
- Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
- @Override
- public Integer compute() {
- if (PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
- 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;
- }
-
- final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
- if (!isVarargs() && applicabilityLevel < ApplicabilityLevel.FIXED_ARITY) {
- return ApplicabilityLevel.NOT_APPLICABLE;
- }
- return applicabilityLevel;
- }
- finally {
- if (alreadyThere == null) {
- map.remove(getMarkerList());
- } else {
- map.put(getMarkerList(), alreadyThere);
- }
- }
- }
- return getApplicabilityLevelInner();
+ 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;
}
- });
- if (boxedLevel == null) {
- return getApplicabilityLevel();
+ level = PsiUtil.getApplicabilityLevel(method, substitutor, argumentTypes, myLanguageLevel);
+ if (!isVarargs() && level < ApplicabilityLevel.FIXED_ARITY) {
+ return ApplicabilityLevel.NOT_APPLICABLE;
+ }
+ }
+ finally {
+ if (alreadyThere == null) {
+ map.remove(getMarkerList());
+ } else {
+ map.put(getMarkerList(), alreadyThere);
+ }
+ }
+ if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(false)) {
+ level = ApplicabilityLevel.NOT_APPLICABLE;
}
- level = boxedLevel;
- if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable(false)) level = ApplicabilityLevel.NOT_APPLICABLE;
return level;
}
return parent instanceof PsiNewExpression ? ((PsiNewExpression)parent).getArgumentList() : super.getMarkerList();
}
};
- if (!varargs && staticFactoryMethod.isVarArgs() && staticFactoryCandidateInfo.getPertinentApplicabilityLevel() < MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY) {
- return inferTypeParametersForStaticFactory(staticFactoryMethod, expression, parent, true);
+ if (!varargs && staticFactoryMethod.isVarArgs()) {
+ final Computable<Integer> computable = new Computable<Integer>() {
+ @Override
+ public Integer compute() {
+ return staticFactoryCandidateInfo.getPertinentApplicabilityLevel();
+ }
+ };
+ final Integer applicability = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(expression, true, computable);
+ if ((applicability != null ? applicability : staticFactoryCandidateInfo.getApplicabilityLevel()) < MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY) {
+ return inferTypeParametersForStaticFactory(staticFactoryMethod, expression, parent, true);
+ }
}
return staticFactoryCandidateInfo.getSubstitutor();
}
package com.intellij.psi.impl.source.tree.java;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.resolve.ResolveCache;
@Nullable
@Override
- public CandidateInfo resolveConflict(@NotNull List<CandidateInfo> conflicts) {
+ protected CandidateInfo guardedOverloadResolution(@NotNull List<CandidateInfo> conflicts) {
if (mySignature == null) return null;
if (conflicts.size() > 1) checkSameSignatures(conflicts);
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSuperMethodImplUtil;
}
@Override
- public CandidateInfo resolveConflict(@NotNull List<CandidateInfo> conflicts){
+ public final CandidateInfo resolveConflict(@NotNull final List<CandidateInfo> conflicts){
+ return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, true, new Computable<CandidateInfo>() {
+ @Override
+ public CandidateInfo compute() {
+ return guardedOverloadResolution(conflicts);
+ }
+ });
+ }
+
+ @Nullable
+ protected CandidateInfo guardedOverloadResolution(@NotNull List<CandidateInfo> conflicts) {
if (conflicts.isEmpty()) return null;
if (conflicts.size() == 1) return conflicts.get(0);
--- /dev/null
+
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+class Test {
+
+ public Long getKey() {
+ return 0L;
+ }
+
+ public static void main(Stream<Test> stream) {
+ stream.map(s -> Inner.of(Test::getKey, s));
+ }
+
+ public static final class Inner<K> {
+ public static <T> Inner<T> of(final Object key, final Test value) {return null;}
+ public static <T> Inner<T> of(final Function< T, Long> keyMapper, final Test value) {return null;}
+ }
+}
\ No newline at end of file
--- /dev/null
+
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+class Test {
+
+ public Long getKey() {
+ return 0L;
+ }
+
+ public static void main(Stream<Test> stream) {
+ stream.map(s -> Inner.of(Test::get<ref>Key, s));
+ }
+
+ public static final class Inner<K> {
+ public static <T> Inner<T> of(final Object key, final Test value) {return null;}
+ public static <T> Inner<T> of(final Function< T, Long> keyMapper, final Test value) {return null;}
+ }
+}
\ No newline at end of file
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
-import com.intellij.idea.Bombed;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
+import junit.framework.Test;
+import junit.framework.TestSuite;
import org.jetbrains.annotations.NonNls;
-import java.util.Calendar;
-
public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/newLambda";
doTest();
}
+ public void testIDEA136759() throws Exception {
+ doTest();
+ }
+
private void doTest() {
doTest(false);
}
/*
public static Test suite() {
final TestSuite suite = new TestSuite();
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 1000; i++) {
suite.addTestSuite(NewLambdaHighlightingTest.class);
}
return suite;
}
public void testSecondConflictResolution() throws Exception {
+ doTestMethodCall();
+ }
+
+ public void testCachedSubstitutionDuringOverloadResolution() throws Exception {
PsiReference ref = configureByFile("/codeInsight/daemonCodeAnalyzer/lambda/resolve/" + getTestName(false) + ".java");
assertNotNull(ref);
- PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(ref.getElement(), PsiMethodCallExpression.class);
+ PsiMethodReferenceExpression methodCallExpression = PsiTreeUtil.getParentOfType(ref.getElement(), PsiMethodReferenceExpression.class, false);
assertNotNull(methodCallExpression);
- assertNotNull(methodCallExpression.resolveMethod());
+ assertNotNull(methodCallExpression.resolve());
}
private LanguageLevel myOldLanguageLevel;
super.tearDown();
}
+ private void doTestMethodCall() throws Exception {
+ PsiReference ref = configureByFile("/codeInsight/daemonCodeAnalyzer/lambda/resolve/" + getTestName(false) + ".java");
+ assertNotNull(ref);
+ PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(ref.getElement(), PsiMethodCallExpression.class);
+ assertNotNull(methodCallExpression);
+ assertNotNull(methodCallExpression.resolveMethod());
+ }
+
private void doTest() throws Exception {
PsiReference ref = configureByFile("/codeInsight/daemonCodeAnalyzer/lambda/resolve/" + getTestName(false) + ".java");
assertNotNull(ref);