org.aspectj.org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during
compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based
@AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step.
This library is a superset of AspectJ weaver and hence also of AspectJ runtime.
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.core.search.indexing;
import java.io.File;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.aspectj.org.eclipse.jdt.core.Flags;
import org.aspectj.org.eclipse.jdt.core.JavaCore;
import org.aspectj.org.eclipse.jdt.core.Signature;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.core.search.SearchDocument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.ClassSignature;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.EnumConstantSignature;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule.IService;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.aspectj.org.eclipse.jdt.internal.core.util.Util;
public class BinaryIndexer extends AbstractIndexer implements SuffixConstants {
private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
private static final char[] INIT = "".toCharArray(); //$NON-NLS-1$
public BinaryIndexer(SearchDocument document) {
super(document);
}
private void addBinaryStandardAnnotations(long annotationTagBits) {
if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) {
return;
}
if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
addBinaryTargetAnnotation(annotationTagBits);
}
if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
addBinaryRetentionAnnotation(annotationTagBits);
}
if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationInherited) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationOverride) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) {
char[][] compoundName = TypeConstants.JAVA_LANG_SAFEVARARGS;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
char[][] compoundName =
TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE;
addAnnotationTypeReference(compoundName[compoundName.length-1]);
}
}
private void addBinaryTargetAnnotation(long bits) {
char[][] compoundName = null;
if ((bits & TagBits.AnnotationForAnnotationType) != 0) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
addFieldReference(TypeConstants.UPPER_ANNOTATION_TYPE);
}
if ((bits & TagBits.AnnotationForConstructor) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_CONSTRUCTOR);
}
if ((bits & TagBits.AnnotationForField) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_FIELD);
}
if ((bits & TagBits.AnnotationForLocalVariable) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_LOCAL_VARIABLE);
}
if ((bits & TagBits.AnnotationForMethod) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_METHOD);
}
if ((bits & TagBits.AnnotationForPackage) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_PACKAGE);
}
if ((bits & TagBits.AnnotationForParameter) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_PARAMETER);
}
if ((bits & TagBits.AnnotationForType) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.TYPE);
}
if ((bits & TagBits.AnnotationForModule) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_MODULE);
}
if ((bits & TagBits.AnnotationForRecordComponent) != 0) {
if (compoundName == null) {
compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
addTypeReference(compoundName[compoundName.length-1]);
}
addFieldReference(TypeConstants.UPPER_RECORD_COMPONENT);
}
}
private void addBinaryRetentionAnnotation(long bits) {
char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY;
addTypeReference(compoundName[compoundName.length-1]);
if ((bits & TagBits.AnnotationRuntimeRetention) == TagBits.AnnotationRuntimeRetention) {
addFieldReference(TypeConstants.UPPER_RUNTIME);
} else if ((bits & TagBits.AnnotationClassRetention) != 0) {
addFieldReference(TypeConstants.UPPER_CLASS);
} else if ((bits & TagBits.AnnotationSourceRetention) != 0) {
addFieldReference(TypeConstants.UPPER_SOURCE);
}
}
private void addBinaryAnnotation(IBinaryAnnotation annotation) {
addAnnotationTypeReference(replace('/', '.', Signature.toCharArray(annotation.getTypeName())));
IBinaryElementValuePair[] valuePairs = annotation.getElementValuePairs();
if (valuePairs != null) {
for (int j=0, vpLength=valuePairs.length; j 2 && typeName[length - 2] == '$') {
switch (typeName[length - 1]) {
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
return; // skip local type names
}
}
// consider that A$B is a member type: so replace '$' with '.'
// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40116)
typeName = CharOperation.replaceOnCopy(typeName, '$', '.'); // copy it so the original is not modified
super.addTypeReference(typeName);
}
/**
* For example:
* - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
* - void foo(int) is (I)V ==> int
*/
private void convertToArrayType(char[][] parameterTypes, int counter, int arrayDim) {
int length = parameterTypes[counter].length;
char[] arrayType = new char[length + arrayDim*2];
System.arraycopy(parameterTypes[counter], 0, arrayType, 0, length);
for (int i = 0; i < arrayDim; i++) {
arrayType[length + (i * 2)] = '[';
arrayType[length + (i * 2) + 1] = ']';
}
parameterTypes[counter] = arrayType;
}
/**
* For example:
* - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
* - void foo(int) is (I)V ==> int
*/
private char[] convertToArrayType(char[] typeName, int arrayDim) {
int length = typeName.length;
char[] arrayType = new char[length + arrayDim*2];
System.arraycopy(typeName, 0, arrayType, 0, length);
for (int i = 0; i < arrayDim; i++) {
arrayType[length + (i * 2)] = '[';
arrayType[length + (i * 2) + 1] = ']';
}
return arrayType;
}
private char[] decodeFieldType(char[] signature) throws ClassFormatException {
if (signature == null) return null;
int arrayDim = 0;
for (int i = 0, max = signature.length; i < max; i++) {
switch(signature[i]) {
case 'B':
if (arrayDim > 0)
return convertToArrayType(BYTE, arrayDim);
return BYTE;
case 'C':
if (arrayDim > 0)
return convertToArrayType(CHAR, arrayDim);
return CHAR;
case 'D':
if (arrayDim > 0)
return convertToArrayType(DOUBLE, arrayDim);
return DOUBLE;
case 'F':
if (arrayDim > 0)
return convertToArrayType(FLOAT, arrayDim);
return FLOAT;
case 'I':
if (arrayDim > 0)
return convertToArrayType(INT, arrayDim);
return INT;
case 'J':
if (arrayDim > 0)
return convertToArrayType(LONG, arrayDim);
return LONG;
case 'L':
int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
if (arrayDim > 0) {
return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim);
}
return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
case 'S':
if (arrayDim > 0)
return convertToArrayType(SHORT, arrayDim);
return SHORT;
case 'Z':
if (arrayDim > 0)
return convertToArrayType(BOOLEAN, arrayDim);
return BOOLEAN;
case 'V':
return VOID;
case '[':
arrayDim++;
break;
default:
throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
}
}
return null;
}
/**
* For example:
* - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
* - void foo(int) is (I)V ==> int
*/
private char[][] decodeParameterTypes(char[] signature, boolean firstIsSynthetic) throws ClassFormatException {
if (signature == null) return null;
int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
if (indexOfClosingParen == 1) {
// there is no parameter
return null;
}
if (indexOfClosingParen == -1) {
throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
}
char[][] parameterTypes = new char[3][];
int parameterTypesCounter = 0;
int arrayDim = 0;
for (int i = 1; i < indexOfClosingParen; i++) {
if (parameterTypesCounter == parameterTypes.length) {
// resize
System.arraycopy(parameterTypes, 0, (parameterTypes = new char[parameterTypesCounter * 2][]), 0, parameterTypesCounter);
}
switch(signature[i]) {
case 'B':
parameterTypes[parameterTypesCounter++] = BYTE;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'C':
parameterTypes[parameterTypesCounter++] = CHAR;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'D':
parameterTypes[parameterTypesCounter++] = DOUBLE;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'F':
parameterTypes[parameterTypesCounter++] = FLOAT;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'I':
parameterTypes[parameterTypesCounter++] = INT;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'J':
parameterTypes[parameterTypesCounter++] = LONG;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'L':
int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
if (firstIsSynthetic && parameterTypesCounter == 0) {
// skip first synthetic parameter
firstIsSynthetic = false;
} else {
parameterTypes[parameterTypesCounter++] = replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
}
i = indexOfSemiColon;
arrayDim = 0;
break;
case 'S':
parameterTypes[parameterTypesCounter++] = SHORT;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case 'Z':
parameterTypes[parameterTypesCounter++] = BOOLEAN;
if (arrayDim > 0)
convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
arrayDim = 0;
break;
case '[':
arrayDim++;
break;
default:
throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
}
}
if (parameterTypes.length != parameterTypesCounter) {
System.arraycopy(parameterTypes, 0, parameterTypes = new char[parameterTypesCounter][], 0, parameterTypesCounter);
}
return parameterTypes;
}
private char[] decodeReturnType(char[] signature) throws ClassFormatException {
if (signature == null) return null;
int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
if (indexOfClosingParen == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
int arrayDim = 0;
for (int i = indexOfClosingParen + 1, max = signature.length; i < max; i++) {
switch(signature[i]) {
case 'B':
if (arrayDim > 0)
return convertToArrayType(BYTE, arrayDim);
return BYTE;
case 'C':
if (arrayDim > 0)
return convertToArrayType(CHAR, arrayDim);
return CHAR;
case 'D':
if (arrayDim > 0)
return convertToArrayType(DOUBLE, arrayDim);
return DOUBLE;
case 'F':
if (arrayDim > 0)
return convertToArrayType(FLOAT, arrayDim);
return FLOAT;
case 'I':
if (arrayDim > 0)
return convertToArrayType(INT, arrayDim);
return INT;
case 'J':
if (arrayDim > 0)
return convertToArrayType(LONG, arrayDim);
return LONG;
case 'L':
int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
if (arrayDim > 0) {
return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim);
}
return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
case 'S':
if (arrayDim > 0)
return convertToArrayType(SHORT, arrayDim);
return SHORT;
case 'Z':
if (arrayDim > 0)
return convertToArrayType(BOOLEAN, arrayDim);
return BOOLEAN;
case 'V':
return VOID;
case '[':
arrayDim++;
break;
default:
throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
}
}
return null;
}
private int extractArgCount(char[] signature, char[] className) throws ClassFormatException {
return extractArgCount(signature, className, false);
}
private int extractArgCount(char[] signature, char[] className, boolean isStaticTypeConstructor) throws ClassFormatException {
int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
if (indexOfClosingParen == 1) {
// there is no parameter
return 0;
}
if (indexOfClosingParen == -1) {
throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
}
int parameterTypesCounter = 0;
for (int i = 1; i < indexOfClosingParen; i++) {
switch(signature[i]) {
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
parameterTypesCounter++;
break;
case 'L':
int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
// verify if first parameter is synthetic
if (className != null && parameterTypesCounter == 0 && !isStaticTypeConstructor) {
char[] classSignature = Signature.createCharArrayTypeSignature(className, true);
int length = indexOfSemiColon-i+1;
if (classSignature.length > (length+1)) {
// synthetic means that parameter type has same signature than given class
for (int j=i, k=0; j 0 && name[0] == '[')
break; // skip over array references
name = replace('/', '.', name); // so that it looks like java.lang.String
addTypeReference(name);
// also add a simple reference on each segment of the qualification (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=24741)
char[][] qualification = CharOperation.splitOn('.', name);
for (int j = 0, length = qualification.length; j < length; j++) {
addNameReference(qualification[j]);
}
break;
}
}
}
private char[] extractType(int[] constantPoolOffsets, ClassFileReader reader, int index) {
int constantPoolIndex = reader.u2At(constantPoolOffsets[index] + 3);
int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[constantPoolIndex] + 3)];
return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
}
@Override
public void indexDocument() {
try {
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((new File(path)).toURI(), contents, path == null ? null : path.toCharArray());
IModule module = reader.getModuleDeclaration();
if (module != null) {
indexModule(module);
return;
}
// 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;
case TypeDeclaration.RECORD_DECL :
superclass = replace('/', '.', reader.getSuperclassName());
addClassDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, typeParameterSignatures, false);
break;
}
// Look for references in class annotations
IBinaryAnnotation[] annotations = reader.getAnnotations();
if (annotations != null) {
for (int a=0, length=annotations.length; a 0) {
addMethodDeclaration(
name,
null,
selector,
parameterTypes == null ? 0 : parameterTypes.length,
signature,
parameterTypes,
method.getArgumentNames(),
returnType,
method.getModifiers(),
packageName,
modifiers,
exceptionTypes,
extraFlags);
}
}
}
// look for references in method annotations
annotations = method.getAnnotations();
if (annotations != null) {
for (int a=0, length=annotations.length; a