22963d041291e788edf4ffb287e5351c85708478
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / classfmt / InnerClassInfo.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.classfmt;
12
13 import net.sourceforge.phpdt.internal.compiler.env.IBinaryNestedType;
14
15 /**
16  * Describes one entry in the classes table of the InnerClasses attribute.
17  * See the inner class specification (The class file attribute "InnerClasses").
18  */
19
20 public class InnerClassInfo extends ClassFileStruct implements IBinaryNestedType {
21         int innerClassNameIndex = -1;
22         int outerClassNameIndex = -1;
23         int innerNameIndex = -1;
24         private char[] innerClassName;
25         private char[] outerClassName;
26         private char[] innerName;
27         private int accessFlags = -1;
28         private int[] constantPoolOffsets;
29         private boolean readInnerClassName = false;
30         private boolean readOuterClassName = false;
31         private boolean readInnerName = false;
32 public InnerClassInfo(byte classFileBytes[], int offsets[], int offset)
33         throws ClassFormatException {
34         super(classFileBytes, offset);
35         constantPoolOffsets = offsets;
36         innerClassNameIndex = u2At(0);
37         outerClassNameIndex = u2At(2);
38         this.innerNameIndex = u2At(4);
39 }
40 /**
41  * Answer the resolved name of the enclosing type in the
42  * class file format as specified in section 4.2 of the Java 2 VM spec.
43  *
44  * For example, java.lang.String is java/lang/String.
45  * @return char[]
46  */
47 public char[] getEnclosingTypeName() {
48         if (!readOuterClassName) {
49                 // read outer class name
50                 readOuterClassName = true;
51                 if (outerClassNameIndex != 0) {
52                         int utf8Offset = 
53                                 constantPoolOffsets[u2At(
54                                         constantPoolOffsets[outerClassNameIndex] - structOffset + 1)]
55                                         - structOffset; 
56                         outerClassName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
57                 }
58
59         }
60         return outerClassName;
61 }
62 /**
63  * Answer an int whose bits are set according the access constants
64  * defined by the VM spec.
65  * @return int
66  */
67 public int getModifiers() {
68         if (accessFlags == -1) {
69                 // read access flag
70                 accessFlags = u2At(6);
71         }
72         return accessFlags;
73 }
74 /**
75  * Answer the resolved name of the member type in the
76  * class file format as specified in section 4.2 of the Java 2 VM spec.
77  *
78  * For example, p1.p2.A.M is p1/p2/A$M.
79  * @return char[]
80  */
81 public char[] getName() {
82         if (!readInnerClassName) {
83                 // read the inner class name
84                 readInnerClassName = true;
85                 if (innerClassNameIndex != 0) {
86                         int  classOffset = constantPoolOffsets[innerClassNameIndex] - structOffset;
87                         int utf8Offset = constantPoolOffsets[u2At(classOffset + 1)] - structOffset;
88                         innerClassName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
89                 }
90         }
91         return innerClassName;
92 }
93 /**
94  * Answer the source name of the member type.
95  *
96  * For example, p1.p2.A.M is M.
97  * @return char[]
98  */
99 public char[] getSourceName() {
100         if (!this.readInnerName) {
101                 this.readInnerName = true;
102                 if (innerNameIndex != 0) {
103                         int utf8Offset = constantPoolOffsets[innerNameIndex] - structOffset;
104                         innerName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
105                 }
106         }
107         return innerName;
108 }
109 /**
110  * Answer the string representation of the receiver
111  * @return java.lang.String
112  */
113 public String toString() {
114         StringBuffer buffer = new StringBuffer();
115         if (getName() != null) {
116                 buffer.append(getName());
117         }
118         buffer.append("\n"); //$NON-NLS-1$
119         if (getEnclosingTypeName() != null) {
120                 buffer.append(getEnclosingTypeName());
121         }
122         buffer.append("\n"); //$NON-NLS-1$
123         if (getSourceName() != null) {
124                 buffer.append(getSourceName());
125         }
126         return buffer.toString();   
127 }
128 /**
129  * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
130  * will be therefore fully initialized and we can get rid of the bytes.
131  */
132 void initialize() {
133         getModifiers();
134         getName();
135         getSourceName();
136         getEnclosingTypeName();
137         reset();
138 }
139 protected void reset() {
140         this.constantPoolOffsets = null;
141         super.reset();
142 }
143 }