mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-123301 Show a warning if 'List<@Nullable X>' is passed to a place where 'List<@NotNull X'> is expected
This commit is contained in:
+46
@@ -25,6 +25,7 @@ import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
|
||||
import com.intellij.codeInspection.dataFlow.Nullness;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
@@ -158,6 +159,51 @@ public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionToo
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
checkCollectionNullityOnAssignment(expression.getOperationSign(), expression.getLExpression().getType(), expression.getRExpression());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLocalVariable(PsiLocalVariable variable) {
|
||||
PsiIdentifier identifier = variable.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
checkCollectionNullityOnAssignment(identifier, variable.getType(), variable.getInitializer());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(PsiCallExpression callExpression) {
|
||||
PsiExpressionList argList = callExpression.getArgumentList();
|
||||
JavaResolveResult result = callExpression.resolveMethodGenerics();
|
||||
PsiMethod method = (PsiMethod)result.getElement();
|
||||
if (method == null || argList == null) return;
|
||||
|
||||
PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiExpression[] arguments = argList.getExpressions();
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
PsiExpression argument = arguments[i];
|
||||
if (i < parameters.length &&
|
||||
(i < parameters.length - 1 || !MethodCallInstruction.isVarArgCall(method, substitutor, arguments, parameters))) {
|
||||
checkCollectionNullityOnAssignment(argument, substitutor.substitute(parameters[i].getType()), argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCollectionNullityOnAssignment(@NotNull PsiElement errorElement, PsiType expectedType, PsiExpression assignedExpression) {
|
||||
PsiType lItemType = JavaGenericsUtil.getCollectionItemType(expectedType, errorElement.getResolveScope());
|
||||
PsiType rItemType = assignedExpression == null ? null : JavaGenericsUtil.getCollectionItemType(assignedExpression);
|
||||
|
||||
if (DfaPsiUtil.getTypeNullability(lItemType) == Nullness.NOT_NULL &&
|
||||
DfaPsiUtil.getTypeNullability(rItemType) == Nullness.NULLABLE) {
|
||||
holder.registerProblem(errorElement,
|
||||
"Assigning a collection of nullable elements into a collection of non-null elements",
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import typeUse.*;
|
||||
import java.util.*;
|
||||
|
||||
class JC {
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<@Nullable String> list = new ArrayList<>();
|
||||
print(<warning descr="Assigning a collection of nullable elements into a collection of non-null elements">list</warning>);
|
||||
|
||||
List<@NotNull String> <warning descr="Assigning a collection of nullable elements into a collection of non-null elements">list2</warning> = list;
|
||||
|
||||
List<@NotNull String> list3;
|
||||
list2 <warning descr="Assigning a collection of nullable elements into a collection of non-null elements">=</warning> list;
|
||||
}
|
||||
|
||||
private static void print(List<@NotNull String> list) {
|
||||
for (String s : list) {
|
||||
System.out.println(s.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,4 +207,9 @@ public class NullableStuffInspectionTest extends LightCodeInsightFixtureTestCase
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPassingNullableCollectionWhereNotNullIsExpected() {
|
||||
DataFlowInspection8Test.setupTypeUseAnnotations("typeUse", myFixture);
|
||||
doTest();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user