⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stateset.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
字号:
/* * Bytecode Analysis Framework * Copyright (C) 2005, University of Maryland *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package edu.umd.cs.findbugs.ba.obl;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** * A dataflow fact used in ObligationAnalysis. * It is a set of State objects, plus the additional capability * to represent top and bottom elements. *  * <p>Invariant: no StateSet may contain more than one * State with the same ObligationSet.</p> * * <p>See Weimer and Necula, * <a href="http://doi.acm.org/10.1145/1028976.1029011" * >Finding and preventing run-time error handling mistakes</a>, * OOPSLA 2004.</p> *  * @author David Hovemeyer */public class StateSet {	public interface StateCallback {		public void apply(State state) throws NonexistentObligationException;	}	private boolean isTop;	private boolean isBottom;	private Map<ObligationSet, State> stateMap;	private ObligationFactory factory;	public StateSet(ObligationFactory factory) {		this.isTop = this.isBottom = false;		this.stateMap = new HashMap<ObligationSet, State>();		this.factory = factory;	}	public void setTop() {		this.isTop = true;		this.isBottom = false;	}	public boolean isTop() {		return isTop;	}	public void setBottom() {		this.isBottom = true;		this.isTop = false;	}	public boolean isBottom() {		return this.isBottom;	}	public boolean isValid() {		return !this.isTop && !this.isBottom;	}	/**	 * Return an Iterator over the States in the StateSet.	 * 	 * @return an Iterator over the States in the StateSet	 */	public Iterator<State> stateIterator() {		return stateMap.values().iterator();	}	/**	 * Get the State which has the given ObligationSet.	 * Returns null if there is no such state.	 * 	 * @param obligationSet we want to get the State with this ObligationSet	 * @return the State with the given ObligationSet, or null if there is no such State	 */	public State getStateWithObligationSet(ObligationSet obligationSet) {		return stateMap.get(obligationSet);	}	/**	 * Initialize this object as the entry fact for a method:	 * a single state with empty obligation set and path.	 * 	 * @param factory the ObligationFactory used for the analysis	 */	public void initEntryFact(ObligationFactory factory) {		this.isTop = this.isBottom = false;		this.stateMap.clear();		// Add initial fact: empty obligations, empty path		State initState = new State(factory.getMaxObligationTypes(), factory);		this.stateMap.put(initState.getObligationSet(), initState);	}	/**	 *  Make this StateSet an exact copy of the given StateSet.	 *  	 *  @param other a StateSet; this StateSet will be made identical to it	 */	public void copyFrom(StateSet other) {		this.isTop = other.isTop;		this.isBottom = other.isBottom;		this.stateMap.clear();		for (State state : other.stateMap.values()) {			State dup = state.duplicate();			this.stateMap.put(dup.getObligationSet(), dup);		}	}	/**	 * Return an exact deep copy of this StateSet.	 * 	 * @return an exact deep copy of this StateSet	 */	public StateSet duplicate() {		StateSet dup = new StateSet(factory);		dup.copyFrom(this);		return dup;	}	/**	 * Add an obligation to every State in the StateSet.	 * 	 * @param obligation the obligation to add	 */	public void addObligation(final Obligation obligation) {		final Map<ObligationSet, State> updatedStateMap =			new HashMap<ObligationSet, State>();		try {			applyToAllStatesAndUpdateMap(new StateCallback() {				public void apply(State state) {					state.getObligationSet().add(obligation);					updatedStateMap.put(state.getObligationSet(), state);				}			}, updatedStateMap);		} catch (NonexistentObligationException e) {			// This can't actually happen.		}	}	/**	 * Remove an Obligation from every State in the StateSet.	 * 	 * @param obligation the obligation to remove	 * @throws NonexistentObligationException	 */	public void deleteObligation(final Obligation obligation)			throws NonexistentObligationException {		final Map<ObligationSet, State> updatedStateMap =			new HashMap<ObligationSet, State>();		applyToAllStatesAndUpdateMap(new StateCallback() {			/* (non-Javadoc)			 * @see edu.umd.cs.findbugs.ba.obl.StateSet.StateCallback#apply(edu.umd.cs.findbugs.ba.obl.State)			 */			public void apply(State state)					throws NonexistentObligationException {				state.getObligationSet().remove(obligation);				updatedStateMap.put(state.getObligationSet(), state);			}		}, updatedStateMap);	}	@Override	public boolean equals(Object o) {		if (o == null || o.getClass() != this.getClass())			return false;		StateSet other = (StateSet) o;		return this.isTop == other.isTop			&& this.isBottom == other.isBottom			&& this.stateMap.equals(other.stateMap);	}	@Override	public int hashCode() {		throw new UnsupportedOperationException();	}	@Override	public String toString() {		if (isTop)			return "TOP";		else if (isBottom)			return "BOTTOM";		else {			StringBuffer buf = new StringBuffer();			boolean first = true;			for (Iterator<State> i = stateIterator(); i.hasNext();) {				State state = i.next();				if (first)					first = false;				else					buf.append(",");				buf.append(state.toString());			}			return buf.toString();		}	}	/**	 * Return a newly allocated Map of ObligationSet to State	 * that may be passed to applyToAllStatesAndUpdateMap().	 */	public Map<ObligationSet, State> createEmptyMap() {		return new HashMap<ObligationSet, State>();	}	/**	 * Apply a callback to all States and replace the	 * ObligationSet -&gt; State map with the one given	 * (which is assumed to be updated by the callback.)	 * 	 * @param callback        the callback	 * @param updatedStateMap updated map of ObligationSets to States	 */	public void applyToAllStatesAndUpdateMap(StateCallback callback,			Map<ObligationSet, State> updatedStateMap)			throws NonexistentObligationException {		applyToAllStates(callback);		this.stateMap = updatedStateMap;	}	/**	 * Apply a callback to all States in the StateSet.	 * 	 * @param callback	 */	public void applyToAllStates(StateCallback callback)			throws NonexistentObligationException {		for (State state : stateMap.values()) {			callback.apply(state);		}	}}// vim:ts=4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -