KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > bcp > PatternElement


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 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.bcp;
21
22 import org.apache.bcel.generic.ConstantPoolGen;
23 import org.apache.bcel.generic.InstructionHandle;
24
25 import edu.umd.cs.findbugs.SystemProperties;
26 import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
27 import edu.umd.cs.findbugs.ba.Edge;
28 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;
29
30 /**
31  * A PatternElement is an element of a ByteCodePattern.
32  * It potentially matches some number of bytecode instructions.
33  */

34 public abstract class PatternElement {
35     private static final boolean DEBUG = SystemProperties.getBoolean("bcp.debug");
36
37     private PatternElement next;
38     private String JavaDoc label;
39     private String JavaDoc dominatedBy;
40     private int index;
41     private boolean allowTrailingEdges = true;
42
43     /**
44      * Get the next PatternElement.
45      */

46     public PatternElement getNext() {
47         return next;
48     }
49
50     /**
51      * Set the next PatternElement.
52      */

53     public void setNext(PatternElement patternElement) {
54         this.next = patternElement;
55     }
56
57     /**
58      * Set a label for this PatternElement.
59      *
60      * @param label the label
61      * @return this object
62      */

63     public PatternElement label(String JavaDoc label) {
64         this.label = label;
65         return this;
66     }
67
68     /**
69      * Get the label of this PatternElement.
70      *
71      * @return the label, or null if the PatternElement is not labeled
72      */

73     public String JavaDoc getLabel() {
74         return label;
75     }
76
77     /**
78      * Set the label of another pattern element whose first
79      * matched instruction must dominate the instruction(s) matched
80      * by this element.
81      */

82     public PatternElement dominatedBy(String JavaDoc dominatedBy) {
83         this.dominatedBy = dominatedBy;
84         return this;
85     }
86
87     /**
88      * Get the label of the pattern element whose first
89      * matched instruction must dominate the instruction(s) matched
90      * by this element.
91      */

92     public String JavaDoc getDominatedBy() {
93         return dominatedBy;
94     }
95
96     /**
97      * Set the index. This is just for debugging.
98      */

99     public void setIndex(int index) {
100         this.index = index;
101     }
102
103     /**
104      * Set whether or not this PatternElement allows trailing edges to be matched.
105      * By default, trailing edges may be matched. When this value is set
106      * to false, it ensures that the successor instruction must be in the
107      * same basic block.
108      *
109      * @param allowTrailingEdges true if trailing edges may be matched,
110      * false if trailing edges will never be matched
111      */

112     public PatternElement setAllowTrailingEdges(boolean allowTrailingEdges) {
113         this.allowTrailingEdges = allowTrailingEdges;
114         return this;
115     }
116
117     /**
118      * Return whether or not this PatternElement may match trailing edges.
119      */

120     public boolean allowTrailingEdges() {
121         return allowTrailingEdges;
122     }
123
124     /**
125      * Look up a variable definition in given BindingSet.
126      *
127      * @param varName the name of the variable
128      * @param bindingSet the BindingSet to look in
129      * @return the Variable, or null if no Variable is bound to the name
130      */

131     public static Variable lookup(String JavaDoc varName, BindingSet bindingSet) {
132         if (bindingSet == null)
133             return null;
134         Binding binding = bindingSet.lookup(varName);
135         return (binding != null) ? binding.getVariable() : null;
136     }
137
138     /**
139      * Return whether or not this element matches the given
140      * instruction with the given Bindings in effect.
141      *
142      * @param handle the instruction
143      * @param cpg the ConstantPoolGen from the method
144      * @param before the ValueNumberFrame representing values in the Java stack frame
145      * just before the execution of the instruction
146      * @param after the ValueNumberFrame representing values in the Java stack frame
147      * just after the execution of the instruction
148      * @param bindingSet the set of Bindings
149      * @return if the match is successful, returns a MatchResult with the PatternElement
150      * and BindingSet; if the match is not successful, returns null
151      */

152     public abstract MatchResult match(InstructionHandle handle, ConstantPoolGen cpg,
153                                       ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException;
154
155     /**
156      * Return whether or not it is acceptable to take the given branch.
157      *
158      * @param edge the Edge representing the branch
159      * @param source the source instruction of the branch
160      * @return true if the Edge is acceptable, false if not
161      */

162     public abstract boolean acceptBranch(Edge edge, InstructionHandle source);
163
164     /**
165      * Return the minimum number of instructions this PatternElement
166      * must match in the ByteCodePattern.
167      */

168     public abstract int minOccur();
169
170     /**
171      * Return the maximum number of instructions this PatternElement
172      * must match in the ByteCodePattern.
173      */

174     public abstract int maxOccur();
175
176     /**
177      * Add a variable definition to the given BindingSet, or if
178      * there is an existing definition, make sure it is consistent with
179      * the new definition.
180      *
181      * @param varName the name of the variable
182      * @param variable the Variable which should be added or checked for consistency
183      * @param bindingSet the existing set of bindings
184      * @return the updated BindingSet (if the variable is consistent with the
185      * previous bindings), or null if the new variable is inconsistent with
186      * the previous bindings
187      */

188     protected static BindingSet addOrCheckDefinition(String JavaDoc varName, Variable variable, BindingSet bindingSet) {
189         Variable existingVariable = lookup(varName, bindingSet);
190         if (existingVariable == null) {
191             bindingSet = new BindingSet(new Binding(varName, variable), bindingSet);
192         } else {
193             if (!existingVariable.sameAs(variable)) {
194                 if (DEBUG) System.out.println("\tConflicting variable " + varName + ": " + variable + " != " + existingVariable);
195                 return null;
196             }
197         }
198
199         return bindingSet;
200     }
201
202     @Override JavaDoc
203          public String JavaDoc toString() {
204         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
205         String JavaDoc className = this.getClass().getName();
206         buf.append(className.substring(className.lastIndexOf('.') + 1));
207         buf.append('(');
208         buf.append(index);
209         buf.append(')');
210         return buf.toString();
211     }
212 }
213
214 // vim:ts=4
215
Popular Tags