KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > bcg > Attributes


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.bcg;
26
27 import org.aspectj.compiler.base.bcg.pool.*;
28
29 import java.lang.reflect.Modifier JavaDoc;
30
31 import java.util.Iterator JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.List JavaDoc;
34
35 import java.io.DataOutputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37
38 import java.io.UnsupportedEncodingException JavaDoc;
39 import org.aspectj.compiler.base.ast.NameType;
40
41 /** Lifecycle: creation, addition of attributes (through the
42     addXAttribute methods), resolution of constant pool (done in the
43     constant pool, when all constant pool entries are set), output.
44     It is an error for these steps to occur out of order, but this is
45     not currently checked. */

46
47 public final class Attributes {
48     ConstantPool pool;
49     Attributes(ConstantPool pool) {
50         this.pool = pool;
51     }
52
53     // ------------------------------
54
// state
55
private /* Attribute */ List JavaDoc attributes = new ArrayList JavaDoc();
56
57     // ------------------------------
58
// building methods
59

60     void addSyntheticAttribute() {
61         attributes.add(new EmptyAttribute(pool.addUtf8("Synthetic")));
62     }
63     void addDeprecatedAttribute() {
64         attributes.add(new EmptyAttribute(pool.addUtf8("Deprecated")));
65     }
66     void addSourceFileAttribute(String JavaDoc sourceFile) {
67         attributes.add(new PoolAttribute(pool.addUtf8("SourceFile"),
68                                          pool.addUtf8(sourceFile)));
69     }
70
71     void addSouceDebugExtensionAttribute(String JavaDoc data) {
72         attributes.add(new SourceDebugExtensionAttribute(pool.addUtf8("SourceDebugExtension"),
73                                                          data));
74     }
75
76     void addConstantValueAttribute(Constant c) {
77         attributes.add(new PoolAttribute(pool.addUtf8("ConstantValue"),
78                                          c));
79
80     }
81
82     void addCodeAttribute(CodeBuilder cb) {
83         attributes.add(new CodeAttribute(pool.addUtf8("Code"), cb));
84     }
85
86     void addLineNumberTableAttribute(Label[] pcs, int[] lines) {
87         attributes.add(new LineNumberTableAttribute(pool.addUtf8("LineNumberTable"), pcs, lines));
88     }
89
90     void addLocalVariableTableAttribute(Label[] starts,
91                                         Label[] ends,
92                                         Constant[] names,
93                                         Constant[] descriptors,
94                                         int[] indices) {
95         attributes.add(new LocalVariableTableAttribute(pool.addUtf8("LocalVariableTable"), starts, ends, names, descriptors, indices));
96     }
97
98     PoolsAttribute exceptionAttribute = null;
99     void addToExceptionsAttribute(NameType nameType) {
100         if (exceptionAttribute == null) {
101             exceptionAttribute = new PoolsAttribute(pool.addUtf8("Exceptions"));
102             attributes.add(exceptionAttribute);
103         }
104         exceptionAttribute.add(pool.addClass(nameType));
105     }
106
107     InnerClassesAttribute innerClassesAttribute = null;
108     void addToInnerClassesAttribute(NameType nameType) {
109         if (innerClassesAttribute == null) {
110             innerClassesAttribute = new InnerClassesAttribute(pool.addUtf8("InnerClasses"));
111             attributes.add(innerClassesAttribute);
112         }
113         if (nameType.isInterface()) {
114             nameType.getTypeDec().getModifiers().setInterface(true);
115         }
116         innerClassesAttribute.add(pool.addClassNoInnerCheck(nameType),
117                                   nameType.isLocal() ? null : pool.addClass(nameType.getEnclosingType()),
118                                   nameType.isAnonymous() ? null : pool.addUtf8(nameType.getId()),
119                                   nameType.getTypeDec().getModifiers().getAcceptableInnerClassValue());
120     }
121
122     // ------------------------------
123
// output methods
124

125     int getByteSize() {
126         int s = 2;
127         for (int i = 0, len = attributes.size(); i < len; i++) {
128             s += ((Attribute) attributes.get(i)).getByteSize();
129         }
130         return s;
131     }
132
133     public void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
134         stream.writeShort((short) attributes.size());
135         for (Iterator JavaDoc i = attributes.iterator(); i.hasNext(); ) {
136             ((Attribute) i.next()).writeTo(stream);
137         }
138     }
139
140     public String JavaDoc toString() {
141         String JavaDoc s = "(Attr";
142         for (Iterator JavaDoc i = attributes.iterator(); i.hasNext(); ) {
143             s += i.next().toString();
144         }
145         return s + ")";
146     }
147
148     // ------------------------------
149
// debugging
150

151     void display(int indent, boolean inline) {
152         indent += 2;
153         System.err.print("(attributes");
154         display(attributes, indent, inline);
155         System.err.print(")");
156     }
157
158     static void display(List JavaDoc l, int indent, boolean inline) {
159         for (Iterator JavaDoc i = l.iterator(); i.hasNext(); ) {
160             Attribute c = (Attribute) i.next();
161             between(indent, inline);
162             c.display(indent, inline);
163         }
164     }
165
166     static void between(int indent, boolean inline) {
167         if (inline) {
168             System.err.print(" ");
169         } else {
170             System.err.println();
171             for (int s=indent; s >= 0; s--) System.err.print(" ");
172         }
173     }
174
175     // ------------------------------
176
// classes
177

178     private abstract class Attribute {
179         Constant name;
180         Attribute(Constant name) { this.name = name; }
181         abstract void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc;
182         abstract void display(int indent, boolean inline);
183         abstract int getByteSize();
184     }
185     private class EmptyAttribute extends Attribute {
186         EmptyAttribute(Constant name) { super(name); }
187         int getByteSize() { return 6; }
188         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
189             name.writeIndex(stream);
190             stream.writeInt(0);
191         }
192         public String JavaDoc toString() { return " " + name; }
193
194         // this is a start if we really want to do a disassembly
195
// static EmptyAttribute readFrom(DataInputStream stream) throws IOException {
196
// int len = stream.readInt();
197
// if (len != 0) {
198
// System.err.println("warning: bad empty attribute");
199
// stream.skipBytes(len);
200
// }
201
// }
202
void display(int indent, boolean inline) {
203             System.err.print("(" + name + ")");
204         }
205     }
206
207     private class PoolAttribute extends Attribute {
208         Constant data;
209         PoolAttribute(Constant name, Constant data) {
210             super(name);
211             this.data = data;
212         }
213         int getByteSize() { return 8; }
214         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
215             name.writeIndex(stream);
216             stream.writeInt(2);
217             data.writeIndex(stream);
218         }
219         public String JavaDoc toString() {
220             return " (" + name + " " + data + ")";
221         }
222         void display(int indent, boolean inline) {
223             System.err.print("(" + name);
224             between(0, true);
225             data.display(indent + 2, inline);
226             System.err.print(")");
227         }
228     }
229
230     private class CodeAttribute extends Attribute {
231         CodeBuilder cb;
232         CodeAttribute(Constant name, CodeBuilder cb) {
233             super(name);
234             this.cb = cb;
235         }
236         int getByteSize() { return 2 + 4 + cb.getByteSize(); }
237         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
238             name.writeIndex(stream);
239             stream.writeInt(cb.getByteSize());
240             cb.writeTo(stream);
241         }
242         public String JavaDoc toString() {
243             return " (" + name + " " + cb + ")";
244         }
245         void display(int indent, boolean inline) {
246             System.err.print("(" + name);
247             between(indent + 2, inline);
248             cb.display(indent + 2, inline);
249             System.err.print(")");
250         }
251     }
252
253     private class PoolsAttribute extends Attribute {
254         /* Constant */ List JavaDoc data = new ArrayList JavaDoc();
255         PoolsAttribute(Constant name) {
256             super(name);
257         }
258
259         void add(Constant constant) {
260             data.add(constant);
261         }
262
263         int getByteSize() { return 2 + 4 + 2 + (2 * data.size()); }
264         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
265             name.writeIndex(stream);
266             stream.writeInt(2 * (data.size() + 1));
267             stream.writeShort(data.size());
268             for (Iterator JavaDoc i = data.iterator(); i.hasNext(); ) {
269                 ((Constant) i.next()).writeIndex(stream);
270             }
271         }
272         public String JavaDoc toString() {
273             String JavaDoc s = " (" + name;
274             for (Iterator JavaDoc i = data.iterator(); i.hasNext(); ) {
275                 s += " " + (Constant) i.next();
276             }
277             return s + ")";
278         }
279         void display(int indent, boolean inline) {
280             System.err.print("(" + name);
281             ConstantPool.display(data, indent + 2, inline);
282             System.err.print(")");
283         }
284     }
285
286     private class LineNumberTableAttribute extends Attribute {
287         Label[] pcs;
288         int[] lines;
289         LineNumberTableAttribute(Constant name, Label[] pcs, int[] lines) {
290             super(name);
291             this.pcs = pcs;
292             this.lines = lines;
293         }
294         int getByteSize() { return 2 + 4 + 2 + (4 * pcs.length); }
295         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
296             final int len = pcs.length;
297             name.writeIndex(stream);
298             stream.writeInt((4 * len) + 2);
299             stream.writeShort(len);
300             for (int i = 0; i < len; i++ ) {
301                 stream.writeShort((short)pcs[i].getPc());
302                 stream.writeShort((short)lines[i]);
303             }
304         }
305         public String JavaDoc toString() {
306             String JavaDoc s = " (" + name;
307             return s + ")";
308         }
309         void display(int indent, boolean inline) {
310             System.err.print("(" + name);
311             for (int i = 0; i < pcs.length; i++) {
312                 between(indent + 2, inline);
313                 System.err.print("((pc " + pcs[i].getPc() + ") (line " + lines[i] + "))");
314             }
315             System.err.print(")");
316         }
317     }
318
319     private class LocalVariableTableAttribute extends Attribute {
320         Label[] starts;
321         Label[] ends;
322         Constant[] names;
323         Constant[] descriptors;
324         int[] indices;
325         LocalVariableTableAttribute(Constant name,
326                                     Label[] starts,
327                                     Label[] ends,
328                                     Constant[] names,
329                                     Constant[] descriptors,
330                                     int[] indices) {
331             super(name);
332             this.starts = starts;
333             this.ends = ends;
334             this.names = names;
335             this.descriptors = descriptors;
336             this.indices = indices;
337         }
338         int getByteSize() { return 2 + 4 + 2 + (10 * starts.length); }
339         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
340 // System.err.println("(ATTRIBUTES) " +
341
// java.util.Arrays.asList(starts) + " " +
342
// java.util.Arrays.asList(ends));
343
final int len = starts.length;
344             name.writeIndex(stream);
345             stream.writeInt((10 * len) + 2);
346             stream.writeShort(len);
347             for (int i = 0; i < len; i++ ) {
348                 int start = starts[i].getPc();
349                 int end = ends[i].getPc();
350                 stream.writeShort((short)start);
351                 stream.writeShort((short)(end - start));
352                 names[i].writeIndex(stream);
353                 descriptors[i].writeIndex(stream);
354                 stream.writeShort((short)indices[i]);
355             }
356         }
357         public String JavaDoc toString() {
358             String JavaDoc s = " (" + name;
359             return s + ")";
360         }
361         void display(int indent, boolean inline) {
362             System.err.print("(" + name);
363             for (int i = 0; i < starts.length; i++) {
364                 between(indent + 2, inline);
365                 System.err.print("(" + names[i]
366                                  + " " + descriptors[i]
367                                  + " at " + indices[i]
368                                  + " from " + starts[i].getPc()
369                                  + " to " + ends[i].getPc()
370                                  + ")");
371             }
372             System.err.print(")");
373         }
374     }
375
376     private class InnerClassesAttribute extends Attribute {
377         List JavaDoc inners = new ArrayList JavaDoc();
378         List JavaDoc outers = new ArrayList JavaDoc();
379         List JavaDoc names = new ArrayList JavaDoc();
380         List JavaDoc modifiers = new ArrayList JavaDoc();
381
382         InnerClassesAttribute(Constant name) {
383             super(name);
384         }
385
386         void add(ClassConstant inner,
387                  ClassConstant outer,
388                  Utf8Constant name,
389                  int mods) {
390             inners.add(inner); outers.add(outer);
391             names.add(name); modifiers.add(new Integer JavaDoc(mods));
392         }
393
394         int getByteSize() { return 2 + 4 + 2 + (8 * inners.size()); }
395         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
396             name.writeIndex(stream);
397             final int len = inners.size();
398             stream.writeInt((8 * len) + 2);
399             stream.writeShort(len);
400             for (int i = 0; i < len; i++) {
401                 ConstantPool.writeIndex((ClassConstant) inners.get(i), stream);
402                 ConstantPool.writeIndex((ClassConstant) outers.get(i), stream);
403                 ConstantPool.writeIndex((Utf8Constant) names.get(i), stream);
404                 stream.writeShort(((Integer JavaDoc) modifiers.get(i)).intValue());
405             }
406         }
407         public String JavaDoc toString() {
408             return "(innerclassattribute)";
409         }
410         void display(int indent, boolean inline) {
411             System.err.print("(" + name);
412             final int len = inners.size();
413             for (int i = 0; i < len; i++) {
414                 between(indent + 2, inline);
415                 System.err.print("(class "); ((ClassConstant) inners.get(i)).display(0, true);
416                 between(indent + 4, inline);
417                 System.err.print("(inside "); ((ClassConstant) outers.get(i)).display(0, true);
418                 System.err.print(")");
419                 between(indent + 4, inline);
420                 System.err.print("(knownAs "); ((Utf8Constant) names.get(i)).display(0, true);
421                 System.err.print(")");
422                 between(indent + 4, inline);
423                 System.err.print("(modifiers " + Modifier.toString(((Integer JavaDoc) modifiers.get(i)).intValue()) + ")");
424                 System.err.print(")");
425             }
426             System.err.print(")");
427         }
428     }
429
430     private class SourceDebugExtensionAttribute extends Attribute {
431         byte[] data;
432         SourceDebugExtensionAttribute(Constant name, String JavaDoc data) {
433             super(name);
434             try {
435             this.data = data.getBytes("UTF-8");
436             } catch (java.io.UnsupportedEncodingException JavaDoc e) {}
437         }
438         int getByteSize() { return 2 + 4 + data.length; }
439         void writeTo(DataOutputStream JavaDoc stream) throws IOException JavaDoc {
440             name.writeIndex(stream);
441             final int len = data.length;
442             stream.writeInt(len);
443             stream.write(data);
444         }
445         public String JavaDoc toString() {
446             try {
447                 return "(SourceDebugExtensionAttribute " + "\"" + new String JavaDoc(data,"UTF-8") + "\")";
448             } catch (UnsupportedEncodingException JavaDoc e) { return null; }
449         }
450
451         void display(int indent, boolean inline) {
452             System.err.println(this);
453         }
454
455     }
456
457     // ------------------------------
458
// disassembly methods
459

460     void readFrom(java.io.DataInputStream JavaDoc stream) throws java.io.IOException JavaDoc {
461         int count = stream.readUnsignedShort();
462         for (int i = count; i > 0; i--) {
463             Utf8Constant name = (Utf8Constant) pool.get(stream.readUnsignedShort());
464             int len = stream.readInt();
465             String JavaDoc id = name.value;
466             if ("ConstantValue".equals(id)) {
467                 attributes.add(new PoolAttribute(name,
468                                                  pool.get(stream.readUnsignedShort())));
469             } else if ("SourceFile".equals(id)) {
470                 attributes.add(new PoolAttribute(name,
471                                                  pool.get(stream.readUnsignedShort())));
472             } else if ("Code".equals(id)) {
473                 attributes.add(new EmptyAttribute(name));
474                 stream.skipBytes(len);
475             } else if ("Exceptions".equals(id)) {
476                 PoolsAttribute a = new PoolsAttribute(name);
477                 int size = stream.readUnsignedShort();
478                 for (int s = size - 1; s >= 0; s--) {
479                     a.add(pool.get(stream.readUnsignedShort()));
480                 }
481                 attributes.add(a);
482             } else if ("InnerClasses".equals(id)) {
483                 InnerClassesAttribute a = new InnerClassesAttribute(name);
484                 int size = stream.readUnsignedShort();
485                 for (int s = size - 1; s >= 0; s--) {
486                     a.add((ClassConstant) pool.get(stream.readUnsignedShort()),
487                           (ClassConstant) pool.get(stream.readUnsignedShort()),
488                           (Utf8Constant) pool.get(stream.readUnsignedShort()),
489                           stream.readUnsignedShort());
490                 }
491                 attributes.add(a);
492             } else {
493                 // Code
494
// LineNumberTable
495
// LocalVariableTable
496
attributes.add(new EmptyAttribute(name));
497                 stream.skipBytes(len);
498             }
499         }
500     }
501 }
502
Popular Tags