mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DFA: improved memory state isSuperState; squash states via isSuperState
This commit is contained in:
+9
@@ -24,6 +24,7 @@ import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DfaInstructionState implements Comparable<DfaInstructionState> {
|
||||
public static final DfaInstructionState[] EMPTY_ARRAY = new DfaInstructionState[0];
|
||||
@@ -93,6 +94,10 @@ class StateQueue {
|
||||
memoryStates.add((DfaMemoryStateImpl)anotherState);
|
||||
}
|
||||
|
||||
if (memoryStates.size() > 1) {
|
||||
memoryStates = squash(memoryStates);
|
||||
}
|
||||
|
||||
if (memoryStates.size() > 1 && joinInstructions.contains(instruction)) {
|
||||
MultiMap<Object, DfaMemoryStateImpl> groups = MultiMap.create();
|
||||
for (DfaMemoryStateImpl memoryState : memoryStates) {
|
||||
@@ -109,6 +114,10 @@ class StateQueue {
|
||||
return ContainerUtil.map(memoryStates, state1 -> new DfaInstructionState(instruction, state1));
|
||||
}
|
||||
|
||||
private static List<DfaMemoryStateImpl> squash(List<DfaMemoryStateImpl> states) {
|
||||
return states.stream().filter(left -> states.stream().noneMatch(right -> right != left && right.isSuperStateOf(left))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
static List<DfaMemoryStateImpl> mergeGroup(List<DfaMemoryStateImpl> group) {
|
||||
if (group.size() < 2) {
|
||||
return group;
|
||||
|
||||
+12
-2
@@ -382,8 +382,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
* @return true if current state is a super-state of the supplied state.
|
||||
*/
|
||||
public boolean isSuperStateOf(DfaMemoryStateImpl that) {
|
||||
if (!equalsSuperficially(that) ||
|
||||
!equalsByUnknownVariables(that) ||
|
||||
if (myEphemeral && !that.myEphemeral) return false;
|
||||
if (myStack.size() != that.myStack.size()) return false;
|
||||
if (StreamEx.zip(myStack, that.myStack, DfaMemoryStateImpl::isSuperValue).has(false)) return false;
|
||||
if (!equalsByUnknownVariables(that) ||
|
||||
!that.getDistinctClassPairs().containsAll(getDistinctClassPairs())) {
|
||||
return false;
|
||||
}
|
||||
@@ -410,6 +412,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isSuperValue(DfaValue superValue, DfaValue subValue) {
|
||||
if (superValue == DfaUnknownValue.getInstance() || superValue == subValue) return true;
|
||||
if (superValue instanceof DfaFactMapValue && subValue instanceof DfaFactMapValue) {
|
||||
return ((DfaFactMapValue)superValue).getFacts().isSuperStateOf(((DfaFactMapValue)subValue).getFacts());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean canBeInRelation(@NotNull DfaValue dfaValue) {
|
||||
DfaValue unwrapped = unwrap(dfaValue);
|
||||
return unwrapped instanceof DfaVariableValue || unwrapped instanceof DfaConstValue;
|
||||
|
||||
Reference in New Issue
Block a user