1 24 25 package org.aspectj.compiler.base.bcg; 26 27 import org.aspectj.compiler.base.bcg.pool.*; 28 29 import java.lang.reflect.Modifier ; 30 31 import java.util.Iterator ; 32 import java.util.ArrayList ; 33 import java.util.List ; 34 35 import java.io.DataOutputStream ; 36 import java.io.IOException ; 37 38 import java.io.UnsupportedEncodingException ; 39 import org.aspectj.compiler.base.ast.NameType; 40 41 46 47 public final class Attributes { 48 ConstantPool pool; 49 Attributes(ConstantPool pool) { 50 this.pool = pool; 51 } 52 53 private List attributes = new ArrayList (); 56 57 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 sourceFile) { 67 attributes.add(new PoolAttribute(pool.addUtf8("SourceFile"), 68 pool.addUtf8(sourceFile))); 69 } 70 71 void addSouceDebugExtensionAttribute(String 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 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 stream) throws IOException { 134 stream.writeShort((short) attributes.size()); 135 for (Iterator i = attributes.iterator(); i.hasNext(); ) { 136 ((Attribute) i.next()).writeTo(stream); 137 } 138 } 139 140 public String toString() { 141 String s = "(Attr"; 142 for (Iterator i = attributes.iterator(); i.hasNext(); ) { 143 s += i.next().toString(); 144 } 145 return s + ")"; 146 } 147 148 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 l, int indent, boolean inline) { 159 for (Iterator 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 178 private abstract class Attribute { 179 Constant name; 180 Attribute(Constant name) { this.name = name; } 181 abstract void writeTo(DataOutputStream stream) throws IOException ; 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 stream) throws IOException { 189 name.writeIndex(stream); 190 stream.writeInt(0); 191 } 192 public String toString() { return " " + name; } 193 194 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 stream) throws IOException { 215 name.writeIndex(stream); 216 stream.writeInt(2); 217 data.writeIndex(stream); 218 } 219 public String 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 stream) throws IOException { 238 name.writeIndex(stream); 239 stream.writeInt(cb.getByteSize()); 240 cb.writeTo(stream); 241 } 242 public String 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 List data = new ArrayList (); 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 stream) throws IOException { 265 name.writeIndex(stream); 266 stream.writeInt(2 * (data.size() + 1)); 267 stream.writeShort(data.size()); 268 for (Iterator i = data.iterator(); i.hasNext(); ) { 269 ((Constant) i.next()).writeIndex(stream); 270 } 271 } 272 public String toString() { 273 String s = " (" + name; 274 for (Iterator 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 stream) throws IOException { 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 toString() { 306 String 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 stream) throws IOException { 340 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 toString() { 358 String 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 inners = new ArrayList (); 378 List outers = new ArrayList (); 379 List names = new ArrayList (); 380 List modifiers = new ArrayList (); 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 (mods)); 392 } 393 394 int getByteSize() { return 2 + 4 + 2 + (8 * inners.size()); } 395 void writeTo(DataOutputStream stream) throws IOException { 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 ) modifiers.get(i)).intValue()); 405 } 406 } 407 public String 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 ) 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 data) { 433 super(name); 434 try { 435 this.data = data.getBytes("UTF-8"); 436 } catch (java.io.UnsupportedEncodingException e) {} 437 } 438 int getByteSize() { return 2 + 4 + data.length; } 439 void writeTo(DataOutputStream stream) throws IOException { 440 name.writeIndex(stream); 441 final int len = data.length; 442 stream.writeInt(len); 443 stream.write(data); 444 } 445 public String toString() { 446 try { 447 return "(SourceDebugExtensionAttribute " + "\"" + new String (data,"UTF-8") + "\")"; 448 } catch (UnsupportedEncodingException e) { return null; } 449 } 450 451 void display(int indent, boolean inline) { 452 System.err.println(this); 453 } 454 455 } 456 457 460 void readFrom(java.io.DataInputStream stream) throws java.io.IOException { 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 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 attributes.add(new EmptyAttribute(name)); 497 stream.skipBytes(len); 498 } 499 } 500 } 501 } 502 | Popular Tags |