assert no type execution under overload lock for diamonds

IDEA-CR-55327

GitOrigin-RevId: e2b1043a41b9548df3c2eb263a27da6d6c22b6be
This commit is contained in:
Anna.Kozlova
2019-11-18 11:41:37 +01:00
committed by intellij-monorepo-bot
parent e7b0a9cde3
commit d4ff582489
4 changed files with 49 additions and 15 deletions

View File

@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.PsiConflictResolver;
@@ -168,7 +169,10 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
if (!(staticFactoryCandidateInfo instanceof MethodCandidateInfo)) {
return DiamondInferenceResult.UNRESOLVED_CONSTRUCTOR;
}
LOG.assertTrue(!PsiMethodCallExpressionImpl.doWePerformGenericMethodOverloadResolutionNow(newExpression, PsiUtil.getLanguageLevel(newExpression)),
"diamond evaluation during overload resolution");
PsiSubstitutor substitutor = staticFactoryCandidateInfo.getSubstitutor();
String errorMessage = ((MethodCandidateInfo)staticFactoryCandidateInfo).getInferenceErrorMessageAssumeAlreadyComputed();

View File

@@ -148,20 +148,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
PsiFile file = call.getContainingFile();
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
final PsiElement callParent = PsiUtil.skipParenthesizedExprUp(call.getParent());
final PsiExpressionList parentArgList;
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
parentArgList = callParent instanceof PsiConditionalExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)callParent)
? null : PsiTreeUtil.getParentOfType(call, PsiExpressionList.class, true, PsiReferenceExpression.class);
}
else {
parentArgList = null;
}
final boolean genericParentOverloadResolution = parentArgList != null &&
MethodCandidateInfo.isOverloadCheck(parentArgList) &&
Arrays.stream(parentArgList.getExpressions())
.map(expression -> PsiUtil.skipParenthesizedExprDown(expression))
.noneMatch(expression -> expression != null && ThreadLocalTypes.hasBindingFor(expression));
final boolean genericParentOverloadResolution = doWePerformGenericMethodOverloadResolutionNow(call, languageLevel);
PsiType theOnly = null;
for (int i = 0; i < results.length; i++) {
@@ -219,6 +206,23 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
}
}
public static boolean doWePerformGenericMethodOverloadResolutionNow(PsiCall call, LanguageLevel languageLevel) {
final PsiElement callParent = PsiUtil.skipParenthesizedExprUp(call.getParent());
final PsiExpressionList parentArgList;
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
parentArgList = callParent instanceof PsiConditionalExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)callParent)
? null : PsiTreeUtil.getParentOfType(call, PsiExpressionList.class, true, PsiReferenceExpression.class);
}
else {
parentArgList = null;
}
return parentArgList != null &&
MethodCandidateInfo.isOverloadCheck(parentArgList) &&
Arrays.stream(parentArgList.getExpressions())
.map(expression -> PsiUtil.skipParenthesizedExprDown(expression))
.noneMatch(expression -> expression != null && ThreadLocalTypes.hasBindingFor(expression));
}
private static PsiType captureReturnType(PsiMethodCallExpression call,
PsiMethod method,
PsiType ret,

View File

@@ -0,0 +1,16 @@
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
class Test {
Test(final Set<? super String> set) {
System.out.println(join(TreeSet.cre<caret>ate(set)));
}
public static String join(Iterable<?> items) {return "";}
public static String join(Collection<String> strings) {return "";}
}
class TreeSet<E> extends Set<E> {
static <T> TreeSet<T> create(Collection<? extends T> c) { return null;}
}

View File

@@ -307,6 +307,16 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
assertEquals("TreeSet<? super java.lang.String>", type.getCanonicalText());
}
public void testResolveDiamondReplacementBeforeOuterCall() {
configure();
PsiMethodCallExpression innerCall =
PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
assertNotNull(innerCall);
PsiType type = innerCall.getType();
assertEquals("TreeSet<? super java.lang.String>", type.getCanonicalText());
}
private void doTestAllMethodCallExpressions() {
configure();
final Collection<PsiCallExpression> methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiCallExpression.class);