mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] Do not allow unchecked conversion for explicit new expression types
Fixes IDEA-326353 Generics error is not displayed in new expression GitOrigin-RevId: 661bf57ed3451096fcee245204dd30adae49e9e1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
51407fc59f
commit
cc8b90376c
@@ -468,8 +468,17 @@ public final class GenericsUtil {
|
||||
//Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the parameterized type C<R1,...,Rn> where at least one of the Ri is a wildcard
|
||||
//type argument, are the direct supertypes of the parameterized type C<X1,...,Xn> which is the result of applying capture conversion to C<R1,...,Rn>.
|
||||
PsiType capturedType = PsiUtil.captureToplevelWildcards(type, referenceParameterList);
|
||||
//allow unchecked conversions in method calls but not in type declaration
|
||||
return checkNotInBounds(capturedType, bound, PsiTreeUtil.getParentOfType(referenceParameterList, PsiCallExpression.class) != null);
|
||||
//allow unchecked conversions in method calls, new expression args, or in diamond types, but not in other places
|
||||
boolean uncheckedConversionByDefault;
|
||||
PsiElement parent = referenceParameterList.getParent();
|
||||
if (parent instanceof PsiReferenceExpression || parent instanceof PsiNewExpression) {
|
||||
uncheckedConversionByDefault = true;
|
||||
}
|
||||
else {
|
||||
PsiTypeElement[] elements = referenceParameterList.getTypeParameterElements();
|
||||
uncheckedConversionByDefault = elements.length == 1 && elements[0].getType() instanceof PsiDiamondType;
|
||||
}
|
||||
return checkNotInBounds(capturedType, bound, uncheckedConversionByDefault);
|
||||
}
|
||||
|
||||
public static boolean checkNotInBounds(PsiType type, PsiType bound, boolean uncheckedConversionByDefault) {
|
||||
|
||||
+8
@@ -17,4 +17,12 @@ class EnumBug {
|
||||
EnumSet<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option>'">Option</error>> enumSetRaw = EnumSet.<Option>noneOf(Option.class);
|
||||
}
|
||||
|
||||
void consume(Runnable r) {}
|
||||
|
||||
void test() {
|
||||
EnumSet<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option>'">Option</error>> set = null;
|
||||
consume(() -> {
|
||||
EnumSet<<error descr="Type parameter 'EnumBug.Option' is not within its bound; should extend 'EnumBug.Enum<EnumBug.Option>'">Option</error>> set1 = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
class InvalidGenericSubclass {
|
||||
public static void main(String[] args) {
|
||||
BaseInput<?, ?> input = new BaseInput<<error descr="Type parameter 'InvalidGenericSubclass.BaseInput' is not within its bound; should extend 'InvalidGenericSubclass.BaseInput<InvalidGenericSubclass.BaseInput,InvalidGenericSubclass.BaseInput.BaseOutput>'">BaseInput</error>, BaseInput.BaseOutput>() {
|
||||
};
|
||||
|
||||
BaseInput<?, ?> input2 = InvalidGenericSubclass.<BaseInput, BaseInput.BaseOutput>create();
|
||||
|
||||
new <BaseInput, BaseInput.BaseOutput>InvalidGenericSubclass();
|
||||
}
|
||||
|
||||
interface Input<InputType extends Input<InputType, OutputType>, OutputType extends Input.Output<InputType, OutputType>> {
|
||||
interface Output<OutputType extends Input<OutputType, InputType>, InputType extends Output<OutputType, InputType>> {
|
||||
}
|
||||
}
|
||||
|
||||
interface BaseInput<BaseInputType extends BaseInput<BaseInputType, BaseOutputType>, BaseOutputType extends BaseInput.BaseOutput<BaseInputType, BaseOutputType>> extends Input<BaseInputType, BaseOutputType> {
|
||||
interface BaseOutput<BaseInputType extends BaseInput<BaseInputType, BaseOutputType>, BaseOutputType extends BaseOutput<BaseInputType, BaseOutputType>> extends Output<BaseInputType, BaseOutputType> {
|
||||
}
|
||||
}
|
||||
|
||||
static <BaseInputType extends BaseInput<BaseInputType, BaseOutputType>, BaseOutputType extends BaseInput.BaseOutput<BaseInputType, BaseOutputType>> BaseInput<BaseInputType, BaseOutputType> create() {
|
||||
return null;
|
||||
}
|
||||
|
||||
<BaseInputType extends BaseInput<BaseInputType, BaseOutputType>, BaseOutputType extends BaseInput.BaseOutput<BaseInputType, BaseOutputType>> InvalidGenericSubclass() {}
|
||||
}
|
||||
+1
@@ -1204,4 +1204,5 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testIgnoreErasureForProperTypeBound() { doTest(); }
|
||||
public void testInferenceErrorAttribution() {doTest();}
|
||||
public void testLocalClassParameters() {doTest();}
|
||||
public void testRawAtFBoundAtNew() { doTest(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user