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 }