mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diamonds: additional diagnostics for cases when constructor is unresolved (IDEA-146028)
This commit is contained in:
@@ -58,6 +58,19 @@ public abstract class PsiDiamondType extends PsiType {
|
||||
}
|
||||
};
|
||||
|
||||
public static final DiamondInferenceResult UNRESOLVED_CONSTRUCTOR = new DiamondInferenceResult() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType[] getTypes() {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return "Cannot infer arguments (unable to resolve constructor)";
|
||||
}
|
||||
};
|
||||
|
||||
public static final DiamondInferenceResult ANONYMOUS_INNER_RESULT = new DiamondInferenceResult() {
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
@@ -147,18 +147,18 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
}
|
||||
|
||||
public static DiamondInferenceResult resolveInferredTypesNoCheck(final PsiNewExpression newExpression, final PsiElement context) {
|
||||
final Ref<MethodCandidateInfo> staticFactoryRef = new Ref<MethodCandidateInfo>();
|
||||
final Ref<JavaResolveResult> staticFactoryRef = new Ref<JavaResolveResult>();
|
||||
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, new Computable<PsiSubstitutor>() {
|
||||
@Override
|
||||
public PsiSubstitutor compute() {
|
||||
final MethodCandidateInfo staticFactoryCandidateInfo = context == newExpression ?
|
||||
final JavaResolveResult staticFactoryCandidateInfo = context == newExpression ?
|
||||
CachedValuesManager.getCachedValue(context,
|
||||
new CachedValueProvider<MethodCandidateInfo>() {
|
||||
new CachedValueProvider<JavaResolveResult>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<MethodCandidateInfo> compute() {
|
||||
return new Result<MethodCandidateInfo>(getStaticFactoryCandidateInfo(newExpression, newExpression),
|
||||
PsiModificationTracker.MODIFICATION_COUNT);
|
||||
public Result<JavaResolveResult> compute() {
|
||||
return new Result<JavaResolveResult>(getStaticFactoryCandidateInfo(newExpression, newExpression),
|
||||
PsiModificationTracker.MODIFICATION_COUNT);
|
||||
}
|
||||
})
|
||||
: getStaticFactoryCandidateInfo(newExpression, context);
|
||||
@@ -169,12 +169,18 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
if (inferredSubstitutor == null) {
|
||||
return DiamondInferenceResult.NULL_RESULT;
|
||||
}
|
||||
final MethodCandidateInfo staticFactoryInfo = staticFactoryRef.get();
|
||||
|
||||
final JavaResolveResult staticFactoryInfo = staticFactoryRef.get();
|
||||
if (staticFactoryInfo == null) {
|
||||
LOG.error(inferredSubstitutor);
|
||||
return DiamondInferenceResult.NULL_RESULT;
|
||||
}
|
||||
final PsiMethod staticFactory = staticFactoryInfo.getElement();
|
||||
|
||||
if (!(staticFactoryInfo instanceof MethodCandidateInfo)) {
|
||||
return DiamondInferenceResult.UNRESOLVED_CONSTRUCTOR;
|
||||
}
|
||||
|
||||
final PsiMethod staticFactory = ((MethodCandidateInfo)staticFactoryInfo).getElement();
|
||||
final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
|
||||
final PsiElement staticFactoryContext = staticFactory.getContext();
|
||||
final PsiClass psiClass = PsiTreeUtil.getContextOfType(staticFactoryContext, PsiClass.class, false);
|
||||
@@ -208,21 +214,24 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static MethodCandidateInfo getStaticFactoryCandidateInfo(PsiNewExpression newExpression,
|
||||
PsiElement context) {
|
||||
private static JavaResolveResult getStaticFactoryCandidateInfo(PsiNewExpression newExpression,
|
||||
PsiElement context) {
|
||||
final PsiExpressionList argumentList = newExpression.getArgumentList();
|
||||
if (argumentList == null) {
|
||||
//token expected diagnostic is provided by parser
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiClass psiClass = findClass(newExpression);
|
||||
if (psiClass == null) {
|
||||
//should not happens: unresolved class reference would be first and inference won't start
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiMethod staticFactory = findConstructorStaticFactory(psiClass, newExpression);
|
||||
if (staticFactory == null) {
|
||||
return null;
|
||||
//additional diagnostics: inference fails due to unresolved constructor
|
||||
return JavaResolveResult.EMPTY;
|
||||
}
|
||||
|
||||
final MethodCandidateInfo staticFactoryCandidateInfo = createMethodCandidate(staticFactory, context, false, argumentList);
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Test {
|
||||
{
|
||||
D<String> ds = new D<<error descr="Cannot infer arguments (unable to resolve constructor)"></error>>(9);
|
||||
}
|
||||
}
|
||||
|
||||
class D<T> {
|
||||
D() {}
|
||||
D(D<T> d){}
|
||||
D(M<T> m){}
|
||||
}
|
||||
|
||||
class M<K> extends D<K> {}
|
||||
+4
@@ -51,6 +51,10 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDiagnosticMessageWhenConstructorIsUnresolved() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user