InnerClassesAttr.java 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright (c) 1998, 2008 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.bytecode;
  4. public class InnerClassesAttr extends Attribute
  5. {
  6. /** Number of entries. */
  7. int count;
  8. short[] data;
  9. /** Add a new InnerClassesAttr to a ClassType. */
  10. public InnerClassesAttr (ClassType cl)
  11. {
  12. super("InnerClasses");
  13. addToFrontOf(cl);
  14. }
  15. public InnerClassesAttr (short[] data, ClassType cl)
  16. {
  17. this(cl);
  18. count = (short) (data.length >> 2);
  19. this.data = data;
  20. }
  21. public static InnerClassesAttr getFirstInnerClasses (Attribute attr)
  22. {
  23. for (; ; attr = attr.getNext())
  24. {
  25. if (attr == null || attr instanceof InnerClassesAttr)
  26. return (InnerClassesAttr) attr;
  27. }
  28. }
  29. /** Add a class from a constant pool entry.
  30. * Doesn't check for duplicates, but there shouldn't be any
  31. * duplicates in a constant pool.. */
  32. void addClass (CpoolClass centry, ClassType owner)
  33. {
  34. int i = 4 * count++;
  35. if (data == null)
  36. data = new short[16];
  37. else if (i >= data.length)
  38. {
  39. short[] tmp = new short[2*i];
  40. System.arraycopy(data, 0, tmp, 0, i);
  41. data = tmp;
  42. }
  43. ConstantPool constants = owner.constants;
  44. ClassType clas = (ClassType) centry.getClassType();
  45. String name = clas.getSimpleName();
  46. int name_index = name == null || name.length() == 0 ? 0
  47. : constants.addUtf8(name).index;
  48. data[i] = (short) centry.index;
  49. ClassType outer = clas.getDeclaringClass();
  50. data[i+1] = outer == null ? 0 :
  51. (short) constants.addClass(outer).index;
  52. data[i+2] = (short) name_index;
  53. int flags = clas.getModifiers();
  54. flags &= ~ Access.SUPER;
  55. data[i+3] = (short) flags;
  56. }
  57. public void assignConstants (ClassType cl)
  58. {
  59. super.assignConstants(cl);
  60. // Real work handled when addClass is called.
  61. }
  62. /** Return the length of the attribute in bytes.
  63. * Does not include the 6-byte header (for the name_index and the length).*/
  64. public int getLength() { return 2 + 8 * count; }
  65. /** Write out the contents of the Attribute.
  66. * Does not write the 6-byte attribute header. */
  67. public void write (java.io.DataOutputStream dstr)
  68. throws java.io.IOException
  69. {
  70. dstr.writeShort(count);
  71. for (int i = 0; i < count; i++)
  72. {
  73. dstr.writeShort(data[4 * i]); // inner_class_info_index
  74. dstr.writeShort(data[4 * i + 1]); // outer_class_info_index
  75. dstr.writeShort(data[4 * i + 2]); // inner_name_index
  76. dstr.writeShort(data[4 * i + 3]); // inner_class_access_flags
  77. }
  78. }
  79. public void print (ClassTypeWriter dst)
  80. {
  81. ClassType ctype = (ClassType) container;
  82. ConstantPool constants = data == null ? null : ctype.getConstants();
  83. dst.print("Attribute \"");
  84. dst.print(getName());
  85. dst.print("\", length:");
  86. dst.print(getLength());
  87. dst.print(", count: ");
  88. dst.println(count);
  89. for (int i = 0; i < count; i++)
  90. {
  91. int inner_index = constants == null ? 0 : data[4*i] & 0xFFFF;
  92. CpoolClass centry = constants == null || inner_index == 0 ? null
  93. : constants.getForcedClass(inner_index);
  94. ClassType clas = centry != null && centry.clas instanceof ClassType
  95. ? (ClassType) centry.clas
  96. : null;
  97. dst.print(' ');
  98. int access = inner_index == 0 && clas != null ? clas.getModifiers()
  99. : data[4*i+3] & 0xFFFF;
  100. dst.print(Access.toString(access, Access.INNERCLASS_CONTEXT));
  101. dst.print(' ');
  102. int index;
  103. String name;
  104. if (inner_index == 0 && clas != null)
  105. name = clas.getSimpleName();
  106. else
  107. {
  108. index = data[4*i+2] & 0xFFFF; // inner_name_index
  109. if (constants == null || index == 0)
  110. name = "(Anonymous)";
  111. else
  112. {
  113. dst.printOptionalIndex(index);
  114. name = ((CpoolUtf8)
  115. (constants.getForced(index, ConstantPool.UTF8))).string;
  116. }
  117. }
  118. dst.print(name);
  119. dst.print(" = ");
  120. if (centry != null)
  121. {
  122. dst.printOptionalIndex(inner_index);
  123. name = centry.getClassName();
  124. }
  125. else
  126. name = "(Unknown)";
  127. dst.print(name);
  128. dst.print("; ");
  129. if (inner_index == 0 && clas != null)
  130. {
  131. String iname = clas.getName();
  132. int dot = iname.lastIndexOf('.');
  133. if (dot > 0)
  134. iname = iname.substring(dot+1);
  135. int start = iname.lastIndexOf('$') + 1;
  136. char ch;
  137. if (start < iname.length()
  138. && ((ch = iname.charAt(start)) >= '0' && ch <= '9'))
  139. dst.print("not a member");
  140. else
  141. {
  142. dst.print("member of ");
  143. dst.print(ctype.getName());
  144. }
  145. }
  146. else
  147. {
  148. CpoolEntry oentry;
  149. index = data[4*i+1] & 0xFFFF; // outer_class_info_index
  150. if (index == 0)
  151. dst.print("not a member");
  152. else
  153. {
  154. dst.print("member of ");
  155. oentry = constants.getForced(index, ConstantPool.CLASS);
  156. dst.print(((CpoolClass) oentry).getStringName());
  157. }
  158. }
  159. dst.println();
  160. }
  161. }
  162. }