mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
type equality constraint: reject type/wildcard pairs; subtyping constraint: become eq constraint for types
This commit is contained in:
+25
-10
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiCapturedWildcardType;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.PsiWildcardType;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceBound;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
|
||||
@@ -23,6 +27,8 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
|
||||
import java.util.List;
|
||||
|
||||
public class SubtypingConstraint implements ConstraintFormula {
|
||||
private static final Logger LOG = Logger.getInstance("#" + SubtypingConstraint.class.getName());
|
||||
|
||||
private PsiType myS;
|
||||
private PsiType myT;
|
||||
|
||||
@@ -72,13 +78,10 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myT).isExtends()) {
|
||||
if (tBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (myS instanceof PsiWildcardType) {
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
if (sBound == null) {
|
||||
constraints.add(new StrictSubtypingConstraint(tBound, ((PsiWildcardType)myS).getExtendsBound()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,12 +89,21 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
constraints.add(new StrictSubtypingConstraint(tBound, sBound));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (((PsiWildcardType)myS).isSuper()) {
|
||||
constraints.add(new TypeEqualityConstraint(tBound, PsiType.getJavaLangObject(((PsiWildcardType)myT).getManager(), myT.getResolveScope())));
|
||||
return true;
|
||||
}
|
||||
|
||||
assert false;
|
||||
}
|
||||
else {
|
||||
constraints.add(new StrictSubtypingConstraint(tBound, myS));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
LOG.assertTrue(((PsiWildcardType)myT).isSuper());
|
||||
|
||||
if (myS instanceof PsiWildcardType) {
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
@@ -120,8 +132,11 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
inferenceVariable.addBound(myS, InferenceBound.EQ);
|
||||
return true;
|
||||
}
|
||||
constraints.add(new StrictSubtypingConstraint(myT, myS));
|
||||
return true;
|
||||
if (myT != null && myS != null) {
|
||||
constraints.add(new TypeEqualityConstraint(myT, myS));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
-27
@@ -39,6 +39,38 @@ public class TypeEqualityConstraint implements ConstraintFormula {
|
||||
|
||||
@Override
|
||||
public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
|
||||
if (myT instanceof PsiWildcardType && myS instanceof PsiWildcardType) {
|
||||
final PsiType tBound = ((PsiWildcardType)myT).getBound();
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
|
||||
if (tBound == null && sBound == null) return true;
|
||||
|
||||
if (sBound == null && ((PsiWildcardType)myT).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myS).getExtendsBound(), tBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tBound == null && ((PsiWildcardType)myS).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myT).getExtendsBound(), sBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myT).isExtends() && ((PsiWildcardType)myS).isExtends() ||
|
||||
((PsiWildcardType)myT).isSuper() && ((PsiWildcardType)myS).isSuper()) {
|
||||
|
||||
LOG.assertTrue(tBound != null);
|
||||
LOG.assertTrue(sBound != null);
|
||||
constraints.add(new TypeEqualityConstraint(tBound, sBound));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (myT instanceof PsiWildcardType || myS instanceof PsiWildcardType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (session.isProperType(myT) && session.isProperType(myS)) {
|
||||
return myT.equals(myS);
|
||||
}
|
||||
@@ -75,33 +107,6 @@ public class TypeEqualityConstraint implements ConstraintFormula {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (myT instanceof PsiWildcardType && myS instanceof PsiWildcardType) {
|
||||
final PsiType tBound = ((PsiWildcardType)myT).getBound();
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
|
||||
if (tBound == null && sBound == null) return true;
|
||||
|
||||
if (sBound == null && ((PsiWildcardType)myT).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myS).getExtendsBound(), tBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tBound == null && ((PsiWildcardType)myS).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myT).getExtendsBound(), sBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myT).isExtends() && ((PsiWildcardType)myS).isExtends() ||
|
||||
((PsiWildcardType)myT).isSuper() && ((PsiWildcardType)myS).isSuper()) {
|
||||
|
||||
LOG.assertTrue(tBound != null);
|
||||
LOG.assertTrue(sBound != null);
|
||||
constraints.add(new TypeEqualityConstraint(tBound, sBound));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -18,14 +18,14 @@ class B<T> extends A<A<T>> {
|
||||
foo2(s);
|
||||
|
||||
foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
|
||||
foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
|
||||
foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
|
||||
foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
|
||||
foo3<error descr="'foo3(A<A<? extends java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
|
||||
foo3<error descr="'foo3(A<A<?>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
|
||||
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.Object>>)' in 'B' cannot be applied to '(B<capture<?>>)'">(b)</error>;
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.Object>>)' in 'B' cannot be applied to '(B<capture<? extends java.lang.String>>)'">(eb)</error>;
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.String>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.Object>>)' in 'B' cannot be applied to '(B<capture<? super java.lang.String>>)'">(sb)</error>;
|
||||
foo4<error descr="'foo4(A<A<? super java.lang.Object>>)' in 'B' cannot be applied to '(B<java.lang.String>)'">(s)</error>;
|
||||
|
||||
foo5(b);
|
||||
foo5(eb);
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class Sample {
|
||||
|
||||
static List<String> getList(Function<Object, String> function, ArrayList<? super String> objects) {
|
||||
return transform(objects, new ArrayList<String>(), function);
|
||||
}
|
||||
|
||||
static <R, S, T extends Collection<S>> T transform(Iterable<? extends R> oldCollection,
|
||||
T newCollection,
|
||||
Function<R, S> function) {
|
||||
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
interface Function<X, Y> {
|
||||
Y apply(X input);
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -42,6 +42,10 @@ public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testSubtypingExtendsSuper() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkWarnings) {
|
||||
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user