Source code: com/techtrader/modules/tools/bytecode/LocalVariableTableAttribute.java
1 package com.techtrader.modules.tools.bytecode;
2
3
4 import java.io.DataOutput;
5 import java.io.DataInput;
6 import java.io.IOException;
7 import java.util.List;
8 import java.util.LinkedList;
9 import java.util.Iterator;
10
11 import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
12
13
14 /**
15 * Represents a local variable table for a method.
16 * TODO: Variables of type long or double should occupy two indeces;
17 * this is not taken into account here.
18 *
19 * @author Abe White
20 */
21 public class LocalVariableTableAttribute
22 extends Attribute
23 {
24 private List _localVariables = new LinkedList ();
25
26
27 /**
28 * Protected constructor.
29 */
30 public LocalVariableTableAttribute (int nameIndex, BCEntity owner)
31 {
32 super (nameIndex, owner);
33 }
34
35
36 /**
37 * Get all the locals of this method.
38 */
39 public LocalVariable[] getLocalVariables ()
40 {
41 return (LocalVariable[]) _localVariables.toArray
42 (new LocalVariable[_localVariables.size ()]);
43 }
44
45
46 /**
47 * Get the local with the given name.
48 */
49 public LocalVariable getLocalVariable (String name)
50 {
51 LocalVariable next;
52 for (Iterator i = _localVariables.iterator (); i.hasNext ();)
53 {
54 next = (LocalVariable) i.next ();
55 if (next.getName ().equals (name))
56 return next;
57 }
58
59 return null;
60 }
61
62
63 /**
64 * Import a local variable from another method/class. Note that
65 * the program counter and length from the given local is copied
66 * directly, and thus will be incorrect unless this method is the same
67 * as the one the local is copied from, or the pc and length are reset.
68 */
69 public LocalVariable importLocalVariable (LocalVariable local)
70 {
71 LocalVariable newLocal= addLocalVariable
72 (local.getName (), local.getTypeName ());
73 newLocal.setStartPc (local.getStartPc ());
74 newLocal.setLength (local.getLength ());
75
76 return newLocal;
77 }
78
79
80 /**
81 * Import all locals from another method.
82 */
83 public void importLocalVariables (LocalVariableTableAttribute other)
84 {
85 LocalVariable[] locals = other.getLocalVariables ();
86 for (int i = 0; i < locals.length; i++)
87 importLocalVariable (locals[i]);
88 }
89
90
91 /**
92 * Add a local to this method.
93 */
94 public LocalVariable addLocalVariable ()
95 {
96 LocalVariable local = new LocalVariable (this);
97 local.setIndex (_localVariables.size ());
98 _localVariables.add (local);
99
100 return local;
101 }
102
103
104 /**
105 * Add a local to this method.
106 */
107 public LocalVariable addLocalVariable (String name, String type)
108 {
109 LocalVariable local = addLocalVariable ();
110 local.setName (name);
111 local.setTypeName (type);
112
113 return local;
114 }
115
116
117 /**
118 * Add a local to this method.
119 */
120 public LocalVariable addLocalVariable (String name, Class type)
121 {
122 return addLocalVariable (name, type.getName ());
123 }
124
125
126 /**
127 * Clear all locals from this method.
128 */
129 public void clearLocalVariables ()
130 {
131 _localVariables.clear ();
132 }
133
134
135 /**
136 * Removes the local with the given name from this method.
137 */
138 public boolean removeLocalVariable (String name)
139 {
140 return removeLocalVariable (getLocalVariable (name));
141 }
142
143
144 /**
145 * Removes a local from this method. After this method, the local
146 * will be invalid, and the result of any operations on it is undefined.
147 */
148 public boolean removeLocalVariable (LocalVariable local)
149 {
150 if (local == null || !_localVariables.remove (local))
151 return false;
152
153 local.invalidate ();
154 return true;
155 }
156
157
158 public int getLength ()
159 {
160 return 2 + 10 * _localVariables.size ();
161 }
162
163
164 protected void copy (Attribute other)
165 {
166 importLocalVariables ((LocalVariableTableAttribute) other);
167 }
168
169
170 protected void readData (DataInput in, int length)
171 throws IOException
172 {
173 _localVariables.clear ();
174 int numLocals = in.readUnsignedShort ();
175
176 LocalVariable localVariable;
177 for (int i = 0; i < numLocals; i++)
178 {
179 localVariable = addLocalVariable ();
180 localVariable.readData (in);
181 }
182 }
183
184
185 protected void writeData (DataOutput out, int length)
186 throws IOException
187 {
188 out.writeShort (_localVariables.size ());
189 for (Iterator i = _localVariables.iterator (); i.hasNext ();)
190 ((LocalVariable) i.next ()).writeData (out);
191 }
192
193
194 public void acceptVisit (BCVisitor visit)
195 {
196 visit.enterLocalVariableTableAttribute (this);
197
198 for (Iterator i = _localVariables.iterator (); i.hasNext ();)
199 ((LocalVariable) i.next ()).acceptVisit (visit);
200
201 visit.exitLocalVariableTableAttribute (this);
202 }
203 }