package org.eclipse.jdt.internal.core.hierarchy;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryField;
import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
import org.eclipse.jdt.internal.compiler.env.ITypeAnnotationWalker;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.ExternalAnnotationStatus;
import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
public class HierarchyBinaryType implements IBinaryType {
private int modifiers;
private char[] sourceName;
private char[] name;
private char[] enclosingTypeName;
private char[] superclass;
private char[][] superInterfaces = NoInterface;
private char[][] typeParameterSignatures;
private char[] genericSignature;
public HierarchyBinaryType(int modifiers, char[] qualification, char[] sourceName, char[] enclosingTypeName, char[][] typeParameterSignatures, char typeSuffix){
this.modifiers = modifiers;
this.sourceName = sourceName;
if (enclosingTypeName == null){
this.name = CharOperation.concat(qualification, sourceName, '/');
} else {
this.name = CharOperation.concat(qualification, '/', enclosingTypeName, '$', sourceName);
this.enclosingTypeName = CharOperation.concat(qualification, enclosingTypeName,'/');
CharOperation.replace(this.enclosingTypeName, '.', '/');
}
this.typeParameterSignatures = typeParameterSignatures;
CharOperation.replace(this.name, '.', '/');
}
public HierarchyBinaryType(int modifiers, char[] binaryName, char[] sourceName, char[] enclosingTypeBinaryName, char[][] typeParameterSignatures) {
this.modifiers = modifiers;
this.sourceName = sourceName;
this.name = binaryName;
this.enclosingTypeName = enclosingTypeBinaryName;
this.typeParameterSignatures = typeParameterSignatures;
if (typeParameterSignatures != null) {
for (char[] next : typeParameterSignatures) {
if (next == null) {
throw new IllegalArgumentException("Parameter's type signature must not be null");
}
}
}
}
@Override
public IBinaryAnnotation[] getAnnotations() {
return null;
}
@Override
public IBinaryTypeAnnotation[] getTypeAnnotations() {
return null;
}
@Override
public char[] getEnclosingMethod() {
return null;
}
@Override
public char[] getEnclosingTypeName() {
return this.enclosingTypeName;
}
@Override
public IBinaryField[] getFields() {
return null;
}
@Override
public char[] getFileName() {
return null;
}
@Override
public char[] getGenericSignature() {
if (this.typeParameterSignatures != null && this.genericSignature == null) {
StringBuffer buffer = new StringBuffer();
buffer.append('<');
for (int i = 0, length = this.typeParameterSignatures.length; i < length; i++) {
buffer.append(this.typeParameterSignatures[i]);
}
buffer.append('>');
if (this.superclass == null)
buffer.append(Signature.createTypeSignature("java.lang.Object", true));
else
buffer.append(Signature.createTypeSignature(this.superclass, true));
if (this.superInterfaces != null)
for (int i = 0, length = this.superInterfaces.length; i < length; i++)
buffer.append(Signature.createTypeSignature(this.superInterfaces[i], true));
this.genericSignature = buffer.toString().toCharArray();
CharOperation.replace(this.genericSignature, '.', '/');
}
return this.genericSignature;
}
@Override
public char[][] getInterfaceNames() {
return this.superInterfaces;
}
@Override
public IBinaryNestedType[] getMemberTypes() {
return null;
}
@Override
public IBinaryMethod[] getMethods() {
return null;
}
@Override
public char[][][] getMissingTypeNames() {
return null;
}
@Override
public int getModifiers() {
return this.modifiers;
}
@Override
public char[] getName() {
return this.name;
}
@Override
public char[] getSourceName() {
return this.sourceName;
}
@Override
public char[] getSuperclassName() {
return this.superclass;
}
@Override
public long getTagBits() {
return 0;
}
@Override
public boolean isAnonymous() {
return false;
}
@Override
public boolean isBinaryType() {
return true;
}
@Override
public boolean isLocal() {
return false;
}
@Override
public boolean isMember() {
return false;
}
public void recordSuperType(char[] superTypeName, char[] superQualification, char superClassOrInterface){
if (superQualification != null){
int length = superQualification.length;
if (superQualification[length-1] == '$'){
char[] enclosingSuperName = CharOperation.lastSegment(superQualification, '.');
superTypeName = CharOperation.concat(enclosingSuperName, superTypeName);
superQualification = CharOperation.subarray(superQualification, 0, length - enclosingSuperName.length - 1);
}
}
if (superClassOrInterface == IIndexConstants.CLASS_SUFFIX){
if (TypeDeclaration.kind(this.modifiers) == TypeDeclaration.INTERFACE_DECL) return;
char[] encodedName = CharOperation.concat(superQualification, superTypeName, '/');
CharOperation.replace(encodedName, '.', '/');
recordSuperclass(encodedName);
} else {
char[] encodedName = CharOperation.concat(superQualification, superTypeName, '/');
CharOperation.replace(encodedName, '.', '/');
recordInterface(encodedName);
}
}
public void recordSuperclass(char[] binaryName) {
this.superclass = binaryName;
}
public void recordInterface(char[] binaryName) {
if (this.superInterfaces == NoInterface){
this.superInterfaces = new char[][] { binaryName };
} else {
int length = this.superInterfaces.length;
System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new char[length+1][], 0, length);
this.superInterfaces[length] = binaryName;
}
}
@Override
public char[] sourceFileName() {
return null;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
if (this.modifiers == ClassFileConstants.AccPublic) {
buffer.append("public ");
}
switch (TypeDeclaration.kind(this.modifiers)) {
case TypeDeclaration.CLASS_DECL :
buffer.append("class ");
break;
case TypeDeclaration.INTERFACE_DECL :
buffer.append("interface ");
break;
case TypeDeclaration.ENUM_DECL :
buffer.append("enum ");
break;
}
if (this.name != null) {
buffer.append(this.name);
}
if (this.superclass != null) {
buffer.append("\n extends ");
buffer.append(this.superclass);
}
int length;
if (this.superInterfaces != null && (length = this.superInterfaces.length) != 0) {
buffer.append("\n implements ");
for (int i = 0; i < length; i++) {
buffer.append(this.superInterfaces[i]);
if (i != length - 1) {
buffer.append(", ");
}
}
}
return buffer.toString();
}
@Override
public ITypeAnnotationWalker enrichWithExternalAnnotationsFor(ITypeAnnotationWalker walker, Object member, LookupEnvironment environment) {
return walker;
}
@Override
public char[] getModule() {
return null;
}
@Override
public ExternalAnnotationStatus getExternalAnnotationStatus() {
return ExternalAnnotationStatus.NOT_EEA_CONFIGURED;
}
}