void setVariableState(DfaVariableValue dfaVar, DfaVariableState state) { assert !myUnknownVariables.contains(dfaVar); if (state.equals(myDefaultVariableStates.get(dfaVar))) { myVariableStates.remove(dfaVar); } else { myVariableStates.put(dfaVar, state); } myCachedHash = null; }
@SuppressWarnings("HardCodedStringLiteral") public String toString() { StringBuilder result = new StringBuilder(); result.append('<'); if (myEphemeral) { result.append("ephemeral, "); } for (EqClass set : getNonTrivialEqClasses()) { result.append(set); } if (!myDistinctClasses.isEmpty()) { result.append("\n distincts: "); List<String> distincts = new ArrayList<>(); for (UnorderedPair<EqClass> pair : getDistinctClassPairs()) { distincts.add("{" + pair.first + ", " + pair.second + "}"); } Collections.sort(distincts); result.append(StringUtil.join(distincts, " ")); } if (!myStack.isEmpty()) { result.append("\n stack: ").append(StringUtil.join(myStack, ",")); } if (!myVariableStates.isEmpty()) { result.append("\n vars: "); for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) { result .append("[") .append(entry.getKey()) .append("->") .append(entry.getValue()) .append("] "); } } if (!myUnknownVariables.isEmpty()) { result.append("\n unknowns: ").append(new HashSet<>(myUnknownVariables)); } result.append('>'); return result.toString(); }
int getPartialHashCode(boolean unknowns, boolean varStates) { int hash = (getNonTrivialEqClasses().hashCode() * 31 + getDistinctClassPairs().hashCode()) * 31 + myStack.hashCode(); if (varStates) { hash = hash * 31 + myVariableStates.hashCode(); } if (unknowns && !myUnknownVariables.isEmpty()) { hash = hash * 31 + myUnknownVariables.hashCode(); } return hash; }
DfaVariableState getVariableState(DfaVariableValue dfaVar) { DfaVariableState state = myVariableStates.get(dfaVar); if (state == null) { state = myDefaultVariableStates.get(dfaVar); if (state == null) { state = createVariableState(dfaVar); DfaTypeValue initialType = dfaVar.getTypeValue(); if (initialType != null) { state = state.withInstanceofValue(initialType); assert state != null; } myDefaultVariableStates.put(dfaVar, state); } if (isUnknownState(dfaVar)) { return state.withNullable(false); } } return state; }
boolean equalsByVariableStates(DfaMemoryStateImpl that) { return myVariableStates.equals(that.myVariableStates); }
void doFlush(@NotNull DfaVariableValue varPlain, boolean markUnknown) { DfaVariableValue varNegated = varPlain.getNegatedValue(); final int idPlain = varPlain.getID(); final int idNegated = varNegated == null ? -1 : varNegated.getID(); int[] classes = myIdToEqClassesIndices.get(idPlain); int[] negatedClasses = myIdToEqClassesIndices.get(idNegated); int[] result = ArrayUtil.mergeArrays( ObjectUtils.notNull(classes, ArrayUtil.EMPTY_INT_ARRAY), ObjectUtils.notNull(negatedClasses, ArrayUtil.EMPTY_INT_ARRAY)); int interruptCount = 0; for (int varClassIndex : result) { EqClass varClass = myEqClasses.get(varClassIndex); if ((++interruptCount & 0xf) == 0) { ProgressManager.checkCanceled(); } varClass = new EqClass(varClass); myEqClasses.set(varClassIndex, varClass); for (int id : varClass.toNativeArray()) { int idUnwrapped; if (id == idPlain || id == idNegated || (idUnwrapped = unwrap(myFactory.getValue(id)).getID()) == idPlain || idUnwrapped == idNegated) { varClass.removeValue(id); } } if (varClass.isEmpty()) { myEqClasses.set(varClassIndex, null); for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) { long pair = iterator.next(); if (low(pair) == varClassIndex || high(pair) == varClassIndex) { iterator.remove(); } } } else if (varClass.containsConstantsOnly()) { for (TLongIterator iterator = myDistinctClasses.iterator(); iterator.hasNext(); ) { long pair = iterator.next(); if (low(pair) == varClassIndex && myEqClasses.get(high(pair)).containsConstantsOnly() || high(pair) == varClassIndex && myEqClasses.get(low(pair)).containsConstantsOnly()) { iterator.remove(); } } } } removeAllFromMap(idPlain); removeAllFromMap(idNegated); myVariableStates.remove(varPlain); if (varNegated != null) { myVariableStates.remove(varNegated); } if (markUnknown) { myUnknownVariables.add(varPlain); } myCachedNonTrivialEqClasses = null; myCachedDistinctClassPairs = null; myCachedHash = null; }
@NotNull Set<DfaVariableValue> getChangedVariables() { return myVariableStates.keySet(); }