mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
[java] inference: completely ignore expressions over which overload resolution is started
logging for EA-241551 - NPE: MethodReferenceResolver$0$0.inferTypeArguments, as there is no reproducible example, still GitOrigin-RevId: 46216cd8171479d14af2283cf9cd4a35e68d9b48
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5ad2a37900
commit
3db82d3846
@@ -1,10 +1,10 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
@@ -486,7 +486,10 @@ public final class LambdaUtil {
|
||||
if (results != null) {
|
||||
final Set<PsiType> types = new HashSet<>();
|
||||
for (JavaResolveResult result : results) {
|
||||
final PsiType functionalExpressionType = MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(functionalExpression, false, () -> getSubstitutedType(functionalExpression, true, lambdaIdx, result));
|
||||
Computable<PsiType> computeType = () -> getSubstitutedType(functionalExpression, true, lambdaIdx, result);
|
||||
final PsiType functionalExpressionType = results.length == 1
|
||||
? computeType.compute()
|
||||
: MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(functionalExpression, false, computeType);
|
||||
if (functionalExpressionType != null && types.add(functionalExpressionType)) {
|
||||
overloadProcessor.consume(functionalExpressionType);
|
||||
}
|
||||
|
||||
@@ -405,13 +405,12 @@ public class InferenceSession {
|
||||
final PsiSubstitutor nestedSubstitutor = myInferenceSessionContainer.findNestedSubstitutor(arg, myInferenceSubstitution);
|
||||
final PsiType parameterType = nestedSubstitutor.substitute(getParameterType(parameters, i, siteSubstitutor, varargs));
|
||||
if (parameterType == null) continue;
|
||||
ExpressionCompatibilityConstraint compatibilityConstraint = new ExpressionCompatibilityConstraint(arg, parameterType);
|
||||
if (arg instanceof PsiFunctionalExpression && ignoreLambdaConstraintTree(arg) || dependsOnIgnoredConstraint(ignoredConstraints, compatibilityConstraint)) {
|
||||
ignoredConstraints.add(compatibilityConstraint);
|
||||
continue;
|
||||
}
|
||||
if (!isPertinentToApplicability(arg, parentMethod)) {
|
||||
ExpressionCompatibilityConstraint compatibilityConstraint = new ExpressionCompatibilityConstraint(arg, parameterType);
|
||||
if (arg instanceof PsiFunctionalExpression && ignoreLambdaConstraintTree(arg) || dependsOnIgnoredConstraint(ignoredConstraints, compatibilityConstraint)) {
|
||||
ignoredConstraints.add(compatibilityConstraint);
|
||||
continue;
|
||||
}
|
||||
|
||||
additionalConstraints.add(compatibilityConstraint);
|
||||
}
|
||||
additionalConstraints.add(new CheckedExceptionCompatibilityConstraint(arg, parameterType));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
|
||||
@@ -18,6 +19,7 @@ import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -26,9 +28,10 @@ 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> {
|
||||
private static final Logger LOG = Logger.getInstance(MethodReferenceResolver.class);
|
||||
|
||||
@Override
|
||||
public JavaResolveResult @NotNull [] resolve(@NotNull PsiMethodReferenceExpressionImpl reference, @NotNull PsiFile containingFile, boolean incompleteCode) {
|
||||
PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(reference);
|
||||
@@ -96,12 +99,19 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, boolean includeReturnConstraint) {
|
||||
return includeReturnConstraint ? inferTypeArguments(true)
|
||||
: Objects.requireNonNull(MethodCandidateInfo.ourOverloadGuard
|
||||
.doPreventingRecursion(reference, false,
|
||||
() -> inferTypeArguments(false)));
|
||||
if (includeReturnConstraint) {
|
||||
return inferTypeArguments(true);
|
||||
}
|
||||
PsiSubstitutor psiSubstitutor = MethodCandidateInfo.ourOverloadGuard
|
||||
.doPreventingRecursion(reference, false, () -> inferTypeArguments(false));
|
||||
if (psiSubstitutor == null) {
|
||||
LOG.error("Recursive call for: " + ObjectUtils.notNull(LambdaUtil.treeWalkUp(reference), reference).getText());
|
||||
return substitutor;
|
||||
}
|
||||
return psiSubstitutor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiSubstitutor inferTypeArguments(boolean includeReturnConstraint) {
|
||||
if (interfaceMethod == null) return substitutor;
|
||||
InferenceSession session = new InferenceSession(method.getTypeParameters(), substitutor, reference.getManager(), reference);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Clazz {
|
||||
|
||||
<T> T foo(BiFunction<T, T, T> d) { return null;}
|
||||
<T> T foo(Function<T, String> d) { return null;}
|
||||
|
||||
{
|
||||
fooBar(foo(this::<caret>bar));
|
||||
}
|
||||
|
||||
<K> void fooBar(K k) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ package com.intellij.java.codeInsight.daemon.lambda;
|
||||
import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromMethodReferenceFix;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
@@ -36,6 +38,15 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
|
||||
assertFalse(call.resolveMethodGenerics().isValidResult());
|
||||
}
|
||||
|
||||
public void testCreateMethodFromMethodReferenceAvailability() {
|
||||
configure();
|
||||
PsiFile file = getFile();
|
||||
Editor editor = getEditor();
|
||||
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
PsiMethodReferenceExpression methodReference = PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class);
|
||||
assertTrue(new CreateMethodFromMethodReferenceFix(methodReference).isAvailable(getProject(), editor, file));
|
||||
}
|
||||
|
||||
public void testNestedLambdaReturnTypeCheck() {
|
||||
configure();
|
||||
PsiMethodCallExpression
|
||||
|
||||
Reference in New Issue
Block a user