KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > Edge


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003-2005 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.ba;
21
22 import java.util.Locale JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.apache.bcel.generic.InstructionHandle;
26
27 import edu.umd.cs.findbugs.graph.AbstractEdge;
28
29 /**
30  * An edge of a control flow graph.
31  *
32  * @author David Hovemeyer
33  * @see BasicBlock
34  * @see CFG
35  */

36 public class Edge extends AbstractEdge<Edge, BasicBlock> implements EdgeTypes, Debug {
37
38     /* ----------------------------------------------------------------------
39      * Fields
40      * ---------------------------------------------------------------------- */

41
42     private int type;
43     private int flags;
44
45     /* ----------------------------------------------------------------------
46      * Public methods
47      * ---------------------------------------------------------------------- */

48
49     /**
50      * Constructor.
51      *
52      * @param source source basic block
53      * @param dest destination basic block
54      */

55     public Edge(BasicBlock source, BasicBlock dest) {
56         super(source, dest);
57     }
58
59     public int getId() {
60         return getLabel();
61     }
62
63     /**
64      * Get the type of edge.
65      */

66     public int getType() {
67         return type;
68     }
69
70     /**
71      * Set the type of edge.
72      */

73     public void setType(int type) {
74         this.type = type;
75     }
76
77     /**
78      * Get the edge flags.
79      */

80     public int getFlags() {
81         return flags;
82     }
83
84     /**
85      * Set the edge flags.
86      */

87     public void setFlags(int flags) {
88         this.flags = flags;
89     }
90
91     /**
92      * Return if given edge flag is set.
93      *
94      * @param flag the edge flag
95      * @return true if the flag is set, false otherwise
96      */

97     public boolean isFlagSet(int flag) {
98         return (this.flags & flag) != 0;
99     }
100
101     /**
102      * Is the edge an exception edge?
103      */

104     public boolean isExceptionEdge() {
105         return type == HANDLED_EXCEPTION_EDGE || type == UNHANDLED_EXCEPTION_EDGE;
106     }
107
108     @Override JavaDoc
109          public boolean equals(Object JavaDoc o) {
110         if (o == null || this.getClass() != o.getClass())
111             return false;
112         Edge other = (Edge) o;
113         return this.getSource() == other.getSource() && this.getTarget() == other.getTarget()
114                 && this.getType() == other.getType();
115     }
116
117     @Override JavaDoc
118          public int hashCode() {
119         return 2003 * getSource().getLabel() + getTarget().getLabel();
120     }
121
122     /**
123      * Compare with other edge.
124      */

125     @Override JavaDoc
126          public int compareTo(Edge other) {
127         int cmp = super.compareTo(other);
128         if (cmp != 0)
129             return cmp;
130         return type - other.type;
131     }
132
133     @Override JavaDoc
134          public String JavaDoc toString() {
135         return formatAsString(false);
136     }
137
138     public boolean isBackwardInBytecode() {
139         BasicBlock source = getSource();
140         BasicBlock target = getTarget();
141
142         InstructionHandle sourceInstruction = source.getLastInstruction();
143         InstructionHandle targetInstruction = target.getFirstInstruction();
144
145         if (targetInstruction == null || sourceInstruction == null) return false;
146         return targetInstruction.getPosition() < sourceInstruction.getPosition();
147
148     }
149     
150     public boolean sourceIsTopOfLoop(Set JavaDoc<Integer JavaDoc> positions) {
151         BasicBlock source = getSource();
152     
153         InstructionHandle sourceInstruction = source.getLastInstruction();
154     
155         if ( sourceInstruction == null) return false;
156         return positions.contains(sourceInstruction.getPosition());
157         
158
159     }
160     /**
161      * Return a string representation of the edge.
162      */

163     public String JavaDoc formatAsString(boolean reverse) {
164         BasicBlock source = getSource();
165         BasicBlock target = getTarget();
166
167         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
168         buf.append(reverse ? "REVERSE_EDGE(" : "EDGE(");
169         buf.append(getLabel());
170         buf.append(") type ");
171         buf.append(edgeTypeToString(type));
172         buf.append(" from block ");
173         buf.append(reverse ? target.getId() : source.getId());
174         buf.append(" to block ");
175         buf.append(reverse ? source.getId() : target.getId());
176         InstructionHandle sourceInstruction = source.getLastInstruction();
177         InstructionHandle targetInstruction = target.getFirstInstruction();
178         String JavaDoc exInfo = " -> ";
179         if (targetInstruction == null && target.isExceptionThrower()) {
180             targetInstruction = target.getExceptionThrower();
181             exInfo = " => ";
182         }
183         if (sourceInstruction != null && targetInstruction != null) {
184             buf.append(" [bytecode ");
185             buf.append(sourceInstruction.getPosition());
186             buf.append(exInfo);
187             buf.append(targetInstruction.getPosition());
188             buf.append(']');
189         } else if (source.isExceptionThrower()) {
190             if (type == FALL_THROUGH_EDGE)
191                 buf.append(" [successful check]");
192             else {
193                 buf.append(" [failed check for ");
194                 buf.append(source.getExceptionThrower().getPosition());
195                 if (targetInstruction != null) {
196                     buf.append(" to ");
197                     buf.append(targetInstruction.getPosition());
198                 }
199                 buf.append(']');
200             }
201         }
202         return buf.toString();
203     }
204
205     /**
206      * Get string representing given edge type.
207      */

208     public static String JavaDoc edgeTypeToString(int edgeType) {
209         switch (edgeType) {
210         case FALL_THROUGH_EDGE:
211             return "FALL_THROUGH";
212         case IFCMP_EDGE:
213             return "IFCMP";
214         case SWITCH_EDGE:
215             return "SWITCH";
216         case SWITCH_DEFAULT_EDGE:
217             return "SWITCH_DEFAULT";
218         case JSR_EDGE:
219             return "JSR";
220         case RET_EDGE:
221             return "RET";
222         case GOTO_EDGE:
223             return "GOTO";
224         case RETURN_EDGE:
225             return "RETURN";
226         case UNHANDLED_EXCEPTION_EDGE:
227             return "UNHANDLED_EXCEPTION";
228         case HANDLED_EXCEPTION_EDGE:
229             return "HANDLED_EXCEPTION";
230         case START_EDGE:
231             return "START";
232         case BACKEDGE_TARGET_EDGE:
233             return "BACKEDGE_TARGET_EDGE";
234         case BACKEDGE_SOURCE_EDGE:
235             return "BACKEDGE_SOURCE_EDGE";
236         case EXIT_EDGE:
237             return "EXIT_EDGE";
238         }
239         throw new IllegalStateException JavaDoc("unknown edge type: " + edgeType);
240     }
241
242     /**
243      * Get numeric edge type from string representation.
244      */

245     public static int stringToEdgeType(String JavaDoc s) {
246         s = s.toUpperCase(Locale.ENGLISH);
247
248         if (s.equals("FALL_THROUGH"))
249             return FALL_THROUGH_EDGE;
250         else if (s.equals("IFCMP"))
251             return IFCMP_EDGE;
252         else if (s.equals("SWITCH"))
253             return SWITCH_EDGE;
254         else if (s.equals("SWITCH_DEFAULT"))
255             return SWITCH_DEFAULT_EDGE;
256         else if (s.equals("JSR"))
257             return JSR_EDGE;
258         else if (s.equals("RET"))
259             return RET_EDGE;
260         else if (s.equals("GOTO"))
261             return GOTO_EDGE;
262         else if (s.equals("RETURN"))
263             return RETURN_EDGE;
264         else if (s.equals("UNHANDLED_EXCEPTION"))
265             return UNHANDLED_EXCEPTION_EDGE;
266         else if (s.equals("HANDLED_EXCEPTION"))
267             return HANDLED_EXCEPTION_EDGE;
268         else if (s.equals("START"))
269             return START_EDGE;
270         else if (s.equals("BACKEDGE_TARGET_EDGE"))
271             return BACKEDGE_TARGET_EDGE;
272         else if (s.equals("BACKEDGE_SOURCE_EDGE"))
273             return BACKEDGE_SOURCE_EDGE;
274         else if (s.equals("EXIT_EDGE"))
275             return EXIT_EDGE;
276         else
277             throw new IllegalArgumentException JavaDoc("Unknown edge type: " + s);
278     }
279 }
280
281 // vim:ts=4
282
Popular Tags