mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-107195 Methods returning primitive types should be treated as @Nonnull
This commit is contained in:
@@ -1050,10 +1050,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
PsiType exprType = expression.getType();
|
||||
|
||||
if (TypeConversionUtil.isPrimitiveAndNotNull(expectedType) && TypeConversionUtil.isPrimitiveWrapper(exprType)) {
|
||||
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING));
|
||||
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType));
|
||||
}
|
||||
else if (TypeConversionUtil.isPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) {
|
||||
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING));
|
||||
addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType));
|
||||
}
|
||||
else if (exprType != expectedType &&
|
||||
TypeConversionUtil.isPrimitiveAndNotNull(exprType) &&
|
||||
|
||||
+6
-5
@@ -229,17 +229,14 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
|
||||
final PsiType type = instruction.getResultType();
|
||||
final MethodCallInstruction.MethodType methodType = instruction.getMethodType();
|
||||
if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
|
||||
return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
|
||||
}
|
||||
|
||||
|
||||
if (methodType == MethodCallInstruction.MethodType.UNBOXING) {
|
||||
return factory.getBoxedFactory().createUnboxed(qualifierValue);
|
||||
}
|
||||
|
||||
if (methodType == MethodCallInstruction.MethodType.BOXING) {
|
||||
DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue);
|
||||
return boxed == null ? DfaUnknownValue.getInstance() : boxed;
|
||||
return boxed == null ? factory.getNotNullFactory().create(type) : boxed;
|
||||
}
|
||||
|
||||
if (methodType == MethodCallInstruction.MethodType.CAST) {
|
||||
@@ -248,6 +245,10 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
}
|
||||
return qualifierValue;
|
||||
}
|
||||
|
||||
if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
|
||||
return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
|
||||
}
|
||||
return DfaUnknownValue.getInstance();
|
||||
}
|
||||
|
||||
|
||||
+18
-23
@@ -36,40 +36,35 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MethodCallInstruction extends Instruction {
|
||||
@Nullable private final PsiCallExpression myCall;
|
||||
@Nullable private PsiType myType;
|
||||
@Nullable private final PsiType myType;
|
||||
@NotNull private final PsiExpression[] myArgs;
|
||||
private boolean myShouldFlushFields;
|
||||
private final boolean myShouldFlushFields;
|
||||
@NotNull private final PsiExpression myContext;
|
||||
private final MethodType myMethodType;
|
||||
@Nullable private DfaValue myPrecalculatedReturnValue;
|
||||
@Nullable private final DfaValue myPrecalculatedReturnValue;
|
||||
public enum MethodType {
|
||||
BOXING, UNBOXING, REGULAR_METHOD_CALL, CAST
|
||||
}
|
||||
|
||||
public MethodCallInstruction(@NotNull PsiCallExpression callExpression, @Nullable DfaValue precalculatedReturnValue) {
|
||||
this(callExpression, MethodType.REGULAR_METHOD_CALL);
|
||||
myPrecalculatedReturnValue = precalculatedReturnValue;
|
||||
}
|
||||
|
||||
public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType, @Nullable PsiType resultType) {
|
||||
this(context, methodType);
|
||||
myType = resultType;
|
||||
myShouldFlushFields = false;
|
||||
}
|
||||
|
||||
public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType) {
|
||||
myContext = context;
|
||||
myMethodType = methodType;
|
||||
myCall = methodType == MethodType.REGULAR_METHOD_CALL && context instanceof PsiCallExpression ? (PsiCallExpression)context : null;
|
||||
final PsiExpressionList argList = myCall == null ? null : myCall.getArgumentList();
|
||||
myCall = null;
|
||||
myArgs = PsiExpression.EMPTY_ARRAY;
|
||||
myType = resultType;
|
||||
myShouldFlushFields = false;
|
||||
myPrecalculatedReturnValue = null;
|
||||
}
|
||||
|
||||
public MethodCallInstruction(@NotNull PsiCallExpression context, @Nullable DfaValue precalculatedReturnValue) {
|
||||
myContext = context;
|
||||
myMethodType = MethodType.REGULAR_METHOD_CALL;
|
||||
myCall = context;
|
||||
final PsiExpressionList argList = context.getArgumentList();
|
||||
myArgs = argList != null ? argList.getExpressions() : PsiExpression.EMPTY_ARRAY;
|
||||
|
||||
myType = myCall == null ? null : myCall.getType();
|
||||
|
||||
myShouldFlushFields = true;
|
||||
if (myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0) {
|
||||
myShouldFlushFields = false;
|
||||
}
|
||||
myType = myCall.getType();
|
||||
myShouldFlushFields = !(myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0);
|
||||
myPrecalculatedReturnValue = precalculatedReturnValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class Foo {
|
||||
public int getValue() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public void nullcheck() {
|
||||
Integer x = getValue();
|
||||
System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
|
||||
}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
@NotNull
|
||||
public Integer getValue() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public void nullcheck() {
|
||||
Integer x = getValue();
|
||||
System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
|
||||
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
|
||||
|
||||
public void testNotNullPrimitive() throws Throwable { doTest(); }
|
||||
public void testBoxing128() throws Throwable { doTest(); }
|
||||
public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); }
|
||||
public void testMultiCatch() throws Throwable { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user