mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
don't multiply dfa states up to infinity when comparing ints (NameUtil.MinusculeMatcher.matchAfterFragment too complex to analyze)
This commit is contained in:
@@ -297,9 +297,13 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
}
|
||||
}
|
||||
|
||||
private int getOrCreateEqClassIndex(DfaValue dfaValue) {
|
||||
@Nullable("for boxed values which can't be compared by ==")
|
||||
private Integer getOrCreateEqClassIndex(DfaValue dfaValue) {
|
||||
int i = getEqClassIndex(dfaValue);
|
||||
if (i != -1) return i;
|
||||
if (!canBeReused(dfaValue) && !(((DfaBoxedValue)dfaValue).getWrappedValue() instanceof DfaConstValue)) {
|
||||
return null;
|
||||
}
|
||||
SortedIntSet aClass = new SortedIntSet();
|
||||
aClass.add(dfaValue.getID());
|
||||
myEqClasses.add(aClass);
|
||||
@@ -338,26 +342,28 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
for (int i = 0; i < myEqClasses.size(); i++) {
|
||||
SortedIntSet aClass = myEqClasses.get(i);
|
||||
if (aClass != null && aClass.contains(dfaValue.getID())) {
|
||||
if (dfaValue instanceof DfaBoxedValue && !canBeReused(((DfaBoxedValue)dfaValue).getWrappedValue(), this) && aClass.size() > 1) return -1;
|
||||
if (!canBeReused(dfaValue) && aClass.size() > 1) return -1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private static boolean canBeReused(final DfaValue valueToWrap, final DfaMemoryState memoryState) {
|
||||
if (valueToWrap instanceof DfaConstValue) {
|
||||
return cacheable((DfaConstValue)valueToWrap);
|
||||
}
|
||||
else if (valueToWrap instanceof DfaVariableValue) {
|
||||
if (PsiType.BOOLEAN.equals(((DfaVariableValue)valueToWrap).getPsiVariable().getType())) return true;
|
||||
List<DfaValue> values = ((DfaMemoryStateImpl)memoryState).getEqClassesFor(valueToWrap);
|
||||
for (DfaValue value : values) {
|
||||
if (value instanceof DfaConstValue && cacheable((DfaConstValue)value)) return true;
|
||||
|
||||
private boolean canBeReused(final DfaValue dfaValue) {
|
||||
if (dfaValue instanceof DfaBoxedValue) {
|
||||
DfaValue valueToWrap = ((DfaBoxedValue)dfaValue).getWrappedValue();
|
||||
if (valueToWrap instanceof DfaConstValue) {
|
||||
return cacheable((DfaConstValue)valueToWrap);
|
||||
}
|
||||
if (valueToWrap instanceof DfaVariableValue) {
|
||||
if (PsiType.BOOLEAN.equals(((DfaVariableValue)valueToWrap).getPsiVariable().getType())) return true;
|
||||
for (DfaValue value : getEqClassesFor(valueToWrap)) {
|
||||
if (value instanceof DfaConstValue && cacheable((DfaConstValue)value)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
//throw new IllegalArgumentException(""+valueToWrap);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean cacheable(DfaConstValue dfaConstValue) {
|
||||
@@ -474,10 +480,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
if (dfaValue instanceof DfaVariableValue || dfaValue instanceof DfaConstValue) {
|
||||
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
|
||||
int c1Index = getOrCreateEqClassIndex(dfaValue);
|
||||
int c2Index = getOrCreateEqClassIndex(dfaNull);
|
||||
Integer c1Index = getOrCreateEqClassIndex(dfaValue);
|
||||
Integer c2Index = getOrCreateEqClassIndex(dfaNull);
|
||||
|
||||
return c1Index == c2Index;
|
||||
return c1Index != null && c1Index.equals(c2Index);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -485,13 +491,16 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
public boolean isNotNull(DfaVariableValue dfaVar) {
|
||||
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
|
||||
int c1Index = getOrCreateEqClassIndex(dfaVar);
|
||||
int c2Index = getOrCreateEqClassIndex(dfaNull);
|
||||
Integer c1Index = getOrCreateEqClassIndex(dfaVar);
|
||||
Integer c2Index = getOrCreateEqClassIndex(dfaNull);
|
||||
if (c1Index == null || c2Index == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long[] pairs = myDistinctClasses.toArray();
|
||||
for (long pair : pairs) {
|
||||
if (low(pair) == c1Index && high(pair) == c2Index ||
|
||||
high(pair) == c1Index && low(pair) == c2Index) {
|
||||
if (c1Index.equals(low(pair)) && c2Index.equals(high(pair)) ||
|
||||
c1Index.equals(high(pair)) && c2Index.equals(low(pair))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -637,15 +646,18 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
private boolean applyRelation(@NotNull final DfaValue dfaLeft, @NotNull final DfaValue dfaRight, boolean isNegated) {
|
||||
// DfaConstValue || DfaVariableValue
|
||||
int c1Index = getOrCreateEqClassIndex(dfaLeft);
|
||||
int c2Index = getOrCreateEqClassIndex(dfaRight);
|
||||
Integer c1Index = getOrCreateEqClassIndex(dfaLeft);
|
||||
Integer c2Index = getOrCreateEqClassIndex(dfaRight);
|
||||
if (c1Index == null || c2Index == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isNegated) { //Equals
|
||||
if (c1Index == c2Index) return true;
|
||||
if (c1Index.equals(c2Index)) return true;
|
||||
if (!uniteClasses(c1Index, c2Index)) return false;
|
||||
}
|
||||
else { // Not Equals
|
||||
if (c1Index == c2Index) return false;
|
||||
if (c1Index.equals(c2Index)) return false;
|
||||
makeClassesDistinct(c1Index, c2Index);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user