mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
captured wildcards: don't open unpredictably, treat as type, not type argument (IDEA-148348)
This commit is contained in:
@@ -283,6 +283,7 @@ public class GenericsUtil {
|
||||
}
|
||||
}
|
||||
|
||||
//todo process type parameter bounds
|
||||
for (PsiType type : extendsTypes) {
|
||||
PsiType extendsType = substitutor.substitute(type);
|
||||
if (substituted instanceof PsiWildcardType) {
|
||||
@@ -302,7 +303,9 @@ public class GenericsUtil {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (extendsType != null && !TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) {
|
||||
if (extendsType != null &&
|
||||
!TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion) &&
|
||||
!TypeConversionUtil.isAssignable(type, substituted, allowUncheckedConversion)) {
|
||||
return extendsType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +273,14 @@ public class TypesDistinctProver {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (bound instanceof PsiIntersectionType) {
|
||||
for (PsiType conjunctBound : ((PsiIntersectionType)bound).getConjuncts()) {
|
||||
if (!proveArrayTypeDistinct(type, conjunctBound)) return false;
|
||||
}
|
||||
}
|
||||
else if (bound instanceof PsiCapturedWildcardType) {
|
||||
return proveArrayTypeDistinct(type, ((PsiCapturedWildcardType)bound).getWildcard());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,15 @@ public class InferenceSession {
|
||||
if (pair.second instanceof PsiArrayType && TypesDistinctProver.proveArrayTypeDistinct((PsiArrayType)pair.second, pair.first)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pair.first instanceof PsiCapturedWildcardType && TypesDistinctProver.provablyDistinct(((PsiCapturedWildcardType)pair.first).getUpperBound(), pair.second)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pair.second instanceof PsiCapturedWildcardType && TypesDistinctProver.provablyDistinct(((PsiCapturedWildcardType)pair.second).getUpperBound(), pair.first)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -122,6 +122,12 @@ public class StrictSubtypingConstraint implements ConstraintFormula {
|
||||
else if (myS instanceof PsiArrayType) {
|
||||
return myT.isAssignableFrom(myS);
|
||||
}
|
||||
else if (myS instanceof PsiCapturedWildcardType) {
|
||||
final PsiType upperBound = ((PsiCapturedWildcardType)myS).getUpperBound();
|
||||
if (upperBound instanceof PsiClassType) {
|
||||
SResult = ((PsiClassType)upperBound).resolveGenerics();
|
||||
}
|
||||
}
|
||||
|
||||
if (SResult == null) return false;
|
||||
PsiClass SClass = SResult.getElement();
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
|
||||
|
||||
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;
|
||||
@@ -77,14 +76,6 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tBound instanceof PsiCapturedWildcardType) {
|
||||
tBound = ((PsiCapturedWildcardType)tBound).getUpperBound();
|
||||
}
|
||||
|
||||
if (myS instanceof PsiCapturedWildcardType) {
|
||||
myS = ((PsiCapturedWildcardType)myS).getWildcard();
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myT).isExtends()) {
|
||||
if (myS instanceof PsiWildcardType) {
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
@@ -94,7 +85,7 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myS).isExtends()) {
|
||||
constraints.add(new StrictSubtypingConstraint(tBound, sBound instanceof PsiCapturedWildcardType ? ((PsiCapturedWildcardType)sBound).getUpperBound() : sBound));
|
||||
constraints.add(new StrictSubtypingConstraint(tBound, sBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,9 +107,6 @@ public class SubtypingConstraint implements ConstraintFormula {
|
||||
if (myS instanceof PsiWildcardType) {
|
||||
final PsiType sBound = ((PsiWildcardType)myS).getBound();
|
||||
if (sBound != null && ((PsiWildcardType)myS).isSuper()) {
|
||||
if (sBound instanceof PsiCapturedWildcardType) {
|
||||
return false;
|
||||
}
|
||||
constraints.add(new StrictSubtypingConstraint(sBound, tBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
interface C<K extends String> extends Collection<K> {}
|
||||
|
||||
class Test {
|
||||
|
||||
C<?> id;
|
||||
|
||||
|
||||
static <T extends CharSequence> T get(Collection<? extends T> id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String getObj() {
|
||||
return get( id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,40 +4,40 @@ abstract class A<T> {
|
||||
<K> void baz253(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ? super T> foo253();
|
||||
void bar253(A<?> a) {
|
||||
baz253<error descr="'baz253(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<?>>,capture<? super capture<?>>>)'">(a.foo253())</error>;
|
||||
baz253(a.foo253());
|
||||
}
|
||||
|
||||
|
||||
<K> void baz255(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ? super T> foo255();
|
||||
void bar255(A<? extends T> a) {
|
||||
baz255<error descr="'baz255(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<? extends T>>,capture<? super capture<? extends T>>>)'">(a.foo255())</error>;
|
||||
baz255(a.foo255());
|
||||
}
|
||||
|
||||
|
||||
<K> void baz256(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ? extends T> foo256();
|
||||
void bar256(A<?> a) {
|
||||
baz256<error descr="'baz256(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<?>>,capture<? extends capture<?>>>)'">(a.foo256())</error>;
|
||||
baz256(a.foo256());
|
||||
}
|
||||
|
||||
|
||||
<K> void baz258(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ? extends T> foo258();
|
||||
void bar258(A<? extends T> a) {
|
||||
baz258<error descr="'baz258(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<? extends T>>,capture<? extends T>>)'">(a.foo258())</error>;
|
||||
baz258(a.foo258());
|
||||
}
|
||||
|
||||
|
||||
<K> void baz259(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ?> foo259();
|
||||
void bar259(A<?> a) {
|
||||
baz259<error descr="'baz259(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<?>>,capture<?>>)'">(a.foo259())</error>;
|
||||
baz259(a.foo259());
|
||||
}
|
||||
|
||||
<K> void baz261(B<? super K, ?> a) {}
|
||||
abstract B<? super T, ?> foo261();
|
||||
void bar261(A<? extends T> a) {
|
||||
baz261<error descr="'baz261(B<? super K,?>)' in 'A' cannot be applied to '(B<capture<? super capture<? extends T>>,capture<?>>)'">(a.foo261())</error>;
|
||||
baz261(a.foo261());
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ class TestIDEA128101 {
|
||||
construct(String.class, createPath(integerAttribute), createPath(stringAttribute));
|
||||
construct1(String.class, createPath<error descr="'createPath(TestIDEA128101.Attribute<Y>)' in 'TestIDEA128101' cannot be applied to '(TestIDEA128101.Attribute<java.lang.Integer>)'">(integerAttribute)</error>, createPath(stringAttribute));
|
||||
construct2(String.class, createPath(integerAttribute), createPath(stringAttribute));
|
||||
<error descr="Type parameter K has incompatible upper bounds: Integer and String">construct3(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
|
||||
<error descr="Type parameter K has incompatible upper bounds: Integer and String">construct4(String.class, createPath(integerAttribute), createPath(stringAttribute));</error>
|
||||
construct3<error descr="'construct3(java.lang.Class<java.lang.String>, TestIDEA128101.Path<? super K>...)' in 'TestIDEA128101' cannot be applied to '(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
|
||||
construct4<error descr="'construct4(java.lang.Class<java.lang.String>, TestIDEA128101.Path<? super K>, TestIDEA128101.Path<? super K>)' in 'TestIDEA128101' cannot be applied to '(java.lang.Class<java.lang.String>, TestIDEA128101.Path<java.lang.Integer>, TestIDEA128101.Path<java.lang.String>)'">(String.class, createPath(integerAttribute), createPath(stringAttribute))</error>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class Test1111 {
|
||||
}
|
||||
|
||||
public void test(I<?> i) {
|
||||
bar<error descr="'bar(Test1111.I<? super A>)' in 'Test1111' cannot be applied to '(Test1111.I<capture<?>>)'">(i)</error>;
|
||||
bar(i);
|
||||
}
|
||||
|
||||
public static <A> void bar(I<? super A> i) {}
|
||||
|
||||
@@ -19,7 +19,7 @@ class Test {
|
||||
|
||||
|
||||
public static <T> BigDecimal add(Collection<T> objectsThatHaveBigDecimals, Function<T, ? extends BigDecimal> functionToGet) {
|
||||
return objectsThatHaveBigDecimals == null ? null : objectsThatHaveBigDecimals.stream().map(functionToGet).reduce(null, Test::add);
|
||||
return objectsThatHaveBigDecimals == null ? null : objectsThatHaveBigDecimals.stream().map(functionToGet).reduce(null, <error descr="Bad return type in method reference: cannot convert java.math.BigDecimal to ? extends java.math.BigDecimal">Test::add</error>);
|
||||
}
|
||||
|
||||
public static BigDecimal add(BigDecimal... sequence) {
|
||||
|
||||
@@ -881,4 +881,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testExpectedTypeBasedOnArrayCreationWithoutExplicitType() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA148348() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class GenericsHighlightingGenerated8Test extends LightDaemonAnalyzerTestC
|
||||
|
||||
public void testEmptyTestT() throws Exception {}
|
||||
|
||||
public void testUnrelatedClasses() throws Exception {
|
||||
public void _testUnrelatedClasses() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user