mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
unchecked generics array creation: in new expressions; detect generic signature in anonymous class creation
This commit is contained in:
+38
-11
@@ -1113,7 +1113,7 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiReferenceExpression referenceExpression, PsiElement resolved){
|
||||
public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiJavaCodeReferenceElement referenceExpression, PsiElement resolved){
|
||||
if (isUncheckedWarning(referenceExpression, resolved, false)) {
|
||||
final HighlightInfo highlightInfo =
|
||||
HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, referenceExpression, "Unchecked generics array creation for varargs parameter");
|
||||
@@ -1123,7 +1123,7 @@ public class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isUncheckedWarning(PsiReferenceExpression expression, PsiElement resolve, boolean ignoreSuppressed) {
|
||||
public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve, boolean ignoreSuppressed) {
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiMethod psiMethod = (PsiMethod)resolve;
|
||||
|
||||
@@ -1140,12 +1140,31 @@ public class GenericsHighlightUtil {
|
||||
final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType();
|
||||
if (!isReifiableType(componentType)) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
final PsiExpression[] args = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions();
|
||||
for (int i = parametersCount - 1; i < args.length; i++) {
|
||||
if (!isReifiableType(args[i].getType())){
|
||||
return true;
|
||||
if (parent instanceof PsiCall) {
|
||||
final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
if (args.length == parametersCount) {
|
||||
final PsiExpression lastArg = args[args.length - 1];
|
||||
if (lastArg instanceof PsiReferenceExpression) {
|
||||
final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve();
|
||||
if (lastArgsResolve instanceof PsiParameter) {
|
||||
if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (lastArg instanceof PsiMethodCallExpression) {
|
||||
if (lastArg.getType() instanceof PsiArrayType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = parametersCount - 1; i < args.length; i++) {
|
||||
if (!isReifiableType(args[i].getType())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return args.length < parametersCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1169,14 +1188,22 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type);
|
||||
if (classType.isRaw()) {
|
||||
return true;
|
||||
}
|
||||
if (!classType.hasParameters()) {
|
||||
return true;
|
||||
PsiType[] parameters = classType.getParameters();
|
||||
|
||||
for (PsiType parameter : parameters) {
|
||||
if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !classType.hasNonTrivialParameters();
|
||||
final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
|
||||
if (resolved instanceof PsiTypeParameter) {
|
||||
return false;
|
||||
}
|
||||
return parameters.length == 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+1
@@ -686,6 +686,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType()));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression.getClassOrAnonymousClassReference(), expression.resolveConstructor()));
|
||||
if (!myHolder.hasErrorResults()) registerConstructorCall(expression);
|
||||
|
||||
if (!myHolder.hasErrorResults()) visitExpression(expression);
|
||||
|
||||
+76
@@ -42,4 +42,80 @@ public class Test {
|
||||
final ArrayList<String> list = new ArrayList<String>();
|
||||
<warning descr="Unchecked generics array creation for varargs parameter">asList</warning>(list);
|
||||
}
|
||||
|
||||
public static <V> void join(V[] list) {
|
||||
Arrays.asList(list);
|
||||
}
|
||||
}
|
||||
|
||||
class NoWarngs {
|
||||
static final SemKey<String> FILE_DESCRIPTION_KEY = <warning descr="Unchecked generics array creation for varargs parameter">SemKey.createKey</warning>("FILE_DESCRIPTION_KEY");
|
||||
|
||||
void f() {
|
||||
OCM<String> o =
|
||||
new <warning descr="Unchecked generics array creation for varargs parameter">OCM<></warning>("", true, new Condition<String>(){
|
||||
@Override
|
||||
public boolean val(String s) {
|
||||
return false;
|
||||
}
|
||||
}, Condition.TRUE);
|
||||
System.out.println(o);
|
||||
}
|
||||
}
|
||||
|
||||
class SemKey<T extends String> {
|
||||
private final String myDebugName;
|
||||
private final SemKey<? super T>[] mySupers;
|
||||
|
||||
private SemKey(String debugName, SemKey<? super T>... supers) {
|
||||
myDebugName = debugName;
|
||||
System.out.println(myDebugName);
|
||||
mySupers = supers;
|
||||
System.out.println(mySupers);
|
||||
}
|
||||
|
||||
public static <T extends String> SemKey<T> createKey(String debugName, SemKey<? super T>... supers) {
|
||||
return new SemKey<T>(debugName, supers);
|
||||
}
|
||||
|
||||
public <K extends T> SemKey<K> subKey(String debugName, SemKey<? super T>... otherSupers) {
|
||||
if (otherSupers.length == 0) {
|
||||
return new <warning descr="Unchecked generics array creation for varargs parameter">SemKey<K></warning>(debugName, this);
|
||||
}
|
||||
return new SemKey<K>(debugName, append(otherSupers, this));
|
||||
}
|
||||
|
||||
public static <T> T[] append(final T[] src, final T element) {
|
||||
return append(src, element, (Class<T>)src.getClass().getComponentType());
|
||||
}
|
||||
|
||||
public static <T> T[] append(T[] src, final T element, Class<T> componentType) {
|
||||
int length = src.length;
|
||||
T[] result = (T[])java.lang.reflect.Array.newInstance(componentType, length + 1);
|
||||
System.arraycopy(src, 0, result, 0, length);
|
||||
result[length] = element;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
interface Condition<T> {
|
||||
boolean val(T t);
|
||||
|
||||
Condition TRUE = new Condition() {
|
||||
@Override
|
||||
public boolean val(Object o) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
class OCM<T> {
|
||||
OCM(T s, boolean b, Condition<T>... c) {
|
||||
System.out.println(s);
|
||||
System.out.println(b);
|
||||
System.out.println(c);
|
||||
}
|
||||
|
||||
OCM(T s, Condition<T>... c) {
|
||||
this(s, false, c);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user