1 cananian 1.1.2.2 // InnerClass.java, created Mon Jan 18 22:44:38 1999 by cananian
  2 cananian 1.1.2.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1 package harpoon.IR.RawClass;
  5 cananian 1.1.2.1 
  6 cananian 1.1.2.1 /** 
  7 cananian 1.1.2.1  * Each <code>InnerClass</code> object describes one encoded inner
  8 cananian 1.1.2.1  * class name, its defining scope, its simple name, and a bitmask
  9 cananian 1.1.2.1  * of the originally declared, untransformed access flags.
 10 cananian 1.1.2.1  *
 11 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 12 cananian 1.2      * @version $Id: InnerClass.java,v 1.2 2002/02/25 21:05:27 cananian Exp $
 13 cananian 1.1.2.1  * @see "Inner Classes Specification"
 14 cananian 1.1.2.1  * @see AttributeInnerClasses
 15 cananian 1.1.2.1  */
 16 cananian 1.1.2.1 public class InnerClass {
 17 cananian 1.1.2.1   /** ClassFile in which this attribute information is found. */
 18 cananian 1.1.2.1   protected ClassFile parent;
 19 cananian 1.1.2.1 
 20 cananian 1.1.2.1   /** <code>CONSTANT_Class_info</code> pointer to class with encoded name. */
 21 cananian 1.1.2.1   public int inner_class_info_index;
 22 cananian 1.1.2.1   /** <code>CONSTANT_Class_info</code> pointer to the defining scope for 
 23 cananian 1.1.2.1    *  the inner class.
 24 cananian 1.1.2.1    *  If the inner class is not a member (of an outer class), then
 25 cananian 1.1.2.1    *  the <code>outer_class_info_index</code> is zero. */
 26 cananian 1.1.2.1   public int outer_class_info_index;
 27 cananian 1.1.2.1   /** <code>CONSTANT_Utf8_info</code> pointer to the simple name of the 
 28 cananian 1.1.2.1    *  encoded inner class. 
 29 cananian 1.1.2.1    *  If the inner class is anonymous, its <code>inner_name_index</code>
 30 cananian 1.1.2.1    *  is zero. <p>
 31 cananian 1.1.2.1    *  <STRONG>ERRATA</STRONG>: although the specification dictates the
 32 cananian 1.1.2.1    *  above, current compilers seem to generate a pointer to a name
 33 cananian 1.1.2.1    *  string of <code>""</code> (that is, a zero-length string) instead.
 34 cananian 1.1.2.1    */
 35 cananian 1.1.2.1   public int inner_name_index;
 36 cananian 1.1.2.1   /** Originally declared, untransformed <code>access_flags</code>. */
 37 cananian 1.1.2.1   public AccessFlags inner_class_access_flags;
 38 cananian 1.1.2.1 
 39 cananian 1.1.2.1   /** Constructor. */
 40 cananian 1.1.2.1   InnerClass(ClassFile parent, ClassDataInputStream in)
 41 cananian 1.1.2.1        throws java.io.IOException 
 42 cananian 1.1.2.1   {
 43 cananian 1.1.2.1     this.parent = parent;
 44 cananian 1.1.2.1 
 45 cananian 1.1.2.1     inner_class_info_index = in.read_u2();
 46 cananian 1.1.2.1     outer_class_info_index = in.read_u2();
 47 cananian 1.1.2.1     inner_name_index       = in.read_u2();
 48 cananian 1.1.2.1     inner_class_access_flags = new AccessFlags(in);
 49 cananian 1.1.2.1   }
 50 cananian 1.1.2.1 
 51 cananian 1.1.2.1   /** Constructor. */
 52 cananian 1.1.2.1   public InnerClass(ClassFile parent, 
 53 cananian 1.1.2.1                     int inner_class_info_index, 
 54 cananian 1.1.2.1                     int outer_class_info_index, 
 55 cananian 1.1.2.1                     int inner_name_index, 
 56 cananian 1.1.2.1                     AccessFlags inner_class_access_flags) {
 57 cananian 1.1.2.1     this.parent = parent;
 58 cananian 1.1.2.1 
 59 cananian 1.1.2.1     this.inner_class_info_index = inner_class_info_index;
 60 cananian 1.1.2.1     this.outer_class_info_index = outer_class_info_index;
 61 cananian 1.1.2.1     this.inner_name_index       = inner_name_index;
 62 cananian 1.1.2.1     this.inner_class_access_flags = inner_class_access_flags;
 63 cananian 1.1.2.1   }
 64 cananian 1.1.2.1 
 65 cananian 1.1.2.1   /** Write to bytecode stream. */
 66 cananian 1.1.2.1   public void write(ClassDataOutputStream out) throws java.io.IOException {
 67 cananian 1.1.2.1     out.write_u2(inner_class_info_index);
 68 cananian 1.1.2.1     out.write_u2(outer_class_info_index);
 69 cananian 1.1.2.1     out.write_u2(inner_name_index);
 70 cananian 1.1.2.1     inner_class_access_flags.write(out);
 71 cananian 1.1.2.1   }
 72 cananian 1.1.2.1 
 73 cananian 1.1.2.1   // convenience
 74 cananian 1.1.2.1   public ConstantClass inner_class_info()
 75 cananian 1.1.2.1   { return (ConstantClass) parent.constant_pool[inner_class_info_index]; }
 76 cananian 1.1.2.1   public ConstantClass outer_class_info() {
 77 cananian 1.1.2.1     if (outer_class_info_index==0) return null;
 78 cananian 1.1.2.1     return (ConstantClass) parent.constant_pool[outer_class_info_index]; 
 79 cananian 1.1.2.1   }
 80 cananian 1.1.2.1   public ConstantUtf8  inner_name_index() {
 81 cananian 1.1.2.1     if (inner_name_index==0) return null;
 82 cananian 1.1.2.1     return (ConstantUtf8)  parent.constant_pool[inner_name_index]; 
 83 cananian 1.1.2.1   }
 84 cananian 1.1.2.1   public String inner_name() { 
 85 cananian 1.1.2.1     if (inner_name_index==0) return null;
 86 cananian 1.1.2.1     return inner_name_index().val; 
 87 cananian 1.1.2.1   }
 88 cananian 1.1.2.1 
 89 cananian 1.1.2.1   /** Human-readable representation. */
 90 cananian 1.1.2.1   public String toString() {
 91 cananian 1.1.2.1     StringBuffer sb = new StringBuffer();
 92 cananian 1.1.2.1     sb.append("InnerClass: ");
 93 cananian 1.1.2.1     sb.append(inner_class_info().name());
 94 cananian 1.1.2.1     sb.append(" {"+inner_class_info_index+"}");
 95 cananian 1.1.2.1     if (outer_class_info_index!=0) {
 96 cananian 1.1.2.1       sb.append(" in " + outer_class_info().name());
 97 cananian 1.1.2.1       sb.append(" {"+outer_class_info_index+"}");
 98 cananian 1.1.2.1     }
 99 cananian 1.1.2.1     sb.append(", originally ");
100 cananian 1.1.2.1     sb.append(inner_class_access_flags.toString());
101 cananian 1.1.2.1     sb.append(" ");
102 cananian 1.1.2.1     if (inner_name()==null || inner_name().equals(""))
103 cananian 1.1.2.1       sb.append("<anonymous>");
104 cananian 1.1.2.1     else
105 cananian 1.1.2.1       sb.append(inner_name());
106 cananian 1.1.2.1     sb.append(" {"+inner_name_index+"}");
107 cananian 1.1.2.1     return sb.toString();
108 cananian 1.1.2.1   }
109 cananian 1.2     }