mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
dfa: fighting too complex methods; join complementary memory states after fork to avoid having too many states
This commit is contained in:
+60
@@ -291,6 +291,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (set == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getEqClassValues(set);
|
||||
}
|
||||
|
||||
private List<DfaValue> getEqClassValues(SortedIntSet set) {
|
||||
final List<DfaValue> result = new ArrayList<DfaValue>(set.size());
|
||||
set.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
@@ -531,6 +535,62 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return myEphemeral;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DfaMemoryState mergeWith(DfaMemoryState _other) {
|
||||
DfaMemoryStateImpl other = (DfaMemoryStateImpl)_other;
|
||||
if (myEphemeral != other.myEphemeral ||
|
||||
!myStack.equals(other.myStack) ||
|
||||
!myOffsetStack.equals(other.myOffsetStack)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<DfaVariableValue> differentVars = ContainerUtil.newHashSet();
|
||||
addDifferentlyValuedVariables(other, differentVars);
|
||||
other.addDifferentlyValuedVariables(this, differentVars);
|
||||
|
||||
for (DfaVariableValue differentVar : differentVars) {
|
||||
DfaMemoryStateImpl copy1 = createCopy();
|
||||
DfaMemoryStateImpl copy2 = other.createCopy();
|
||||
copy1.flushVariable(differentVar);
|
||||
copy2.flushVariable(differentVar);
|
||||
copy1.myUnknownVariables.addAll(copy2.myUnknownVariables);
|
||||
copy2.myUnknownVariables.addAll(copy1.myUnknownVariables);
|
||||
|
||||
if (!copy1.equals(copy2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isNull(differentVar) || other.isNull(differentVar)) {
|
||||
copy1.getVariableState(differentVar).setNullable(true);
|
||||
}
|
||||
return copy1;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addDifferentlyValuedVariables(DfaMemoryStateImpl other, Set<DfaVariableValue> differentVars) {
|
||||
for (SortedIntSet aClass : myEqClasses) {
|
||||
if (aClass == null || aClass.size() < 2) continue;
|
||||
List<DfaValue> values = getEqClassValues(aClass);
|
||||
outer: for (DfaValue var : values) {
|
||||
if (var instanceof DfaVariableValue && !differentVars.contains(var)) {
|
||||
for (DfaValue val : values) {
|
||||
if (val != var && other.areDistinct(var, val)) {
|
||||
differentVars.add((DfaVariableValue)var);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areDistinct(DfaValue val1, DfaValue val2) {
|
||||
return myDistinctClasses.contains(createPair(getEqClassIndex(val1), getEqClassIndex(val2)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyInstanceofOrNull(DfaRelationValue dfaCond) {
|
||||
DfaValue left = unwrap(dfaCond.getLeftOperand());
|
||||
|
||||
Reference in New Issue
Block a user