mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
capture conversion: add upper bound for ? super if corresponding type parameter has upper bounds( IDEA-128328; IDEA-128972)
This commit is contained in:
@@ -28,6 +28,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
@NotNull private final PsiElement myContext;
|
||||
@Nullable private final PsiTypeParameter myParameter;
|
||||
|
||||
private PsiType myUpperBound;
|
||||
|
||||
@NotNull
|
||||
public static PsiCapturedWildcardType create(@NotNull PsiWildcardType existential, @NotNull PsiElement context) {
|
||||
return create(existential, context, null);
|
||||
@@ -40,11 +42,28 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
return new PsiCapturedWildcardType(existential, context, parameter);
|
||||
}
|
||||
|
||||
private PsiCapturedWildcardType(@NotNull PsiWildcardType existential, @NotNull PsiElement context, @Nullable PsiTypeParameter parameter) {
|
||||
private PsiCapturedWildcardType(@NotNull PsiWildcardType existential,
|
||||
@NotNull PsiElement context,
|
||||
@Nullable PsiTypeParameter parameter) {
|
||||
super(PsiAnnotation.EMPTY_ARRAY);
|
||||
myExistential = existential;
|
||||
myContext = context;
|
||||
myParameter = parameter;
|
||||
if (parameter != null) {
|
||||
final PsiClassType[] boundTypes = parameter.getExtendsListTypes();
|
||||
if (boundTypes.length > 0) {
|
||||
PsiType result = null;
|
||||
for (PsiType type : boundTypes) {
|
||||
if (result == null) {
|
||||
result = type;
|
||||
}
|
||||
else {
|
||||
result = GenericsUtil.getGreatestLowerBound(result, type);
|
||||
}
|
||||
}
|
||||
myUpperBound = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,10 +147,14 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
return PsiWildcardType.createSuper(myContext.getManager(), ((PsiCapturedWildcardType)bound).getUpperBound());
|
||||
}
|
||||
else {
|
||||
return PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
|
||||
return myUpperBound != null ? myUpperBound : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
|
||||
}
|
||||
}
|
||||
|
||||
public void setUpperBound(PsiType upperBound) {
|
||||
myUpperBound = upperBound;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiWildcardType getWildcard() {
|
||||
return myExistential;
|
||||
@@ -141,4 +164,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
|
||||
public PsiElement getContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
public PsiTypeParameter getTypeParameter() {
|
||||
return myParameter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper()) {
|
||||
} else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper() && !(oldSubstituted instanceof PsiCapturedWildcardType)) {
|
||||
final PsiType erasure = TypeConversionUtil.erasure(((PsiWildcardType)substituted).getBound());
|
||||
if (erasure != null) {
|
||||
final PsiType[] boundTypes = typeParameter.getExtendsListTypes();
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
class Test<T > {
|
||||
interface Event{}
|
||||
|
||||
interface EventListener<V extends Event> {
|
||||
void handleEvent(V event);
|
||||
}
|
||||
|
||||
public void addListener(EventListener<? super T> listener) {
|
||||
EventListener<? extends Event> localListener = listener;
|
||||
<error descr="Incompatible types. Found: 'Test.EventListener<capture<? super T>>', required: 'Test.EventListener<? super Test.Event>'">EventListener<? super Event> localListener1 = listener;</error>
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
|
||||
public static class Entity<E extends Entity<E>> {
|
||||
|
||||
public final <T, V extends EntityVisitor<? super E, T>> T handle(final V visitor) {
|
||||
return visitor.handle(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface EntityVisitor<E extends Entity<E>, T> {
|
||||
|
||||
T handle(Entity<? extends E> e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@ abstract class ProcedureService {
|
||||
abstract <C extends Command<Result>> Class<? extends Procedure<Command<Result>>> getProcedure(Class<C> cmd);
|
||||
|
||||
public <C extends Command<Result>> void execute(Class<? extends Command> aClass) {
|
||||
Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);
|
||||
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Procedure<Command<Result>>>>', required: 'java.lang.Class<Procedure<Command<Result>>>'">Class<Procedure<Command<Result>>> procedureClass = getProcedure(aClass);</error>
|
||||
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<Command>'">Class<Command> c = aClass;</error>
|
||||
<error descr="Incompatible types. Found: 'java.lang.Class<capture<? extends Command>>', required: 'java.lang.Class<C>'">Class<C> c1 = aClass;</error>
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ class Bug2<T extends Integer>{
|
||||
}
|
||||
|
||||
void bug1(Parametrized<? super T> param) {
|
||||
<error descr="Inferred type 'capture<? super T>' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
|
||||
foo(param);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class Test {
|
||||
}
|
||||
|
||||
void bug1(Parametrized<? super T> param) {
|
||||
<error descr="Inferred type 'java.io.Serializable' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
|
||||
<error descr="Inferred type 'capture<? super T>' for type parameter 'I' is not within its bound; should extend 'java.lang.Number'">foo(param)</error>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -372,6 +372,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
|
||||
public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
|
||||
public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
|
||||
public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
|
||||
public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); }
|
||||
//jdk should propagate LL 1.4 but actually it provides LL 1.7?!
|
||||
public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); }
|
||||
|
||||
+1
-1
@@ -688,7 +688,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA110869() {
|
||||
doTest();
|
||||
}
|
||||
/*public void testIDEA110947() { doTest5(false); }*/
|
||||
public void testIDEA110947() { doTest(false); }
|
||||
public void testIDEA112122() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user