mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
new inference: assert that no resolve is performed on the "inference-in-progress" reference
This commit is contained in:
@@ -418,7 +418,7 @@ public class InferenceSession {
|
||||
final Computable<JavaResolveResult> computableResolve = new Computable<JavaResolveResult>() {
|
||||
@Override
|
||||
public JavaResolveResult compute() {
|
||||
return callExpression.resolveMethodGenerics();
|
||||
return getResolveResult(callExpression, argumentList);
|
||||
}
|
||||
};
|
||||
MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
@@ -428,6 +428,24 @@ public class InferenceSession {
|
||||
: PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, false, computableResolve);
|
||||
}
|
||||
|
||||
public static JavaResolveResult getResolveResult(PsiCallExpression callExpression, PsiExpressionList argumentList) {
|
||||
if (callExpression instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)callExpression).getClassOrAnonymousClassReference();
|
||||
final JavaResolveResult resolveResult = classReference != null ? classReference.advancedResolve(false) : null;
|
||||
final PsiElement psiClass = resolveResult != null ? resolveResult.getElement() : null;
|
||||
if (psiClass instanceof PsiClass) {
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(callExpression.getProject());
|
||||
final JavaResolveResult constructor = facade.getResolveHelper()
|
||||
.resolveConstructor(facade.getElementFactory().createType((PsiClass)psiClass).rawType(), argumentList, callExpression);
|
||||
return constructor.getElement() == null ? resolveResult : constructor;
|
||||
}
|
||||
else {
|
||||
return JavaResolveResult.EMPTY;
|
||||
}
|
||||
}
|
||||
return callExpression.resolveMethodGenerics();
|
||||
}
|
||||
|
||||
public PsiSubstitutor retrieveNonPrimitiveEqualsBounds(Collection<InferenceVariable> variables) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
for (InferenceVariable variable : variables) {
|
||||
|
||||
@@ -84,33 +84,19 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(((PsiCallExpression)myExpression).getArgumentList());
|
||||
final JavaResolveResult resolveResult;
|
||||
PsiType returnType = null;
|
||||
PsiTypeParameter[] typeParams = null;
|
||||
final JavaResolveResult resolveResult = candidateProperties != null ? null : InferenceSession.getResolveResult((PsiCallExpression)myExpression, argumentList);
|
||||
PsiMethod method = null;
|
||||
if (candidateProperties != null) {
|
||||
resolveResult = null;
|
||||
method = candidateProperties.getMethod();
|
||||
}
|
||||
else {
|
||||
if (myExpression instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)myExpression).getClassOrAnonymousClassReference();
|
||||
final PsiElement psiClass = classReference != null ? classReference.resolve() : null;
|
||||
if (psiClass instanceof PsiClass) {
|
||||
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(myExpression.getProject());
|
||||
resolveResult = facade.getResolveHelper().resolveConstructor(facade.getElementFactory().createType((PsiClass)psiClass).rawType(), argumentList, myExpression);
|
||||
|
||||
returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType((PsiClass)psiClass, PsiSubstitutor.EMPTY);
|
||||
typeParams = ((PsiClass)psiClass).getTypeParameters();
|
||||
}
|
||||
else {
|
||||
resolveResult = JavaResolveResult.EMPTY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
resolveResult = ((PsiCallExpression)myExpression).resolveMethodGenerics();
|
||||
final PsiElement element = resolveResult.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
method = (PsiMethod)element;
|
||||
}
|
||||
}
|
||||
final PsiMethod method = candidateProperties != null ? candidateProperties.getMethod() : (PsiMethod)resolveResult.getElement();
|
||||
|
||||
if (method != null && !method.isConstructor()) {
|
||||
returnType = method.getReturnType();
|
||||
@@ -118,6 +104,13 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
typeParams = method.getTypeParameters();
|
||||
}
|
||||
}
|
||||
else if (resolveResult != null) {
|
||||
final PsiClass psiClass = method != null ? method.getContainingClass() : (PsiClass)resolveResult.getElement();
|
||||
if (psiClass != null) {
|
||||
returnType = JavaPsiFacade.getElementFactory(argumentList.getProject()).createType(psiClass, PsiSubstitutor.EMPTY);
|
||||
typeParams = psiClass.getTypeParameters();
|
||||
}
|
||||
}
|
||||
|
||||
if (typeParams != null) {
|
||||
PsiSubstitutor siteSubstitutor =
|
||||
|
||||
@@ -73,12 +73,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
public final CandidateInfo resolveConflict(@NotNull final List<CandidateInfo> conflicts){
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(myArgumentsList);
|
||||
if (properties != null) {
|
||||
final PsiMethod method = properties.getMethod();
|
||||
for (CandidateInfo conflict : conflicts) {
|
||||
if (conflict.getElement() == method) {
|
||||
return conflict;
|
||||
}
|
||||
}
|
||||
LOG.error("Recursive conflict resolution for:" + properties.getMethod());
|
||||
}
|
||||
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, true, new Computable<CandidateInfo>() {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
public static void main(String[] args) {
|
||||
new A<>(new B<>(of("")));
|
||||
}
|
||||
|
||||
static <E> List<E> of(E element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class A<K> {
|
||||
A(String s) {}
|
||||
A(B<K> b) {}
|
||||
}
|
||||
|
||||
static class B<T> extends ArrayList<List<T>> {
|
||||
public B(List<T> l) {}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.psi.PsiMethodCallExpression;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -35,13 +35,24 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
|
||||
doTestAllMethodCallExpressions();
|
||||
}
|
||||
|
||||
public void testAvoidClassRefCachingDuringInference() throws Exception {
|
||||
doTestAllMethodCallExpressions();
|
||||
}
|
||||
|
||||
private void doTestAllMethodCallExpressions() {
|
||||
configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
|
||||
final Collection<PsiMethodCallExpression> methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiMethodCallExpression.class);
|
||||
for (PsiMethodCallExpression expression : methodCallExpressions) {
|
||||
final Collection<PsiCallExpression> methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiCallExpression.class);
|
||||
for (PsiCallExpression expression : methodCallExpressions) {
|
||||
getPsiManager().dropResolveCaches();
|
||||
assertNotNull("Failed inference for: " + expression.getText(), expression.getType());
|
||||
}
|
||||
|
||||
final Collection<PsiReferenceParameterList> parameterLists = PsiTreeUtil.findChildrenOfType(getFile(), PsiReferenceParameterList.class);
|
||||
for (PsiReferenceParameterList list : parameterLists) {
|
||||
getPsiManager().dropResolveCaches();
|
||||
final PsiType[] arguments = list.getTypeArguments();
|
||||
assertNotNull("Failed inference for: " + list.getParent().getText(), arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user