apply capture conversion for captured wildcard bound according to the direct supertype of parameterized type specification (IDEA-157586)

This commit is contained in:
Anna Kozlova
2016-06-22 15:22:32 +03:00
parent 61adc187bb
commit 7968b2bbbb
7 changed files with 37 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -181,13 +182,18 @@ public class PsiCapturedWildcardType extends PsiType.Stub {
@NotNull
public PsiType getUpperBound () {
return getUpperBound(true);
}
@NotNull
public PsiType getUpperBound(boolean capture) {
final PsiType bound = myExistential.getBound();
if (myExistential.isExtends() && myParameter == null) {
assert bound != null : myExistential.getCanonicalText();
return bound;
}
else {
return myUpperBound;
return isCapture() && capture ? PsiUtil.captureToplevelWildcards(myUpperBound, myContext) : myUpperBound;
}
}

View File

@@ -774,7 +774,7 @@ public class TypeConversionUtil {
}
if (right instanceof PsiCapturedWildcardType) {
return isAssignable(left, ((PsiCapturedWildcardType)right).getUpperBound(), allowUncheckedConversion, capture);
return isAssignable(left, ((PsiCapturedWildcardType)right).getUpperBound(capture), allowUncheckedConversion, capture);
}
if (left instanceof PsiCapturedWildcardType) {

View File

@@ -134,7 +134,7 @@ public class StrictSubtypingConstraint implements ConstraintFormula {
else if (myS instanceof PsiCapturedWildcardType) {
final PsiType upperBound = ((PsiCapturedWildcardType)myS).getUpperBound();
if (upperBound instanceof PsiClassType) {
sType = (PsiClassType)PsiUtil.captureToplevelWildcards(upperBound, ((PsiCapturedWildcardType)myS).getContext());
sType = (PsiClassType)upperBound;
}
}

View File

@@ -4,5 +4,6 @@ interface B<T extends A<?>> { }
class C {
void foo(A<?> x){
<error descr="Incompatible types. Found: 'A<capture<?>>', required: 'A<? extends B<? extends A<?>>>'">A<? extends B<? extends A<?>>> y = x;</error>
Object y1 = (A<? extends B<? extends A<?>>>) x;
}
}

View File

@@ -1,4 +1,6 @@
import java.util.List;
import java.util.Set;
import java.util.function.Function;
class Test {
void f(List<? extends I<?>> list) {
@@ -11,4 +13,27 @@ class Test {
interface I<Z> {
}
}
class Test1 {
private static void getMarketDataValues(ScenarioMarketData marketData,
Set<? extends MarketDataId<?>> ids) {
ids.add(bar(marketData::getValue));
}
interface ScenarioMarketData {
<T> MarketDataBox<T> getValue(MarketDataId<T> id);
}
interface MarketDataBox<J> {
}
interface MarketDataId<M> {
}
static <T, V> T bar(Function<T, V> valueExtractor) {
return null;
}
}

View File

@@ -4,6 +4,6 @@ abstract class A<S> {
{
A<? extends A<? super A<Object>>> a = null;
A<? extends A<? super A<String>>> b = null;
A<? extends A<?>> m = foo(a, b);
A<? extends A<? extends Object>> m = foo(a, b);
}
}

View File

@@ -509,7 +509,7 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
}
public void testDenotableType1() {
doTest(new MockIntroduceVariableHandler("m", false, false, false, "A<? extends A<?>>"));
doTest(new MockIntroduceVariableHandler("m", false, false, false, "A<? extends A<? extends java.lang.Object>>"));
}
public void testDenotableType2() {