mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Do not track equality on assignments like Object x = 5 (IDEA-200233)
DfaBoxedValue now reports type when possible
This commit is contained in:
+2
-1
@@ -1448,7 +1448,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
else if (TypeConversionUtil.isPrimitiveAndNotNull(actualType) && TypeConversionUtil.isAssignableFromPrimitiveWrapper(expectedType)) {
|
||||
addConditionalRuntimeThrow();
|
||||
addInstruction(new MethodCallInstruction(context, MethodType.BOXING, expectedType));
|
||||
PsiType boxedType = ((PsiPrimitiveType)actualType).getBoxedType(context);
|
||||
addInstruction(new MethodCallInstruction(context, MethodType.BOXING, boxedType));
|
||||
}
|
||||
else if (actualType != expectedType &&
|
||||
TypeConversionUtil.isPrimitiveAndNotNull(actualType) &&
|
||||
|
||||
+13
-4
@@ -235,6 +235,11 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (value instanceof DfaFactMapValue) {
|
||||
setVariableState(var, state.withFacts(((DfaFactMapValue)value).getFacts()));
|
||||
}
|
||||
else if (DfaUtil.isComparedByEquals(value.getType()) && !DfaUtil.isComparedByEquals(var.getType())) {
|
||||
// Like Object x = "foo" or Object x = 5;
|
||||
TypeConstraint typeConstraint = TypeConstraint.empty().withInstanceofValue(myFactory.createDfaType(value.getType()));
|
||||
setVariableState(var, new DfaVariableState(getFactMap(value).with(DfaFactType.TYPE_CONSTRAINT, typeConstraint)));
|
||||
}
|
||||
else {
|
||||
setVariableState(var, isNull(value) ? state.withFact(DfaFactType.NULLABILITY, DfaNullability.NULLABLE) : state);
|
||||
DfaRelationValue dfaEqual = myFactory.getRelationFactory().createRelation(var, RelationType.EQ, value);
|
||||
@@ -761,7 +766,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
DfaValue dfaTrue = myFactory.getConstFactory().getTrue();
|
||||
if (dfaVar.getSource() == SpecialField.UNBOX) {
|
||||
dfaVar = dfaVar.getQualifier();
|
||||
dfaTrue = myFactory.getBoxedFactory().createBoxed(dfaTrue);
|
||||
dfaTrue = myFactory.getBoxedFactory().createBoxed(dfaTrue, null);
|
||||
}
|
||||
return applyRelationCondition(myFactory.getRelationFactory().createRelation(dfaVar, RelationType.EQ, dfaTrue));
|
||||
}
|
||||
@@ -1162,7 +1167,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return DfaFactMap.fromDfaValue(value);
|
||||
}
|
||||
|
||||
void setVariableState(DfaVariableValue dfaVar, DfaVariableState state) {
|
||||
void setVariableState(@NotNull DfaVariableValue dfaVar, @NotNull DfaVariableState state) {
|
||||
dfaVar = canonicalize(dfaVar);
|
||||
if (state.equals(getDefaultState(dfaVar))) {
|
||||
myVariableStates.remove(dfaVar);
|
||||
@@ -1188,8 +1193,12 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (value instanceof DfaVariableValue) {
|
||||
return canonicalize((DfaVariableValue)value);
|
||||
}
|
||||
if (value instanceof DfaBoxedValue && ((DfaBoxedValue)value).getWrappedValue() instanceof DfaVariableValue) {
|
||||
return Objects.requireNonNull(myFactory.getBoxedFactory().createBoxed(canonicalize(((DfaBoxedValue)value).getWrappedValue())));
|
||||
if (value instanceof DfaBoxedValue) {
|
||||
DfaBoxedValue boxedValue = (DfaBoxedValue)value;
|
||||
if (boxedValue.getWrappedValue() instanceof DfaVariableValue) {
|
||||
DfaValue canonicalized = canonicalize(boxedValue.getWrappedValue());
|
||||
return Objects.requireNonNull(myFactory.getBoxedFactory().createBoxed(canonicalized, boxedValue.getType()));
|
||||
}
|
||||
}
|
||||
if (value instanceof DfaConstValue) {
|
||||
Object constant = ((DfaConstValue)value).getValue();
|
||||
|
||||
@@ -347,7 +347,7 @@ public class DfaUtil {
|
||||
if (TypeConversionUtil.isPrimitiveWrapper(type)) {
|
||||
if (value instanceof DfaConstValue ||
|
||||
(value instanceof DfaVariableValue && TypeConversionUtil.isPrimitiveAndNotNull(value.getType()))) {
|
||||
DfaValue boxed = value.getFactory().getBoxedFactory().createBoxed(value);
|
||||
DfaValue boxed = value.getFactory().getBoxedFactory().createBoxed(value, type);
|
||||
return boxed == null ? DfaUnknownValue.getInstance() : boxed;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -535,7 +535,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
|
||||
}
|
||||
|
||||
if (methodType == MethodCallInstruction.MethodType.BOXING) {
|
||||
DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue);
|
||||
DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue, type);
|
||||
return boxed == null ? factory.createTypeValue(type, Nullability.NOT_NULL) : boxed;
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -17,6 +17,7 @@ package com.intellij.codeInspection.dataFlow.value;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.SpecialField;
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -27,10 +28,12 @@ import java.util.Map;
|
||||
|
||||
public class DfaBoxedValue extends DfaValue {
|
||||
private final DfaValue myWrappedValue;
|
||||
private final @Nullable PsiType myType;
|
||||
|
||||
private DfaBoxedValue(DfaValue valueToWrap, DfaValueFactory factory) {
|
||||
private DfaBoxedValue(DfaValue valueToWrap, DfaValueFactory factory, @Nullable PsiType type) {
|
||||
super(factory);
|
||||
myWrappedValue = valueToWrap;
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@@ -42,6 +45,12 @@ public class DfaBoxedValue extends DfaValue {
|
||||
return myWrappedValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
public static class Factory {
|
||||
private final Map<Object, DfaBoxedValue> cachedValues = new HashMap<>();
|
||||
|
||||
@@ -56,7 +65,7 @@ public class DfaBoxedValue extends DfaValue {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DfaValue createBoxed(DfaValue valueToWrap) {
|
||||
public DfaValue createBoxed(DfaValue valueToWrap, @Nullable PsiType type) {
|
||||
if (valueToWrap instanceof DfaVariableValue && ((DfaVariableValue)valueToWrap).getSource() == SpecialField.UNBOX) {
|
||||
return ((DfaVariableValue)valueToWrap).getQualifier();
|
||||
}
|
||||
@@ -66,7 +75,7 @@ public class DfaBoxedValue extends DfaValue {
|
||||
if (o == null) return null;
|
||||
DfaBoxedValue boxedValue = cachedValues.get(o);
|
||||
if (boxedValue == null) {
|
||||
cachedValues.put(o, boxedValue = new DfaBoxedValue(valueToWrap, myFactory));
|
||||
cachedValues.put(o, boxedValue = new DfaBoxedValue(valueToWrap, myFactory, type));
|
||||
}
|
||||
return boxedValue;
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public class DfaConstValue extends DfaValue {
|
||||
Boolean boo = computeJavaLangBooleanFieldReference(variable);
|
||||
if (boo != null) {
|
||||
DfaConstValue unboxed = createFromValue(boo, PsiType.BOOLEAN);
|
||||
return myFactory.getBoxedFactory().createBoxed(unboxed);
|
||||
return myFactory.getBoxedFactory().createBoxed(unboxed, PsiType.BOOLEAN.getBoxedType(variable));
|
||||
}
|
||||
PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(variable.getInitializer());
|
||||
if (initializer instanceof PsiLiteralExpression && initializer.textMatches(PsiKeyword.NULL)) {
|
||||
|
||||
@@ -68,7 +68,7 @@ public class aaa {
|
||||
a = 4;
|
||||
}
|
||||
|
||||
if (<warning descr="Condition 'a != null' is always 'true'">a != null</warning> && a instanceof aaa) {
|
||||
if (<warning descr="Condition 'a != null && a instanceof aaa' is always 'false'"><warning descr="Condition 'a != null' is always 'true'">a != null</warning> && <warning descr="Condition 'a instanceof aaa' is always 'false' when reached">a instanceof aaa</warning></warning>) {
|
||||
if (<warning descr="Condition is always true">true</warning>) {
|
||||
//a = new aaa();
|
||||
}
|
||||
|
||||
+6
@@ -1,4 +1,10 @@
|
||||
class X {
|
||||
void test() {
|
||||
Object obj1 = 100000L;
|
||||
Object obj2 = 100000L;
|
||||
if(obj1 == obj2) {}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int primitive = 1024;
|
||||
Object object = primitive;
|
||||
|
||||
@@ -90,4 +90,10 @@ class StringEquality {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testObject() {
|
||||
Object x = " foo ".trim();
|
||||
Object y = " foo ".trim();
|
||||
if (x == y) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user