mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-197241: fixed false-positive when variable type is narrowed from Object to String
This commit is contained in:
+20
@@ -675,12 +675,32 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return false;
|
||||
}
|
||||
setVariableState((DfaVariableValue)value, newState);
|
||||
if (newState.getTypeConstraint().isExact(CommonClassNames.JAVA_LANG_STRING) &&
|
||||
!newState.getTypeConstraint().equals(oldState.getTypeConstraint())) {
|
||||
// Type is narrowed to java.lang.String: we consider String equivalence by content,
|
||||
// but other object types by reference, so we need to remove distinct pairs, if any.
|
||||
convertReferenceEqualityToValueEquality(value);
|
||||
}
|
||||
updateEquivalentVariables((DfaVariableValue)value, newState);
|
||||
return updateEqClassesByState((DfaVariableValue)value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void convertReferenceEqualityToValueEquality(DfaValue value) {
|
||||
int id = value.getID();
|
||||
int[] indices = myIdToEqClassesIndices.get(id);
|
||||
for (int index : indices) {
|
||||
for (Iterator<DistinctPairSet.DistinctPair> iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) {
|
||||
DistinctPairSet.DistinctPair pair = iterator.next();
|
||||
EqClass otherClass = pair.getOtherClass(index);
|
||||
if (otherClass != null && otherClass.findConstant(false) != getFactory().getConstFactory().getNull()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateEqClassesByState(DfaVariableValue value) {
|
||||
if (DfaNullability.isNotNull(getVariableState(value).myFactMap)) {
|
||||
return applyRelation(value, getFactory().getConstFactory().getNull(), true);
|
||||
|
||||
@@ -68,6 +68,8 @@ public abstract class TypeConstraint {
|
||||
|
||||
public abstract boolean isExact();
|
||||
|
||||
public abstract boolean isExact(String typeName);
|
||||
|
||||
|
||||
static final class Exact extends TypeConstraint {
|
||||
final @NotNull DfaPsiType myType;
|
||||
@@ -159,6 +161,11 @@ public abstract class TypeConstraint {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExact(String typeName) {
|
||||
return myType.getPsiType().equalsToText(typeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myType.hashCode();
|
||||
@@ -404,6 +411,11 @@ public abstract class TypeConstraint {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExact(String typeName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -42,10 +42,14 @@ class StringEquality {
|
||||
}
|
||||
|
||||
boolean compare(Object a, Object b) {
|
||||
if(a == b) return true;
|
||||
if(a == b) {
|
||||
if(a instanceof String) {
|
||||
return <warning descr="Result of '((String)a).equals(b)' is always 'true'">((String)a).equals(b)</warning>;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(a instanceof String && b instanceof String) {
|
||||
// false-positive
|
||||
return <warning descr="Result of '((String)a).equals((String)b)' is always 'false'">((String)a).equals((String)b)</warning>;
|
||||
return ((String)a).equals(b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user