From a8e05220c14778d93c97911044ff5124aadbd77c Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 4 Nov 2012 13:04:21 -0800 Subject: [PATCH] Refactor how method/field/string/type references are handled --- .../jf/baksmali/Adaptors/ClassDefinition.java | 12 +- .../EncodedValue/EncodedValueAdaptor.java | 5 +- .../Format/InstructionMethodItem.java | 8 +- .../baksmali/Adaptors/ReferenceFormatter.java | 21 +++- .../main/java/org/jf/baksmali/baksmali.java | 4 - .../dexlib2/dexbacked/DexBackedClassDef.java | 4 +- .../jf/dexlib2/dexbacked/DexBackedField.java | 5 + .../jf/dexlib2/dexbacked/DexBackedMethod.java | 1 + .../org/jf/dexlib2/dexbacked/DexBuffer.java | 20 ++-- .../instruction/DexBackedInstruction.java | 23 ++-- .../reference/DexBackedFieldReference.java | 65 +++++++++++ .../reference/DexBackedMethodReference.java | 105 ++++++++++++++++++ .../reference/DexBackedReference.java | 56 ++++++++++ .../reference/DexBackedStringReference.java | 53 +++++++++ .../reference/DexBackedTypeReference.java | 52 +++++++++ .../value/DexBackedEncodedValue.java | 8 +- .../main/java/org/jf/dexlib2/iface/Field.java | 4 +- .../java/org/jf/dexlib2/iface/Method.java | 5 +- .../org/jf/dexlib2/iface/MethodParameter.java | 3 +- .../instruction/ReferenceInstruction.java | 4 +- .../instruction/formats/Instruction22c.java | 2 +- .../iface/reference/BasicMethodParameter.java | 38 +++++++ .../iface/reference/FieldReference.java | 40 +++++++ .../iface/reference/MethodReference.java | 42 +++++++ .../jf/dexlib2/iface/reference/Reference.java | 35 ++++++ .../iface/reference/StringReference.java | 38 +++++++ .../iface/reference/TypeReference.java | 38 +++++++ .../iface/value/FieldEncodedValue.java | 4 +- .../iface/value/MethodEncodedValue.java | 4 +- .../jf/dexlib2/immutable/ImmutableField.java | 11 +- .../jf/dexlib2/immutable/ImmutableMethod.java | 16 ++- .../instruction/ImmutableInstruction.java | 3 +- .../instruction/ImmutableInstruction21c.java | 12 +- .../instruction/ImmutableInstruction22c.java | 10 +- .../instruction/ImmutableInstruction31c.java | 10 +- .../instruction/ImmutableInstruction35c.java | 10 +- .../instruction/ImmutableInstruction3rc.java | 10 +- .../ImmutableBasicMethodParameter.java | 77 +++++++++++++ .../reference/ImmutableFieldReference.java | 65 +++++++++++ .../reference/ImmutableMethodReference.java | 85 ++++++++++++++ .../reference/ImmutableReference.java | 72 ++++++++++++ .../reference/ImmutableStringReference.java | 54 +++++++++ .../reference/ImmutableTypeReference.java | 54 +++++++++ .../value/ImmutableFieldEncodedValue.java | 7 +- .../value/ImmutableMethodEncodedValue.java | 7 +- .../org/jf/dexlib2/util/Preconditions.java | 6 +- .../org/jf/dexlib2/util/ReferenceUtil.java | 87 +++++++++++++++ .../util/InstructionOffsetMapTest.java | 16 ++- 48 files changed, 1216 insertions(+), 95 deletions(-) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedFieldReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedStringReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedTypeReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/BasicMethodParameter.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/FieldReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/Reference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/StringReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/TypeReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableBasicMethodParameter.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableFieldReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableStringReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableTypeReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java index d9543847..be2091fc 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ClassDefinition.java @@ -30,32 +30,30 @@ package org.jf.baksmali.Adaptors; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.iface.*; -import org.jf.dexlib2.iface.instruction.Instruction; -import org.jf.dexlib2.iface.instruction.formats.Instruction21c; import org.jf.util.StringUtils; import org.jf.util.IndentingWriter; import javax.annotation.Nonnull; import java.io.IOException; -import java.util.HashSet; import java.util.List; public class ClassDefinition { @Nonnull public final ClassDef classDef; - @Nonnull private final HashSet fieldsSetInStaticConstructor; + //@Nonnull private final HashSet fieldsSetInStaticConstructor; protected boolean validationErrors; public ClassDefinition(ClassDef classDef) { this.classDef = classDef; - fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); + //fieldsSetInStaticConstructor = findFieldsSetInStaticConstructor(); } public boolean hadValidationErrors() { return validationErrors; } - @Nonnull + //TODO: uncomment + /*@Nonnull private HashSet findFieldsSetInStaticConstructor() { HashSet fieldsSetInStaticConstructor = new HashSet(); @@ -85,7 +83,7 @@ public class ClassDefinition { } } return fieldsSetInStaticConstructor; - } + }*/ public void writeTo(IndentingWriter writer) throws IOException { writeClass(writer); diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/EncodedValue/EncodedValueAdaptor.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/EncodedValue/EncodedValueAdaptor.java index ee3f69af..19f8750e 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/EncodedValue/EncodedValueAdaptor.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/EncodedValue/EncodedValueAdaptor.java @@ -31,6 +31,7 @@ package org.jf.baksmali.Adaptors.EncodedValue; import org.jf.baksmali.Adaptors.ReferenceFormatter; import org.jf.dexlib2.ValueType; import org.jf.dexlib2.iface.value.*; +import org.jf.dexlib2.util.ReferenceUtil; import org.jf.util.IndentingWriter; import org.jf.baksmali.Renderers.*; @@ -62,7 +63,7 @@ public abstract class EncodedValueAdaptor { writer.write(((EnumEncodedValue)encodedValue).getValue()); return; case ValueType.FIELD: - writer.write(((FieldEncodedValue)encodedValue).getValue()); + ReferenceUtil.writeFieldDescriptor(writer, ((FieldEncodedValue)encodedValue).getValue()); return; case ValueType.FLOAT: FloatRenderer.writeTo(writer, ((FloatEncodedValue)encodedValue).getValue()); @@ -74,7 +75,7 @@ public abstract class EncodedValueAdaptor { LongRenderer.writeTo(writer, ((LongEncodedValue)encodedValue).getValue()); return; case ValueType.METHOD: - writer.write(((MethodEncodedValue)encodedValue).getValue()); + ReferenceUtil.writeMethodDescriptor(writer, ((MethodEncodedValue)encodedValue).getValue()); return; case ValueType.NULL: writer.write("null"); diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java index 30127730..884643d3 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java @@ -339,12 +339,8 @@ public class InstructionMethodItem extends MethodItem { }*/ protected void writeReference(IndentingWriter writer) throws IOException { - String reference = ((ReferenceInstruction)instruction).getReference(); - if (instruction.getOpcode().referenceType == ReferenceType.STRING) { - ReferenceFormatter.writeStringReference(writer, reference); - } else { - writer.write(reference); - } + ReferenceFormatter.writeReference(writer, instruction.getOpcode().referenceType, + ((ReferenceInstruction)instruction).getReference()); } //TODO: uncomment diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ReferenceFormatter.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ReferenceFormatter.java index 92bbc095..a39b66d6 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/ReferenceFormatter.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/ReferenceFormatter.java @@ -28,8 +28,10 @@ package org.jf.baksmali.Adaptors; +import org.jf.dexlib2.ReferenceType; +import org.jf.dexlib2.iface.reference.*; +import org.jf.dexlib2.util.ReferenceUtil; import org.jf.util.IndentingWriter; -import org.jf.dexlib.*; import org.jf.util.StringUtils; import java.io.IOException; @@ -40,4 +42,21 @@ public class ReferenceFormatter { StringUtils.writeEscapedString(writer, item); writer.write('"'); } + + public static void writeReference(IndentingWriter writer, int referenceType, + Reference reference) throws IOException { + switch (referenceType) { + case ReferenceType.STRING: + writeStringReference(writer, ((StringReference)reference).getString()); + return; + case ReferenceType.TYPE: + writer.write(((TypeReference)reference).getType()); + return; + case ReferenceType.METHOD: + ReferenceUtil.writeMethodDescriptor(writer, (MethodReference)reference); + return; + case ReferenceType.FIELD: + ReferenceUtil.writeFieldDescriptor(writer, (FieldReference)reference); + } + } } diff --git a/baksmali/src/main/java/org/jf/baksmali/baksmali.java b/baksmali/src/main/java/org/jf/baksmali/baksmali.java index 9d5c3ad1..83d79d2d 100644 --- a/baksmali/src/main/java/org/jf/baksmali/baksmali.java +++ b/baksmali/src/main/java/org/jf/baksmali/baksmali.java @@ -29,7 +29,6 @@ package org.jf.baksmali; import org.jf.baksmali.Adaptors.ClassDefinition; -import org.jf.dexlib.ClassDefItem; import org.jf.dexlib.Code.Analysis.*; import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.DexFile; @@ -37,9 +36,6 @@ import org.jf.util.ClassFileNameHandler; import org.jf.util.IndentingWriter; import java.io.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedClassDef.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedClassDef.java index 589137ce..ddb8a223 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedClassDef.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedClassDef.java @@ -149,8 +149,8 @@ public class DexBackedClassDef implements ClassDef { previousFieldIndex = 0; annotationIterator.reset(); } - DexBackedField item = new DexBackedField(reader, previousFieldIndex, - staticInitialValueIterator, annotationIterator); + DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this, + previousFieldIndex, staticInitialValueIterator, annotationIterator); previousFieldIndex = item.fieldIndex; return item; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedField.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedField.java index 339a01ce..86a74467 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedField.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedField.java @@ -33,6 +33,7 @@ package org.jf.dexlib2.dexbacked; import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory; import org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator; +import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.Field; import org.jf.dexlib2.iface.value.EncodedValue; @@ -42,6 +43,7 @@ import java.util.List; public class DexBackedField implements Field { @Nonnull public final DexBuffer dexBuf; + @Nonnull public final ClassDef classDef; public final int accessFlags; @Nullable public final EncodedValue initialValue; @@ -56,10 +58,12 @@ public class DexBackedField implements Field { private static final int NAME_OFFSET = 4; public DexBackedField(@Nonnull DexReader reader, + @Nonnull DexBackedClassDef classDef, int previousFieldIndex, @Nonnull StaticInitialValueIterator staticInitialValueIterator, @Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) { this.dexBuf = reader.getDexBuffer(); + this.classDef = classDef; int fieldIndexDiff = reader.readSmallUleb128(); this.fieldIndex = fieldIndexDiff + previousFieldIndex; @@ -81,6 +85,7 @@ public class DexBackedField implements Field { return dexBuf.getType(dexBuf.readUshort(getFieldIdItemOffset() + TYPE_OFFSET)); } + @Nonnull @Override public String getContainingClass() { return classDef.getName(); } @Override public int getAccessFlags() { return accessFlags; } @Nullable @Override public EncodedValue getInitialValue() { return initialValue; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedMethod.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedMethod.java index c22f3cf9..3bda2427 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedMethod.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedMethod.java @@ -98,6 +98,7 @@ public class DexBackedMethod implements Method { this.parameterAnnotationSetListOffset = paramaterAnnotationIterator.seekTo(methodIndex); } + @Nonnull @Override public String getContainingClass() { return classDef.getName(); } @Override public int getAccessFlags() { return accessFlags; } @Nonnull diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBuffer.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBuffer.java index cb495fcc..206139a6 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBuffer.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBuffer.java @@ -82,19 +82,19 @@ public class DexBuffer { private static final int METHOD_ID_ITEM_SIZE = 8; private static final int CLASS_DEF_ITEM_SIZE = 32; - private static final int FIELD_CLASS_IDX_OFFSET = 0; - private static final int FIELD_TYPE_IDX_OFFSET = 2; - private static final int FIELD_NAME_IDX_OFFSET = 4; + public static final int FIELD_CLASS_IDX_OFFSET = 0; + public static final int FIELD_TYPE_IDX_OFFSET = 2; + public static final int FIELD_NAME_IDX_OFFSET = 4; - private static final int METHOD_CLASS_IDX_OFFSET = 0; - private static final int METHOD_PROTO_IDX_OFFSET = 2; - private static final int METHOD_NAME_IDX_OFFSET = 4; + public static final int METHOD_CLASS_IDX_OFFSET = 0; + public static final int METHOD_PROTO_IDX_OFFSET = 2; + public static final int METHOD_NAME_IDX_OFFSET = 4; - private static final int PROTO_RETURN_TYPE_IDX_OFFSET = 4; - private static final int PROTO_PARAM_LIST_OFF_OFFSET = 8; + public static final int PROTO_RETURN_TYPE_IDX_OFFSET = 4; + public static final int PROTO_PARAM_LIST_OFF_OFFSET = 8; - private static final int TYPE_LIST_SIZE_OFFSET = 0; - private static final int TYPE_LIST_LIST_OFFSET = 4; + public static final int TYPE_LIST_SIZE_OFFSET = 0; + public static final int TYPE_LIST_LIST_OFFSET = 4; protected DexBuffer(@Nonnull byte[] buf, boolean bare) { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java index 0fefcf0f..87be4ace 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java @@ -31,10 +31,13 @@ package org.jf.dexlib2.dexbacked.instruction; +import org.jf.dexlib2.dexbacked.DexBuffer; import org.jf.dexlib2.dexbacked.DexReader; import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.dexbacked.reference.DexBackedReference; import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.formats.*; +import org.jf.dexlib2.iface.reference.Reference; import org.jf.dexlib2.immutable.instruction.*; import org.jf.util.ExceptionWithContext; import org.jf.util.NibbleUtils; @@ -165,9 +168,10 @@ public abstract class DexBackedInstruction { @Nonnull private static Instruction21c instruction21c(@Nonnull Opcode opcode, @Nonnull DexReader reader) { + DexBuffer dexBuf = reader.getDexBuffer(); int registerA = reader.readUbyte(); int referenceIndex = reader.readUshort(); - String reference = reader.getReference(opcode.referenceType, referenceIndex); + Reference reference = DexBackedReference.makeReference(dexBuf, opcode.referenceType, referenceIndex); return new ImmutableInstruction21c(opcode, registerA, reference); } @@ -209,12 +213,12 @@ public abstract class DexBackedInstruction { @Nonnull private static Instruction22c instruction22c(@Nonnull Opcode opcode, @Nonnull DexReader reader) { + DexBuffer dexBuf = reader.getDexBuffer(); int b = reader.readUbyte(); int registerA = NibbleUtils.extractLowUnsignedNibble(b); int registerB = NibbleUtils.extractHighUnsignedNibble(b); - int referenceIndex = reader.readUshort(); - String reference = reader.getReference(opcode.referenceType, referenceIndex); + Reference reference = DexBackedReference.makeReference(dexBuf, opcode.referenceType, referenceIndex); return new ImmutableInstruction22c(opcode, registerA, registerB, reference); } @@ -260,9 +264,10 @@ public abstract class DexBackedInstruction { @Nonnull private static Instruction31c instruction31c(@Nonnull Opcode opcode, @Nonnull DexReader reader) { + DexBuffer dexBuf = reader.getDexBuffer(); int registerA = reader.readUbyte(); int referenceIndex = reader.readSmallUint(); - String reference = reader.getReference(opcode.referenceType, referenceIndex); + Reference reference = DexBackedReference.makeReference(dexBuf, opcode.referenceType, referenceIndex); return new ImmutableInstruction31c(opcode, registerA, reference); } @@ -290,12 +295,12 @@ public abstract class DexBackedInstruction { @Nonnull private static Instruction35c instruction35c(@Nonnull Opcode opcode, @Nonnull DexReader reader) { + DexBuffer dexBuf = reader.getDexBuffer(); int b = reader.readUbyte(); int registerCount = NibbleUtils.extractHighUnsignedNibble(b); int registerG = NibbleUtils.extractLowUnsignedNibble(b); int referenceIndex = reader.readUshort(); - String reference = reader.getReference(opcode.referenceType, referenceIndex); b = reader.readUbyte(); int registerC = NibbleUtils.extractLowUnsignedNibble(b); @@ -305,16 +310,18 @@ public abstract class DexBackedInstruction { int registerE = NibbleUtils.extractLowUnsignedNibble(b); int registerF = NibbleUtils.extractHighUnsignedNibble(b); - return new ImmutableInstruction35c(opcode, registerCount, registerC, registerD, - registerE, registerF, registerG, reference); + Reference reference = DexBackedReference.makeReference(dexBuf, opcode.referenceType, referenceIndex); + return new ImmutableInstruction35c(opcode, registerCount, registerC, registerD, registerE, registerF, + registerG, reference); } @Nonnull private static Instruction3rc instruction3rc(@Nonnull Opcode opcode, @Nonnull DexReader reader) { + DexBuffer dexBuf = reader.getDexBuffer(); int registerCount = reader.readUbyte(); int referenceIndex = reader.readUshort(); - String reference = reader.getReference(opcode.referenceType, referenceIndex); int startRegister = reader.readUshort(); + Reference reference = DexBackedReference.makeReference(dexBuf, opcode.referenceType, referenceIndex); return new ImmutableInstruction3rc(opcode, startRegister, registerCount, reference); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedFieldReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedFieldReference.java new file mode 100644 index 00000000..afebd7b1 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedFieldReference.java @@ -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.reference; + +import org.jf.dexlib2.dexbacked.DexBuffer; +import org.jf.dexlib2.iface.reference.FieldReference; + +import javax.annotation.Nonnull; + +public class DexBackedFieldReference implements FieldReference { + @Nonnull public final DexBuffer dexBuf; + public final int fieldIdItemOffset; + + public DexBackedFieldReference(@Nonnull DexBuffer dexBuf, int fieldIndex) { + this.dexBuf = dexBuf; + this.fieldIdItemOffset = dexBuf.getFieldIdItemOffset(fieldIndex); + } + + @Nonnull + @Override + public String getContainingClass() { + return dexBuf.getType(dexBuf.readUshort(fieldIdItemOffset + DexBuffer.FIELD_CLASS_IDX_OFFSET)); + } + + @Nonnull + @Override + public String getName() { + return dexBuf.getString(dexBuf.readSmallUint(fieldIdItemOffset + DexBuffer.FIELD_NAME_IDX_OFFSET)); + } + + @Nonnull + @Override + public String getType() { + return dexBuf.getType(dexBuf.readUshort(fieldIdItemOffset + DexBuffer.FIELD_TYPE_IDX_OFFSET)); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodReference.java new file mode 100644 index 00000000..37041350 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodReference.java @@ -0,0 +1,105 @@ +/* + * 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.reference; + +import com.google.common.collect.ImmutableList; +import org.jf.dexlib2.dexbacked.DexBuffer; +import org.jf.dexlib2.dexbacked.util.FixedSizeList; +import org.jf.dexlib2.iface.reference.BasicMethodParameter; +import org.jf.dexlib2.iface.reference.MethodReference; + +import javax.annotation.Nonnull; +import java.util.List; + +public class DexBackedMethodReference implements MethodReference { + @Nonnull public final DexBuffer dexBuf; + public final int methodIdItemOffset; + private int protoIdItemOffset; + + public DexBackedMethodReference(@Nonnull DexBuffer dexBuf, int methodIndex) { + this.dexBuf = dexBuf; + this.methodIdItemOffset = dexBuf.getMethodIdItemOffset(methodIndex); + } + + @Nonnull + @Override + public String getContainingClass() { + return dexBuf.getType(dexBuf.readUshort(methodIdItemOffset + DexBuffer.METHOD_CLASS_IDX_OFFSET)); + } + + @Nonnull + @Override + public String getName() { + return dexBuf.getString(dexBuf.readSmallUint(methodIdItemOffset + DexBuffer.METHOD_NAME_IDX_OFFSET)); + } + + @Nonnull + @Override + public List getParameters() { + int protoIdItemOffset = getProtoIdItemOffset(); + final int parametersOffset = dexBuf.readSmallUint(protoIdItemOffset + DexBuffer.PROTO_PARAM_LIST_OFF_OFFSET); + if (parametersOffset > 0) { + final int parameterCount = dexBuf.readSmallUint(parametersOffset + DexBuffer.TYPE_LIST_SIZE_OFFSET); + final int paramListStart = parametersOffset + DexBuffer.TYPE_LIST_LIST_OFFSET; + return new FixedSizeList() { + @Nonnull + @Override + public BasicMethodParameter readItem(final int index) { + return new BasicMethodParameter() { + @Nonnull + @Override + public String getType() { + return dexBuf.getType(dexBuf.readUshort(paramListStart + 2*index)); + } + }; + } + @Override public int size() { return parameterCount; } + }; + } + return ImmutableList.of(); + } + + @Nonnull + @Override + public String getReturnType() { + int protoIdItemOffset = getProtoIdItemOffset(); + return dexBuf.getType(dexBuf.readSmallUint(protoIdItemOffset + DexBuffer.PROTO_RETURN_TYPE_IDX_OFFSET)); + } + + private int getProtoIdItemOffset() { + if (protoIdItemOffset == 0) { + protoIdItemOffset = dexBuf.getProtoIdItemOffset( + dexBuf.readUshort(methodIdItemOffset + DexBuffer.METHOD_PROTO_IDX_OFFSET)); + } + return protoIdItemOffset; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java new file mode 100644 index 00000000..a8912903 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java @@ -0,0 +1,56 @@ +/* + * 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.reference; + +import org.jf.dexlib2.ReferenceType; +import org.jf.dexlib2.dexbacked.DexBuffer; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.util.ExceptionWithContext; + +import javax.annotation.Nonnull; + +public abstract class DexBackedReference { + public static Reference makeReference(@Nonnull DexBuffer dexBuf, int referenceType, int referenceIndex) { + switch (referenceType) { + case ReferenceType.STRING: + return new DexBackedStringReference(dexBuf, referenceIndex); + case ReferenceType.TYPE: + return new DexBackedTypeReference(dexBuf, referenceIndex); + case ReferenceType.METHOD: + return new DexBackedMethodReference(dexBuf, referenceIndex); + case ReferenceType.FIELD: + return new DexBackedFieldReference(dexBuf, referenceIndex); + default: + throw new ExceptionWithContext("Invalid reference type: %d", referenceType); + } + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedStringReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedStringReference.java new file mode 100644 index 00000000..7d52edcb --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedStringReference.java @@ -0,0 +1,53 @@ +/* + * 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.reference; + +import org.jf.dexlib2.dexbacked.DexBuffer; +import org.jf.dexlib2.iface.reference.StringReference; + +import javax.annotation.Nonnull; + +public class DexBackedStringReference implements StringReference { + @Nonnull public final DexBuffer dexBuf; + public final int stringIndex; + + public DexBackedStringReference(@Nonnull DexBuffer dexBuf, + int stringIndex) { + this.dexBuf = dexBuf; + this.stringIndex = stringIndex; + } + + @Nonnull + public String getString() { + return dexBuf.getString(stringIndex); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedTypeReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedTypeReference.java new file mode 100644 index 00000000..2cce7ecd --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedTypeReference.java @@ -0,0 +1,52 @@ +/* + * 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.reference; + +import org.jf.dexlib2.dexbacked.DexBuffer; +import org.jf.dexlib2.iface.reference.TypeReference; + +import javax.annotation.Nonnull; + +public class DexBackedTypeReference implements TypeReference { + @Nonnull public final DexBuffer dexBuf; + public final int typeIndex; + + public DexBackedTypeReference(@Nonnull DexBuffer dexBuf, + int typeIndex) { + this.dexBuf = dexBuf; + this.typeIndex = typeIndex; + } + + @Nonnull public String getType() { + return dexBuf.getType(typeIndex); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/value/DexBackedEncodedValue.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/value/DexBackedEncodedValue.java index 254ddebc..b5c91c1d 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/value/DexBackedEncodedValue.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/value/DexBackedEncodedValue.java @@ -31,6 +31,8 @@ package org.jf.dexlib2.dexbacked.value; +import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference; +import org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference; import org.jf.dexlib2.dexbacked.DexReader; import org.jf.dexlib2.ValueType; import org.jf.dexlib2.iface.value.EncodedValue; @@ -82,10 +84,12 @@ public abstract class DexBackedEncodedValue { return new ImmutableTypeEncodedValue(reader.getType(reader.readSizedSmallUint(valueArg + 1))); case ValueType.FIELD: Preconditions.checkValueArg(valueArg, 3); - return new ImmutableFieldEncodedValue(reader.getField(reader.readSizedSmallUint(valueArg + 1))); + return new ImmutableFieldEncodedValue(new DexBackedFieldReference(reader.getDexBuffer(), + reader.readSizedSmallUint(valueArg + 1))); case ValueType.METHOD: Preconditions.checkValueArg(valueArg, 3); - return new ImmutableMethodEncodedValue(reader.getMethod(reader.readSizedSmallUint(valueArg + 1))); + return new ImmutableMethodEncodedValue(new DexBackedMethodReference(reader.getDexBuffer(), + reader.readSizedSmallUint(valueArg + 1))); case ValueType.ENUM: Preconditions.checkValueArg(valueArg, 3); return new ImmutableEnumEncodedValue(reader.getField(reader.readSizedSmallUint(valueArg + 1))); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/Field.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/Field.java index 13a38388..14cb66f9 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/Field.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/Field.java @@ -31,13 +31,15 @@ package org.jf.dexlib2.iface; +import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.value.EncodedValue; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; -public interface Field { +public interface Field extends FieldReference { + @Nonnull String getContainingClass(); @Nonnull String getName(); @Nonnull String getType(); int getAccessFlags(); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/Method.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/Method.java index b501a26a..fb582d1b 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/Method.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/Method.java @@ -31,11 +31,14 @@ package org.jf.dexlib2.iface; +import org.jf.dexlib2.iface.reference.MethodReference; + import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; -public interface Method { +public interface Method extends MethodReference { + @Nonnull String getContainingClass(); @Nonnull String getName(); @Nonnull List getParameters(); @Nonnull String getReturnType(); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/MethodParameter.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/MethodParameter.java index 9ba7242a..5b77baac 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/MethodParameter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/MethodParameter.java @@ -32,12 +32,13 @@ package org.jf.dexlib2.iface; import org.jf.dexlib2.iface.debug.LocalInfo; +import org.jf.dexlib2.iface.reference.BasicMethodParameter; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; -public interface MethodParameter extends LocalInfo { +public interface MethodParameter extends LocalInfo, BasicMethodParameter { @Nonnull String getType(); @Nonnull List getAnnotations(); @Nullable String getName(); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/ReferenceInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/ReferenceInstruction.java index 549c9309..3f557fb7 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/ReferenceInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/ReferenceInstruction.java @@ -31,8 +31,10 @@ package org.jf.dexlib2.iface.instruction; +import org.jf.dexlib2.iface.reference.Reference; + import javax.annotation.Nonnull; public interface ReferenceInstruction extends Instruction { - @Nonnull String getReference(); + @Nonnull Reference getReference(); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22c.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22c.java index 871fcdd3..d255f341 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction22c.java @@ -34,5 +34,5 @@ package org.jf.dexlib2.iface.instruction.formats; import org.jf.dexlib2.iface.instruction.ReferenceInstruction; import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction; -public interface Instruction22c extends TwoRegisterInstruction, ReferenceInstruction{ +public interface Instruction22c extends TwoRegisterInstruction, ReferenceInstruction { } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/BasicMethodParameter.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/BasicMethodParameter.java new file mode 100644 index 00000000..6eaca50a --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/BasicMethodParameter.java @@ -0,0 +1,38 @@ +/* + * 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.reference; + +import javax.annotation.Nonnull; + +public interface BasicMethodParameter { + @Nonnull String getType(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/FieldReference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/FieldReference.java new file mode 100644 index 00000000..4966922a --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/FieldReference.java @@ -0,0 +1,40 @@ +/* + * 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.reference; + +import javax.annotation.Nonnull; + +public interface FieldReference extends Reference { + @Nonnull String getContainingClass(); + @Nonnull String getName(); + @Nonnull String getType(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodReference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodReference.java new file mode 100644 index 00000000..1a3ec249 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodReference.java @@ -0,0 +1,42 @@ +/* + * 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.reference; + +import javax.annotation.Nonnull; +import java.util.List; + +public interface MethodReference extends Reference { + @Nonnull String getContainingClass(); + @Nonnull String getName(); + @Nonnull List getParameters(); + @Nonnull String getReturnType(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/Reference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/Reference.java new file mode 100644 index 00000000..be0c5ba4 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/Reference.java @@ -0,0 +1,35 @@ +/* + * 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.reference; + +public interface Reference { +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/StringReference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/StringReference.java new file mode 100644 index 00000000..2e9332fc --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/StringReference.java @@ -0,0 +1,38 @@ +/* + * 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.reference; + +import javax.annotation.Nonnull; + +public interface StringReference extends Reference { + @Nonnull String getString(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/TypeReference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/TypeReference.java new file mode 100644 index 00000000..b39928b6 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/TypeReference.java @@ -0,0 +1,38 @@ +/* + * 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.reference; + +import javax.annotation.Nonnull; + +public interface TypeReference extends Reference { + @Nonnull String getType(); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/value/FieldEncodedValue.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/value/FieldEncodedValue.java index c3c93600..8534cd04 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/value/FieldEncodedValue.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/value/FieldEncodedValue.java @@ -31,8 +31,10 @@ package org.jf.dexlib2.iface.value; +import org.jf.dexlib2.iface.reference.FieldReference; + import javax.annotation.Nonnull; public interface FieldEncodedValue extends EncodedValue { - @Nonnull String getValue(); + @Nonnull FieldReference getValue(); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/value/MethodEncodedValue.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/value/MethodEncodedValue.java index 923c019a..3e62bf4b 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/value/MethodEncodedValue.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/value/MethodEncodedValue.java @@ -31,8 +31,10 @@ package org.jf.dexlib2.iface.value; +import org.jf.dexlib2.iface.reference.MethodReference; + import javax.annotation.Nonnull; public interface MethodEncodedValue extends EncodedValue { - @Nonnull String getValue(); + @Nonnull MethodReference getValue(); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableField.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableField.java index a9f895f8..ce1e1505 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableField.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableField.java @@ -44,17 +44,20 @@ import javax.annotation.Nullable; import java.util.List; public class ImmutableField 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 annotations; - public ImmutableField(@Nonnull String name, + public ImmutableField(@Nonnull String containingClass, + @Nonnull String name, @Nonnull String type, int accessFlags, @Nullable EncodedValue initialValue, @Nullable List annotations) { + this.containingClass = containingClass; this.name = name; this.type = type; this.accessFlags = accessFlags; @@ -62,11 +65,13 @@ public class ImmutableField implements Field { this.annotations = ImmutableAnnotation.immutableListOf(annotations); } - public ImmutableField(@Nonnull String name, + public ImmutableField(@Nonnull String containingClass, + @Nonnull String name, @Nonnull String type, int accessFlags, @Nullable ImmutableEncodedValue initialValue, @Nullable ImmutableList annotations) { + this.containingClass = containingClass; this.name = name; this.type = type; this.accessFlags = accessFlags; @@ -79,6 +84,7 @@ public class ImmutableField implements Field { return (ImmutableField)field; } return new ImmutableField( + field.getContainingClass(), field.getName(), field.getType(), field.getAccessFlags(), @@ -86,6 +92,7 @@ public class ImmutableField implements Field { field.getAnnotations()); } + @Nonnull @Override public String getContainingClass() { return containingClass; } @Nonnull @Override public String getName() { return name; } @Nonnull @Override public String getType() { return type; } @Override public int getAccessFlags() { return accessFlags; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableMethod.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableMethod.java index ec195e6d..df36a24e 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableMethod.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableMethod.java @@ -33,10 +33,7 @@ package org.jf.dexlib2.immutable; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; -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.dexlib2.iface.*; import org.jf.util.ImmutableListConverter; import javax.annotation.Nonnull; @@ -44,6 +41,7 @@ import javax.annotation.Nullable; import java.util.List; public class ImmutableMethod implements Method { + @Nonnull public final String containingClass; @Nonnull public final String name; @Nonnull public final ImmutableList parameters; @Nonnull public final String returnType; @@ -51,12 +49,14 @@ public class ImmutableMethod implements Method { @Nonnull public final ImmutableList annotations; @Nullable public final ImmutableMethodImplementation methodImplementation; - public ImmutableMethod(@Nonnull String name, + public ImmutableMethod(@Nonnull String containingClass, + @Nonnull String name, @Nullable List parameters, @Nonnull String returnType, int accessFlags, @Nullable List annotations, @Nullable MethodImplementation methodImplementation) { + this.containingClass = containingClass; this.name = name; this.parameters = ImmutableMethodParameter.immutableListOf(parameters); this.returnType = returnType; @@ -65,12 +65,14 @@ public class ImmutableMethod implements Method { this.methodImplementation = ImmutableMethodImplementation.of(methodImplementation); } - public ImmutableMethod(@Nonnull String name, + public ImmutableMethod(@Nonnull String containingClass, + @Nonnull String name, @Nullable ImmutableList parameters, @Nonnull String returnType, int accessFlags, @Nullable ImmutableList annotations, @Nullable ImmutableMethodImplementation methodImplementation) { + this.containingClass = containingClass; this.name = name; this.parameters = Objects.firstNonNull(parameters, ImmutableList.of()); this.returnType = returnType; @@ -84,6 +86,7 @@ public class ImmutableMethod implements Method { return (ImmutableMethod)method; } return new ImmutableMethod( + method.getContainingClass(), method.getName(), method.getParameters(), method.getReturnType(), @@ -92,6 +95,7 @@ public class ImmutableMethod implements Method { method.getImplementation()); } + @Nonnull public String getContainingClass() { return containingClass; } @Nonnull public String getName() { return name; } @Nonnull public ImmutableList getParameters() { return parameters; } @Nonnull public String getReturnType() { return returnType; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java index 7add448a..18d3984f 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java @@ -34,13 +34,14 @@ package org.jf.dexlib2.immutable.instruction; import com.google.common.collect.ImmutableList; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.ReferenceType; import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.formats.*; +import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.util.Preconditions; import org.jf.util.ImmutableListConverter; import javax.annotation.Nonnull; -import java.util.List; public abstract class ImmutableInstruction implements Instruction { @Nonnull public final Opcode opcode; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction21c.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction21c.java index 8f2b3926..5a40776c 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction21c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction21c.java @@ -34,6 +34,8 @@ package org.jf.dexlib2.immutable.instruction; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.iface.instruction.formats.Instruction21c; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.util.Preconditions; import javax.annotation.Nonnull; @@ -42,15 +44,15 @@ public class ImmutableInstruction21c extends ImmutableInstruction implements Ins public static final Format FORMAT = Format.Format21c; public final int registerA; - @Nonnull public final String reference; + @Nonnull public final ImmutableReference reference; public ImmutableInstruction21c(@Nonnull Opcode opcode, - int registerA, - @Nonnull String reference) { + int registerA, + @Nonnull Reference reference) { super(opcode); Preconditions.checkFormat(opcode, FORMAT); this.registerA = Preconditions.checkByteRegister(registerA); - this.reference = Preconditions.checkReference(reference, opcode.referenceType); + this.reference = ImmutableReference.of(opcode.referenceType, reference); } public static ImmutableInstruction21c of(Instruction21c instruction) { @@ -64,7 +66,7 @@ public class ImmutableInstruction21c extends ImmutableInstruction implements Ins } @Override public int getRegisterA() { return registerA; } - @Nonnull @Override public String getReference() { return reference; } + @Nonnull @Override public ImmutableReference getReference() { return reference; } @Override public Format getFormat() { return FORMAT; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22c.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22c.java index 40573791..eac8ed86 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction22c.java @@ -34,6 +34,8 @@ package org.jf.dexlib2.immutable.instruction; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.iface.instruction.formats.Instruction22c; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.util.Preconditions; import javax.annotation.Nonnull; @@ -43,17 +45,17 @@ public class ImmutableInstruction22c extends ImmutableInstruction implements Ins public final int registerA; public final int registerB; - public final String reference; + @Nonnull public final ImmutableReference reference; public ImmutableInstruction22c(@Nonnull Opcode opcode, int registerA, int registerB, - @Nonnull String reference) { + @Nonnull Reference reference) { super(opcode); Preconditions.checkFormat(opcode, FORMAT); this.registerA = Preconditions.checkNibbleRegister(registerA); this.registerB = Preconditions.checkNibbleRegister(registerB); - this.reference = Preconditions.checkReference(reference, opcode.referenceType); + this.reference = ImmutableReference.of(opcode.referenceType, reference); } public static ImmutableInstruction22c of(Instruction22c instruction) { @@ -69,7 +71,7 @@ public class ImmutableInstruction22c extends ImmutableInstruction implements Ins @Override public int getRegisterA() { return registerA; } @Override public int getRegisterB() { return registerB; } - @Nonnull @Override public String getReference() { return reference; } + @Nonnull @Override public ImmutableReference getReference() { return reference; } @Override public Format getFormat() { return FORMAT; } } \ No newline at end of file diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction31c.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction31c.java index b3db36ed..96e3a8e6 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction31c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction31c.java @@ -34,6 +34,8 @@ package org.jf.dexlib2.immutable.instruction; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.iface.instruction.formats.Instruction31c; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.util.Preconditions; import javax.annotation.Nonnull; @@ -42,15 +44,15 @@ public class ImmutableInstruction31c extends ImmutableInstruction implements Ins public static final Format FORMAT = Format.Format31c; public final int registerA; - @Nonnull public final String reference; + @Nonnull public final ImmutableReference reference; public ImmutableInstruction31c(@Nonnull Opcode opcode, int registerA, - @Nonnull String reference) { + @Nonnull Reference reference) { super(opcode); Preconditions.checkFormat(opcode, FORMAT); this.registerA = Preconditions.checkByteRegister(registerA); - this.reference = Preconditions.checkReference(reference, opcode.referenceType); + this.reference = ImmutableReference.of(opcode.referenceType, reference); } public static ImmutableInstruction31c of(Instruction31c instruction) { @@ -64,7 +66,7 @@ public class ImmutableInstruction31c extends ImmutableInstruction implements Ins } @Override public int getRegisterA() { return registerA; } - @Nonnull @Override public String getReference() { return reference; } + @Nonnull @Override public ImmutableReference getReference() { return reference; } @Override public Format getFormat() { return FORMAT; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java index 662b5bab..0d30c510 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java @@ -34,6 +34,8 @@ package org.jf.dexlib2.immutable.instruction; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.iface.instruction.formats.Instruction35c; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.util.Preconditions; import javax.annotation.Nonnull; @@ -47,7 +49,7 @@ public class ImmutableInstruction35c extends ImmutableInstruction implements Ins public final int registerE; public final int registerF; public final int registerG; - @Nonnull public final String reference; + @Nonnull public final ImmutableReference reference; public ImmutableInstruction35c(@Nonnull Opcode opcode, int registerCount, @@ -56,7 +58,7 @@ public class ImmutableInstruction35c extends ImmutableInstruction implements Ins int registerE, int registerF, int registerG, - @Nonnull String reference) { + @Nonnull Reference reference) { super(opcode); Preconditions.checkFormat(opcode, FORMAT); this.registerCount = Preconditions.check35cRegisterCount(registerCount); @@ -65,7 +67,7 @@ public class ImmutableInstruction35c extends ImmutableInstruction implements Ins this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; this.registerF = (registerCount>3) ? Preconditions.checkNibbleRegister(registerF) : 0; this.registerG = (registerCount>4) ? Preconditions.checkNibbleRegister(registerG) : 0; - this.reference = Preconditions.checkReference(reference, opcode.referenceType); + this.reference = ImmutableReference.of(opcode.referenceType, reference); } public static ImmutableInstruction35c of(Instruction35c instruction) { @@ -89,7 +91,7 @@ public class ImmutableInstruction35c extends ImmutableInstruction implements Ins @Override public int getRegisterE() { return registerE; } @Override public int getRegisterF() { return registerF; } @Override public int getRegisterG() { return registerG; } - @Nonnull @Override public String getReference() { return reference; } + @Nonnull @Override public ImmutableReference getReference() { return reference; } @Override public Format getFormat() { return FORMAT; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction3rc.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction3rc.java index 26514921..d64f6bb4 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction3rc.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction3rc.java @@ -34,6 +34,8 @@ package org.jf.dexlib2.immutable.instruction; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.iface.instruction.formats.Instruction3rc; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.util.Preconditions; import javax.annotation.Nonnull; @@ -44,17 +46,17 @@ public class ImmutableInstruction3rc extends ImmutableInstruction implements Ins public final int startRegister; public final int registerCount; - @Nonnull public final String reference; + @Nonnull public final ImmutableReference reference; public ImmutableInstruction3rc(@Nonnull Opcode opcode, int startRegister, int registerCount, - @Nonnull String reference) { + @Nonnull Reference reference) { super(opcode); Preconditions.checkFormat(opcode, Format.Format3rc); this.startRegister = Preconditions.checkShortRegister(startRegister); this.registerCount = Preconditions.check3rcRegisterCount(registerCount); - this.reference = Preconditions.checkReference(reference, opcode.referenceType); + this.reference = ImmutableReference.of(opcode.referenceType, reference); } public static ImmutableInstruction3rc of(Instruction3rc instruction) { @@ -70,7 +72,7 @@ public class ImmutableInstruction3rc extends ImmutableInstruction implements Ins @Override public int getStartRegister() { return startRegister; } @Override public int getRegisterCount() { return registerCount; } - @Nonnull @Override public String getReference() { return reference; } + @Nonnull @Override public ImmutableReference getReference() { return reference; } @Override public Format getFormat() { return FORMAT; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableBasicMethodParameter.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableBasicMethodParameter.java new file mode 100644 index 00000000..cae0f056 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableBasicMethodParameter.java @@ -0,0 +1,77 @@ +/* + * 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.immutable.reference; + +import com.google.common.collect.ImmutableList; +import org.jf.dexlib2.iface.reference.BasicMethodParameter; +import org.jf.util.ImmutableListConverter; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ImmutableBasicMethodParameter implements BasicMethodParameter { + @Nonnull public final String type; + + public ImmutableBasicMethodParameter(@Nonnull String type) { + this.type = type; + } + + @Nonnull + public static ImmutableBasicMethodParameter of(@Nonnull BasicMethodParameter param) { + if (param instanceof ImmutableBasicMethodParameter) { + return (ImmutableBasicMethodParameter)param; + } + return new ImmutableBasicMethodParameter(param.getType()); + } + + @Nonnull @Override public String getType() { return type; } + + @Nonnull + public static ImmutableList immutableListOf( + @Nullable List list) { + return CONVERTER.convert(list); + } + + private static final ImmutableListConverter CONVERTER = + new ImmutableListConverter() { + @Override + protected boolean isImmutable(BasicMethodParameter item) { + return item instanceof ImmutableBasicMethodParameter; + } + + @Override + protected ImmutableBasicMethodParameter makeImmutable(BasicMethodParameter item) { + return ImmutableBasicMethodParameter.of(item); + } + }; +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableFieldReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableFieldReference.java new file mode 100644 index 00000000..7adf63a4 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableFieldReference.java @@ -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.immutable.reference; + +import org.jf.dexlib2.iface.reference.FieldReference; + +import javax.annotation.Nonnull; + +public class ImmutableFieldReference extends ImmutableReference implements FieldReference { + @Nonnull public final String containingClass; + @Nonnull public final String name; + @Nonnull public final String type; + + public ImmutableFieldReference(@Nonnull String containingClass, + @Nonnull String name, + @Nonnull String type) { + this.containingClass = containingClass; + this.name = name; + this.type = type; + } + + @Nonnull + public static ImmutableFieldReference of(@Nonnull FieldReference fieldReference) { + if (fieldReference instanceof ImmutableFieldReference) { + return (ImmutableFieldReference)fieldReference; + } + return new ImmutableFieldReference( + fieldReference.getContainingClass(), + fieldReference.getName(), + fieldReference.getType()); + } + + @Nonnull public String getContainingClass() { return containingClass; } + @Nonnull public String getName() { return name; } + @Nonnull public String getType() { return type; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodReference.java new file mode 100644 index 00000000..cbb98971 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodReference.java @@ -0,0 +1,85 @@ +/* + * 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.immutable.reference; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; +import org.jf.dexlib2.iface.reference.BasicMethodParameter; +import org.jf.dexlib2.iface.reference.MethodReference; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +public class ImmutableMethodReference extends ImmutableReference implements MethodReference { + @Nonnull public final String containingClass; + @Nonnull public final String name; + @Nonnull public final ImmutableList parameters; + @Nonnull public final String returnType; + + public ImmutableMethodReference(@Nonnull String containingClass, + @Nonnull String name, + @Nullable List parameters, + @Nonnull String returnType) { + this.containingClass = containingClass; + this.name = name; + this.parameters = ImmutableBasicMethodParameter.immutableListOf(parameters); + this.returnType = returnType; + } + + public ImmutableMethodReference(@Nonnull String containingClass, + @Nonnull String name, + @Nullable ImmutableList parameters, + @Nonnull String returnType) { + this.containingClass = containingClass; + this.name = name; + this.parameters = Objects.firstNonNull(parameters, ImmutableList.of()); + this.returnType = returnType; + } + + @Nonnull + public static ImmutableMethodReference of(@Nonnull MethodReference methodReference) { + if (methodReference instanceof ImmutableMethodReference) { + return (ImmutableMethodReference)methodReference; + } + return new ImmutableMethodReference( + methodReference.getContainingClass(), + methodReference.getName(), + ImmutableList.copyOf(methodReference.getParameters()), + methodReference.getReturnType()); + } + + @Nonnull @Override public String getContainingClass() { return containingClass; } + @Nonnull @Override public String getName() { return name; } + @Nonnull @Override public List getParameters() { return parameters; } + @Nonnull @Override public String getReturnType() { return returnType; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReference.java new file mode 100644 index 00000000..c007f0fa --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReference.java @@ -0,0 +1,72 @@ +/* + * 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.immutable.reference; + +import org.jf.dexlib2.ReferenceType; +import org.jf.dexlib2.iface.reference.*; +import org.jf.util.ExceptionWithContext; + +import javax.annotation.Nonnull; + +public class ImmutableReference implements Reference { + @Nonnull + public static ImmutableReference of(Reference reference) { + if (reference instanceof StringReference) { + return ImmutableStringReference.of((StringReference)reference); + } + if (reference instanceof TypeReference) { + return ImmutableTypeReference.of((TypeReference)reference); + } + if (reference instanceof FieldReference) { + return ImmutableFieldReference.of((FieldReference)reference); + } + if (reference instanceof MethodReference) { + return ImmutableMethodReference.of((MethodReference)reference); + } + throw new ExceptionWithContext("Invalid reference type"); + } + + @Nonnull + public static ImmutableReference of(int referenceType, Reference reference) { + switch (referenceType) { + case ReferenceType.STRING: + return ImmutableStringReference.of((StringReference)reference); + case ReferenceType.TYPE: + return ImmutableTypeReference.of((TypeReference)reference); + case ReferenceType.FIELD: + return ImmutableFieldReference.of((FieldReference)reference); + case ReferenceType.METHOD: + return ImmutableMethodReference.of((MethodReference)reference); + } + throw new ExceptionWithContext("Invalid reference type: %d", referenceType); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableStringReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableStringReference.java new file mode 100644 index 00000000..beae6115 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableStringReference.java @@ -0,0 +1,54 @@ +/* + * 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.immutable.reference; + +import org.jf.dexlib2.iface.reference.StringReference; + +import javax.annotation.Nonnull; + +public class ImmutableStringReference extends ImmutableReference implements StringReference { + @Nonnull public final String str; + + public ImmutableStringReference(String str) { + this.str = str; + } + + @Nonnull + public static ImmutableStringReference of(@Nonnull StringReference stringReference) { + if (stringReference instanceof ImmutableStringReference) { + return (ImmutableStringReference)stringReference; + } + return new ImmutableStringReference(stringReference.getString()); + } + + @Nonnull @Override public String getString() { return str; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableTypeReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableTypeReference.java new file mode 100644 index 00000000..5cbe2c39 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableTypeReference.java @@ -0,0 +1,54 @@ +/* + * 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.immutable.reference; + +import org.jf.dexlib2.iface.reference.TypeReference; + +import javax.annotation.Nonnull; + +public class ImmutableTypeReference extends ImmutableReference implements TypeReference { + @Nonnull public final String type; + + public ImmutableTypeReference(String type) { + this.type = type; + } + + @Nonnull + public static ImmutableTypeReference of(@Nonnull TypeReference typeReference) { + if (typeReference instanceof ImmutableTypeReference) { + return (ImmutableTypeReference)typeReference; + } + return new ImmutableTypeReference(typeReference.getType()); + } + + @Nonnull @Override public String getType() { return type; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableFieldEncodedValue.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableFieldEncodedValue.java index eaa7541a..5ce04fd2 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableFieldEncodedValue.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableFieldEncodedValue.java @@ -32,14 +32,15 @@ package org.jf.dexlib2.immutable.value; import org.jf.dexlib2.ValueType; +import org.jf.dexlib2.iface.reference.FieldReference; import org.jf.dexlib2.iface.value.FieldEncodedValue; import javax.annotation.Nonnull; public class ImmutableFieldEncodedValue extends ImmutableEncodedValue implements FieldEncodedValue { - @Nonnull public final String value; + @Nonnull public final FieldReference value; - public ImmutableFieldEncodedValue(@Nonnull String value) { + public ImmutableFieldEncodedValue(@Nonnull FieldReference value) { super(ValueType.FIELD); this.value = value; } @@ -52,7 +53,7 @@ public class ImmutableFieldEncodedValue extends ImmutableEncodedValue implements } @Nonnull - public String getValue() { + public FieldReference getValue() { return value; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableMethodEncodedValue.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableMethodEncodedValue.java index 97360366..772ca9a1 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableMethodEncodedValue.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/value/ImmutableMethodEncodedValue.java @@ -32,15 +32,16 @@ package org.jf.dexlib2.immutable.value; import org.jf.dexlib2.ValueType; +import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.dexlib2.iface.value.MethodEncodedValue; import javax.annotation.Nonnull; public class ImmutableMethodEncodedValue extends ImmutableEncodedValue implements MethodEncodedValue { @Nonnull - public final String value; + public final MethodReference value; - public ImmutableMethodEncodedValue(@Nonnull String value) { + public ImmutableMethodEncodedValue(@Nonnull MethodReference value) { super(ValueType.METHOD); this.value = value; } @@ -53,7 +54,7 @@ public class ImmutableMethodEncodedValue extends ImmutableEncodedValue implement } @Nonnull - public String getValue() { + public MethodReference getValue() { return value; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java index 4e4b3dcd..5ded0643 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -33,6 +33,7 @@ package org.jf.dexlib2.util; import org.jf.dexlib2.Format; import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.iface.reference.Reference; public class Preconditions { public static void checkFormat(Opcode opcode, Format expectedFormat) { @@ -122,11 +123,6 @@ public class Preconditions { return register; } - public static String checkReference(String reference, int referenceType) { - //TODO: implement this - return reference; - } - public static int check35cRegisterCount(int registerCount) { if (registerCount < 0 || registerCount > 5) { throw new IllegalArgumentException( diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java new file mode 100644 index 00000000..7925dc17 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java @@ -0,0 +1,87 @@ +/* + * 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.util; + +import org.jf.dexlib2.iface.reference.BasicMethodParameter; +import org.jf.dexlib2.iface.reference.FieldReference; +import org.jf.dexlib2.iface.reference.MethodReference; + +import java.io.IOException; +import java.io.Writer; + +public abstract class ReferenceUtil { + public static String getMethodDescriptor(MethodReference methodReference) { + // TODO: try using a thread local StringBuilder + StringBuilder sb = new StringBuilder(); + sb.append(methodReference.getContainingClass()); + sb.append("->"); + sb.append(methodReference.getName()); + sb.append('('); + for (BasicMethodParameter param: methodReference.getParameters()) { + sb.append(param.getType()); + } + sb.append(')'); + sb.append(methodReference.getReturnType()); + return sb.toString(); + } + + public static void writeMethodDescriptor(Writer writer, MethodReference methodReference) throws IOException { + writer.write(methodReference.getContainingClass()); + writer.write("->"); + writer.write(methodReference.getName()); + writer.write('('); + for (BasicMethodParameter param: methodReference.getParameters()) { + writer.write(param.getType()); + } + writer.write(')'); + writer.write(methodReference.getReturnType()); + } + + public static String getFieldDescriptor(FieldReference fieldReference) { + // TODO: try using a thread local StringBuilder + StringBuilder sb = new StringBuilder(); + sb.append(fieldReference.getContainingClass()); + sb.append("->"); + sb.append(fieldReference.getName()); + sb.append(':'); + sb.append(fieldReference.getType()); + return sb.toString(); + } + + public static void writeFieldDescriptor(Writer writer, FieldReference fieldReference) throws IOException { + writer.write(fieldReference.getContainingClass()); + writer.write("->"); + writer.write(fieldReference.getName()); + writer.write(':'); + writer.write(fieldReference.getType()); + } +} diff --git a/dexlib2/src/test/java/org/jf/dexlib2/util/InstructionOffsetMapTest.java b/dexlib2/src/test/java/org/jf/dexlib2/util/InstructionOffsetMapTest.java index 1732529d..37a94506 100644 --- a/dexlib2/src/test/java/org/jf/dexlib2/util/InstructionOffsetMapTest.java +++ b/dexlib2/src/test/java/org/jf/dexlib2/util/InstructionOffsetMapTest.java @@ -36,6 +36,8 @@ import junit.framework.Assert; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.immutable.ImmutableMethodImplementation; import org.jf.dexlib2.immutable.instruction.*; +import org.jf.dexlib2.immutable.reference.ImmutableStringReference; +import org.jf.dexlib2.immutable.reference.ImmutableTypeReference; import org.jf.util.ExceptionWithContext; import org.junit.Test; @@ -49,24 +51,28 @@ public class InstructionOffsetMapTest { /*03: 0x03*/ new ImmutableInstruction11x(Opcode.RETURN, 4), /*04: 0x04*/ new ImmutableInstruction12x(Opcode.ARRAY_LENGTH, 5, 6), /*05: 0x05*/ new ImmutableInstruction20t(Opcode.GOTO_16, 7), - /*06: 0x07*/ new ImmutableInstruction21c(Opcode.SGET, 8, "Lclass;->field:Ltype;"), + /*06: 0x07*/ new ImmutableInstruction21c(Opcode.CONST_STRING, 8, new ImmutableStringReference("blah")), /*07: 0x09*/ new ImmutableInstruction21ih(Opcode.CONST_HIGH16, 9, 0x10000), /*08: 0x0b*/ new ImmutableInstruction21lh(Opcode.CONST_WIDE_HIGH16, 10, 0x1000000000000L), /*09: 0x0d*/ new ImmutableInstruction21s(Opcode.CONST_16, 11, 12), /*10: 0x0f*/ new ImmutableInstruction21t(Opcode.IF_EQZ, 12, 13), /*11: 0x11*/ new ImmutableInstruction22b(Opcode.ADD_INT_LIT8, 14, 15, 16), - /*12: 0x13*/ new ImmutableInstruction22c(Opcode.INSTANCE_OF, 0, 1, "Ltype;"), + /*12: 0x13*/ new ImmutableInstruction22c(Opcode.INSTANCE_OF, 0, 1, + new ImmutableTypeReference("Ltype;")), /*13: 0x15*/ new ImmutableInstruction22s(Opcode.ADD_INT_LIT16, 2, 3, 17), /*14: 0x17*/ new ImmutableInstruction22t(Opcode.IF_EQ, 4, 5, 18), /*15: 0x19*/ new ImmutableInstruction22x(Opcode.MOVE_FROM16, 19, 20), /*16: 0x1b*/ new ImmutableInstruction23x(Opcode.AGET, 21, 22, 23), /*17: 0x1d*/ new ImmutableInstruction30t(Opcode.GOTO_32, 24), - /*18: 0x20*/ new ImmutableInstruction31c(Opcode.CONST_STRING_JUMBO, 25, "this is a string"), + /*18: 0x20*/ new ImmutableInstruction31c(Opcode.CONST_STRING_JUMBO, 25, + new ImmutableStringReference("this is a string")), /*19: 0x23*/ new ImmutableInstruction31i(Opcode.CONST, 26, 27), /*20: 0x26*/ new ImmutableInstruction31t(Opcode.FILL_ARRAY_DATA, 28, 29), /*21: 0x29*/ new ImmutableInstruction32x(Opcode.MOVE_16, 30, 31), - /*22: 0x2c*/ new ImmutableInstruction35c(Opcode.INVOKE_STATIC, 0, 0, 0, 0, 0, 0, "Lclass;->method()V"), - /*23: 0x2f*/ new ImmutableInstruction3rc(Opcode.INVOKE_STATIC_RANGE, 0, 0, "Lclass;->method()V" ), + /*22: 0x2c*/ new ImmutableInstruction35c(Opcode.FILLED_NEW_ARRAY, 0, 0, 0, 0, 0, 0, + new ImmutableTypeReference("Ltype;")), + /*23: 0x2f*/ new ImmutableInstruction3rc(Opcode.FILLED_NEW_ARRAY_RANGE, 0, 0, + new ImmutableTypeReference("Ltype;")), /*24: 0x32*/ new ImmutableInstruction51l(Opcode.CONST_WIDE, 32, 33), /*25: 0x37*/ new ImmutableInstruction10t(Opcode.GOTO, 1) );