final byte[] contents = this.document.getByteContents();
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=107124
// contents can potentially be null if a IOException occurs while retrieving the contents
if (contents == null) return;
final String path = this.document.getPath();
ClassFileReader reader = new ClassFileReader(contents, path == null ? null : path.toCharArray());
// first add type references
char[] className = replace('/', '.', reader.getName()); // looks like java/lang/String
// need to extract the package name and the simple name
int packageNameIndex = CharOperation.lastIndexOf('.', className);
char[] packageName = null;
char[] name = null;
if (packageNameIndex >= 0) {
packageName = CharOperation.subarray(className, 0, packageNameIndex);
name = CharOperation.subarray(className, packageNameIndex + 1, className.length);
} else {
packageName = CharOperation.NO_CHAR;
name = className;
}
char[] enclosingTypeName = null;
boolean isNestedType = reader.isNestedType();
if (isNestedType) {
if (reader.isAnonymous()) {
name = CharOperation.NO_CHAR;
} else {
name = reader.getInnerSourceName();
}
if (reader.isLocal() || reader.isAnonymous()) {
// set specific ['0'] value for local and anonymous to be able to filter them
enclosingTypeName = ONE_ZERO;
} else {
char[] fullEnclosingName = reader.getEnclosingTypeName();
int nameLength = fullEnclosingName.length - packageNameIndex - 1;
if (nameLength <= 0) {
// See PR 1GIR345: ITPJCORE:ALL - Indexer: NegativeArraySizeException
return;
}
enclosingTypeName = new char[nameLength];
System.arraycopy(fullEnclosingName, packageNameIndex + 1, enclosingTypeName, 0, nameLength);
}
}
// type parameters
char[][] typeParameterSignatures = null;
char[] genericSignature = reader.getGenericSignature();
if (genericSignature != null) {
CharOperation.replace(genericSignature, '/', '.');
typeParameterSignatures = Signature.getTypeParameters(genericSignature);
}
// eliminate invalid innerclasses (1G4KCF7)
if (name == null) return;
char[][] superinterfaces = replace('/', '.', reader.getInterfaceNames());
char[][] enclosingTypeNames = enclosingTypeName == null ? null : new char[][] {enclosingTypeName};
int modifiers = reader.getModifiers();
switch (TypeDeclaration.kind(modifiers)) {
case TypeDeclaration.CLASS_DECL :
char[] superclass = replace('/', '.', reader.getSuperclassName());
addClassDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, typeParameterSignatures, false);
break;
case TypeDeclaration.INTERFACE_DECL :
addInterfaceDeclaration(modifiers, packageName, name, enclosingTypeNames, superinterfaces, typeParameterSignatures, false);
break;
case TypeDeclaration.ENUM_DECL :
superclass = replace('/', '.', reader.getSuperclassName());
addEnumDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, false);
break;
case TypeDeclaration.ANNOTATION_TYPE_DECL :
addAnnotationTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, false);
break;
}
// Look for references in class annotations
IBinaryAnnotation[] annotations = reader.getAnnotations();
if (annotations != null) {
for (int a=0, length=annotations.length; a<length; a++) {
IBinaryAnnotation annotation = annotations[a];
addBinaryAnnotation(annotation);
}
}
long tagBits = reader.getTagBits() & TagBits.AllStandardAnnotationsMask;
if (tagBits != 0) {
addBinaryStandardAnnotations(tagBits);
}
int extraFlags = ExtraFlags.getExtraFlags(reader);
// first reference all methods declarations and field declarations
MethodInfo[] methods = (MethodInfo[]) reader.getMethods();
boolean noConstructor = true;
if (methods != null) {
for (int i = 0, max = methods.length; i < max; i++) {
MethodInfo method = methods[i];
boolean isConstructor = method.isConstructor();
char[] descriptor = method.getMethodDescriptor();
char[][] parameterTypes = decodeParameterTypes(descriptor, isConstructor && isNestedType);
char[] returnType = decodeReturnType(descriptor);
char[][] exceptionTypes = replace('/', '.', method.getExceptionTypeNames());
if (isConstructor) {
noConstructor = false;
char[] signature = method.getGenericSignature();
if (signature == null) {
if (reader.isNestedType() && ((modifiers & ClassFileConstants.AccStatic) == 0)) {
signature = removeFirstSyntheticParameter(descriptor);
} else {
signature = descriptor;
}
}
addConstructorDeclaration(
name,
parameterTypes == null ? 0 : parameterTypes.length,
signature,
parameterTypes,
method.getArgumentNames(),
method.getModifiers(),
packageName,
modifiers,
exceptionTypes,
extraFlags);
} else {
if (!method.isClinit()) {
addMethodDeclaration(method.getSelector(), parameterTypes, returnType, exceptionTypes);
}
}
// look for references in method annotations
annotations = method.getAnnotations();
if (annotations != null) {
for (int a=0, length=annotations.length; a<length; a++) {
IBinaryAnnotation annotation = annotations[a];
addBinaryAnnotation(annotation);
}
}
tagBits = method.getTagBits() & TagBits.AllStandardAnnotationsMask;
if (tagBits != 0) {
addBinaryStandardAnnotations(tagBits);
}
}
}
if (noConstructor) {
addDefaultConstructorDeclaration(className, packageName, modifiers, extraFlags);
}
FieldInfo[] fields = (FieldInfo[]) reader.getFields();
if (fields != null) {
for (int i = 0, max = fields.length; i < max; i++) {
FieldInfo field = fields[i];
char[] fieldName = field.getName();
char[] fieldType = decodeFieldType(replace('/', '.', field.getTypeName()));