001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.core.hierarchy;
011:
012: import org.eclipse.jdt.core.Signature;
013: import org.eclipse.jdt.core.compiler.CharOperation;
014: import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
015: import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
016: import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
017: import org.eclipse.jdt.internal.compiler.env.IBinaryField;
018: import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
019: import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
020: import org.eclipse.jdt.internal.compiler.env.IBinaryType;
021: import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
022:
023: public class HierarchyBinaryType implements IBinaryType {
024: private int modifiers;
025: private char[] sourceName;
026: private char[] name;
027: private char[] enclosingTypeName;
028: private char[] super class;
029: private char[][] super Interfaces = NoInterface;
030: private char[][] typeParameterSignatures;
031: private char[] genericSignature;
032:
033: public HierarchyBinaryType(int modifiers, char[] qualification,
034: char[] sourceName, char[] enclosingTypeName,
035: char[][] typeParameterSignatures, char typeSuffix) {
036:
037: this .modifiers = modifiers;
038: this .sourceName = sourceName;
039: if (enclosingTypeName == null) {
040: this .name = CharOperation.concat(qualification, sourceName,
041: '/');
042: } else {
043: this .name = CharOperation.concat(qualification, '/',
044: enclosingTypeName, '$', sourceName); //rebuild A$B name
045: this .enclosingTypeName = CharOperation.concat(
046: qualification, enclosingTypeName, '/');
047: CharOperation.replace(this .enclosingTypeName, '.', '/');
048: }
049: this .typeParameterSignatures = typeParameterSignatures;
050: CharOperation.replace(this .name, '.', '/');
051: }
052:
053: /**
054: * Answer the resolved name of the enclosing type in the
055: * class file format as specified in section 4.2 of the Java 2 VM spec
056: * or null if the receiver is a top level type.
057: *
058: * For example, java.lang.String is java/lang/String.
059: */
060: public char[] getEnclosingTypeName() {
061: return this .enclosingTypeName;
062: }
063:
064: /**
065: * Answer the receiver's fields or null if the array is empty.
066: */
067: public IBinaryField[] getFields() {
068: return null;
069: }
070:
071: /**
072: * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
073: */
074: public char[] getFileName() {
075: return null;
076: }
077:
078: public char[] getGenericSignature() {
079: if (this .typeParameterSignatures != null
080: && this .genericSignature == null) {
081: StringBuffer buffer = new StringBuffer();
082: buffer.append('<');
083: for (int i = 0, length = this .typeParameterSignatures.length; i < length; i++) {
084: buffer.append(this .typeParameterSignatures[i]);
085: }
086: buffer.append('>');
087: if (this .super class == null)
088: buffer.append(Signature.createTypeSignature(
089: "java.lang.Object", true/*resolved*/)); //$NON-NLS-1$
090: else
091: buffer.append(Signature.createTypeSignature(
092: this .super class, true/*resolved*/));
093: if (this .super Interfaces != null)
094: for (int i = 0, length = this .super Interfaces.length; i < length; i++)
095: buffer
096: .append(Signature
097: .createTypeSignature(
098: this .super Interfaces[i],
099: true/*resolved*/));
100: this .genericSignature = buffer.toString().toCharArray();
101: CharOperation.replace(this .genericSignature, '.', '/');
102: }
103: return this .genericSignature;
104: }
105:
106: /**
107: * Answer the resolved names of the receiver's interfaces in the
108: * class file format as specified in section 4.2 of the Java 2 VM spec
109: * or null if the array is empty.
110: *
111: * For example, java.lang.String is java/lang/String.
112: */
113: public char[][] getInterfaceNames() {
114: return this .super Interfaces;
115: }
116:
117: /**
118: * Answer the receiver's nested types or null if the array is empty.
119: *
120: * This nested type info is extracted from the inner class attributes.
121: * Ask the name environment to find a member type using its compound name.
122: */
123: public IBinaryNestedType[] getMemberTypes() {
124: return null;
125: }
126:
127: /**
128: * Answer the receiver's methods or null if the array is empty.
129: */
130: public IBinaryMethod[] getMethods() {
131: return null;
132: }
133:
134: /**
135: * Answer an int whose bits are set according the access constants
136: * defined by the VM spec.
137: */
138: public int getModifiers() {
139: return this .modifiers;
140: }
141:
142: /**
143: * Answer the resolved name of the type in the
144: * class file format as specified in section 4.2 of the Java 2 VM spec.
145: *
146: * For example, java.lang.String is java/lang/String.
147: */
148: public char[] getName() {
149: return this .name;
150: }
151:
152: public char[] getSourceName() {
153: return this .sourceName;
154: }
155:
156: /**
157: * Answer the resolved name of the receiver's superclass in the
158: * class file format as specified in section 4.2 of the Java 2 VM spec
159: * or null if it does not have one.
160: *
161: * For example, java.lang.String is java/lang/String.
162: */
163: public char[] getSuperclassName() {
164: return this .super class;
165: }
166:
167: public boolean isAnonymous() {
168: return false; // index did not record this information (since unused for hierarchies)
169: }
170:
171: /**
172: * Answer whether the receiver contains the resolved binary form
173: * or the unresolved source form of the type.
174: */
175: public boolean isBinaryType() {
176: return true;
177: }
178:
179: public boolean isLocal() {
180: return false; // index did not record this information (since unused for hierarchies)
181: }
182:
183: public boolean isMember() {
184: return false; // index did not record this information (since unused for hierarchies)
185: }
186:
187: public void recordSuperType(char[] super TypeName,
188: char[] super Qualification, char super ClassOrInterface) {
189:
190: // index encoding of p.A$B was B/p.A$, rebuild the proper name
191: if (super Qualification != null) {
192: int length = super Qualification.length;
193: if (super Qualification[length - 1] == '$') {
194: char[] enclosingSuperName = CharOperation.lastSegment(
195: super Qualification, '.');
196: super TypeName = CharOperation.concat(
197: enclosingSuperName, super TypeName);
198: super Qualification = CharOperation.subarray(
199: super Qualification, 0, length
200: - enclosingSuperName.length - 1);
201: }
202: }
203:
204: if (super ClassOrInterface == IIndexConstants.CLASS_SUFFIX) {
205: // interfaces are indexed as having superclass references to Object by default,
206: // this is an artifact used for being able to query them only.
207: if (TypeDeclaration.kind(this .modifiers) == TypeDeclaration.INTERFACE_DECL)
208: return;
209: char[] encodedName = CharOperation.concat(
210: super Qualification, super TypeName, '/');
211: CharOperation.replace(encodedName, '.', '/');
212: this .super class = encodedName;
213: } else {
214: char[] encodedName = CharOperation.concat(
215: super Qualification, super TypeName, '/');
216: CharOperation.replace(encodedName, '.', '/');
217: if (this .super Interfaces == NoInterface) {
218: this .super Interfaces = new char[][] { encodedName };
219: } else {
220: int length = this .super Interfaces.length;
221: System.arraycopy(this .super Interfaces, 0,
222: this .super Interfaces = new char[length + 1][],
223: 0, length);
224: this .super Interfaces[length] = encodedName;
225: }
226: }
227: }
228:
229: public String toString() {
230: StringBuffer buffer = new StringBuffer();
231: if (this .modifiers == ClassFileConstants.AccPublic) {
232: buffer.append("public "); //$NON-NLS-1$
233: }
234: switch (TypeDeclaration.kind(this .modifiers)) {
235: case TypeDeclaration.CLASS_DECL:
236: buffer.append("class "); //$NON-NLS-1$
237: break;
238: case TypeDeclaration.INTERFACE_DECL:
239: buffer.append("interface "); //$NON-NLS-1$
240: break;
241: case TypeDeclaration.ENUM_DECL:
242: buffer.append("enum "); //$NON-NLS-1$
243: break;
244: }
245: if (this .name != null) {
246: buffer.append(this .name);
247: }
248: if (this .super class != null) {
249: buffer.append("\n extends "); //$NON-NLS-1$
250: buffer.append(this .super class);
251: }
252: int length;
253: if (this .super Interfaces != null
254: && (length = this .super Interfaces.length) != 0) {
255: buffer.append("\n implements "); //$NON-NLS-1$
256: for (int i = 0; i < length; i++) {
257: buffer.append(this .super Interfaces[i]);
258: if (i != length - 1) {
259: buffer.append(", "); //$NON-NLS-1$
260: }
261: }
262: }
263: return buffer.toString();
264: }
265:
266: /**
267: * @see org.eclipse.jdt.internal.compiler.env.IBinaryType
268: */
269: public IBinaryAnnotation[] getAnnotations() {
270: return null;
271: }
272:
273: /**
274: * @see org.eclipse.jdt.internal.compiler.env.IBinaryType
275: */
276: public char[] sourceFileName() {
277: return null;
278: }
279:
280: // TODO (jerome) please verify that we don't need the tagbits for the receiver
281: public long getTagBits() {
282: return 0;
283: }
284: }
|