Major cleanup of the interface and library in general

This commit is contained in:
Ben Gruver 2012-11-17 17:51:36 -08:00
parent bea9627ed7
commit 22c3185bb7
170 changed files with 2987 additions and 1974 deletions

View File

@ -41,7 +41,6 @@ import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class ClassDefinition {
@Nonnull public final ClassDef classDef;
@ -77,7 +76,7 @@ public class ClassDefinition {
case SPUT_WIDE: {
Instruction21c ins = (Instruction21c)instruction;
FieldReference fieldRef = (FieldReference)ins.getReference();
if (fieldRef.getContainingClass().equals((classDef.getType()))) {
if (fieldRef.getDefiningClass().equals((classDef.getType()))) {
fieldsSetInStaticConstructor.add(ReferenceUtil.getShortFieldDescriptor(fieldRef));
}
break;
@ -135,7 +134,7 @@ public class ClassDefinition {
}
private void writeInterfaces(IndentingWriter writer) throws IOException {
List<String> interfaces = classDef.getInterfaces();
Collection<String> interfaces = classDef.getInterfaces();
if (interfaces.size() != 0) {
writer.write('\n');
writer.write("# interfaces\n");

View File

@ -31,37 +31,44 @@
package org.jf.dexlib2.base;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.util.CollectionUtils;
import javax.annotation.Nonnull;
import java.util.Comparator;
public abstract class BaseAnnotation implements Annotation {
@Override
public int hashCode() {
return hashCode(this);
int hashCode = getVisibility();
hashCode = hashCode*31 + getType().hashCode();
return hashCode*31 + getElements().hashCode();
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof Annotation) {
return equals(this, (Annotation)o);
if (o instanceof Annotation) {
Annotation other = (Annotation)o;
return (getVisibility() == other.getVisibility()) &&
getType().equals(other.getType()) &&
getElements().equals(other.getElements());
}
return false;
}
public static int hashCode(@Nonnull Annotation annotation) {
int hashCode = annotation.getVisibility();
hashCode = hashCode*31 + annotation.getType().hashCode();
for (AnnotationElement element: annotation.getElements()) {
hashCode = hashCode*31 + element.hashCode();
}
return hashCode;
@Override
public int compareTo(Annotation o) {
int res = Ints.compare(getVisibility(), o.getVisibility());
if (res != 0) return res;
res = getType().compareTo(o.getType());
if (res != 0) return res;
return CollectionUtils.compareAsSet(getElements(), o.getElements());
}
public static boolean equals(@Nonnull Annotation annotation1, @Nonnull Annotation annotation2) {
return (annotation1.getVisibility() == annotation2.getVisibility()) &&
annotation1.getType().equals(annotation2.getType()) &&
annotation1.getElements().equals(annotation2.getElements());
public static final Comparator<Annotation> COMPARE_BY_TYPE = new Comparator<Annotation>() {
@Override
public int compare(Annotation annotation1, Annotation annotation2) {
return annotation1.getType().compareTo(annotation2.getType());
}
};
}

View File

@ -33,6 +33,9 @@ package org.jf.dexlib2.base;
import org.jf.dexlib2.iface.AnnotationElement;
import javax.annotation.Nonnull;
import java.util.Comparator;
public abstract class BaseAnnotationElement implements AnnotationElement {
@Override
public int hashCode() {
@ -49,4 +52,18 @@ public abstract class BaseAnnotationElement implements AnnotationElement {
}
return false;
}
@Override
public int compareTo(AnnotationElement o) {
int res = getName().compareTo(o.getName());
if (res != 0) return res;
return getValue().compareTo(o.getValue());
}
public static final Comparator<AnnotationElement> COMPARE_BY_NAME = new Comparator<AnnotationElement>() {
@Override
public int compare(@Nonnull AnnotationElement element1, @Nonnull AnnotationElement element2) {
return element1.getName().compareTo(element2.getName());
}
};
}

View File

@ -29,35 +29,45 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.immutable.sorted.value;
package org.jf.dexlib2.base;
import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.base.value.BaseArrayEncodedValue;
import org.jf.dexlib2.iface.sorted.value.SortedArrayEncodedValue;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import com.google.common.base.Objects;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.iface.ExceptionHandler;
import javax.annotation.Nonnull;
import java.util.Collection;
import javax.annotation.Nullable;
public class SortedImmutableArrayEncodedValue extends BaseArrayEncodedValue
implements SortedImmutableEncodedValue, SortedArrayEncodedValue {
@Nonnull public final ImmutableList<? extends SortedImmutableEncodedValue> value;
public SortedImmutableArrayEncodedValue(@Nonnull Collection<? extends EncodedValue> value) {
this.value = SortedImmutableEncodedValueFactory.immutableListOf(value);
public abstract class BaseExceptionHandler implements ExceptionHandler {
@Override
public int hashCode() {
String exceptionType = getExceptionType();
int hashCode = exceptionType==null?0:exceptionType.hashCode();
return hashCode*31 + getHandlerCodeAddress();
}
public SortedImmutableArrayEncodedValue(@Nonnull ImmutableList<SortedImmutableEncodedValue> value) {
this.value = value;
@Override
public boolean equals(@Nullable Object o) {
if (o instanceof ExceptionHandler) {
ExceptionHandler other = (ExceptionHandler)o;
return Objects.equal(getExceptionType(), other.getExceptionType()) &&
(getHandlerCodeAddress() == other.getHandlerCodeAddress());
}
return false;
}
public static SortedImmutableArrayEncodedValue of(@Nonnull ArrayEncodedValue arrayEncodedValue) {
if (arrayEncodedValue instanceof SortedImmutableArrayEncodedValue) {
return (SortedImmutableArrayEncodedValue)arrayEncodedValue;
@Override
public int compareTo(@Nonnull ExceptionHandler o) {
int res;
String exceptionType = getExceptionType();
if (exceptionType == null) {
if (o.getExceptionType() != null) {
return 1;
}
return new SortedImmutableArrayEncodedValue(arrayEncodedValue.getValue());
} else {
res = exceptionType.compareTo(o.getExceptionType());
if (res != 0) return res;
}
return Ints.compare(getHandlerCodeAddress(), o.getHandlerCodeAddress());
}
@Nonnull public ImmutableList<? extends SortedImmutableEncodedValue> getValue() { return value; }
}

View File

@ -31,8 +31,54 @@
package org.jf.dexlib2.base;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.base.reference.BaseTypeReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.MethodParameter;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.StringEncodedValue;
import javax.annotation.Nullable;
public abstract class BaseMethodParameter extends BaseTypeReference implements MethodParameter {
@Nullable
@Override
public String getSignature() {
Annotation signatureAnnotation = null;
for (Annotation annotation: getAnnotations()) {
if (annotation.getType().equals("Ldalvik/annotation/Signature;")) {
signatureAnnotation = annotation;
break;
}
}
if (signatureAnnotation == null) {
return null;
}
ArrayEncodedValue signatureValues = null;
for (AnnotationElement annotationElement: signatureAnnotation.getElements()) {
if (annotationElement.getName().equals("value")) {
EncodedValue encodedValue = annotationElement.getValue();
if (encodedValue.getValueType() != ValueType.ARRAY) {
return null;
}
signatureValues = (ArrayEncodedValue)encodedValue;
break;
}
}
if (signatureValues == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (EncodedValue signatureValue: signatureValues.getValue()) {
if (signatureValue.getValueType() != ValueType.STRING) {
return null;
}
sb.append(((StringEncodedValue)signatureValue).getValue());
}
return sb.toString();
}
}

View File

@ -34,30 +34,34 @@ package org.jf.dexlib2.base.reference;
import org.jf.dexlib2.iface.reference.FieldReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseFieldReference implements FieldReference {
@Override
public int hashCode() {
return hashCode(this);
int hashCode = getDefiningClass().hashCode();
hashCode = hashCode*31 + getName().hashCode();
return hashCode*31 + getType().hashCode();
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof FieldReference) {
return equals(this, (FieldReference)o);
public boolean equals(@Nullable Object o) {
if (o instanceof FieldReference) {
FieldReference other = (FieldReference)o;
return getDefiningClass().equals(other.getDefiningClass()) &&
getName().equals(other.getName()) &&
getType().equals(other.getType());
}
return false;
}
public static int hashCode(@Nonnull FieldReference fieldRef) {
int hashCode = fieldRef.getContainingClass().hashCode();
hashCode = hashCode*31 + fieldRef.getName().hashCode();
return hashCode*31 + fieldRef.getType().hashCode();
}
public static boolean equals(@Nonnull FieldReference fieldRef1, @Nonnull FieldReference fieldRef2) {
return fieldRef1.getContainingClass().equals(fieldRef2.getContainingClass()) &&
fieldRef1.getName().equals(fieldRef2.getName()) &&
fieldRef1.getType().equals(fieldRef2.getType());
@Override
public int compareTo(@Nonnull FieldReference o) {
int res = getDefiningClass().compareTo(o.getDefiningClass());
if (res != 0) return res;
res = getName().compareTo(o.getName());
if (res != 0) return res;
return getType().compareTo(o.getType());
}
}

View File

@ -32,38 +32,40 @@
package org.jf.dexlib2.base.reference;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.util.CollectionUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseMethodReference implements MethodReference {
@Override
public int hashCode() {
return hashCode(this);
int hashCode = getDefiningClass().hashCode();
hashCode = hashCode*31 + getName().hashCode();
hashCode = hashCode*31 + getReturnType().hashCode();
return hashCode*31 + getParameters().hashCode();
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (o != null && o instanceof MethodReference) {
return equals(this, (MethodReference)o);
MethodReference other = (MethodReference)o;
return getDefiningClass().equals(other.getDefiningClass()) &&
getName().equals(other.getName()) &&
getReturnType().equals(other.getReturnType()) &&
getParameters().equals(other.getParameters());
}
return false;
}
public static int hashCode(@Nonnull MethodReference methodRef) {
int hashCode = methodRef.getContainingClass().hashCode();
hashCode = hashCode*31 + methodRef.getName().hashCode();
hashCode = hashCode*31 + methodRef.getReturnType().hashCode();
for (TypeReference param: methodRef.getParameters()) {
hashCode = hashCode*31 + param.hashCode();
}
return hashCode;
}
public static boolean equals(@Nonnull MethodReference methodRef1, @Nonnull MethodReference methodRef2) {
return methodRef1.getContainingClass().equals(methodRef2.getContainingClass()) &&
methodRef1.getName().equals(methodRef2.getName()) &&
methodRef1.getReturnType().equals(methodRef2.getReturnType()) &&
methodRef1.getParameters().equals(methodRef2.getParameters());
@Override
public int compareTo(@Nonnull MethodReference o) {
int res = getDefiningClass().compareTo(o.getDefiningClass());
if (res != 0) return res;
res = getName().compareTo(o.getName());
if (res != 0) return res;
res = getReturnType().compareTo(o.getReturnType());
if (res != 0) return res;
return CollectionUtils.compareAsList(getParameters(), o.getParameters());
}
}

View File

@ -34,27 +34,25 @@ package org.jf.dexlib2.base.reference;
import org.jf.dexlib2.iface.reference.StringReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseStringReference implements StringReference {
@Override
public int hashCode() {
return hashCode(this);
return getString().hashCode();
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (o != null && o instanceof StringReference) {
return equals(this, (StringReference)o);
return getString().equals(((StringReference)o).getString());
}
return false;
}
public static int hashCode(@Nonnull StringReference stringRef) {
return stringRef.getString().hashCode();
}
public static boolean equals(@Nonnull StringReference stringRef1, @Nonnull StringReference stringRef2) {
return stringRef1.getString().equals(stringRef2.getString());
@Override
public int compareTo(@Nonnull CharSequence o) {
return getString().compareTo(o.toString());
}
@Override public int length() { return getString().length(); }

View File

@ -38,23 +38,20 @@ import javax.annotation.Nonnull;
public abstract class BaseTypeReference implements TypeReference {
@Override
public int hashCode() {
return hashCode(this);
return getType().hashCode();
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof TypeReference) {
return equals(this, (TypeReference)o);
return getType().equals(((TypeReference)o).getType());
}
return false;
}
public static int hashCode(@Nonnull TypeReference typeRef) {
return typeRef.getType().hashCode();
}
public static boolean equals(@Nonnull TypeReference typeRef1, @Nonnull TypeReference typeRef2) {
return typeRef1.getType().equals(typeRef2.getType());
@Override
public int compareTo(@Nonnull CharSequence o) {
return getType().compareTo(o.toString());
}
@Override public int length() { return getType().length(); }

View File

@ -31,8 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.util.CollectionUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseAnnotationEncodedValue implements AnnotationEncodedValue {
@Override
@ -42,13 +48,26 @@ public abstract class BaseAnnotationEncodedValue implements AnnotationEncodedVal
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof AnnotationEncodedValue) {
return getType().equals(((AnnotationEncodedValue) o).getType()) &&
getElements().equals(((AnnotationEncodedValue) o).getElements());
public boolean equals(@Nullable Object o) {
if (o instanceof AnnotationEncodedValue) {
AnnotationEncodedValue other = (AnnotationEncodedValue)o;
return getType().equals(other.getType()) &&
getElements().equals(other.getElements());
}
return false;
}
public int getValueType() { return ValueType.ANNOTATION; }
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
AnnotationEncodedValue other = (AnnotationEncodedValue)o;
res = getType().compareTo(other.getType());
if (res != 0) return res;
return CollectionUtils.compareAsSet(getElements(), other.getElements());
}
public int getValueType() {
return ValueType.ANNOTATION;
}
}

View File

@ -31,8 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.util.CollectionUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseArrayEncodedValue implements ArrayEncodedValue {
@Override
@ -41,12 +47,18 @@ public abstract class BaseArrayEncodedValue implements ArrayEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof ArrayEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof ArrayEncodedValue) {
return getValue().equals(((ArrayEncodedValue)o).getValue());
}
return false;
}
@Override public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return CollectionUtils.compareAsList(getValue(), ((ArrayEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.ARRAY; }
}

View File

@ -31,8 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Booleans;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.BooleanEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseBooleanEncodedValue implements BooleanEncodedValue {
@Override
@ -41,12 +47,19 @@ public abstract class BaseBooleanEncodedValue implements BooleanEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof BooleanEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof BooleanEncodedValue) {
return getValue() == ((BooleanEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Booleans.compare(getValue(), ((BooleanEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.BOOLEAN; }
}

View File

@ -31,8 +31,13 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.ByteEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseByteEncodedValue implements ByteEncodedValue {
@Override
@ -41,12 +46,19 @@ public abstract class BaseByteEncodedValue implements ByteEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof ByteEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof ByteEncodedValue) {
return getValue() == ((ByteEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Ints.compare(getValue(), ((ByteEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.BYTE; }
}

View File

@ -31,8 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Chars;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.CharEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseCharEncodedValue implements CharEncodedValue {
@Override
@ -41,12 +47,19 @@ public abstract class BaseCharEncodedValue implements CharEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof CharEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof CharEncodedValue) {
return getValue() == ((CharEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Chars.compare(getValue(), ((CharEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.CHAR; }
}

View File

@ -31,24 +31,36 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.DoubleEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseDoubleEncodedValue implements DoubleEncodedValue {
@Override
public int hashCode() {
long value = Double.doubleToRawLongBits(getValue());
int hashCode = (int)value;
return hashCode*31 + (int)(value>>>32);
long v = Double.doubleToRawLongBits(getValue());
return (int)(v^(v>>>32));
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof DoubleEncodedValue) {
return getValue() == ((DoubleEncodedValue) o).getValue();
public boolean equals(@Nullable Object o) {
if (o instanceof DoubleEncodedValue) {
return Double.doubleToRawLongBits(getValue()) ==
Double.doubleToRawLongBits(((DoubleEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Double.compare(getValue(), ((DoubleEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.DOUBLE; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.EnumEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseEnumEncodedValue implements EnumEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseEnumEncodedValue implements EnumEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof EnumEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof EnumEncodedValue) {
return getValue().equals(((EnumEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return getValue().compareTo(((EnumEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.ENUM; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.FieldEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseFieldEncodedValue implements FieldEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseFieldEncodedValue implements FieldEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof FieldEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof FieldEncodedValue) {
return getValue().equals(((FieldEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return getValue().compareTo(((FieldEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.FIELD; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.FloatEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseFloatEncodedValue implements FloatEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseFloatEncodedValue implements FloatEncodedValue {
}
@Override
public boolean equals(Object o) {
public boolean equals(@Nullable Object o) {
if (o != null && o instanceof FloatEncodedValue) {
return getValue() == ((FloatEncodedValue) o).getValue();
return Float.floatToRawIntBits(getValue()) == Float.floatToRawIntBits(((FloatEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Float.compare(getValue(), ((FloatEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.FLOAT; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.IntEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseIntEncodedValue implements IntEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseIntEncodedValue implements IntEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof IntEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof IntEncodedValue) {
return getValue() == ((IntEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Ints.compare(getValue(), ((IntEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.INT; }
}

View File

@ -31,9 +31,15 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.LongEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseLongEncodedValue implements LongEncodedValue {
@Override
public int hashCode() {
@ -43,12 +49,19 @@ public abstract class BaseLongEncodedValue implements LongEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof LongEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof LongEncodedValue) {
return getValue() == ((LongEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Longs.compare(getValue(), ((LongEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.LONG; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.MethodEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseMethodEncodedValue implements MethodEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseMethodEncodedValue implements MethodEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof MethodEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof MethodEncodedValue) {
return getValue().equals(((MethodEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return getValue().compareTo(((MethodEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.METHOD; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.NullEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseNullEncodedValue implements NullEncodedValue {
@Override
public int hashCode() {
@ -41,8 +46,13 @@ public abstract class BaseNullEncodedValue implements NullEncodedValue {
}
@Override
public boolean equals(Object o) {
return o != null && o instanceof NullEncodedValue;
public boolean equals(@Nullable Object o) {
return o instanceof NullEncodedValue;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
return Ints.compare(getValueType(), o.getValueType());
}
public int getValueType() { return ValueType.NULL; }

View File

@ -31,9 +31,15 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Shorts;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.ShortEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseShortEncodedValue implements ShortEncodedValue {
@Override
public int hashCode() {
@ -41,12 +47,19 @@ public abstract class BaseShortEncodedValue implements ShortEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof ShortEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof ShortEncodedValue) {
return getValue() == ((ShortEncodedValue)o).getValue();
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return Shorts.compare(getValue(), ((ShortEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.SHORT; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.StringEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseStringEncodedValue implements StringEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseStringEncodedValue implements StringEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof StringEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof StringEncodedValue) {
return getValue().equals(((StringEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return getValue().compareTo(((StringEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.STRING; }
}

View File

@ -31,9 +31,14 @@
package org.jf.dexlib2.base.value;
import com.google.common.primitives.Ints;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.iface.value.TypeEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class BaseTypeEncodedValue implements TypeEncodedValue {
@Override
public int hashCode() {
@ -41,12 +46,19 @@ public abstract class BaseTypeEncodedValue implements TypeEncodedValue {
}
@Override
public boolean equals(Object o) {
if (o != null && o instanceof TypeEncodedValue) {
public boolean equals(@Nullable Object o) {
if (o instanceof TypeEncodedValue) {
return getValue().equals(((TypeEncodedValue)o).getValue());
}
return false;
}
@Override
public int compareTo(@Nonnull EncodedValue o) {
int res = Ints.compare(getValueType(), o.getValueType());
if (res != 0) return res;
return getValue().compareTo(((TypeEncodedValue)o).getValue());
}
public int getValueType() { return ValueType.TYPE; }
}

View File

@ -32,10 +32,10 @@
package org.jf.dexlib2.dexbacked;
import org.jf.dexlib2.base.BaseAnnotation;
import org.jf.dexlib2.dexbacked.util.VariableSizeCollection;
import org.jf.dexlib2.dexbacked.util.VariableSizeSet;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Set;
public class DexBackedAnnotation extends BaseAnnotation {
@Nonnull public final DexBuffer dexBuf;
@ -59,11 +59,11 @@ public class DexBackedAnnotation extends BaseAnnotation {
@Nonnull
@Override
public Collection<? extends DexBackedAnnotationElement> getElements() {
public Set<? extends DexBackedAnnotationElement> getElements() {
DexReader reader = dexBuf.readerAt(elementsOffset);
final int size = reader.readSmallUleb128();
return new VariableSizeCollection<DexBackedAnnotationElement>(dexBuf, reader.getOffset(), size) {
return new VariableSizeSet<DexBackedAnnotationElement>(dexBuf, reader.getOffset(), size) {
@Nonnull
@Override
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader reader, int index) {

View File

@ -31,12 +31,13 @@
package org.jf.dexlib2.dexbacked;
import org.jf.dexlib2.base.BaseExceptionHandler;
import org.jf.dexlib2.iface.ExceptionHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class DexBackedCatchAllExceptionHandler implements ExceptionHandler {
public class DexBackedCatchAllExceptionHandler extends BaseExceptionHandler implements ExceptionHandler {
private final int handlerCodeAddress;
public DexBackedCatchAllExceptionHandler(@Nonnull DexReader reader) {

View File

@ -31,17 +31,19 @@
package org.jf.dexlib2.dexbacked;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.reference.BaseTypeReference;
import org.jf.dexlib2.dexbacked.util.*;
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
import org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator;
import org.jf.dexlib2.dexbacked.util.VariableSizeIterator;
import org.jf.dexlib2.iface.ClassDef;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
@Nonnull public final DexBuffer dexBuf;
@ -92,11 +94,11 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
@Nonnull
@Override
public List<String> getInterfaces() {
public Set<String> getInterfaces() {
final int interfacesOffset = dexBuf.readSmallUint(classDefOffset + INTERFACES_OFFSET);
if (interfacesOffset > 0) {
final int size = dexBuf.readSmallUint(interfacesOffset);
return new FixedSizeList<String>() {
return new FixedSizeSet<String>() {
@Nonnull
@Override
public String readItem(int index) {
@ -106,18 +108,18 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
@Override public int size() { return size; }
};
}
return ImmutableList.of();
return ImmutableSet.of();
}
@Nonnull
@Override
public List<? extends DexBackedAnnotation> getAnnotations() {
public Set<? extends DexBackedAnnotation> getAnnotations() {
return getAnnotationsDirectory().getClassAnnotations();
}
@Nonnull
@Override
public Collection<? extends DexBackedField> getFields() {
public Set<? extends DexBackedField> getFields() {
int classDataOffset = getClassDataOffset();
if (getClassDataOffset() != 0) {
DexReader reader = dexBuf.readerAt(classDataOffset);
@ -133,7 +135,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
dexBuf.readSmallUint(classDefOffset + STATIC_INITIAL_VALUES_OFFSET);
final int fieldsStartOffset = reader.getOffset();
return new AbstractCollection<DexBackedField>() {
return new AbstractSet<DexBackedField>() {
@Nonnull
@Override
public Iterator<DexBackedField> iterator() {
@ -165,12 +167,12 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
};
}
}
return ImmutableList.of();
return ImmutableSet.of();
}
@Nonnull
@Override
public Collection<? extends DexBackedMethod> getMethods() {
public Set<? extends DexBackedMethod> getMethods() {
int classDataOffset = getClassDataOffset();
if (classDataOffset > 0) {
DexReader reader = dexBuf.readerAt(classDataOffset);
@ -185,7 +187,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int methodsStartOffset = reader.getOffset();
return new AbstractCollection<DexBackedMethod>() {
return new AbstractSet<DexBackedMethod>() {
@Nonnull
@Override
public Iterator<DexBackedMethod> iterator() {
@ -218,7 +220,7 @@ public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
};
}
}
return ImmutableList.of();
return ImmutableSet.of();
}
private int getClassDataOffset() {

View File

@ -31,11 +31,11 @@
package org.jf.dexlib2.dexbacked;
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
import org.jf.dexlib2.iface.DexFile;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;
public class DexBackedDexFile implements DexFile {
@Nonnull public final DexBuffer dexBuf;
@ -46,10 +46,10 @@ public class DexBackedDexFile implements DexFile {
@Nonnull
@Override
public List<? extends DexBackedClassDef> getClasses() {
public Set<? extends DexBackedClassDef> getClasses() {
final int classCount = dexBuf.getClassCount();
return new FixedSizeList<DexBackedClassDef>() {
return new FixedSizeSet<DexBackedClassDef>() {
@Nonnull
@Override
public DexBackedClassDef readItem(int index) {

View File

@ -31,11 +31,12 @@
package org.jf.dexlib2.dexbacked;
import org.jf.dexlib2.base.BaseExceptionHandler;
import org.jf.dexlib2.iface.ExceptionHandler;
import javax.annotation.Nonnull;
public class DexBackedExceptionHandler implements ExceptionHandler {
public class DexBackedExceptionHandler extends BaseExceptionHandler implements ExceptionHandler {
@Nonnull private final DexBuffer dexBuf;
private final int typeId;
private final int handlerCodeAddress;

View File

@ -40,7 +40,7 @@ import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
public class DexBackedField extends BaseFieldReference implements Field {
@Nonnull public final DexBuffer dexBuf;
@ -86,13 +86,13 @@ public class DexBackedField extends BaseFieldReference implements Field {
return dexBuf.getType(dexBuf.readUshort(getFieldIdItemOffset() + TYPE_OFFSET));
}
@Nonnull @Override public String getContainingClass() { return classDef.getType(); }
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
@Override public int getAccessFlags() { return accessFlags; }
@Nullable @Override public EncodedValue getInitialValue() { return initialValue; }
@Nonnull
@Override
public List<? extends DexBackedAnnotation> getAnnotations() {
public Set<? extends DexBackedAnnotation> getAnnotations() {
return AnnotationsDirectory.getAnnotations(dexBuf, annotationSetOffset);
}

View File

@ -32,6 +32,7 @@
package org.jf.dexlib2.dexbacked;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.BaseMethodParameter;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
@ -42,8 +43,8 @@ import org.jf.dexlib2.iface.MethodParameter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class DexBackedMethod extends BaseMethodReference implements Method {
@Nonnull public final DexBuffer dexBuf;
@ -101,7 +102,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
this.parameterAnnotationSetListOffset = paramaterAnnotationIterator.seekTo(methodIndex);
}
@Nonnull @Override public String getContainingClass() { return classDef.getType(); }
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
@Override public int getAccessFlags() { return accessFlags; }
@Nonnull
@ -118,7 +119,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
@Nonnull
@Override
public Collection<? extends MethodParameter> getParameters() {
public List<? extends MethodParameter> getParameters() {
if (getParametersOffset() > 0) {
DexBackedMethodImplementation methodImpl = getImplementation();
if (methodImpl != null) {
@ -134,7 +135,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
final int parametersOffset = getParametersOffset();
if (parametersOffset > 0) {
final int size = dexBuf.readSmallUint(parametersOffset);
final List<List<? extends DexBackedAnnotation>> parameterAnnotations =
final List<Set<? extends DexBackedAnnotation>> parameterAnnotations =
AnnotationsDirectory.getParameterAnnotations(dexBuf, parameterAnnotationSetListOffset);
return new FixedSizeList<MethodParameter>() {
@ -151,11 +152,11 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
@Nonnull
@Override
public List<? extends Annotation> getAnnotations() {
public Set<? extends Annotation> getAnnotations() {
if (index < parameterAnnotations.size()) {
return parameterAnnotations.get(index);
}
return ImmutableList.of();
return ImmutableSet.of();
}
@Nullable @Override public String getName() { return null; }
@ -173,7 +174,7 @@ public class DexBackedMethod extends BaseMethodReference implements Method {
@Nonnull
@Override
public List<? extends Annotation> getAnnotations() {
public Set<? extends Annotation> getAnnotations() {
return AnnotationsDirectory.getAnnotations(dexBuf, methodAnnotationSetOffset);
}

View File

@ -44,7 +44,6 @@ import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.util.AlignmentUtils;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@ -96,6 +95,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
@Nonnull
@Override
public List<? extends TryBlock> getTryBlocks() {
// TODO: provide utility to put try blocks into a "canonical", easy to use format, which more closely matches java's try blocks
final int triesSize = dexBuf.readUshort(codeOffset + TRIES_SIZE_OFFSET);
if (triesSize > 0) {
int instructionsSize = dexBuf.readSmallUint(codeOffset + INSTRUCTIONS_SIZE_OFFSET);
@ -132,7 +132,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
}
@Nonnull
public Collection<? extends MethodParameter> getParametersWithNames() {
public List<? extends MethodParameter> getParametersWithNames() {
return getDebugInfo().getParametersWithNames();
}
}

View File

@ -31,12 +31,12 @@
package org.jf.dexlib2.dexbacked;
import org.jf.dexlib2.dexbacked.util.VariableSizeCollection;
import org.jf.dexlib2.dexbacked.util.VariableSizeSet;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.dexlib2.iface.TryBlock;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Set;
public class DexBackedTryBlock implements TryBlock {
@Nonnull public final DexBuffer dexBuf;
@ -60,14 +60,14 @@ public class DexBackedTryBlock implements TryBlock {
@Nonnull
@Override
public Collection<? extends ExceptionHandler> getExceptionHandlers() {
public Set<? extends ExceptionHandler> getExceptionHandlers() {
DexReader reader =
dexBuf.readerAt(handlersStartOffset + dexBuf.readUshort(tryItemOffset + HANDLER_OFFSET_OFFSET));
final int encodedSize = reader.readSleb128();
if (encodedSize > 0) {
//no catch-all
return new VariableSizeCollection<ExceptionHandler>(dexBuf, reader.getOffset(), encodedSize) {
return new VariableSizeSet<ExceptionHandler>(dexBuf, reader.getOffset(), encodedSize) {
@Nonnull
@Override
protected DexBackedExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
@ -77,7 +77,7 @@ public class DexBackedTryBlock implements TryBlock {
} else {
//with catch-all
final int sizeWithCatchAll = (-1 * encodedSize) + 1;
return new VariableSizeCollection<ExceptionHandler>(dexBuf, reader.getOffset(), sizeWithCatchAll) {
return new VariableSizeSet<ExceptionHandler>(dexBuf, reader.getOffset(), sizeWithCatchAll) {
@Nonnull
@Override
protected ExceptionHandler readNextItem(@Nonnull DexReader dexReader, int index) {

View File

@ -47,7 +47,7 @@ public class DexBackedFieldReference extends BaseFieldReference {
@Nonnull
@Override
public String getContainingClass() {
public String getDefiningClass() {
return dexBuf.getType(dexBuf.readUshort(fieldIdItemOffset + DexBuffer.FIELD_CLASS_IDX_OFFSET));
}

View File

@ -53,7 +53,7 @@ public class DexBackedMethodReference extends BaseMethodReference {
@Nonnull
@Override
public String getContainingClass() {
public String getDefiningClass() {
return dexBuf.getType(dexBuf.readUshort(methodIdItemOffset + DexBuffer.METHOD_CLASS_IDX_OFFSET));
}

View File

@ -32,23 +32,25 @@
package org.jf.dexlib2.dexbacked.util;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.dexbacked.DexBackedAnnotation;
import org.jf.dexlib2.dexbacked.DexBuffer;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;
public abstract class AnnotationsDirectory {
public static final AnnotationsDirectory EMPTY = new AnnotationsDirectory() {
@Override public int getFieldAnnotationCount() { return 0; }
@Nonnull @Override public List<? extends DexBackedAnnotation> getClassAnnotations() {return ImmutableList.of();}
@Nonnull @Override public Set<? extends DexBackedAnnotation> getClassAnnotations() { return ImmutableSet.of(); }
@Nonnull @Override public AnnotationIterator getFieldAnnotationIterator() { return AnnotationIterator.EMPTY; }
@Nonnull @Override public AnnotationIterator getMethodAnnotationIterator() { return AnnotationIterator.EMPTY; }
@Nonnull @Override public AnnotationIterator getParameterAnnotationIterator() {return AnnotationIterator.EMPTY;}
};
public abstract int getFieldAnnotationCount();
@Nonnull public abstract List<? extends DexBackedAnnotation> getClassAnnotations();
@Nonnull public abstract Set<? extends DexBackedAnnotation> getClassAnnotations();
@Nonnull public abstract AnnotationIterator getFieldAnnotationIterator();
@Nonnull public abstract AnnotationIterator getMethodAnnotationIterator();
@Nonnull public abstract AnnotationIterator getParameterAnnotationIterator();
@ -74,11 +76,11 @@ public abstract class AnnotationsDirectory {
}
@Nonnull
public static List<? extends DexBackedAnnotation> getAnnotations(@Nonnull final DexBuffer dexBuf,
public static Set<? extends DexBackedAnnotation> getAnnotations(@Nonnull final DexBuffer dexBuf,
final int annotationSetOffset) {
if (annotationSetOffset != 0) {
final int size = dexBuf.readSmallUint(annotationSetOffset);
return new FixedSizeList<DexBackedAnnotation>() {
return new FixedSizeSet<DexBackedAnnotation>() {
@Nonnull
@Override
public DexBackedAnnotation readItem(int index) {
@ -90,19 +92,19 @@ public abstract class AnnotationsDirectory {
};
}
return ImmutableList.of();
return ImmutableSet.of();
}
@Nonnull
public static List<List<? extends DexBackedAnnotation>> getParameterAnnotations(@Nonnull final DexBuffer dexBuf,
public static List<Set<? extends DexBackedAnnotation>> getParameterAnnotations(@Nonnull final DexBuffer dexBuf,
final int annotationSetListOffset) {
if (annotationSetListOffset > 0) {
final int size = dexBuf.readSmallUint(annotationSetListOffset);
return new FixedSizeList<List<? extends DexBackedAnnotation>>() {
return new FixedSizeList<Set<? extends DexBackedAnnotation>>() {
@Nonnull
@Override
public List<? extends DexBackedAnnotation> readItem(int index) {
public Set<? extends DexBackedAnnotation> readItem(int index) {
int annotationSetOffset = dexBuf.readSmallUint(annotationSetListOffset + 4 + index * 4);
return getAnnotations(dexBuf, annotationSetOffset);
}
@ -146,7 +148,7 @@ public abstract class AnnotationsDirectory {
}
@Nonnull
public List<? extends DexBackedAnnotation> getClassAnnotations() {
public Set<? extends DexBackedAnnotation> getClassAnnotations() {
return getAnnotations(dexBuf, dexBuf.readSmallUint(directoryOffset));
}

View File

@ -48,13 +48,10 @@ import org.jf.dexlib2.immutable.debug.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.*;
public abstract class DebugInfo implements Iterable<DebugItem> {
@Nonnull public abstract Collection<? extends MethodParameter> getParametersWithNames();
@Nonnull public abstract List<? extends MethodParameter> getParametersWithNames();
public static DebugInfo newOrEmpty(@Nonnull DexBuffer dexBuf, int debugInfoOffset,
@Nonnull DexBackedMethodImplementation methodImpl) {
@ -104,8 +101,8 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
final LocalInfo[] locals = new LocalInfo[registerCount];
Arrays.fill(locals, EMPTY_LOCAL_INFO);
final VariableSizeIterator<? extends MethodParameter> parameterIterator =
getParametersWithNames().iterator();
final VariableSizeListIterator<? extends MethodParameter> parameterIterator =
getParametersWithNames().listIterator();
// first, we grab all the parameters and temporarily store them at the beginning of locals,
// disregarding any wide types
@ -234,7 +231,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
@Nonnull
@Override
public VariableSizeCollection<MethodParameter> getParametersWithNames() {
public VariableSizeList<MethodParameter> getParametersWithNames() {
DexReader reader = dexBuf.readerAt(debugInfoOffset);
reader.skipUleb128();
final int parameterNameCount = reader.readSmallUleb128();
@ -242,7 +239,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
methodImpl.method.getParametersWithoutNames();
//TODO: make sure dalvik doesn't allow more parameter names than we have parameters
return new VariableSizeCollection<MethodParameter>(dexBuf, reader.getOffset(),
return new VariableSizeList<MethodParameter>(dexBuf, reader.getOffset(),
methodParametersWithoutNames.size()) {
@Nonnull
@Override
@ -258,7 +255,7 @@ public abstract class DebugInfo implements Iterable<DebugItem> {
@Nonnull @Override public String getType() { return methodParameter.getType(); }
@Nullable @Override public String getName() { return name; }
@Nullable @Override public String getSignature() { return methodParameter.getSignature();}
@Nonnull @Override public Collection<? extends Annotation> getAnnotations() {
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
return methodParameter.getAnnotations();
}
};

View File

@ -0,0 +1,68 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.dexbacked.util;
import javax.annotation.Nonnull;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* This provides a wrapper around AbstractSet to allow easy implementation when backed by a list that can be randomly
* accessed.
*/
public abstract class FixedSizeSet<T> extends AbstractSet<T> {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
int index = 0;
@Override public boolean hasNext() { return index < size(); }
@Override public void remove() { throw new UnsupportedOperationException(); }
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return readItem(index++);
}
};
}
/**
* Reads the item at {@code index}
* @param index The index of the item. This is guaranteed to be in [0, size)
* @return The item at the given index
*/
@Nonnull
public abstract T readItem(int index);
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.dexbacked.util;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
import java.util.AbstractSequentialList;
public abstract class VariableSizeList<T> extends AbstractSequentialList<T> {
@Nonnull private final DexBuffer dexBuf;
private final int offset;
private final int size;
public VariableSizeList(@Nonnull DexBuffer dexBuf, int offset, int size) {
this.dexBuf = dexBuf;
this.offset = offset;
this.size = size;
}
@Nonnull protected abstract T readNextItem(@Nonnull DexReader reader, int index);
@Override
public VariableSizeListIterator<T> listIterator() {
return listIterator(0);
}
@Override public int size() { return size; }
@Override
public VariableSizeListIterator<T> listIterator(int index) {
VariableSizeListIterator<T> iterator = new VariableSizeListIterator<T>(dexBuf, offset, size) {
@Nonnull
@Override
protected T readNextItem(@Nonnull DexReader reader, int index) {
return VariableSizeList.this.readNextItem(reader, index);
}
};
while (index++ > 0) {
iterator.next();
}
return iterator;
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.dexbacked.util;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
import java.util.ListIterator;
import java.util.NoSuchElementException;
public abstract class VariableSizeListIterator<T> implements ListIterator<T> {
@Nonnull private DexReader reader;
protected final int size;
private final int startOffset;
private int index;
protected VariableSizeListIterator(@Nonnull DexBuffer dexBuf, int offset, int size) {
this.reader = dexBuf.readerAt(offset);
this.startOffset = offset;
this.size = size;
}
/**
* Reads the next item from reader.
*
* @param reader The {@code DexReader} to read the next item from
* @param index The index of the item being read. This is guaranteed to be less than {@code size}
* @return The item that was read
*/
@Nonnull protected abstract T readNextItem(@Nonnull DexReader reader, int index);
public int getReaderOffset() {
return reader.getOffset();
}
@Override
public boolean hasNext() {
return index < size;
}
@Override
@Nonnull
public T next() {
if (index >= size) {
throw new NoSuchElementException();
}
return readNextItem(reader, index++);
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public T previous() {
int targetIndex = index-1;
reader.setOffset(startOffset);
index = 0;
while (index < targetIndex) {
readNextItem(reader, index++);
}
return readNextItem(reader, index++);
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index - 1;
}
@Override public void remove() { throw new UnsupportedOperationException(); }
@Override public void set(T t) { throw new UnsupportedOperationException(); }
@Override public void add(T t) { throw new UnsupportedOperationException(); }
}

View File

@ -0,0 +1,65 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.dexbacked.util;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
import java.util.AbstractSet;
public abstract class VariableSizeSet<T> extends AbstractSet<T> {
@Nonnull private final DexBuffer dexBuf;
private final int offset;
private final int size;
public VariableSizeSet(@Nonnull DexBuffer dexBuf, int offset, int size) {
this.dexBuf = dexBuf;
this.offset = offset;
this.size = size;
}
@Nonnull protected abstract T readNextItem(@Nonnull DexReader reader, int index);
@Override
public VariableSizeIterator<T> iterator() {
return new VariableSizeIterator<T>(dexBuf, offset, size) {
@Nonnull
@Override
protected T readNextItem(@Nonnull DexReader reader, int index) {
return VariableSizeSet.this.readNextItem(reader, index);
}
};
}
@Override public int size() { return size; }
}

View File

@ -35,11 +35,11 @@ import org.jf.dexlib2.base.value.BaseAnnotationEncodedValue;
import org.jf.dexlib2.dexbacked.DexBackedAnnotationElement;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.util.VariableSizeCollection;
import org.jf.dexlib2.dexbacked.util.VariableSizeSet;
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Set;
public class DexBackedAnnotationEncodedValue extends BaseAnnotationEncodedValue implements AnnotationEncodedValue {
@Nonnull public final DexBuffer dexBuf;
@ -72,8 +72,8 @@ public class DexBackedAnnotationEncodedValue extends BaseAnnotationEncodedValue
@Nonnull
@Override
public Collection<? extends DexBackedAnnotationElement> getElements() {
return new VariableSizeCollection<DexBackedAnnotationElement>(dexBuf, elementsOffset, elementCount) {
public Set<? extends DexBackedAnnotationElement> getElements() {
return new VariableSizeSet<DexBackedAnnotationElement>(dexBuf, elementsOffset, elementCount) {
@Nonnull
@Override
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader dexReader, int index) {

View File

@ -34,12 +34,12 @@ package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.base.value.BaseArrayEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.util.VariableSizeCollection;
import org.jf.dexlib2.dexbacked.util.VariableSizeList;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
public class DexBackedArrayEncodedValue extends BaseArrayEncodedValue implements ArrayEncodedValue {
@Nonnull public final DexBuffer dexBuf;
@ -66,8 +66,8 @@ public class DexBackedArrayEncodedValue extends BaseArrayEncodedValue implements
@Nonnull
@Override
public Collection<? extends EncodedValue> getValue() {
return new VariableSizeCollection<EncodedValue>(dexBuf, encodedArrayOffset, elementCount) {
public List<? extends EncodedValue> getValue() {
return new VariableSizeList<EncodedValue>(dexBuf, encodedArrayOffset, elementCount) {
@Nonnull
@Override
protected EncodedValue readNextItem(@Nonnull DexReader dexReader, int index) {

View File

@ -33,8 +33,6 @@ package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.ValueType;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference;
import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.immutable.value.*;
import org.jf.dexlib2.util.Preconditions;
@ -78,22 +76,19 @@ public abstract class DexBackedEncodedValue {
reader.readSizedRightExtendedLong(valueArg + 1)));
case ValueType.STRING:
Preconditions.checkValueArg(valueArg, 3);
return new ImmutableStringEncodedValue(reader.getString(reader.readSizedSmallUint(valueArg + 1)));
return new DexBackedStringEncodedValue(reader, valueArg);
case ValueType.TYPE:
Preconditions.checkValueArg(valueArg, 3);
return new ImmutableTypeEncodedValue(reader.getType(reader.readSizedSmallUint(valueArg + 1)));
case ValueType.FIELD:
Preconditions.checkValueArg(valueArg, 3);
return new ImmutableFieldEncodedValue(new DexBackedFieldReference(reader.getDexBuffer(),
reader.readSizedSmallUint(valueArg + 1)));
return new DexBackedFieldEncodedValue(reader, valueArg);
case ValueType.METHOD:
Preconditions.checkValueArg(valueArg, 3);
return new ImmutableMethodEncodedValue(new DexBackedMethodReference(reader.getDexBuffer(),
reader.readSizedSmallUint(valueArg + 1)));
return new DexBackedMethodEncodedValue(reader, valueArg);
case ValueType.ENUM:
Preconditions.checkValueArg(valueArg, 3);
return new ImmutableEnumEncodedValue(new DexBackedFieldReference(reader.getDexBuffer(),
reader.readSizedSmallUint(valueArg + 1)));
return new DexBackedEnumEncodedValue(reader, valueArg);
case ValueType.ARRAY:
Preconditions.checkValueArg(valueArg, 0);
return new DexBackedArrayEncodedValue(reader);
@ -101,6 +96,7 @@ public abstract class DexBackedEncodedValue {
Preconditions.checkValueArg(valueArg, 0);
return new DexBackedAnnotationEncodedValue(reader);
case ValueType.NULL:
Preconditions.checkValueArg(valueArg, 0);
return ImmutableNullEncodedValue.INSTANCE;
case ValueType.BOOLEAN:
Preconditions.checkValueArg(valueArg, 1);

View File

@ -29,15 +29,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.base.value.BaseEnumEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference;
import org.jf.dexlib2.iface.reference.FieldReference;
import javax.annotation.Nonnull;
import java.util.SortedSet;
public interface SortedClassDef extends ClassDef {
@Nonnull SortedSet<? extends SortedAnnotation> getAnnotations();
@Nonnull SortedSet<? extends SortedField> getFields();
@Nonnull SortedSet<? extends SortedMethod> getMethods();
public class DexBackedEnumEncodedValue extends BaseEnumEncodedValue {
@Nonnull public final DexBuffer dexBuf;
private final int fieldIndex;
public DexBackedEnumEncodedValue(@Nonnull DexReader reader, int valueArg) {
this.dexBuf = reader.getDexBuffer();
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
}
@Override public FieldReference getValue() {
return new DexBackedFieldReference(dexBuf, fieldIndex);
}
}

View File

@ -29,16 +29,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import org.jf.dexlib2.base.value.BaseFieldEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference;
import org.jf.dexlib2.iface.reference.FieldReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.SortedSet;
public interface SortedField extends Field {
@Nullable SortedEncodedValue getInitialValue();
@Nonnull SortedSet<? extends SortedAnnotation> getAnnotations();
public class DexBackedFieldEncodedValue extends BaseFieldEncodedValue {
@Nonnull public final DexBuffer dexBuf;
private final int fieldIndex;
public DexBackedFieldEncodedValue(@Nonnull DexReader reader, int valueArg) {
this.dexBuf = reader.getDexBuffer();
fieldIndex = reader.readSizedSmallUint(valueArg + 1);
}
@Override public FieldReference getValue() {
return new DexBackedFieldReference(dexBuf, fieldIndex);
}
}

View File

@ -29,13 +29,26 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted.value;
package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
import org.jf.dexlib2.base.value.BaseMethodEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference;
import org.jf.dexlib2.iface.reference.MethodReference;
import javax.annotation.Nonnull;
import java.util.Collection;
public interface SortedArrayEncodedValue extends SortedEncodedValue, ArrayEncodedValue{
@Nonnull Collection<? extends SortedEncodedValue> getValue();
public class DexBackedMethodEncodedValue extends BaseMethodEncodedValue {
@Nonnull public final DexBuffer dexBuf;
private final int MethodIndex;
public DexBackedMethodEncodedValue(@Nonnull DexReader reader, int valueArg) {
this.dexBuf = reader.getDexBuffer();
MethodIndex = reader.readSizedSmallUint(valueArg + 1);
}
@Override public MethodReference getValue() {
return new DexBackedMethodReference(dexBuf, MethodIndex);
}
}

View File

@ -29,13 +29,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import org.jf.dexlib2.base.value.BaseStringEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
public interface SortedAnnotationElement extends AnnotationElement {
@Nonnull SortedEncodedValue getValue();
public class DexBackedStringEncodedValue extends BaseStringEncodedValue {
@Nonnull public final DexBuffer dexBuf;
private final int stringIndex;
public DexBackedStringEncodedValue(@Nonnull DexReader reader, int valueArg) {
this.dexBuf = reader.getDexBuffer();
stringIndex = reader.readSizedSmallUint(valueArg + 1);
}
@Override public String getValue() {
return dexBuf.getString(stringIndex);
}
}

View File

@ -29,13 +29,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
package org.jf.dexlib2.dexbacked.value;
import org.jf.dexlib2.iface.MethodParameter;
import org.jf.dexlib2.base.value.BaseTypeEncodedValue;
import org.jf.dexlib2.dexbacked.DexBuffer;
import org.jf.dexlib2.dexbacked.DexReader;
import javax.annotation.Nonnull;
import java.util.SortedSet;
public interface SortedMethodParameter extends MethodParameter {
@Nonnull SortedSet<? extends SortedAnnotation> getAnnotations();
public class DexBackedTypeEncodedValue extends BaseTypeEncodedValue {
@Nonnull public final DexBuffer dexBuf;
private final int typeIndex;
public DexBackedTypeEncodedValue(@Nonnull DexReader reader, int valueArg) {
this.dexBuf = reader.getDexBuffer();
typeIndex = reader.readSizedSmallUint(valueArg + 1);
}
@Override public String getValue() {
return dexBuf.getType(typeIndex);
}
}

View File

@ -32,16 +32,78 @@
package org.jf.dexlib2.iface;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
public interface Annotation {
// The possible annotation visibility values
public static final int BUILD = 0;
public static final int RUNTIME = 1;
public static final int SYSTEM = 2;
import javax.annotation.Nullable;
import java.util.Set;
/**
* This class represents a specific instance of an annotation applied to a class/field/method/parameter
*/
public interface Annotation extends Comparable<Annotation> {
/**
* Gets the visibility of this annotation.
*
* This will be one of the AnnotationVisibility.* constants.
*
* @return The visibility of this annotation
*/
int getVisibility();
/**
* Gets the type of this annotation.
*
* This will be the type descriptor of the class that defines this annotation.
*
* @return The type of this annotation
*/
@Nonnull String getType();
@Nonnull Collection<? extends AnnotationElement> getElements();
/**
* Gets a set of the name/value elements associated with this annotation.
*
* The elements in the returned set will be unique with respect to the element name.
*
* @return A set of AnnotationElements
*/
@Nonnull Set<? extends AnnotationElement> getElements();
/**
* Returns a hashcode for this Annotation.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getVisibility();
* hashCode = hashCode*31 + getType().hashCode();
* hashCode = hashCode*31 + getElements().hashCode();
* }</pre>
*
* @return The hash code value for this Annotation
*/
@Override int hashCode();
/**
* Compares this Annotation to another Annotation for equality.
*
* This Annotation is equal to another Annotation if all of it's "fields" are equal. That is, if the return values
* of getVisibility(), getType(), and getElements() are all equal.
*
* TODO: when an Annotation is used in a set, need to specify that the uniqueness in the set is based on annotation type
*
* @param o The object to be compared for equality with this Annotation
* @return true if the specified object is equal to this Annotation
*/
@Override boolean equals(@Nullable Object o);
/**
* Compares this Annotation to another Annotation.
*
* The comparison is based on the value of getVisibility(), getType() and getElements(), in that order. When
* comparing the set of elements, the comparison is done with the semantics of
* org.jf.util.CollectionUtils.compareAsSet(), using the natural ordering of AnnotationElement.
*
* @param o The Annotation to compare with this Annotation
* @return An integer representing the result of the comparison
*/
@Override int compareTo(Annotation o);
}

View File

@ -34,8 +34,59 @@ package org.jf.dexlib2.iface;
import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface AnnotationElement {
/**
* This class represents an individual name/value element in an annotation
*/
public interface AnnotationElement extends Comparable<AnnotationElement> {
/**
* Gets the name of the element.
*
* @return The name of the element.
*/
@Nonnull String getName();
/**
* Gets the value of the element.
*
* @return The value of the element
*/
@Nonnull EncodedValue getValue();
/**
* Returns a hashcode for this AnnotationElement.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getName().hashCode();
* hashCode = hashCode*31 + getValue().hashCode();
* }</pre>
*
* @return The hash code value for this AnnotationElement
*/
@Override int hashCode();
/**
* Compares this AnnotationElement to another AnnotationElement for equality.
*
* This AnnotationElement is equal to another AnnotationElement if all of it's "fields" are equal. That is, if
* the return values of getName() and getValue() are both equal.
*
* @param o The object to be compared for equality with this AnnotationElement
* @return true if the specified object is equal to this AnnotationElement
*/
@Override boolean equals(@Nullable Object o);
/**
* Compares this AnnotationElement to another AnnotationElement.
*
* The comparison is based on the value of getName() and getValue(), in that order.
*
* @param o The AnnotationElement to compare with this AnnotationElement
* @return An integer representing the result of the comparison
*/
@Override int compareTo(AnnotationElement o);
}

View File

@ -35,16 +35,83 @@ import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* This class represents a class definition.
*
* It also acts as a TypeReference to itself. Any equality/comparison is based on its identity as a TypeReference,
* and shouldn't take into account anything other than the type of this class.
*/
public interface ClassDef extends TypeReference {
@Nonnull String getType();
/**
* Gets the class type.
*
* This will be a type descriptor per the dex file specification.
*
* @return The class type
*/
@Override @Nonnull String getType();
/**
* Gets the access flags for this class.
*
* This will be a combination of the AccessFlags.* flags that are marked as compatible for use with a class.
*
* @return The access flags for this class
*/
int getAccessFlags();
/**
* Gets the superclass of this class.
*
* This will only be null if this is the base java.lang.Object class.
*
* @return The superclass of this class
*/
@Nullable String getSuperclass();
@Nonnull List<String> getInterfaces();
/**
* Gets a set of the interfaces that this class implements.
*
* @return A set of the interfaces that this class implements
*/
@Nonnull Set<String> getInterfaces();
/**
* Gets the name of the primary source file that this class is defined in, if available.
*
* This will be the default source file associated with all methods defined in this class. This can be overridden
* for sections of an individual method with the SetSourceFile debug item.
*
* @return The name of the primary source file for this class, or null if not available
*/
@Nullable String getSourceFile();
@Nonnull Collection<? extends Annotation> getAnnotations();
@Nonnull Collection<? extends Field> getFields();
@Nonnull Collection<? extends Method> getMethods();
/**
* Gets a set of the annotations that are applied to this class.
*
* The annotations in the returned set are guaranteed to have unique types.
*
* @return A set of the annotations that are applied to this class
*/
@Nonnull Set<? extends Annotation> getAnnotations();
/**
* Gets a set of the fields that are defined by this class.
*
* TODO: uniqueness?
*
* @return A set of the fields that are defined by this class
*/
@Nonnull Set<? extends Field> getFields();
/**
* Gets a set of the methods that are defined by this class.
*
* TODO: uniqueness?
*
* @return A set of the methods that are defined by this class.
*/
@Nonnull Set<? extends Method> getMethods();
}

View File

@ -32,8 +32,18 @@
package org.jf.dexlib2.iface;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;
/**
* This class is a high level representation of a dex file - essentially a set of class definitions.
*/
public interface DexFile {
@Nonnull List<? extends ClassDef> getClasses();
/**
* Get a set of the classes defined in this dex file.
*
* The classes in the returned set will all have unique types.
*
* @return A set of the classes defined in this dex file
*/
@Nonnull Set<? extends ClassDef> getClasses();
}

View File

@ -31,9 +31,63 @@
package org.jf.dexlib2.iface;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface ExceptionHandler {
/**
* This class represents an individual exception handler entry, in a try block.
*/
public interface ExceptionHandler extends Comparable<ExceptionHandler> {
/**
* Gets the type of exception that is handled by this handler.
*
* @return The type of exception that is handled by this handler, or null if this is a catch-all handler.
*/
@Nullable String getExceptionType();
/**
* Gets the code offset of the handler.
*
* @return The offset of the handler from the the beginning of the bytecode for the method. The offset will be in
* terms of 16-bit code units
*/
int getHandlerCodeAddress();
/**
* Returns a hashcode for this ExceptionHandler.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* String exceptionType = getExceptionType();
* int hashCode = exceptionType==null?0:exceptionType.hashCode();
* return hashCode*31 + getHandlerCodeAddress();
* }</pre>
*
* @return The hash code value for this ExceptionHandler
*/
@Override int hashCode();
/**
* Compares this ExceptionHandler to another ExceptionHandler for equality.
*
* This ExceptionHandler is equal to another ExceptionHandler if all of it's "fields" are equal. That is, if
* the return values of getExceptionType() and getHandlerCodeAddress() are both equal.
*
* @param o The object to be compared for equality with this ExceptionHandler
* @return true if the specified object is equal to this ExceptionHandler
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this ExceptionHandler to another ExceptionHandler.
*
* The comparison is based on the comparison of the return values of getExceptionType() and
* getHandlerCodeAddress() in that order. A null value for getExceptionType() compares after a non-null value.
*
* @param o The ExceptionHandler to compare with this ExceptionHandler
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull ExceptionHandler o);
}

View File

@ -36,13 +36,61 @@ import org.jf.dexlib2.iface.value.EncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Set;
/**
* This class represents a specific field definition in a class.
*
* It also acts as a FieldReference to itself. Any equality/comparison is based on its identity as a FieldReference,
* and shouldn't take into account any non-FieldReference specifics of this field.
*/
public interface Field extends FieldReference {
@Nonnull String getContainingClass();
/**
* Gets the type of the class that defines this field.
*
* @return The type of the class that defines this field
*/
@Nonnull String getDefiningClass();
/**
* Gets the name of this field.
*
* @return The name of this field
*/
@Nonnull String getName();
/**
* Gets the type of this field.
*
* @return The type of this field
*/
@Nonnull String getType();
/**
* Gets the access flags for this field.
*
* This will be a combination of the AccessFlags.* flags that are marked as compatible for use with a field.
*
* @return The access flags for this field
*/
int getAccessFlags();
/**
* Gets the initial value for this field, if available.
*
* Only static field may have an initial value set, but are not required to have an initial value.
*
* @return The initial value for this field, or null if this field is not a static field, or if this static field
* does not have an initial value.
*/
@Nullable EncodedValue getInitialValue();
@Nonnull Collection<? extends Annotation> getAnnotations();
/**
* Gets a set of the annotations that are applied to this field.
*
* The annotations in the returned set are guaranteed to have unique types.
*
* @return A set of the annotations that are applied to this field
*/
@Nonnull Set<? extends Annotation> getAnnotations();
}

View File

@ -35,14 +35,76 @@ import org.jf.dexlib2.iface.reference.MethodReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* This class represents a specific method definition in a class.
*
* It also acts as a MethodReference to itself. Any equality/comparison is based on its identity as a MethodReference,
* and shouldn't take into account any non-MethodReference specifics of this method.
*/
public interface Method extends MethodReference {
@Nonnull String getContainingClass();
@Nonnull String getName();
@Nonnull Collection<? extends MethodParameter> getParameters();
@Nonnull String getReturnType();
/**
* Gets the type of the class that defines this method.
*
* @return The type of the class that defines this method
*/
@Override @Nonnull String getDefiningClass();
/**
* Gets the name of this method.
*
* @return The name of this method
*/
@Override @Nonnull String getName();
/**
* Gets a list of the types of the parameters of this method.
*
* As per the MethodReference interface, the MethodParameter objects contained in the returned list also act
* as a simple reference to the type of the parameter. However, the MethodParameter object can also contain
* additional information about the parameter.
*
* Note: In some implementations, the returned list is likely to *not* provide efficient random access.
*
* @return A list of MethodParameter objects, representing the parameters of this method.
*/
@Override @Nonnull List<? extends MethodParameter> getParameters();
/**
* Gets the return type of this method.
*
* @return The return type of this method.
*/
@Override @Nonnull String getReturnType();
/**
* Gets the access flags for this method.
*
* This will be a combination of the AccessFlags.* flags that are marked as compatible for use with a method.
*
* @return The access flags for this method
*/
int getAccessFlags();
@Nonnull Collection<? extends Annotation> getAnnotations();
/**
* Gets a set of the annotations that are applied to this method.
*
* The annotations in the returned set are guaranteed to have unique types.
*
* @return A set of the annotations that are applied to this method
*/
@Nonnull Set<? extends Annotation> getAnnotations();
/**
* Gets a MethodImplementation object that defines the implementation of the method.
*
* If this is an abstract method in an abstract class, or an interface method in an interface definition, then the
* method has no implementation, and this will return null.
*
* @return A MethodImplementation object defining the implementation of this method, or null if the method has no
* implementation
*/
@Nullable MethodImplementation getImplementation();
}

View File

@ -37,9 +37,48 @@ import org.jf.dexlib2.iface.instruction.Instruction;
import javax.annotation.Nonnull;
import java.util.List;
/**
* This class represents the implementation details of a method.
*/
public interface MethodImplementation {
/**
* Gets the number of registers in this method.
*
* @return The number of register in this method.
*/
int getRegisterCount();
/**
* Gets the instructions in this method.
*
* @return An Iterable of the instructions in this method
*/
@Nonnull Iterable<? extends Instruction> getInstructions();
/**
* Gets a list of the try blocks defined for this method.
*
* Try blocks may overlap freely, and do not need to be strictly nested, as in java. This is a more relaxed
* requirement than specified by the dex format, where try blocks may not overlap, and must be specified in
* ascending order. When writing to a dex file, the try blocks will be massaged into the appropriate format.
*
* In any region where there are overlapping try blocks, set of exception handlers for the overlapping region will
* consist of the union of all handlers in any try block that covers that region.
*
* If multiple overlapping try blocks define a handler for the same exception type, or define a catch-all
* handler, then those duplicate handlers must use the same handler offset.
*
* @return A list of the TryBlock items
*/
@Nonnull List<? extends TryBlock> getTryBlocks();
/**
* Get a list of debug items for this method.
*
* This generally matches the semantics of the debug_info_item in the dex specification, although in an easier to
* digest form.
*
* @return A list of DebugInfo items
*/
@Nonnull Iterable<? extends DebugItem> getDebugItems();
}

View File

@ -36,11 +36,50 @@ import org.jf.dexlib2.iface.reference.TypeReference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Set;
/**
* This class represents a method parameter.
*
* It also acts as a TypeReference to the type of this parameter. Any equality/comparison is based on its identity as a
* TypeReference, and should not take into account any details other than the parameter type.
*
* It also acts as a LocalInfo object, and conceptually defines the debug information for any parameter register at the
* beginning of the method.
*/
public interface MethodParameter extends TypeReference, LocalInfo {
/**
* The type of this method parameter.
*
* This may be any type, including primitive or array types, other than the void (V) type.
*
* @return The type of this method parameter
*/
@Nonnull String getType();
@Nonnull Collection<? extends Annotation> getAnnotations();
/**
* Gets a set of the annotations that are applied to this parameter.
*
* The annotations in the returned set are guaranteed to have unique types.
*
* @return A set of the annotations that are applied to this parameter
*/
@Nonnull Set<? extends Annotation> getAnnotations();
/**
* Gets the name of this parameter, if available.
*
* @return The name of this parameter, or null if the name is not available.
*/
@Nullable String getName();
/**
* Gets the signature of this parameter, if available.
*
* The signature of a parameter is defined to be the concatenated version of the dalvik.annotation.Signature
* annotation applied to this parameter, or null if there is no dalvik.annotation.Signature annotation.
*
* @return The signature of this parameter, or null if not available
*/
@Nullable String getSignature();
}

View File

@ -32,10 +32,39 @@
package org.jf.dexlib2.iface;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Set;
/**
* This class represents an individual try block and associated set of handlers.
*/
public interface TryBlock {
/**
* Gets the code offset of the start of this try block.
*
* The starting location must not occur in the middle of an instruction.
*
* @return The offset of the start of the try block from the the beginning of the bytecode for the method. The
* offset will be in terms of 16-bit code units.
*/
int getStartCodeAddress();
/**
* Gets the number of code units covered by this try block.
*
* The end of the try block is typically coincident with the end of an instruction, but does not strictly need to
* be. If the last instruction is only partly covered by this try block, it is considered to be covered.
*
* @return The number of code units covered by this try block.
*/
int getCodeUnitCount();
@Nonnull Collection<? extends ExceptionHandler> getExceptionHandlers();
/**
* A set of the exception handlers associated with this try block.
*
* The exception handlers in the returned set will all have a unique type, including at most 1 with no type, which
* is the catch-all handler.
*
* @return A set of ExceptionHandler objects
*/
@Nonnull Set<? extends ExceptionHandler> getExceptionHandlers();
}

View File

@ -31,7 +31,25 @@
package org.jf.dexlib2.iface.debug;
/**
* This class represents a generic debug item.
*
* The specific sub-types of this class correspond to the various debug opcodes specified in the debug_info_item type
* in the dex file specification.
*/
public interface DebugItem {
/**
* The type of this debug item.
*
* The returned integer will be one of the DebugItemType.* constants.
*
* @return The type of this debug item.
*/
int getDebugItemType();
/**
* The code address
* @return
*/
int getCodeAddress();
}

View File

@ -33,7 +33,26 @@ package org.jf.dexlib2.iface.instruction;
import org.jf.dexlib2.Opcode;
/**
* This class represents a generic instruction.
*
* There are two categories of sub-interfaces of this interface. The dexlib2.iface.instruction.* interfaces are set of
* generic categories of instructions, while the dexlib2.iface.instruction.formats.* interfaces each represent a
* specific instruction format, and are typically built up as a composite of generic instruction interfaces.
*/
public interface Instruction {
/**
* Gets the opcode of this instruction.
*
* @return The Opcode of this instruction.
*/
Opcode getOpcode();
/**
* Gets the size of this instruction.
*
* @return The size of this instruction, as a count of the number of 16-bit code units that make up this
* instruction.
*/
int getCodeUnits();
}

View File

@ -32,9 +32,68 @@
package org.jf.dexlib2.iface.reference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface FieldReference extends Reference {
@Nonnull String getContainingClass();
/**
* This class represents a reference to a field.
*/
public interface FieldReference extends Reference, Comparable<FieldReference> {
/**
* Gets the type of the class that defines the referenced field.
*
* @return The type of the class that defines the referenced field
*/
@Nonnull String getDefiningClass();
/**
* Gets the name of the referenced field.
*
* @return The name of the referenced field
*/
@Nonnull String getName();
/**
* Gets the type of the referenced field.
*
* @return The type of the referenced field
*/
@Nonnull String getType();
/**
* Returns a hashcode for this FieldReference.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getDefiningClass().hashCode();
* hashCode = hashCode*31 + getName().hashCode();
* hashCode = hashCode*31 + getType().hashCode();
* }</pre>
*
* @return The hash code value for this FieldReference
*/
@Override int hashCode();
/**
* Compares this FieldReference to another FieldReference for equality.
*
* This FieldReference is equal to another FieldReference if all of it's "fields" are equal. That is, if
* the return values of getDefiningClass(), getName() and getType() are all equal.
*
* @param o The object to be compared for equality with this FieldReference
* @return true if the specified object is equal to this FieldReference
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this FieldReference to another FieldReference.
*
* The comparison is based on the comparison of the return values of getDefiningClass(), getName() and
* getType(), in that order.
*
* @param o The FieldReference to compare with this FieldReference
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull FieldReference o);
}

View File

@ -32,11 +32,80 @@
package org.jf.dexlib2.iface.reference;
import javax.annotation.Nonnull;
import java.util.Collection;
import javax.annotation.Nullable;
import java.util.List;
public interface MethodReference extends Reference {
@Nonnull String getContainingClass();
/**
* This class represents a reference to a method.
*/
public interface MethodReference extends Reference, Comparable<MethodReference> {
/**
* Gets the type of the class that defines the referenced method.
*
* @return The type of the class that defines the referenced method
*/
@Nonnull String getDefiningClass();
/**
* Gets the name of the referenced method.
*
* @return The name of the referenced method
*/
@Nonnull String getName();
@Nonnull Collection<? extends TypeReference> getParameters();
/**
* Gets a list of the types of the parameters of the referenced method.
*
* Note: In some implementations, the returned list is likely to *not* provide efficient random access.
*
* @return A list of the types of the parameters of the referenced method
*/
@Nonnull List<? extends TypeReference> getParameters();
/**
* Gets the return type of the referenced method.
*
* @return The return type of the referenced method.
*/
@Nonnull String getReturnType();
/**
* Returns a hashcode for this MethodReference.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getDefiningClass().hashCode();
* hashCode = hashCode*31 + getName().hashCode();
* hashCode = hashCode*31 + getReturnType().hashCode();
* hashCode = hashCode*31 + getParameters().hashCode();
* }</pre>
*
* @return The hash code value for this MethodReference
*/
@Override int hashCode();
/**
* Compares this MethodReference to another MethodReference for equality.
*
* This MethodReference is equal to another MethodReference if all of it's "fields" are equal. That is, if
* the return values of getDefiningClass(), getName(), getReturnType() and getParameters() are all equal.
*
* @param o The object to be compared for equality with this MethodReference
* @return true if the specified object is equal to this MethodReference
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this MethodReference to another MethodReference.
*
* The comparison is based on the comparison of the return values of getDefiningClass(), getName(),
* getReturnType() and getParameters(), in that order. getParameters() should be compared using the semantics
* of org.jf.util.CollectionUtils.compareAsList()
*
* @param o The MethodReference to compare with this MethodReference
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull MethodReference o);
}

View File

@ -31,5 +31,9 @@
package org.jf.dexlib2.iface.reference;
/**
* This class is the base interface for field/method/string/type references in a dex file. It has no functionality or
* contract itself.
*/
public interface Reference {
}

View File

@ -32,7 +32,55 @@
package org.jf.dexlib2.iface.reference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface StringReference extends Reference, CharSequence {
/**
* This class represents a reference to an arbitrary string.
*
* When possible, elsewhere in the interface, a string is represented directly by its value. A StringReference is only
* used in those cases where a generic Reference is needed
*
* This type also acts as a CharSequence wrapper around the referenced string value. As per the CharSequence contract,
* calling toString() on a StringReference yields the referenced string value. This is the same value returned by
* getString().
*/
public interface StringReference extends Reference, CharSequence, Comparable<CharSequence> {
/**
* Gets the referenced string.
*
* @return the referenced string
*/
@Nonnull String getString();
/**
* Returns a hashcode for this StringReference.
*
* This is defined to be getString().hashCode().
*
* @return The hash code value for this StringReference
*/
@Override int hashCode();
/**
* Compares this StringReference to another CharSequence for equality.
*
* String StringReference is equal to a CharSequence iff this.getString().equals(other.toString()).
*
* Equivalently, This StringReference is equal to another StringReference iff
* this.getString().equals(other.getString()).
*
* @param o The object to be compared for equality with this TypeReference
* @return true if the specified object is equal to this TypeReference
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this StringReference to another StringReference, or more generally to another CharSequence.
*
* The comparison is defined to be this.getString().compareTo(other.toString()).
*
* @param o The CharSequence to compare with this StringReference
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull CharSequence o);
}

View File

@ -32,7 +32,59 @@
package org.jf.dexlib2.iface.reference;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface TypeReference extends Reference, CharSequence {
/**
* This class represents a reference to a type.
*
* When possible, elsewhere in the interface, a type is referenced directly as a String. A TypeReference is only used
* in those cases where a generic Reference is needed
*
* The type being referenced is represented as a String in the format of a TypeDescriptor, as defined by the dex file
* specification.
*
* This type also acts as a CharSequence wrapper around the TypeDescriptor string. As per the CharSequence contract,
* calling toString() on a TypeReference yields the type descriptor as a String. This is the same value returned by
* getType()
*/
public interface TypeReference extends Reference, CharSequence, Comparable<CharSequence> {
/**
* Gets the string representation of the referenced type.
*
* The returned string will be a TypeDescriptor, as defined in the dex file specification
*
* @return The string representation of the referenced type.
*/
@Nonnull String getType();
/**
* Returns a hashcode for this TypeReference.
*
* This is defined to be getType().hashCode()
*
* @return The hash code value for this TypeReference
*/
@Override int hashCode();
/**
* Compares this TypeReference to another TypeReference, or more generally to another CharSequence for equality.
*
* This TypeReference is equal to a CharSequence iff this.getType().equals(other.getString()).
*
* Equivalently, This TypeReference is equal to another TypeReference iff this.getType().equals(other.getType()).
*
* @param o The object to be compared for equality with this TypeReference
* @return true if the specified object is equal to this TypeReference
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this TypeReference to another TypeReference, or more generally to another CharSequence.
*
* The comparison is defined to be this.getType().compareTo(other.toString())
*
* @param o The CharSequence to compare with this TypeReference
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull CharSequence o);
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
import org.jf.dexlib2.iface.Annotation;
import javax.annotation.Nonnull;
import java.util.SortedSet;
public interface SortedAnnotation extends Annotation {
@Nonnull SortedSet<? extends SortedAnnotationElement> getElements();
}

View File

@ -1,43 +0,0 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted;
import org.jf.dexlib2.iface.Method;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.SortedSet;
public interface SortedMethod extends Method {
@Nonnull Collection<? extends SortedMethodParameter> getParameters();
@Nonnull SortedSet<? extends SortedAnnotation> getAnnotations();
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted.value;
import org.jf.dexlib2.iface.sorted.SortedAnnotationElement;
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
import javax.annotation.Nonnull;
import java.util.SortedSet;
public interface SortedAnnotationEncodedValue extends SortedEncodedValue, AnnotationEncodedValue {
@Nonnull SortedSet<? extends SortedAnnotationElement> getElements();
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2012, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib2.iface.sorted.value;
import org.jf.dexlib2.iface.value.EncodedValue;
public interface SortedEncodedValue extends EncodedValue {
}

View File

@ -34,10 +34,66 @@ package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.AnnotationElement;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import java.util.Set;
/**
* This class represents an encoded annotation value.
*/
public interface AnnotationEncodedValue extends EncodedValue {
/**
* Gets the type of this annotation.
*
* This will be the type descriptor of the class that defines this annotation.
*
* @return The type of this annotation
*/
@Nonnull String getType();
@Nonnull Collection<? extends AnnotationElement> getElements();
/**
* Gets a set of the name/value elements associated with this annotation.
*
* The elements in the returned set will be unique by name.
*
* @return A set of AnnotationElements
*/
@Nonnull Set<? extends AnnotationElement> getElements();
/**
* Returns a hashcode for this AnnotationEncodedValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getType().hashCode();
* hashCode = hashCode*31 + getElements().hashCode();
* }</pre>
*
* @return The hash code value for this AnnotationEncodedValue
*/
@Override int hashCode();
/**
* Compares this AnnotationEncodedValue to another AnnotationEncodedValue for equality.
*
* This AnnotationEncodedValue is equal to another AnnotationEncodedValue if all of it's "fields" are equal. That
* is, if the return values getType() and getElements() are both equal.
*
* @param o The object to be compared for equality with this AnnotationEncodedValue
* @return true if the specified object is equal to this AnnotationEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this AnnotationEncodedValue to another EncodedValue.
*
* The comparison is based on the value of getType() and getElements(), in that order. When
* comparing the set of elements, the comparison is done with the semantics of
* org.jf.util.CollectionUtils.compareAsSet(), using the natural ordering of AnnotationElement.
*
* @param o The EncodedValue to compare with this AnnotationEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -32,9 +32,53 @@
package org.jf.dexlib2.iface.value;
import javax.annotation.Nonnull;
import java.util.Collection;
import javax.annotation.Nullable;
import java.util.List;
/**
* This class represents an encoded array value.
*/
public interface ArrayEncodedValue extends EncodedValue {
@Nonnull Collection<? extends EncodedValue> getValue();
/**
* Gets the list of the values contained in this ArrayEncodedValue
*
* @return A list of EncodedValue instances
*/
@Nonnull List<? extends EncodedValue> getValue();
/**
* Returns a hashcode for this EncodedArrayValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue().hashCode();
* }</pre>
*
* @return The hash code value for this EncodedArrayValue
*/
@Override int hashCode();
/**
* Compares this ArrayEncodedValue to another ArrayEncodedValue for equality.
*
* This ArrayEncodedValue is equal to another ArrayEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this ArrayEncodedValue
* @return true if the specified object is equal to this ArrayEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this ArrayEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* ArrayEncodedValue, the lists returned by getValue() are compared, based on the semantics of
* org.jf.util.ComparisonUtils.compareAsList(), using the natural ordering for EncodedValue.
*
* @param o The EncodedValue to compare with this ArrayEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,53 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface BooleanEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded boolean value.
*/
public interface BooleanEncodedValue extends EncodedValue {
/**
* Gets the boolean value.
*
* @return the boolean value
*/
boolean getValue();
/**
* Returns a hashcode for this EncodedBooleanValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue()?1:0;
* }</pre>
*
* @return The hash code value for this EncodedBooleanValue
*/
@Override int hashCode();
/**
* Compares this BooleanEncodedValue to another BooleanEncodedValue for equality.
*
* This BooleanEncodedValue is equal to another BooleanEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this BooleanEncodedValue
* @return true if the specified object is equal to this BooleanEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this BooleanEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* BooleanEncodedValue, the return values of getValue() are compared, based on the semantics of
* Boolean.compareTo().
*
* @param o The EncodedValue to compare with this BooleanEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface ByteEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded byte value.
*/
public interface ByteEncodedValue extends EncodedValue {
/**
* Gets the byte value.
*
* @return the byte value
*/
byte getValue();
/**
* Returns a hashcode for this EncodedByteValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue();
* }</pre>
*
* @return The hash code value for this EncodedByteValue
*/
@Override int hashCode();
/**
* Compares this ByteEncodedValue to another ByteEncodedValue for equality.
*
* This ByteEncodedValue is equal to another ByteEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this ByteEncodedValue
* @return true if the specified object is equal to this ByteEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this ByteEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* ByteEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this ByteEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface CharEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded char value.
*/
public interface CharEncodedValue extends EncodedValue {
/**
* Gets the char value.
*
* @return the char value
*/
char getValue();
/**
* Returns a hashcode for this EncodedCharValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue();
* }</pre>
*
* @return The hash code value for this EncodedCharValue
*/
@Override int hashCode();
/**
* Compares this CharEncodedValue to another CharEncodedValue for equality.
*
* This CharEncodedValue is equal to another CharEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this CharEncodedValue
* @return true if the specified object is equal to this CharEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this CharEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* CharEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this CharEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,59 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface DoubleEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded double value.
*/
public interface DoubleEncodedValue extends EncodedValue {
/**
* Gets the double value.
*
* @return the double value
*/
double getValue();
/**
* Returns a hashcode for this EncodedDoubleValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* long v = Double.doubleToRawLongBits(getValue());
* int hashCode = (int)(v^(v>>>32));
* }</pre>
*
* Note: This is slightly different than the definition of Double.hashCode(). This uses doubleToRawLongBits()
* instead of doubleToLongBits(), in order to preserve as much information as possible.
*
* @return The hash code value for this EncodedDoubleValue
*/
@Override int hashCode();
/**
* Compares this DoubleEncodedValue to another DoubleEncodedValue for equality.
*
* This DoubleEncodedValue is equal to another DoubleEncodedValue if the values returned by
* getValue().doubleToRawLongBits() are equal.
*
* Note: this isn't quite the same as getValue() == getValue(), due to various NaN issues and signed zero issues.
*
* @param o The object to be compared for equality with this DoubleEncodedValue
* @return true if the specified object is equal to this DoubleEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this DoubleEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(), and then if the other value is another
* DoubleEncodedValue, the return values of getValue() are compared, using the semantics of Double.compare()
*
* @param o The EncodedValue to compare with this DoubleEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,6 +31,18 @@
package org.jf.dexlib2.iface.value;
public interface EncodedValue {
/**
* This class represents a generic encoded value.
*
* It acts as the base interface for each specific type of encoded value.
*/
public interface EncodedValue extends Comparable<EncodedValue> {
/**
* Returns the type of this encoded value.
*
* The returned integer will be one of the ValueType.* constants.
*
* @return The type of this encoded value
*/
int getValueType();
}

View File

@ -32,10 +32,55 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface EnumEncodedValue extends EncodedValue, SortedEncodedValue {
@Nonnull FieldReference getValue();
/**
* This class represents an encoded enum value.
*
* The enum value is represented as a FieldReference to the field on an enum class that holds the enum value.
*/
public interface EnumEncodedValue extends EncodedValue {
/**
* Gets the enum value.
*
* @return a reference to the field on the enum class that holds the enum value, as a FieldReference
*/
FieldReference getValue();
/**
* Returns a hashcode for this EncodedEnumValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue.hashCode();
* }</pre>
*
* @return The hash code value for this EncodedEnumValue
*/
@Override int hashCode();
/**
* Compares this EnumEncodedValue to another EnumEncodedValue for equality.
*
* This EnumEncodedValue is equal to another EnumEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this EnumEncodedValue
* @return true if the specified object is equal to this EnumEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this EnumEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* EnumEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this EnumEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -32,10 +32,56 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.reference.FieldReference;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface FieldEncodedValue extends EncodedValue, SortedEncodedValue {
@Nonnull FieldReference getValue();
/**
* This class represents an encoded field value.
*/
public interface FieldEncodedValue extends EncodedValue {
/**
* Gets the field value.
*
* @return the field value as a FieldReference
*/
FieldReference getValue();
/**
* Returns a hashcode for this EncodedFieldValue.
* <p/>
* This hashCode is defined to be the following:
* <p/>
* <pre>
* {@code
* int hashCode = getValue.hashCode();
* }</pre>
*
* @return The hash code value for this EncodedFieldValue
*/
@Override
int hashCode();
/**
* Compares this FieldEncodedValue to another FieldEncodedValue for equality.
* <p/>
* This FieldEncodedValue is equal to another FieldEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this FieldEncodedValue
* @return true if the specified object is equal to this FieldEncodedValue
*/
@Override
boolean equals(@Nullable Object o);
/**
* Compare this FieldEncodedValue to another EncodedValue.
* <p/>
* The comparison is first done on the return values of getValueType(). If the other value is another
* FieldEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this FieldEncodedValue
* @return An integer representing the result of the comparison
*/
@Override
int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,58 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface FloatEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded float value.
*/
public interface FloatEncodedValue extends EncodedValue {
/**
* Gets the float value.
*
* @return the float value
*/
float getValue();
/**
* Returns a hashcode for this EncodedFloatValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = Float.floatToRawIntBits(getValue());
* }</pre>
*
* Note: This is slightly different than the definition of Float.hashCode(). This uses floatToRawIntBits()
* instead of floatToIntBits(), in order to preserve as much information as possible.
*
* @return The hash code value for this EncodedFloatValue
*/
@Override int hashCode();
/**
* Compares this FloatEncodedValue to another FloatEncodedValue for equality.
*
* This FloatEncodedValue is equal to another FloatEncodedValue if the values returned by
* getValue().floatToRawIntBits() are equal.
*
* Note: this isn't quite the same as getValue() == getValue(), due to various NaN issues and signed zero issues.
*
* @param o The object to be compared for equality with this FloatEncodedValue
* @return true if the specified object is equal to this FloatEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this FloatEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* FloatEncodedValue, the return values of getValue() are compared, using the semantics of Float.compare()
*
* @param o The EncodedValue to compare with this FloatEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface IntEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded integer value.
*/
public interface IntEncodedValue extends EncodedValue {
/**
* Gets the integer value.
*
* @return the int value
*/
int getValue();
/**
* Returns a hashcode for this EncodedIntValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue();
* }</pre>
*
* @return The hash code value for this EncodedIntValue
*/
@Override int hashCode();
/**
* Compares this IntEncodedValue to another IntEncodedValue for equality.
*
* This IntEncodedValue is equal to another IntEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this IntEncodedValue
* @return true if the specified object is equal to this IntEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this IntEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* IntEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this IntEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,53 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface LongEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded long value.
*/
public interface LongEncodedValue extends EncodedValue {
/**
* Gets the long value.
*
* @return the long value
*/
long getValue();
/**
* Returns a hashcode for this EncodedLongValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* long v = getValue();
* int hashCode = (int)(v^(v>>>32));
* }</pre>
*
* @return The hash code value for this EncodedLongValue
*/
@Override int hashCode();
/**
* Compares this LongEncodedValue to another LongEncodedValue for equality.
*
* This LongEncodedValue is equal to another LongEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this LongEncodedValue
* @return true if the specified object is equal to this LongEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this LongEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* LongEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this LongEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -32,10 +32,53 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface MethodEncodedValue extends EncodedValue, SortedEncodedValue {
@Nonnull MethodReference getValue();
/**
* This class represents an encoded method value.
*/
public interface MethodEncodedValue extends EncodedValue {
/**
* Gets the method value.
*
* @return the method value as a MethodReference
*/
MethodReference getValue();
/**
* Returns a hashcode for this EncodedMethodValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue.hashCode();
* }</pre>
*
* @return The hash code value for this EncodedMethodValue
*/
@Override int hashCode();
/**
* Compares this MethodEncodedValue to another MethodEncodedValue for equality.
*
* This MethodEncodedValue is equal to another MethodEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this MethodEncodedValue
* @return true if the specified object is equal to this MethodEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this MethodEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* MethodEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this MethodEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,45 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface NullEncodedValue extends EncodedValue, SortedEncodedValue {
//no value
/**
* This class represents an encoded null value.
*/
public interface NullEncodedValue extends EncodedValue {
/**
* Returns a hashcode for this EncodedNullValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = 0;
* }</pre>
*
* @return The hash code value for this EncodedNullValue
*/
@Override int hashCode();
/**
* Compares this NullEncodedValue to another NullEncodedValue for equality.
*
* This NullEncodedValue is always equal to another other NullEncodedValue
*
* @param o The object to be compared for equality with this NullEncodedValue
* @return true if the specified object is equal to this NullEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this NullEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* NullEncodedValue, then 0 is returned.
*
* @param o The EncodedValue to compare with this NullEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,8 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface ShortEncodedValue extends EncodedValue, SortedEncodedValue {
/**
* This class represents an encoded short value.
*/
public interface ShortEncodedValue extends EncodedValue {
/**
* Gets the short value.
*
* @return the short value
*/
short getValue();
/**
* Returns a hashcode for this EncodedShortValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue();
* }</pre>
*
* @return The hash code value for this EncodedShortValue
*/
@Override int hashCode();
/**
* Compares this ShortEncodedValue to another ShortEncodedValue for equality.
*
* This ShortEncodedValue is equal to another ShortEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this ShortEncodedValue
* @return true if the specified object is equal to this ShortEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this ShortEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* ShortEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this ShortEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,10 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface StringEncodedValue extends EncodedValue, SortedEncodedValue {
@Nonnull String getValue();
/**
* This class represents an encoded string value.
*/
public interface StringEncodedValue extends EncodedValue {
/**
* Gets the string value.
*
* @return the string value
*/
String getValue();
/**
* Returns a hashcode for this EncodedStringValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue().hashCode();
* }</pre>
*
* @return The hash code value for this EncodedStringValue
*/
@Override int hashCode();
/**
* Compares this StringEncodedValue to another StringEncodedValue for equality.
*
* This StringEncodedValue is equal to another StringEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this StringEncodedValue
* @return true if the specified object is equal to this StringEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this StringEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* StringEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this StringEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,10 +31,52 @@
package org.jf.dexlib2.iface.value;
import org.jf.dexlib2.iface.sorted.value.SortedEncodedValue;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public interface TypeEncodedValue extends EncodedValue, SortedEncodedValue {
@Nonnull String getValue();
/**
* This class represents an encoded type value.
*/
public interface TypeEncodedValue extends EncodedValue {
/**
* Gets the type value.
*
* @return the type value
*/
String getValue();
/**
* Returns a hashcode for this EncodedTypeValue.
*
* This hashCode is defined to be the following:
*
* <pre>
* {@code
* int hashCode = getValue().hashCode();
* }</pre>
*
* @return The hash code value for this EncodedTypeValue
*/
@Override int hashCode();
/**
* Compares this TypeEncodedValue to another TypeEncodedValue for equality.
*
* This TypeEncodedValue is equal to another TypeEncodedValue if the values returned by getValue() are equal.
*
* @param o The object to be compared for equality with this TypeEncodedValue
* @return true if the specified object is equal to this TypeEncodedValue
*/
@Override boolean equals(@Nullable Object o);
/**
* Compare this TypeEncodedValue to another EncodedValue.
*
* The comparison is first done on the return values of getValueType(). If the other value is another
* TypeEncodedValue, the return values of getValue() are compared.
*
* @param o The EncodedValue to compare with this TypeEncodedValue
* @return An integer representing the result of the comparison
*/
@Override int compareTo(@Nonnull EncodedValue o);
}

View File

@ -31,11 +31,11 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.BaseAnnotation;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
@ -43,24 +43,24 @@ import javax.annotation.Nullable;
import java.util.Collection;
public class ImmutableAnnotation extends BaseAnnotation {
public final int visibility;
@Nonnull public final String type;
@Nonnull public final ImmutableList<? extends ImmutableAnnotationElement> elements;
protected final int visibility;
@Nonnull protected final String type;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotationElement> elements;
public ImmutableAnnotation(int visibility,
@Nonnull String type,
@Nullable Collection<? extends AnnotationElement> elements) {
this.visibility = visibility;
this.type = type;
this.elements = ImmutableAnnotationElement.immutableListOf(elements);
this.elements = ImmutableAnnotationElement.immutableSetOf(elements);
}
public ImmutableAnnotation(int visibility,
@Nonnull String type,
@Nullable ImmutableList<? extends ImmutableAnnotationElement> elements) {
@Nullable ImmutableSet<? extends ImmutableAnnotationElement> elements) {
this.visibility = visibility;
this.type = type;
this.elements = ImmutableUtils.nullToEmptyList(elements);
this.elements = ImmutableUtils.nullToEmptySet(elements);
}
public static ImmutableAnnotation of(Annotation annotation) {
@ -75,15 +75,15 @@ public class ImmutableAnnotation extends BaseAnnotation {
@Override public int getVisibility() { return visibility; }
@Nonnull @Override public String getType() { return type; }
@Nonnull @Override public ImmutableList<? extends ImmutableAnnotationElement> getElements() { return elements; }
@Nonnull @Override public ImmutableSet<? extends ImmutableAnnotationElement> getElements() { return elements; }
@Nonnull
public static ImmutableList<ImmutableAnnotation> immutableListOf(@Nullable Iterable<? extends Annotation> list) {
return CONVERTER.convert(list);
public static ImmutableSet<ImmutableAnnotation> immutableSetOf(@Nullable Iterable<? extends Annotation> list) {
return CONVERTER.toSet(list);
}
private static final ImmutableListConverter<ImmutableAnnotation, Annotation> CONVERTER =
new ImmutableListConverter<ImmutableAnnotation, Annotation>() {
private static final ImmutableConverter<ImmutableAnnotation, Annotation> CONVERTER =
new ImmutableConverter<ImmutableAnnotation, Annotation>() {
@Override
protected boolean isImmutable(@Nonnull Annotation item) {
return item instanceof ImmutableAnnotation;

View File

@ -31,20 +31,20 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.BaseAnnotationElement;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.immutable.value.ImmutableEncodedValue;
import org.jf.dexlib2.immutable.value.ImmutableEncodedValueFactory;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ImmutableAnnotationElement extends BaseAnnotationElement {
@Nonnull public final String name;
@Nonnull public final ImmutableEncodedValue value;
@Nonnull protected final String name;
@Nonnull protected final ImmutableEncodedValue value;
public ImmutableAnnotationElement(@Nonnull String name,
@Nonnull EncodedValue value) {
@ -71,13 +71,13 @@ public class ImmutableAnnotationElement extends BaseAnnotationElement {
@Nonnull @Override public EncodedValue getValue() { return value; }
@Nonnull
public static ImmutableList<ImmutableAnnotationElement> immutableListOf(
public static ImmutableSet<ImmutableAnnotationElement> immutableSetOf(
@Nullable Iterable<? extends AnnotationElement> list) {
return CONVERTER.convert(list);
return CONVERTER.toSet(list);
}
private static final ImmutableListConverter<ImmutableAnnotationElement, AnnotationElement> CONVERTER =
new ImmutableListConverter<ImmutableAnnotationElement, AnnotationElement>() {
private static final ImmutableConverter<ImmutableAnnotationElement, AnnotationElement> CONVERTER =
new ImmutableConverter<ImmutableAnnotationElement, AnnotationElement>() {
@Override
protected boolean isImmutable(@Nonnull AnnotationElement item) {
return item instanceof ImmutableAnnotationElement;

View File

@ -31,34 +31,33 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.reference.BaseTypeReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.iface.Method;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
@Nonnull public final String type;
public final int accessFlags;
@Nullable public final String superclass;
@Nonnull public final ImmutableList<String> interfaces;
@Nullable public final String sourceFile;
@Nonnull public final ImmutableList<? extends ImmutableAnnotation> annotations;
@Nonnull public final ImmutableList<? extends ImmutableField> fields;
@Nonnull public final ImmutableList<? extends ImmutableMethod> methods;
@Nonnull protected final String type;
protected final int accessFlags;
@Nullable protected final String superclass;
@Nonnull protected final ImmutableSet<String> interfaces;
@Nullable protected final String sourceFile;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
@Nonnull protected final ImmutableSet<? extends ImmutableField> fields;
@Nonnull protected final ImmutableSet<? extends ImmutableMethod> methods;
public ImmutableClassDef(@Nonnull String type,
int accessFlags,
@Nullable String superclass,
@Nullable List<String> interfaces,
@Nullable Collection<String> interfaces,
@Nullable String sourceFile,
@Nullable Collection<? extends Annotation> annotations,
@Nullable Collection<? extends Field> fields,
@ -66,29 +65,29 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
this.type = type;
this.accessFlags = accessFlags;
this.superclass = superclass;
this.interfaces = interfaces==null ? ImmutableList.<String>of() : ImmutableList.copyOf(interfaces);
this.interfaces = interfaces==null ? ImmutableSet.<String>of() : ImmutableSet.copyOf(interfaces);
this.sourceFile = sourceFile;
this.annotations = ImmutableAnnotation.immutableListOf(annotations);
this.fields = ImmutableField.immutableListOf(fields);
this.methods = ImmutableMethod.immutableListOf(methods);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.fields = ImmutableField.immutableSetOf(fields);
this.methods = ImmutableMethod.immutableSetOf(methods);
}
public ImmutableClassDef(@Nonnull String type,
int accessFlags,
@Nullable String superclass,
@Nullable ImmutableList<String> interfaces,
@Nullable ImmutableSet<String> interfaces,
@Nullable String sourceFile,
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableList<? extends ImmutableField> fields,
@Nullable ImmutableList<? extends ImmutableMethod> methods) {
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableSet<? extends ImmutableField> fields,
@Nullable ImmutableSet<? extends ImmutableMethod> methods) {
this.type = type;
this.accessFlags = accessFlags;
this.superclass = superclass;
this.interfaces = ImmutableUtils.nullToEmptyList(interfaces);
this.interfaces = ImmutableUtils.nullToEmptySet(interfaces);
this.sourceFile = sourceFile;
this.annotations = ImmutableUtils.nullToEmptyList(annotations);
this.fields = ImmutableUtils.nullToEmptyList(fields);
this.methods = ImmutableUtils.nullToEmptyList(methods);
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
this.fields = ImmutableUtils.nullToEmptySet(fields);
this.methods = ImmutableUtils.nullToEmptySet(methods);
}
public static ImmutableClassDef of(ClassDef classDef) {
@ -109,19 +108,19 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef {
@Nonnull @Override public String getType() { return type; }
@Override public int getAccessFlags() { return accessFlags; }
@Nullable @Override public String getSuperclass() { return superclass; }
@Nonnull @Override public ImmutableList<String> getInterfaces() { return interfaces; }
@Nonnull @Override public ImmutableSet<String> getInterfaces() { return interfaces; }
@Nullable @Override public String getSourceFile() { return sourceFile; }
@Nonnull @Override public ImmutableList<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public ImmutableList<? extends ImmutableField> getFields() { return fields; }
@Nonnull @Override public ImmutableList<? extends ImmutableMethod> getMethods() { return methods; }
@Nonnull @Override public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public ImmutableSet<? extends ImmutableField> getFields() { return fields; }
@Nonnull @Override public ImmutableSet<? extends ImmutableMethod> getMethods() { return methods; }
@Nonnull
public static ImmutableList<ImmutableClassDef> immutableListOf(@Nullable List<? extends ClassDef> list) {
return CONVERTER.convert(list);
public static ImmutableSet<ImmutableClassDef> immutableSetOf(@Nullable Iterable<? extends ClassDef> iterable) {
return CONVERTER.toSet(iterable);
}
private static final ImmutableListConverter<ImmutableClassDef, ClassDef> CONVERTER =
new ImmutableListConverter<ImmutableClassDef, ClassDef>() {
private static final ImmutableConverter<ImmutableClassDef, ClassDef> CONVERTER =
new ImmutableConverter<ImmutableClassDef, ClassDef>() {
@Override
protected boolean isImmutable(@Nonnull ClassDef item) {
return item instanceof ImmutableClassDef;

View File

@ -31,24 +31,24 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Collection;
public class ImmutableDexFile implements DexFile {
@Nonnull public final ImmutableList<? extends ImmutableClassDef> classes;
@Nonnull protected final ImmutableSet<? extends ImmutableClassDef> classes;
public ImmutableDexFile(@Nullable List<? extends ClassDef> classes) {
this.classes = ImmutableClassDef.immutableListOf(classes);
public ImmutableDexFile(@Nullable Collection<? extends ClassDef> classes) {
this.classes = ImmutableClassDef.immutableSetOf(classes);
}
public ImmutableDexFile(@Nullable ImmutableList<? extends ImmutableClassDef> classes) {
this.classes = ImmutableUtils.nullToEmptyList(classes);
public ImmutableDexFile(@Nullable ImmutableSet<? extends ImmutableClassDef> classes) {
this.classes = ImmutableUtils.nullToEmptySet(classes);
}
public static ImmutableDexFile of(DexFile dexFile) {
@ -58,5 +58,5 @@ public class ImmutableDexFile implements DexFile {
return new ImmutableDexFile(dexFile.getClasses());
}
@Nonnull @Override public List<? extends ClassDef> getClasses() { return classes; }
@Nonnull @Override public ImmutableSet<? extends ImmutableClassDef> getClasses() { return classes; }
}

View File

@ -31,16 +31,17 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.BaseExceptionHandler;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ImmutableExceptionHandler implements ExceptionHandler {
@Nullable public final String exceptionType;
public final int handlerCodeAddress;
public class ImmutableExceptionHandler extends BaseExceptionHandler implements ExceptionHandler {
@Nullable protected final String exceptionType;
protected final int handlerCodeAddress;
public ImmutableExceptionHandler(@Nullable String exceptionType,
int handlerCodeAddress) {
@ -61,13 +62,13 @@ public class ImmutableExceptionHandler implements ExceptionHandler {
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
@Nonnull
public static ImmutableList<ImmutableExceptionHandler> immutableListOf(
public static ImmutableSet<ImmutableExceptionHandler> immutableSetOf(
@Nullable Iterable<? extends ExceptionHandler> list) {
return CONVERTER.convert(list);
return CONVERTER.toSet(list);
}
private static final ImmutableListConverter<ImmutableExceptionHandler, ExceptionHandler> CONVERTER =
new ImmutableListConverter<ImmutableExceptionHandler, ExceptionHandler>() {
private static final ImmutableConverter<ImmutableExceptionHandler, ExceptionHandler> CONVERTER =
new ImmutableConverter<ImmutableExceptionHandler, ExceptionHandler>() {
@Override
protected boolean isImmutable(@Nonnull ExceptionHandler item) {
return item instanceof ImmutableExceptionHandler;

View File

@ -31,14 +31,14 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.reference.BaseFieldReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Field;
import org.jf.dexlib2.iface.value.EncodedValue;
import org.jf.dexlib2.immutable.value.ImmutableEncodedValue;
import org.jf.dexlib2.immutable.value.ImmutableEncodedValueFactory;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
@ -46,39 +46,39 @@ import javax.annotation.Nullable;
import java.util.Collection;
public class ImmutableField extends BaseFieldReference implements Field {
@Nonnull public final String containingClass;
@Nonnull public final String name;
@Nonnull public final String type;
public final int accessFlags;
@Nullable public final ImmutableEncodedValue initialValue;
@Nonnull public final ImmutableList<? extends ImmutableAnnotation> annotations;
@Nonnull protected final String definingClass;
@Nonnull protected final String name;
@Nonnull protected final String type;
protected final int accessFlags;
@Nullable protected final ImmutableEncodedValue initialValue;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
public ImmutableField(@Nonnull String containingClass,
public ImmutableField(@Nonnull String definingClass,
@Nonnull String name,
@Nonnull String type,
int accessFlags,
@Nullable EncodedValue initialValue,
@Nullable Collection<? extends Annotation> annotations) {
this.containingClass = containingClass;
this.definingClass = definingClass;
this.name = name;
this.type = type;
this.accessFlags = accessFlags;
this.initialValue = ImmutableEncodedValueFactory.ofNullable(initialValue);
this.annotations = ImmutableAnnotation.immutableListOf(annotations);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
}
public ImmutableField(@Nonnull String containingClass,
public ImmutableField(@Nonnull String definingClass,
@Nonnull String name,
@Nonnull String type,
int accessFlags,
@Nullable ImmutableEncodedValue initialValue,
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations) {
this.containingClass = containingClass;
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations) {
this.definingClass = definingClass;
this.name = name;
this.type = type;
this.accessFlags = accessFlags;
this.initialValue = initialValue;
this.annotations = ImmutableUtils.nullToEmptyList(annotations);
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
}
public static ImmutableField of(Field field) {
@ -86,7 +86,7 @@ public class ImmutableField extends BaseFieldReference implements Field {
return (ImmutableField)field;
}
return new ImmutableField(
field.getContainingClass(),
field.getDefiningClass(),
field.getName(),
field.getType(),
field.getAccessFlags(),
@ -94,20 +94,20 @@ public class ImmutableField extends BaseFieldReference implements Field {
field.getAnnotations());
}
@Nonnull @Override public String getContainingClass() { return containingClass; }
@Nonnull @Override public String getDefiningClass() { return definingClass; }
@Nonnull @Override public String getName() { return name; }
@Nonnull @Override public String getType() { return type; }
@Override public int getAccessFlags() { return accessFlags; }
@Override public EncodedValue getInitialValue() { return initialValue;}
@Nonnull @Override public ImmutableList<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull @Override public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull
public static ImmutableList<ImmutableField> immutableListOf(@Nullable Iterable<? extends Field> list) {
return CONVERTER.convert(list);
public static ImmutableSet<ImmutableField> immutableSetOf(@Nullable Iterable<? extends Field> list) {
return CONVERTER.toSet(list);
}
private static final ImmutableListConverter<ImmutableField, Field> CONVERTER =
new ImmutableListConverter<ImmutableField, Field>() {
private static final ImmutableConverter<ImmutableField, Field> CONVERTER =
new ImmutableConverter<ImmutableField, Field>() {
@Override
protected boolean isImmutable(@Nonnull Field item) {
return item instanceof ImmutableField;

View File

@ -32,56 +32,60 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import org.jf.dexlib2.base.reference.BaseMethodReference;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.MethodImplementation;
import org.jf.dexlib2.iface.MethodParameter;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class ImmutableMethod extends BaseMethodReference implements Method {
@Nonnull public final String containingClass;
@Nonnull public final String name;
@Nonnull public final ImmutableList<? extends ImmutableMethodParameter> parameters;
@Nonnull public final String returnType;
public final int accessFlags;
@Nonnull public final ImmutableList<? extends ImmutableAnnotation> annotations;
@Nullable public final ImmutableMethodImplementation methodImplementation;
@Nonnull protected final String definingClass;
@Nonnull protected final String name;
@Nonnull protected final ImmutableList<? extends ImmutableMethodParameter> parameters;
@Nonnull protected final String returnType;
protected final int accessFlags;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
@Nullable protected final ImmutableMethodImplementation methodImplementation;
public ImmutableMethod(@Nonnull String containingClass,
public ImmutableMethod(@Nonnull String definingClass,
@Nonnull String name,
@Nullable Collection<? extends MethodParameter> parameters,
@Nullable List<? extends MethodParameter> parameters,
@Nonnull String returnType,
int accessFlags,
@Nullable Collection<? extends Annotation> annotations,
@Nullable Set<? extends Annotation> annotations,
@Nullable MethodImplementation methodImplementation) {
this.containingClass = containingClass;
this.definingClass = definingClass;
this.name = name;
this.parameters = ImmutableMethodParameter.immutableListOf(parameters);
this.returnType = returnType;
this.accessFlags = accessFlags;
this.annotations = ImmutableAnnotation.immutableListOf(annotations);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.methodImplementation = ImmutableMethodImplementation.of(methodImplementation);
}
public ImmutableMethod(@Nonnull String containingClass,
public ImmutableMethod(@Nonnull String definingClass,
@Nonnull String name,
@Nullable ImmutableList<? extends ImmutableMethodParameter> parameters,
@Nonnull String returnType,
int accessFlags,
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableMethodImplementation methodImplementation) {
this.containingClass = containingClass;
this.definingClass = definingClass;
this.name = name;
this.parameters = ImmutableUtils.nullToEmptyList(parameters);
this.returnType = returnType;
this.accessFlags = accessFlags;
this.annotations = ImmutableUtils.nullToEmptyList(annotations);
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
this.methodImplementation = methodImplementation;
}
@ -90,7 +94,7 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
return (ImmutableMethod)method;
}
return new ImmutableMethod(
method.getContainingClass(),
method.getDefiningClass(),
method.getName(),
method.getParameters(),
method.getReturnType(),
@ -99,21 +103,21 @@ public class ImmutableMethod extends BaseMethodReference implements Method {
method.getImplementation());
}
@Nonnull public String getContainingClass() { return containingClass; }
@Nonnull public String getDefiningClass() { return definingClass; }
@Nonnull public String getName() { return name; }
@Nonnull public ImmutableList<? extends ImmutableMethodParameter> getParameters() { return parameters; }
@Nonnull public String getReturnType() { return returnType; }
public int getAccessFlags() { return accessFlags; }
@Nonnull public ImmutableList<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nonnull public ImmutableSet<? extends ImmutableAnnotation> getAnnotations() { return annotations; }
@Nullable public ImmutableMethodImplementation getImplementation() { return methodImplementation; }
@Nonnull
public static ImmutableList<ImmutableMethod> immutableListOf(@Nullable Iterable<? extends Method> list) {
return CONVERTER.convert(list);
public static ImmutableSortedSet<ImmutableMethod> immutableSetOf(@Nullable Iterable<? extends Method> list) {
return CONVERTER.toSortedSet(Ordering.natural(), list);
}
private static final ImmutableListConverter<ImmutableMethod, Method> CONVERTER =
new ImmutableListConverter<ImmutableMethod, Method>() {
private static final ImmutableConverter<ImmutableMethod, Method> CONVERTER =
new ImmutableConverter<ImmutableMethod, Method>() {
@Override
protected boolean isImmutable(@Nonnull Method item) {
return item instanceof ImmutableMethod;

View File

@ -45,10 +45,10 @@ import javax.annotation.Nullable;
import java.util.List;
public class ImmutableMethodImplementation implements MethodImplementation {
public final int registerCount;
@Nonnull public final ImmutableList<? extends ImmutableInstruction> instructions;
@Nonnull public final ImmutableList<? extends ImmutableTryBlock> tryBlocks;
@Nonnull public final ImmutableList<? extends ImmutableDebugItem> debugItems;
protected final int registerCount;
@Nonnull protected final ImmutableList<? extends ImmutableInstruction> instructions;
@Nonnull protected final ImmutableList<? extends ImmutableTryBlock> tryBlocks;
@Nonnull protected final ImmutableList<? extends ImmutableDebugItem> debugItems;
public ImmutableMethodImplementation(int registerCount,
@Nullable Iterable<? extends Instruction> instructions,

View File

@ -32,35 +32,35 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.base.BaseMethodParameter;
import org.jf.dexlib2.iface.Annotation;
import org.jf.dexlib2.iface.MethodParameter;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class ImmutableMethodParameter extends BaseMethodParameter {
@Nonnull public final String type;
@Nonnull public final ImmutableList<? extends ImmutableAnnotation> annotations;
@Nullable public final String name;
@Nonnull protected final String type;
@Nonnull protected final ImmutableSet<? extends ImmutableAnnotation> annotations;
@Nullable protected final String name;
public ImmutableMethodParameter(@Nonnull String type,
@Nullable Collection<? extends Annotation> annotations,
@Nullable Set<? extends Annotation> annotations,
@Nullable String name) {
this.type = type;
this.annotations = ImmutableAnnotation.immutableListOf(annotations);
this.annotations = ImmutableAnnotation.immutableSetOf(annotations);
this.name = name;
}
public ImmutableMethodParameter(@Nonnull String type,
@Nullable ImmutableList<? extends ImmutableAnnotation> annotations,
@Nullable ImmutableSet<? extends ImmutableAnnotation> annotations,
@Nullable String name) {
this.type = type;
this.annotations = ImmutableUtils.nullToEmptyList(annotations);
this.annotations = ImmutableUtils.nullToEmptySet(annotations);
this.name = name;
}
@ -75,7 +75,7 @@ public class ImmutableMethodParameter extends BaseMethodParameter {
}
@Nonnull @Override public String getType() { return type; }
@Nonnull @Override public List<? extends Annotation> getAnnotations() { return annotations; }
@Nonnull @Override public Set<? extends Annotation> getAnnotations() { return annotations; }
@Nullable @Override public String getName() { return name; }
//TODO: iterate over the annotations to get the signature
@ -84,11 +84,11 @@ public class ImmutableMethodParameter extends BaseMethodParameter {
@Nonnull
public static ImmutableList<ImmutableMethodParameter> immutableListOf(
@Nullable Iterable<? extends MethodParameter> list) {
return CONVERTER.convert(list);
return CONVERTER.toList(list);
}
private static final ImmutableListConverter<ImmutableMethodParameter, MethodParameter> CONVERTER =
new ImmutableListConverter<ImmutableMethodParameter, MethodParameter>() {
private static final ImmutableConverter<ImmutableMethodParameter, MethodParameter> CONVERTER =
new ImmutableConverter<ImmutableMethodParameter, MethodParameter>() {
@Override
protected boolean isImmutable(@Nonnull MethodParameter item) {
return item instanceof ImmutableMethodParameter;

View File

@ -32,35 +32,36 @@
package org.jf.dexlib2.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.dexlib2.iface.TryBlock;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import org.jf.util.ImmutableUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class ImmutableTryBlock implements TryBlock {
public final int startCodeAddress;
public final int codeUnitCount;
@Nonnull public final ImmutableList<? extends ImmutableExceptionHandler> exceptionHandlers;
protected final int startCodeAddress;
protected final int codeUnitCount;
@Nonnull protected final ImmutableSet<? extends ImmutableExceptionHandler> exceptionHandlers;
public ImmutableTryBlock(int startCodeAddress,
int codeUnitCount,
@Nullable Collection<? extends ExceptionHandler> exceptionHandlers) {
@Nullable Set<? extends ExceptionHandler> exceptionHandlers) {
this.startCodeAddress = startCodeAddress;
this.codeUnitCount = codeUnitCount;
this.exceptionHandlers = ImmutableExceptionHandler.immutableListOf(exceptionHandlers);
this.exceptionHandlers = ImmutableExceptionHandler.immutableSetOf(exceptionHandlers);
}
public ImmutableTryBlock(int startCodeAddress,
int codeUnitCount,
@Nullable ImmutableList<? extends ImmutableExceptionHandler> exceptionHandlers) {
@Nullable ImmutableSet<? extends ImmutableExceptionHandler> exceptionHandlers) {
this.startCodeAddress = startCodeAddress;
this.codeUnitCount = codeUnitCount;
this.exceptionHandlers = ImmutableUtils.nullToEmptyList(exceptionHandlers);
this.exceptionHandlers = ImmutableUtils.nullToEmptySet(exceptionHandlers);
}
public static ImmutableTryBlock of(TryBlock tryBlock) {
@ -76,17 +77,17 @@ public class ImmutableTryBlock implements TryBlock {
@Override public int getStartCodeAddress() { return startCodeAddress; }
@Override public int getCodeUnitCount() { return codeUnitCount; }
@Nonnull @Override public ImmutableList<? extends ImmutableExceptionHandler> getExceptionHandlers() {
@Nonnull @Override public ImmutableSet<? extends ImmutableExceptionHandler> getExceptionHandlers() {
return exceptionHandlers;
}
@Nonnull
public static ImmutableList<ImmutableTryBlock> immutableListOf(@Nullable List<? extends TryBlock> list) {
return CONVERTER.convert(list);
return CONVERTER.toList(list);
}
private static final ImmutableListConverter<ImmutableTryBlock, TryBlock> CONVERTER =
new ImmutableListConverter<ImmutableTryBlock, TryBlock>() {
private static final ImmutableConverter<ImmutableTryBlock, TryBlock> CONVERTER =
new ImmutableConverter<ImmutableTryBlock, TryBlock>() {
@Override
protected boolean isImmutable(@Nonnull TryBlock item) {
return item instanceof ImmutableTryBlock;

View File

@ -35,13 +35,13 @@ import com.google.common.collect.ImmutableList;
import org.jf.dexlib2.DebugItemType;
import org.jf.dexlib2.iface.debug.*;
import org.jf.util.ExceptionWithContext;
import org.jf.util.ImmutableListConverter;
import org.jf.util.ImmutableConverter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class ImmutableDebugItem implements DebugItem {
public final int codeAddress;
protected final int codeAddress;
public ImmutableDebugItem(int codeAddress) {
this.codeAddress = codeAddress;
@ -76,11 +76,11 @@ public abstract class ImmutableDebugItem implements DebugItem {
@Nonnull
public static ImmutableList<ImmutableDebugItem> immutableListOf(@Nullable Iterable<? extends DebugItem> list) {
return CONVERTER.convert(list);
return CONVERTER.toList(list);
}
private static final ImmutableListConverter<ImmutableDebugItem, DebugItem> CONVERTER =
new ImmutableListConverter<ImmutableDebugItem, DebugItem>() {
private static final ImmutableConverter<ImmutableDebugItem, DebugItem> CONVERTER =
new ImmutableConverter<ImmutableDebugItem, DebugItem>() {
@Override
protected boolean isImmutable(@Nonnull DebugItem item) {
return item instanceof ImmutableDebugItem;

View File

@ -38,10 +38,10 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ImmutableEndLocal extends ImmutableDebugItem implements EndLocal {
public final int register;
@Nullable public final String name;
@Nullable public final String type;
@Nullable public final String signature;
protected final int register;
@Nullable protected final String name;
@Nullable protected final String type;
@Nullable protected final String signature;
public ImmutableEndLocal(int codeAddress,
int register) {

Some files were not shown because too many files have changed in this diff Show More