001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2006-2007 University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.ba.npe;
021:
022: import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
023:
024: /**
025: * A dataflow value that indicates what kind of return path
026: * is possible at the current program location.
027: * Either:
028: * <ul>
029: * <li>It is possible to return normally</li>
030: * <li>It is not possible to return normally
031: * (i.e., an exception is guaranteed to be thrown)</li>
032: * </ul>
033: *
034: * @author David Hovemeyer
035: */
036: public class ReturnPathType {
037: private static final int CAN_RETURN_NORMALLY = 0;
038: private static final int CANNOT_RETURN_NORMALLY = 1;
039: private static final int TOP = 2;
040:
041: private int type;
042:
043: /**
044: * Constructor.
045: * Creates a top dataflow fact.
046: */
047: public ReturnPathType() {
048: type = TOP;
049: }
050:
051: /**
052: * @return true if the method can return normally at this
053: * location, false otherwise
054: */
055: public boolean canReturnNormally() throws DataflowAnalysisException {
056: if (!isValid()) {
057: throw new DataflowAnalysisException(
058: "Checking invalid ReturnPathType");
059: }
060: return type == CAN_RETURN_NORMALLY;
061: }
062:
063: /**
064: * Make this dataflow fact an exact copy of the other one.
065: *
066: * @param other another dataflow fact
067: */
068: public void copyFrom(ReturnPathType other) {
069: this .type = other.type;
070: }
071:
072: /**
073: * Set the dataflow fact to top.
074: */
075: public void setTop() {
076: type = TOP;
077: }
078:
079: /**
080: * @return true if the dataflow fact is top, false otherwise
081: */
082: public boolean isTop() {
083: return type == TOP;
084: }
085:
086: /**
087: * Set whether or not it is possible to return normally.
088: *
089: * @param canReturnNormally true if the method can return normally at this
090: * location, false otherwise
091: */
092: public void setCanReturnNormally(boolean canReturnNormally) {
093: type = canReturnNormally ? CAN_RETURN_NORMALLY
094: : CANNOT_RETURN_NORMALLY;
095: }
096:
097: /**
098: * Merge this fact with given fact.
099: *
100: * @param fact another dataflow fact
101: */
102: public void mergeWith(ReturnPathType fact) {
103: if (fact.isTop()) {
104: // other fact is top: no change to this one
105: return;
106: } else if (this .isTop()) {
107: // this fact is top: copy other fact
108: this .copyFrom(fact);
109: } else {
110: // neither fact is top: as long as one of the two
111: // facts represents a (possible) normal return, then the result
112: // is a possible normal return
113: if (fact.type == CAN_RETURN_NORMALLY) {
114: this .type = CAN_RETURN_NORMALLY;
115: }
116: }
117: }
118:
119: /**
120: * Determine whether this dataflow fact is identical to another one.
121: *
122: * @param other another dataflow fact
123: * @return true if the two dataflow facts are identical,
124: * false if they are different
125: */
126: boolean sameAs(ReturnPathType other) {
127: return this .type == other.type;
128: }
129:
130: /**
131: * @return true if this is a valid dataflow fact (not top or bottom),
132: * false if not a valid dataflow fact
133: */
134: public boolean isValid() {
135: return type != TOP;
136: }
137:
138: /* (non-Javadoc)
139: * @see java.lang.Object#toString()
140: */
141: @Override
142: public String toString() {
143: switch (type) {
144: case TOP:
145: return "[TOP]";
146: case CAN_RETURN_NORMALLY:
147: return "-";
148: case CANNOT_RETURN_NORMALLY:
149: return "X";
150: default:
151: throw new IllegalStateException();
152: }
153: }
154: }
|