mirror of
https://github.com/revanced/smali.git
synced 2025-05-04 16:44:25 +02:00
Refactor the interface of AnnotationDirectoryItem
This makes it easier to use, and fixes a few null safeness issues.
This commit is contained in:
parent
2bfc114146
commit
b71c12967b
@ -31,6 +31,9 @@ package org.jf.baksmali.Adaptors;
|
|||||||
import org.jf.dexlib.Util.Utf8Utils;
|
import org.jf.dexlib.Util.Utf8Utils;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
import org.jf.dexlib.*;
|
import org.jf.dexlib.*;
|
||||||
|
import static org.jf.dexlib.AnnotationDirectoryItem.FieldAnnotation;
|
||||||
|
import static org.jf.dexlib.AnnotationDirectoryItem.MethodAnnotation;
|
||||||
|
import static org.jf.dexlib.AnnotationDirectoryItem.ParameterAnnotation;
|
||||||
import org.jf.dexlib.Code.Analysis.ValidationException;
|
import org.jf.dexlib.Code.Analysis.ValidationException;
|
||||||
import org.jf.dexlib.Code.Format.Instruction21c;
|
import org.jf.dexlib.Code.Format.Instruction21c;
|
||||||
import org.jf.dexlib.Code.Format.Instruction41c;
|
import org.jf.dexlib.Code.Format.Instruction41c;
|
||||||
@ -74,28 +77,29 @@ public class ClassDefinition {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
methodAnnotationsMap = new SparseArray<AnnotationSetItem>(annotationDirectory.getMethodAnnotationCount());
|
int fieldAnnotationCount = annotationDirectory.getFieldAnnotationCount();
|
||||||
annotationDirectory.iterateMethodAnnotations(new AnnotationDirectoryItem.MethodAnnotationIteratorDelegate() {
|
fieldAnnotationsMap = new SparseArray<AnnotationSetItem>(fieldAnnotationCount);
|
||||||
public void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations) {
|
if (fieldAnnotationCount > 0) {
|
||||||
methodAnnotationsMap.put(method.getIndex(), methodAnnotations);
|
for (FieldAnnotation fieldAnnotation: annotationDirectory.getFieldAnnotations()) {
|
||||||
|
fieldAnnotationsMap.put(fieldAnnotation.field.getIndex(), fieldAnnotation.annotationSet);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
fieldAnnotationsMap = new SparseArray<AnnotationSetItem>(annotationDirectory.getFieldAnnotationCount());
|
int methodAnnotationCount = annotationDirectory.getMethodAnnotationCount();
|
||||||
annotationDirectory.iterateFieldAnnotations(new AnnotationDirectoryItem.FieldAnnotationIteratorDelegate() {
|
methodAnnotationsMap = new SparseArray<AnnotationSetItem>(methodAnnotationCount);
|
||||||
public void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations) {
|
if (methodAnnotationCount > 0) {
|
||||||
fieldAnnotationsMap.put(field.getIndex(), fieldAnnotations);
|
for (MethodAnnotation methodAnnotation: annotationDirectory.getMethodAnnotations()) {
|
||||||
|
methodAnnotationsMap.put(methodAnnotation.method.getIndex(), methodAnnotation.annotationSet);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
parameterAnnotationsMap = new SparseArray<AnnotationSetRefList>(
|
int parameterAnnotationCount = annotationDirectory.getParameterAnnotationCount();
|
||||||
annotationDirectory.getParameterAnnotationCount());
|
parameterAnnotationsMap = new SparseArray<AnnotationSetRefList>(parameterAnnotationCount);
|
||||||
annotationDirectory.iterateParameterAnnotations(
|
if (parameterAnnotationCount > 0) {
|
||||||
new AnnotationDirectoryItem.ParameterAnnotationIteratorDelegate() {
|
for (ParameterAnnotation parameterAnnotation: annotationDirectory.getParameterAnnotations()) {
|
||||||
public void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations) {
|
parameterAnnotationsMap.put(parameterAnnotation.method.getIndex(), parameterAnnotation.annotationSet);
|
||||||
parameterAnnotationsMap.put(method.getIndex(), parameterAnnotations);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findFieldsSetInStaticConstructor() {
|
private void findFieldsSetInStaticConstructor() {
|
||||||
|
@ -24,5 +24,15 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.6</version>
|
<version>4.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
|
<artifactId>jsr305</artifactId>
|
||||||
|
<version>1.3.9</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.collections</groupId>
|
||||||
|
<artifactId>google-collections</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -28,32 +28,36 @@
|
|||||||
|
|
||||||
package org.jf.dexlib;
|
package org.jf.dexlib;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import org.jf.dexlib.Util.AnnotatedOutput;
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
import org.jf.dexlib.Util.ExceptionWithContext;
|
import org.jf.dexlib.Util.ExceptionWithContext;
|
||||||
import org.jf.dexlib.Util.Input;
|
import org.jf.dexlib.Util.Input;
|
||||||
|
import org.jf.dexlib.Util.ReadOnlyArrayList;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
||||||
|
@Nullable
|
||||||
private AnnotationSetItem classAnnotations;
|
private AnnotationSetItem classAnnotations;
|
||||||
|
@Nullable
|
||||||
private FieldIdItem[] fieldAnnotationFields;
|
private FieldAnnotation[] fieldAnnotations;
|
||||||
private AnnotationSetItem[] fieldAnnotations;
|
@Nullable
|
||||||
|
private MethodAnnotation[] methodAnnotations;
|
||||||
private MethodIdItem[] methodAnnotationMethods;
|
@Nullable
|
||||||
private AnnotationSetItem[] methodAnnotations;
|
private ParameterAnnotation[] parameterAnnotations;
|
||||||
|
|
||||||
private MethodIdItem[] parameterAnnotationMethods;
|
|
||||||
private AnnotationSetRefList[] parameterAnnotations;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when
|
* typically each AnnotationDirectoryItem will have a distinct parent. The only case that isn't true is when
|
||||||
* the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
|
* the AnnotationDirectoryItem *only* contains class annotations, with no other type of annotation. In that
|
||||||
* case, the same AnnotationDirectoryItem could be referenced from multiple classes.
|
* case, the same AnnotationDirectoryItem could be referenced from multiple classes.
|
||||||
* This isn't a problem though, because this field is only used in compareTo to determine the sort order,
|
* This isn't a problem though, because this field is only used in compareTo to determine the sort order, which
|
||||||
* which handles it as a special case
|
* which knows it should handle a null value as a special case
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private ClassDefItem parent = null;
|
private ClassDefItem parent = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,32 +72,43 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
* Creates a new <code>AnnotationDirectoryItem</code> with the given values
|
* Creates a new <code>AnnotationDirectoryItem</code> with the given values
|
||||||
* @param dexFile The <code>DexFile</code> that this item belongs to
|
* @param dexFile The <code>DexFile</code> that this item belongs to
|
||||||
* @param classAnnotations The annotations associated with the overall class
|
* @param classAnnotations The annotations associated with the overall class
|
||||||
* @param fieldAnnotationFields An array of <code>FieldIdItem</code> objects that the annotations in
|
* @param fieldAnnotations A list of <code>FieldAnnotation</code> objects that contain the field annotations for
|
||||||
* <code>fieldAnnotations</code> are associated with
|
* this class
|
||||||
* @param fieldAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
|
* @param methodAnnotations A list of <code>MethodAnnotation</code> objects that contain the method annotations for
|
||||||
* fields in <code>fieldAnnotationFields</code>
|
* this class
|
||||||
* @param methodAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
|
* @param parameterAnnotations A list of <code>ParameterAnnotation</code> objects that contain the parameter
|
||||||
* <code>methodAnnotations</code> are associated with
|
* annotations for the methods in this class
|
||||||
* @param methodAnnotations An array of <code>AnnotationSetItem</code> objects that contain the annotations for the
|
|
||||||
* methods in <code>methodAnnotationMethods</code>
|
|
||||||
* @param parameterAnnotationMethods An array of <code>MethodIdItem</code> objects that the annotations in
|
|
||||||
* <code>parameterAnnotations</code> are associated with
|
|
||||||
* @param parameterAnnotations An array of <code>AnnotationSetRefList</code> objects that contain the parameter
|
|
||||||
* annotations for the methods in <code>parameterAnnotationMethods</code>
|
|
||||||
*/
|
*/
|
||||||
private AnnotationDirectoryItem(DexFile dexFile, AnnotationSetItem classAnnotations,
|
private AnnotationDirectoryItem(DexFile dexFile, @Nullable AnnotationSetItem classAnnotations,
|
||||||
FieldIdItem[] fieldAnnotationFields, AnnotationSetItem[] fieldAnnotations,
|
@Nullable List<FieldAnnotation> fieldAnnotations,
|
||||||
MethodIdItem[] methodAnnotationMethods, AnnotationSetItem[] methodAnnotations,
|
@Nullable List<MethodAnnotation> methodAnnotations,
|
||||||
MethodIdItem[] parameterAnnotationMethods,
|
@Nullable List<ParameterAnnotation> parameterAnnotations) {
|
||||||
AnnotationSetRefList[] parameterAnnotations) {
|
|
||||||
super(dexFile);
|
super(dexFile);
|
||||||
this.classAnnotations = classAnnotations;
|
this.classAnnotations = classAnnotations;
|
||||||
this.fieldAnnotationFields = fieldAnnotationFields;
|
|
||||||
this.fieldAnnotations = fieldAnnotations;
|
if (fieldAnnotations == null || fieldAnnotations.size() == 0) {
|
||||||
this.methodAnnotationMethods = methodAnnotationMethods;
|
this.fieldAnnotations = null;
|
||||||
this.methodAnnotations = methodAnnotations;
|
} else {
|
||||||
this.parameterAnnotationMethods = parameterAnnotationMethods;
|
this.fieldAnnotations = new FieldAnnotation[fieldAnnotations.size()];
|
||||||
this.parameterAnnotations = parameterAnnotations;
|
this.fieldAnnotations = fieldAnnotations.toArray(this.fieldAnnotations);
|
||||||
|
Arrays.sort(this.fieldAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methodAnnotations == null || methodAnnotations.size() == 0) {
|
||||||
|
this.methodAnnotations = null;
|
||||||
|
} else {
|
||||||
|
this.methodAnnotations = new MethodAnnotation[methodAnnotations.size()];
|
||||||
|
this.methodAnnotations = methodAnnotations.toArray(this.methodAnnotations);
|
||||||
|
Arrays.sort(this.methodAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameterAnnotations == null || parameterAnnotations.size() == 0) {
|
||||||
|
this.parameterAnnotations = null;
|
||||||
|
} else {
|
||||||
|
this.parameterAnnotations = new ParameterAnnotation[parameterAnnotations.size()];
|
||||||
|
this.parameterAnnotations = parameterAnnotations.toArray(this.parameterAnnotations);
|
||||||
|
Arrays.sort(this.parameterAnnotations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,55 +128,8 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
List<FieldAnnotation> fieldAnnotations,
|
List<FieldAnnotation> fieldAnnotations,
|
||||||
List<MethodAnnotation> methodAnnotations,
|
List<MethodAnnotation> methodAnnotations,
|
||||||
List<ParameterAnnotation> parameterAnnotations) {
|
List<ParameterAnnotation> parameterAnnotations) {
|
||||||
FieldIdItem[] fieldAnnotationFields = null;
|
|
||||||
AnnotationSetItem[] fieldAnnotationsArray = null;
|
|
||||||
MethodIdItem[] methodAnnotationMethods = null;
|
|
||||||
AnnotationSetItem[] methodAnnotationsArray = null;
|
|
||||||
MethodIdItem[] parameterAnnotationMethods = null;
|
|
||||||
AnnotationSetRefList[] parameterAnnotationsArray = null;
|
|
||||||
|
|
||||||
if (fieldAnnotations != null && fieldAnnotations.size() > 0) {
|
|
||||||
fieldAnnotationFields = new FieldIdItem[fieldAnnotations.size()];
|
|
||||||
fieldAnnotationsArray = new AnnotationSetItem[fieldAnnotations.size()];
|
|
||||||
|
|
||||||
Collections.sort(fieldAnnotations);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
|
|
||||||
fieldAnnotationFields[index] = fieldAnnotation.field;
|
|
||||||
fieldAnnotationsArray[index++] = fieldAnnotation.annotationSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodAnnotations != null && methodAnnotations.size() > 0) {
|
|
||||||
methodAnnotationMethods = new MethodIdItem[methodAnnotations.size()];
|
|
||||||
methodAnnotationsArray = new AnnotationSetItem[methodAnnotations.size()];
|
|
||||||
|
|
||||||
Collections.sort(methodAnnotations);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (MethodAnnotation methodAnnotation: methodAnnotations) {
|
|
||||||
methodAnnotationMethods[index] = methodAnnotation.method;
|
|
||||||
methodAnnotationsArray[index++] = methodAnnotation.annotationSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameterAnnotations != null && parameterAnnotations.size() > 0) {
|
|
||||||
parameterAnnotationMethods = new MethodIdItem[parameterAnnotations.size()];
|
|
||||||
parameterAnnotationsArray = new AnnotationSetRefList[parameterAnnotations.size()];
|
|
||||||
|
|
||||||
Collections.sort(parameterAnnotations);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
|
|
||||||
parameterAnnotationMethods[index] = parameterAnnotation.method;
|
|
||||||
parameterAnnotationsArray[index++] = parameterAnnotation.annotationSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations,
|
AnnotationDirectoryItem annotationDirectoryItem = new AnnotationDirectoryItem(dexFile, classAnnotations,
|
||||||
fieldAnnotationFields, fieldAnnotationsArray, methodAnnotationMethods, methodAnnotationsArray,
|
fieldAnnotations, methodAnnotations, parameterAnnotations);
|
||||||
parameterAnnotationMethods, parameterAnnotationsArray);
|
|
||||||
return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem);
|
return dexFile.AnnotationDirectoriesSection.intern(annotationDirectoryItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,45 +137,67 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
protected void readItem(Input in, ReadContext readContext) {
|
protected void readItem(Input in, ReadContext readContext) {
|
||||||
classAnnotations = (AnnotationSetItem)readContext.getOptionalOffsettedItemByOffset(
|
classAnnotations = (AnnotationSetItem)readContext.getOptionalOffsettedItemByOffset(
|
||||||
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
||||||
fieldAnnotationFields = new FieldIdItem[in.readInt()];
|
|
||||||
fieldAnnotations = new AnnotationSetItem[fieldAnnotationFields.length];
|
|
||||||
|
|
||||||
methodAnnotationMethods = new MethodIdItem[in.readInt()];
|
int fieldAnnotationCount = in.readInt();
|
||||||
methodAnnotations = new AnnotationSetItem[methodAnnotationMethods.length];
|
if (fieldAnnotationCount > 0) {
|
||||||
|
fieldAnnotations = new FieldAnnotation[fieldAnnotationCount];
|
||||||
|
} else {
|
||||||
|
fieldAnnotations = null;
|
||||||
|
}
|
||||||
|
|
||||||
parameterAnnotationMethods = new MethodIdItem[in.readInt()];
|
int methodAnnotationCount = in.readInt();
|
||||||
parameterAnnotations = new AnnotationSetRefList[parameterAnnotationMethods.length];
|
if (methodAnnotationCount > 0) {
|
||||||
|
methodAnnotations = new MethodAnnotation[methodAnnotationCount];
|
||||||
|
} else {
|
||||||
|
methodAnnotations = null;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
int parameterAnnotationCount = in.readInt();
|
||||||
try {
|
if (parameterAnnotationCount > 0) {
|
||||||
fieldAnnotationFields[i] = dexFile.FieldIdsSection.getItemByIndex(in.readInt());
|
parameterAnnotations = new ParameterAnnotation[parameterAnnotationCount];
|
||||||
fieldAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
|
} else {
|
||||||
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
parameterAnnotations = null;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
throw ExceptionWithContext.withContext(ex,
|
|
||||||
"Error occured while reading FieldAnnotation at index " + i);
|
if (fieldAnnotations != null) {
|
||||||
|
for (int i=0; i<fieldAnnotations.length; i++) {
|
||||||
|
try {
|
||||||
|
FieldIdItem fieldIdItem = dexFile.FieldIdsSection.getItemByIndex(in.readInt());
|
||||||
|
AnnotationSetItem fieldAnnotationSet = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
|
||||||
|
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
||||||
|
fieldAnnotations[i] = new FieldAnnotation(fieldIdItem, fieldAnnotationSet);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw ExceptionWithContext.withContext(ex,
|
||||||
|
"Error occured while reading FieldAnnotation at index " + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<methodAnnotations.length; i++) {
|
if (methodAnnotations != null) {
|
||||||
try {
|
for (int i=0; i<methodAnnotations.length; i++) {
|
||||||
methodAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
|
try {
|
||||||
methodAnnotations[i] = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
|
MethodIdItem methodIdItem = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
|
||||||
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
AnnotationSetItem methodAnnotationSet = (AnnotationSetItem)readContext.getOffsettedItemByOffset(
|
||||||
} catch (Exception ex) {
|
ItemType.TYPE_ANNOTATION_SET_ITEM, in.readInt());
|
||||||
throw ExceptionWithContext.withContext(ex,
|
methodAnnotations[i] = new MethodAnnotation(methodIdItem, methodAnnotationSet);
|
||||||
"Error occured while reading MethodAnnotation at index " + i);
|
} catch (Exception ex) {
|
||||||
|
throw ExceptionWithContext.withContext(ex,
|
||||||
|
"Error occured while reading MethodAnnotation at index " + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
if (parameterAnnotations != null) {
|
||||||
try {
|
for (int i=0; i<parameterAnnotations.length; i++) {
|
||||||
parameterAnnotationMethods[i] = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
|
try {
|
||||||
parameterAnnotations[i] = (AnnotationSetRefList)readContext.getOffsettedItemByOffset(
|
MethodIdItem methodIdItem = dexFile.MethodIdsSection.getItemByIndex(in.readInt());
|
||||||
ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt());
|
AnnotationSetRefList paramaterAnnotationSet = (AnnotationSetRefList)readContext.getOffsettedItemByOffset(
|
||||||
} catch (Exception ex) {
|
ItemType.TYPE_ANNOTATION_SET_REF_LIST, in.readInt());
|
||||||
throw ExceptionWithContext.withContext(ex,
|
parameterAnnotations[i] = new ParameterAnnotation(methodIdItem, paramaterAnnotationSet);
|
||||||
"Error occured while reading ParameterAnnotation at index " + i);
|
} catch (Exception ex) {
|
||||||
|
throw ExceptionWithContext.withContext(ex,
|
||||||
|
"Error occured while reading ParameterAnnotation at index " + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,35 +235,38 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
int index;
|
int index;
|
||||||
if (fieldAnnotations != null) {
|
if (fieldAnnotations != null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
|
||||||
out.annotate(0, "[" + index++ + "] field_annotation");
|
out.annotate(0, "[" + index++ + "] field_annotation");
|
||||||
|
|
||||||
out.indent();
|
out.indent();
|
||||||
out.annotate(4, "field: " + fieldAnnotationFields[i].getFieldName().getStringValue() + ":" +
|
out.annotate(4, "field: " + fieldAnnotation.field.getFieldName().getStringValue() + ":" +
|
||||||
fieldAnnotationFields[i].getFieldType().getTypeDescriptor());
|
fieldAnnotation.field.getFieldType().getTypeDescriptor());
|
||||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(fieldAnnotations[i].getOffset()));
|
out.annotate(4, "annotations_off: 0x" +
|
||||||
|
Integer.toHexString(fieldAnnotation.annotationSet.getOffset()));
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodAnnotations != null) {
|
if (methodAnnotations != null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int i=0; i<methodAnnotations.length; i++) {
|
for (MethodAnnotation methodAnnotation: methodAnnotations) {
|
||||||
out.annotate(0, "[" + index++ + "] method_annotation");
|
out.annotate(0, "[" + index++ + "] method_annotation");
|
||||||
out.indent();
|
out.indent();
|
||||||
out.annotate(4, "method: " + methodAnnotationMethods[i].getMethodString());
|
out.annotate(4, "method: " + methodAnnotation.method.getMethodString());
|
||||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(methodAnnotations[i].getOffset()));
|
out.annotate(4, "annotations_off: 0x" +
|
||||||
|
Integer.toHexString(methodAnnotation.annotationSet.getOffset()));
|
||||||
out.deindent();
|
out.deindent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameterAnnotations != null) {
|
if (parameterAnnotations != null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
|
||||||
out.annotate(0, "[" + index++ + "] parameter_annotation");
|
out.annotate(0, "[" + index++ + "] parameter_annotation");
|
||||||
out.indent();
|
out.indent();
|
||||||
out.annotate(4, "method: " + parameterAnnotationMethods[i].getMethodString());
|
out.annotate(4, "method: " + parameterAnnotation.method.getMethodString());
|
||||||
out.annotate(4, "annotations_off: 0x" + Integer.toHexString(parameterAnnotations[i].getOffset()));
|
out.annotate(4, "annotations_off: 0x" +
|
||||||
|
Integer.toHexString(parameterAnnotation.annotationSet.getOffset()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,23 +277,23 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
|
out.writeInt(parameterAnnotations==null?0:parameterAnnotations.length);
|
||||||
|
|
||||||
if (fieldAnnotations != null) {
|
if (fieldAnnotations != null) {
|
||||||
for (int i=0; i<fieldAnnotations.length; i++) {
|
for (FieldAnnotation fieldAnnotation: fieldAnnotations) {
|
||||||
out.writeInt(fieldAnnotationFields[i].getIndex());
|
out.writeInt(fieldAnnotation.field.getIndex());
|
||||||
out.writeInt(fieldAnnotations[i].getOffset());
|
out.writeInt(fieldAnnotation.annotationSet.getOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodAnnotations != null) {
|
if (methodAnnotations != null) {
|
||||||
for (int i=0; i<methodAnnotations.length; i++) {
|
for (MethodAnnotation methodAnnotation: methodAnnotations) {
|
||||||
out.writeInt(methodAnnotationMethods[i].getIndex());
|
out.writeInt(methodAnnotation.method.getIndex());
|
||||||
out.writeInt(methodAnnotations[i].getOffset());
|
out.writeInt(methodAnnotation.annotationSet.getOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameterAnnotations != null) {
|
if (parameterAnnotations != null) {
|
||||||
for (int i=0; i<parameterAnnotations.length; i++) {
|
for (ParameterAnnotation parameterAnnotation: parameterAnnotations) {
|
||||||
out.writeInt(parameterAnnotationMethods[i].getIndex());
|
out.writeInt(parameterAnnotation.method.getIndex());
|
||||||
out.writeInt(parameterAnnotations[i].getOffset());
|
out.writeInt(parameterAnnotation.annotationSet.getOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,8 +313,11 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public int compareTo(AnnotationDirectoryItem o) {
|
public int compareTo(AnnotationDirectoryItem o) {
|
||||||
|
Preconditions.checkNotNull(o);
|
||||||
if (!isInternable()) {
|
if (!isInternable()) {
|
||||||
if (!o.isInternable()) {
|
if (!o.isInternable()) {
|
||||||
|
Preconditions.checkState(parent != null && o.parent != null,
|
||||||
|
"Must call setParent before comparing AnnotationDirectoryItem instances");
|
||||||
return parent.compareTo(o.parent);
|
return parent.compareTo(o.parent);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -335,91 +331,78 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The annotations associated with the class
|
* @return An <code>AnnotationSetItem</code> containing the annotations associated with this class, or null
|
||||||
|
* if there are no class annotations
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public AnnotationSetItem getClassAnnotations() {
|
public AnnotationSetItem getClassAnnotations() {
|
||||||
return classAnnotations;
|
return classAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates over the field annotations, calling delegate.processFieldAnnotations for each
|
* Get a list of the field annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
* @param delegate the delegate to call
|
* @return A list of FieldAnnotation objects, or null if there are no field annotations
|
||||||
*/
|
*/
|
||||||
public void iterateFieldAnnotations(FieldAnnotationIteratorDelegate delegate) {
|
@Nonnull
|
||||||
for (int i=0; i<fieldAnnotationFields.length; i++) {
|
public List<FieldAnnotation> getFieldAnnotations() {
|
||||||
try {
|
if (fieldAnnotations == null) {
|
||||||
delegate.processFieldAnnotations(fieldAnnotationFields[i], fieldAnnotations[i]);
|
return Collections.emptyList();
|
||||||
} catch (Exception ex) {
|
|
||||||
throw addExceptionContext(ExceptionWithContext.withContext(ex,
|
|
||||||
"Error occured while processing field annotations for field: " +
|
|
||||||
fieldAnnotationFields[i].getFieldString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return ReadOnlyArrayList.of(fieldAnnotations);
|
||||||
|
|
||||||
public static interface FieldAnnotationIteratorDelegate {
|
|
||||||
void processFieldAnnotations(FieldIdItem field, AnnotationSetItem fieldAnnotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of field annotations in this <code>AnnotationDirectoryItem</code>
|
* Get a list of the method annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
|
* @return A list of MethodAnnotation objects, or null if there are no method annotations
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public List<MethodAnnotation> getMethodAnnotations() {
|
||||||
|
if (methodAnnotations == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return ReadOnlyArrayList.of(methodAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of the parameter annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
|
* @return A list of ParameterAnnotation objects, or null if there are no parameter annotations
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public List<ParameterAnnotation> getParameterAnnotations() {
|
||||||
|
if (parameterAnnotations == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return ReadOnlyArrayList.of(parameterAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of field annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
*/
|
*/
|
||||||
public int getFieldAnnotationCount() {
|
public int getFieldAnnotationCount() {
|
||||||
return fieldAnnotationFields.length;
|
if (fieldAnnotations == null) {
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over the method annotations, calling delegate.processMethodAnnotations for each
|
|
||||||
* @param delegate the delegate to call
|
|
||||||
*/
|
|
||||||
public void iterateMethodAnnotations(MethodAnnotationIteratorDelegate delegate) {
|
|
||||||
for (int i=0; i<methodAnnotationMethods.length; i++) {
|
|
||||||
try {
|
|
||||||
delegate.processMethodAnnotations(methodAnnotationMethods[i], methodAnnotations[i]);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw addExceptionContext(ExceptionWithContext.withContext(ex,
|
|
||||||
"Error occured while processing method annotations for method: " +
|
|
||||||
methodAnnotationMethods[i].getMethodString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return fieldAnnotations.length;
|
||||||
|
|
||||||
public static interface MethodAnnotationIteratorDelegate {
|
|
||||||
void processMethodAnnotations(MethodIdItem method, AnnotationSetItem methodAnnotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of method annotations in this <code>AnnotationDirectoryItem</code>
|
* @return The number of method annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
*/
|
*/
|
||||||
public int getMethodAnnotationCount() {
|
public int getMethodAnnotationCount() {
|
||||||
return methodAnnotationMethods.length;
|
if (methodAnnotations == null) {
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over the parameter annotations, calling delegate.processParameterAnnotations for each
|
|
||||||
* @param delegate the delegate to call
|
|
||||||
*/
|
|
||||||
public void iterateParameterAnnotations(ParameterAnnotationIteratorDelegate delegate) {
|
|
||||||
for (int i=0; i<parameterAnnotationMethods.length; i++) {
|
|
||||||
try {
|
|
||||||
delegate.processParameterAnnotations(parameterAnnotationMethods[i], parameterAnnotations[i]);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw addExceptionContext(ExceptionWithContext.withContext(ex,
|
|
||||||
"Error occured while processing parameter annotations for method: " +
|
|
||||||
parameterAnnotationMethods[i].getMethodString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return methodAnnotations.length;
|
||||||
|
|
||||||
public static interface ParameterAnnotationIteratorDelegate {
|
|
||||||
void processParameterAnnotations(MethodIdItem method, AnnotationSetRefList parameterAnnotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of parameter annotations in this <code>AnnotationDirectoryItem</code>
|
* @return The number of parameter annotations in this <code>AnnotationDirectoryItem</code>
|
||||||
*/
|
*/
|
||||||
public int getParameterAnnotationCount() {
|
public int getParameterAnnotationCount() {
|
||||||
return parameterAnnotationMethods.length;
|
if (parameterAnnotations == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return parameterAnnotations.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -435,19 +418,23 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated with.
|
* Sets the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated with.
|
||||||
* This is only applicable if this AnnotationDirectoryItem contains only class annotations, and no field, method
|
*
|
||||||
* or parameter annotations.
|
|
||||||
* @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated
|
* @param classDefItem the <code>ClassDefItem</code> that this <code>AnnotationDirectoryItem</code> is associated
|
||||||
* with
|
* with.
|
||||||
*/
|
*/
|
||||||
protected void setParent(ClassDefItem classDefItem) {
|
protected void setParent(ClassDefItem classDefItem) {
|
||||||
|
// If this AnnotationDirectoryItem is internable, then setParent may be called multiple times, because it is
|
||||||
|
// reused for multiple classes. In this case, the parent field isn't used, so it doesn't matter if we overwrite
|
||||||
|
// it.
|
||||||
|
// If, on the other hand, it is not internable, we want to make sure that only a single parent is set. parent
|
||||||
|
// should either be null, or be equal to the new parent
|
||||||
|
Preconditions.checkState(this.isInternable() || (parent == null || parent.equals(classDefItem)));
|
||||||
this.parent = classDefItem;
|
this.parent = classDefItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
//an instance is only internable if it has only class annotations, but
|
// An instance is internable only if it has only class annotations, but no other type of annotation
|
||||||
//no other type of annotation
|
|
||||||
if (!isInternable()) {
|
if (!isInternable()) {
|
||||||
return super.hashCode();
|
return super.hashCode();
|
||||||
}
|
}
|
||||||
@ -479,6 +466,19 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
public int compareTo(FieldAnnotation other) {
|
public int compareTo(FieldAnnotation other) {
|
||||||
return field.compareTo(other.field);
|
return field.compareTo(other.field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
return compareTo((FieldAnnotation)o) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return field.hashCode() + 31 * annotationSet.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MethodAnnotation implements Comparable<MethodAnnotation> {
|
public static class MethodAnnotation implements Comparable<MethodAnnotation> {
|
||||||
@ -493,6 +493,19 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
public int compareTo(MethodAnnotation other) {
|
public int compareTo(MethodAnnotation other) {
|
||||||
return method.compareTo(other.method);
|
return method.compareTo(other.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
return compareTo((MethodAnnotation)o) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return method.hashCode() + 31 * annotationSet.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ParameterAnnotation implements Comparable<ParameterAnnotation> {
|
public static class ParameterAnnotation implements Comparable<ParameterAnnotation> {
|
||||||
@ -507,5 +520,18 @@ public class AnnotationDirectoryItem extends Item<AnnotationDirectoryItem> {
|
|||||||
public int compareTo(ParameterAnnotation other) {
|
public int compareTo(ParameterAnnotation other) {
|
||||||
return method.compareTo(other.method);
|
return method.compareTo(other.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
return compareTo((ParameterAnnotation)o) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return method.hashCode() + 31 * annotationSet.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,4 +45,8 @@ public class ReadOnlyArrayList<T> extends AbstractList<T> implements RandomAcces
|
|||||||
public T get(int i) {
|
public T get(int i) {
|
||||||
return arr[i];
|
return arr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> ReadOnlyArrayList<T> of(T... items) {
|
||||||
|
return new ReadOnlyArrayList<T>(items);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user