Add new experimental dex rewriter functionality
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationElementRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationElementRewriter.java
new file mode 100644
index 0000000..945f022
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationElementRewriter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.BaseAnnotationElement;
+import org.jf.dexlib2.iface.AnnotationElement;
+import org.jf.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+
+public class AnnotationElementRewriter implements Rewriter<AnnotationElement> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public AnnotationElementRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public AnnotationElement rewrite(@Nonnull AnnotationElement annotationElement) {
+ return new RewrittenAnnotationElement(annotationElement);
+ }
+
+ protected class RewrittenAnnotationElement extends BaseAnnotationElement {
+ @Nonnull protected AnnotationElement annotationElement;
+
+ public RewrittenAnnotationElement(@Nonnull AnnotationElement annotationElement) {
+ this.annotationElement = annotationElement;
+ }
+
+ @Nonnull @Override public String getName() {
+ return annotationElement.getName();
+ }
+
+ @Nonnull @Override public EncodedValue getValue() {
+ return rewriters.getEncodedValueRewriter().rewrite(annotationElement.getValue());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationRewriter.java
new file mode 100644
index 0000000..725d2f2
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/AnnotationRewriter.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.BaseAnnotation;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.AnnotationElement;
+
+import javax.annotation.Nonnull;
+import java.util.Set;
+
+public class AnnotationRewriter implements Rewriter<Annotation> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public AnnotationRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public Annotation rewrite(@Nonnull Annotation value) {
+ return new RewrittenAnnotation(value);
+ }
+
+ protected class RewrittenAnnotation extends BaseAnnotation {
+ @Nonnull protected Annotation annotation;
+
+ public RewrittenAnnotation(@Nonnull Annotation annotation) {
+ this.annotation = annotation;
+ }
+
+ @Override public int getVisibility() {
+ return annotation.getVisibility();
+ }
+
+ @Override @Nonnull public String getType() {
+ return rewriters.getTypeRewriter().rewrite(annotation.getType());
+ }
+
+ @Override @Nonnull public Set<? extends AnnotationElement> getElements() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationElementRewriter(), annotation.getElements());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ClassDefRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ClassDefRewriter.java
new file mode 100644
index 0000000..ad246e5
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ClassDefRewriter.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import com.google.common.collect.Iterators;
+import org.jf.dexlib2.base.reference.BaseTypeReference;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.ClassDef;
+import org.jf.dexlib2.iface.Field;
+import org.jf.dexlib2.iface.Method;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Iterator;
+import java.util.Set;
+
+public class ClassDefRewriter implements Rewriter<ClassDef> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public ClassDefRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public ClassDef rewrite(@Nonnull ClassDef classDef) {
+ return new RewrittenClassDef(classDef);
+ }
+
+ protected class RewrittenClassDef extends BaseTypeReference implements ClassDef {
+ @Nonnull protected ClassDef classDef;
+
+ public RewrittenClassDef(@Nonnull ClassDef classdef) {
+ this.classDef = classdef;
+ }
+
+ @Override @Nonnull public String getType() {
+ return rewriters.getTypeRewriter().rewrite(classDef.getType());
+ }
+
+ @Override public int getAccessFlags() {
+ return classDef.getAccessFlags();
+ }
+
+ @Override @Nullable public String getSuperclass() {
+ return RewriterUtils.rewriteNullable(rewriters.getTypeRewriter(), classDef.getSuperclass());
+ }
+
+ @Override @Nonnull public Set<String> getInterfaces() {
+ return RewriterUtils.rewriteSet(rewriters.getTypeRewriter(), classDef.getInterfaces());
+ }
+
+ @Override @Nullable public String getSourceFile() {
+ return classDef.getSourceFile();
+ }
+
+ @Override @Nonnull public Set<? extends Annotation> getAnnotations() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), classDef.getAnnotations());
+ }
+
+ @Override @Nonnull public Iterable<? extends Field> getStaticFields() {
+ return RewriterUtils.rewriteIterable(rewriters.getFieldRewriter(), classDef.getStaticFields());
+ }
+
+ @Override @Nonnull public Iterable<? extends Field> getInstanceFields() {
+ return RewriterUtils.rewriteIterable(rewriters.getFieldRewriter(), classDef.getInstanceFields());
+ }
+
+ @Nonnull
+ @Override
+ public Iterable<? extends Field> getFields() {
+ return new Iterable<Field>() {
+ @Nonnull
+ @Override
+ public Iterator<Field> iterator() {
+ return Iterators.concat(getStaticFields().iterator(), getInstanceFields().iterator());
+ }
+ };
+ }
+
+ @Override @Nonnull public Iterable<? extends Method> getDirectMethods() {
+ return RewriterUtils.rewriteIterable(rewriters.getMethodRewriter(), classDef.getDirectMethods());
+ }
+
+ @Override @Nonnull public Iterable<? extends Method> getVirtualMethods() {
+ return RewriterUtils.rewriteIterable(rewriters.getMethodRewriter(), classDef.getVirtualMethods());
+ }
+
+ @Nonnull
+ @Override
+ public Iterable<? extends Method> getMethods() {
+ return new Iterable<Method>() {
+ @Nonnull
+ @Override
+ public Iterator<Method> iterator() {
+ return Iterators.concat(getDirectMethods().iterator(), getVirtualMethods().iterator());
+ }
+ };
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DebugItemRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DebugItemRewriter.java
new file mode 100644
index 0000000..4fc753a
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DebugItemRewriter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.DebugItemType;
+import org.jf.dexlib2.iface.debug.*;
+import org.jf.dexlib2.iface.reference.StringReference;
+import org.jf.dexlib2.iface.reference.TypeReference;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class DebugItemRewriter implements Rewriter<DebugItem> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public DebugItemRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public DebugItem rewrite(@Nonnull DebugItem value) {
+ switch (value.getDebugItemType()) {
+ case DebugItemType.START_LOCAL:
+ return new RewrittenStartLocal((StartLocal)value);
+ case DebugItemType.END_LOCAL:
+ return new RewrittenEndLocal((EndLocal)value);
+ case DebugItemType.RESTART_LOCAL:
+ return new RewrittenRestartLocal((RestartLocal)value);
+ default:
+ return value;
+ }
+ }
+
+ protected class BaseRewrittenLocalInfoDebugItem<T extends DebugItem & LocalInfo> implements DebugItem, LocalInfo {
+ @Nonnull protected T debugItem;
+
+ public BaseRewrittenLocalInfoDebugItem (@Nonnull T debugItem) {
+ this.debugItem = debugItem;
+ }
+
+ @Override public int getDebugItemType() {
+ return debugItem.getDebugItemType();
+ }
+
+ @Override public int getCodeAddress() {
+ return debugItem.getCodeAddress();
+ }
+
+ @Override @Nullable public String getName() {
+ return debugItem.getName();
+ }
+
+ @Override @Nullable public String getType() {
+ return RewriterUtils.rewriteNullable(rewriters.getTypeRewriter(), debugItem.getType());
+ }
+
+ @Override @Nullable public String getSignature() {
+ return debugItem.getSignature();
+ }
+ }
+
+ protected class RewrittenStartLocal extends BaseRewrittenLocalInfoDebugItem<StartLocal> implements StartLocal {
+ public RewrittenStartLocal(@Nonnull StartLocal debugItem) {
+ super(debugItem);
+ }
+
+ @Override public int getRegister() {
+ return debugItem.getRegister();
+ }
+
+ @Override @Nullable public StringReference getNameReference() {
+ return debugItem.getNameReference();
+ }
+
+ @Override @Nullable public TypeReference getTypeReference() {
+ TypeReference typeReference = debugItem.getTypeReference();
+ if (typeReference == null) {
+ return null;
+ }
+
+ return RewriterUtils.rewriteTypeReference(rewriters.getTypeRewriter(), typeReference);
+ }
+
+ @Override @Nullable public StringReference getSignatureReference() {
+ return debugItem.getSignatureReference();
+ }
+ }
+
+ protected class RewrittenEndLocal extends BaseRewrittenLocalInfoDebugItem<EndLocal> implements EndLocal {
+ public RewrittenEndLocal(@Nonnull EndLocal instruction) {
+ super(instruction);
+ }
+
+ public int getRegister() {
+ return debugItem.getRegister();
+ }
+ }
+
+ protected class RewrittenRestartLocal extends BaseRewrittenLocalInfoDebugItem<RestartLocal>
+ implements RestartLocal {
+ public RewrittenRestartLocal(@Nonnull RestartLocal instruction) {
+ super(instruction);
+ }
+
+ public int getRegister() {
+ return debugItem.getRegister();
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DexRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DexRewriter.java
new file mode 100644
index 0000000..e482cd0
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/DexRewriter.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.iface.*;
+import org.jf.dexlib2.iface.debug.DebugItem;
+import org.jf.dexlib2.iface.instruction.Instruction;
+import org.jf.dexlib2.iface.reference.FieldReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+import org.jf.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+import java.util.Set;
+
+/**
+ * Out-of-the box, this class does nothing except make a picture-perfect copy of a dex file.
+ *
+ * However, it provides many points where you can hook into this process and selectively modify
+ * the dex file. For example, If you want to rename all instances (including definitions and references)
+ * of the class Lorg/blah/MyBlah; to Lorg/blah/YourBlah;
+ *
+ * <pre>
+ * {@code
+ * DexRewriter rewriter = new DexRewriter(new RewriterModule() {
+ * public Rewriter<String> getTypeRewriter(Rewriters rewriters) {
+ * return new Rewriter<String>() {
+ * public String rewrite(String value) {
+ * if (value.equals("Lorg/blah/MyBlah;")) {
+ * return "Lorg/blah/YourBlah;";
+ * }
+ * return value;
+ * }
+ * };
+ * }
+ * });
+ * DexFile rewrittenDexFile = rewriter.rewriteDexFile(dexFile);
+ * }
+ * </pre>
+ */
+public class DexRewriter implements Rewriters {
+ private final Rewriter<ClassDef> classDefRewriter;
+ private final Rewriter<Field> fieldRewriter;
+ private final Rewriter<Method> methodRewriter;
+ private final Rewriter<MethodParameter> methodParameterRewriter;
+ private final Rewriter<MethodImplementation> methodImplementationRewriter;
+ private final Rewriter<Instruction> instructionRewriter;
+ private final Rewriter<TryBlock<? extends ExceptionHandler>> tryBlockRewriter;
+ private final Rewriter<ExceptionHandler> exceptionHandlerRewriter;
+ private final Rewriter<DebugItem> debugItemRewriter;
+ private final Rewriter<String> typeRewriter;
+ private final Rewriter<FieldReference> fieldReferenceRewriter;
+ private final Rewriter<MethodReference> methodReferenceRewriter;
+ private final Rewriter<Annotation> annotationRewriter;
+ private final Rewriter<AnnotationElement> annotationElementRewriter;
+ private final Rewriter<EncodedValue> encodedValueRewriter;
+
+ public DexRewriter(RewriterModule module) {
+ this.classDefRewriter = module.getClassDefRewriter(this);
+ this.fieldRewriter = module.getFieldRewriter(this);
+ this.methodRewriter = module.getMethodRewriter(this);
+ this.methodParameterRewriter = module.getMethodParameterRewriter(this);
+ this.methodImplementationRewriter = module.getMethodImplementationRewriter(this);
+ this.instructionRewriter = module.getInstructionRewriter(this);
+ this.tryBlockRewriter = module.getTryBlockRewriter(this);
+ this.exceptionHandlerRewriter = module.getExceptionHandlerRewriter(this);
+ this.debugItemRewriter = module.getDebugItemRewriter(this);
+ this.typeRewriter = module.getTypeRewriter(this);
+ this.fieldReferenceRewriter = module.getFieldReferenceRewriter(this);
+ this.methodReferenceRewriter = module.getMethodReferenceRewriter(this);
+ this.annotationRewriter = module.getAnnotationRewriter(this);
+ this.annotationElementRewriter = module.getAnnotationElementRewriter(this);
+ this.encodedValueRewriter = module.getEncodedValueRewriter(this);
+ }
+
+ @Nonnull
+ public DexFile rewriteDexFile(@Nonnull DexFile dexFile) {
+ return new RewrittenDexFile(dexFile);
+ }
+
+ protected class RewrittenDexFile implements DexFile {
+ @Nonnull protected final DexFile dexFile;
+
+ public RewrittenDexFile(@Nonnull DexFile dexFile) {
+ this.dexFile = dexFile;
+ }
+
+ @Override @Nonnull public Set<? extends ClassDef> getClasses() {
+ return RewriterUtils.rewriteSet(getClassDefRewriter(), dexFile.getClasses());
+ }
+ }
+
+ @Nonnull @Override public Rewriter<ClassDef> getClassDefRewriter() { return classDefRewriter; }
+ @Nonnull @Override public Rewriter<Field> getFieldRewriter() { return fieldRewriter; }
+ @Nonnull @Override public Rewriter<Method> getMethodRewriter() { return methodRewriter; }
+ @Nonnull @Override public Rewriter<MethodParameter> getMethodParameterRewriter() { return methodParameterRewriter; }
+ @Nonnull @Override public Rewriter<MethodImplementation> getMethodImplementationRewriter() { return methodImplementationRewriter; }
+ @Nonnull @Override public Rewriter<Instruction> getInstructionRewriter() { return instructionRewriter; }
+ @Nonnull @Override public Rewriter<TryBlock<? extends ExceptionHandler>> getTryBlockRewriter() { return tryBlockRewriter; }
+ @Nonnull @Override public Rewriter<ExceptionHandler> getExceptionHandlerRewriter() { return exceptionHandlerRewriter; }
+ @Nonnull @Override public Rewriter<DebugItem> getDebugItemRewriter() { return debugItemRewriter; }
+ @Nonnull @Override public Rewriter<String> getTypeRewriter() { return typeRewriter; }
+ @Nonnull @Override public Rewriter<FieldReference> getFieldReferenceRewriter() { return fieldReferenceRewriter; }
+ @Nonnull @Override public Rewriter<MethodReference> getMethodReferenceRewriter() { return methodReferenceRewriter; }
+ @Nonnull @Override public Rewriter<Annotation> getAnnotationRewriter() { return annotationRewriter; }
+ @Nonnull @Override public Rewriter<AnnotationElement> getAnnotationElementRewriter() { return annotationElementRewriter; }
+ @Nonnull @Override public Rewriter<EncodedValue> getEncodedValueRewriter() { return encodedValueRewriter; }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/EncodedValueRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/EncodedValueRewriter.java
new file mode 100644
index 0000000..9719dcd
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/EncodedValueRewriter.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.ValueType;
+import org.jf.dexlib2.base.value.*;
+import org.jf.dexlib2.iface.AnnotationElement;
+import org.jf.dexlib2.iface.reference.FieldReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+import org.jf.dexlib2.iface.value.*;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+import java.util.Set;
+
+public class EncodedValueRewriter implements Rewriter<EncodedValue> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public EncodedValueRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public EncodedValue rewrite(@Nonnull EncodedValue encodedValue) {
+ switch (encodedValue.getValueType()) {
+ case ValueType.TYPE:
+ return new RewrittenTypeEncodedValue((TypeEncodedValue)encodedValue);
+ case ValueType.FIELD:
+ return new RewrittenFieldEncodedValue((FieldEncodedValue)encodedValue);
+ case ValueType.METHOD:
+ return new RewrittenMethodEncodedValue((MethodEncodedValue)encodedValue);
+ case ValueType.ENUM:
+ return new RewrittenEnumEncodedValue((EnumEncodedValue)encodedValue);
+ case ValueType.ARRAY:
+ return new RewrittenArrayEncodedValue((ArrayEncodedValue)encodedValue);
+ case ValueType.ANNOTATION:
+ return new RewrittenAnnotationEncodedValue((AnnotationEncodedValue)encodedValue);
+ default:
+ return encodedValue;
+ }
+ }
+
+ protected class RewrittenTypeEncodedValue extends BaseTypeEncodedValue {
+ @Nonnull protected TypeEncodedValue typeEncodedValue;
+
+ public RewrittenTypeEncodedValue(@Nonnull TypeEncodedValue typeEncodedValue) {
+ this.typeEncodedValue = typeEncodedValue;
+ }
+
+ @Override @Nonnull public String getValue() {
+ return rewriters.getTypeRewriter().rewrite(typeEncodedValue.getValue());
+ }
+ }
+
+ protected class RewrittenFieldEncodedValue extends BaseFieldEncodedValue {
+ @Nonnull protected FieldEncodedValue fieldEncodedValue;
+
+ public RewrittenFieldEncodedValue(@Nonnull FieldEncodedValue fieldEncodedValue) {
+ this.fieldEncodedValue = fieldEncodedValue;
+ }
+
+ @Override @Nonnull public FieldReference getValue() {
+ return rewriters.getFieldReferenceRewriter().rewrite(fieldEncodedValue.getValue());
+ }
+ }
+
+ protected class RewrittenEnumEncodedValue extends BaseEnumEncodedValue {
+ @Nonnull protected EnumEncodedValue enumEncodedValue;
+
+ public RewrittenEnumEncodedValue(@Nonnull EnumEncodedValue enumEncodedValue) {
+ this.enumEncodedValue = enumEncodedValue;
+ }
+
+ @Override @Nonnull public FieldReference getValue() {
+ return rewriters.getFieldReferenceRewriter().rewrite(enumEncodedValue.getValue());
+ }
+ }
+
+ protected class RewrittenMethodEncodedValue extends BaseMethodEncodedValue {
+ @Nonnull protected MethodEncodedValue methodEncodedValue;
+
+ public RewrittenMethodEncodedValue(@Nonnull MethodEncodedValue methodEncodedValue) {
+ this.methodEncodedValue = methodEncodedValue;
+ }
+
+ @Override @Nonnull public MethodReference getValue() {
+ return rewriters.getMethodReferenceRewriter().rewrite(methodEncodedValue.getValue());
+ }
+ }
+
+ protected class RewrittenArrayEncodedValue extends BaseArrayEncodedValue {
+ @Nonnull protected ArrayEncodedValue arrayEncodedValue;
+
+ public RewrittenArrayEncodedValue(@Nonnull ArrayEncodedValue arrayEncodedValue) {
+ this.arrayEncodedValue = arrayEncodedValue;
+ }
+
+ @Override @Nonnull public List<? extends EncodedValue> getValue() {
+ return RewriterUtils.rewriteList(EncodedValueRewriter.this, arrayEncodedValue.getValue());
+ }
+ }
+
+ protected class RewrittenAnnotationEncodedValue extends BaseAnnotationEncodedValue {
+ @Nonnull protected AnnotationEncodedValue annotationEncodedValue;
+
+ public RewrittenAnnotationEncodedValue(@Nonnull AnnotationEncodedValue annotationEncodedValue) {
+ this.annotationEncodedValue = annotationEncodedValue;
+ }
+
+ @Nonnull @Override public String getType() {
+ return rewriters.getTypeRewriter().rewrite(annotationEncodedValue.getType());
+ }
+
+ @Nonnull @Override public Set<? extends AnnotationElement> getElements() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationElementRewriter(),
+ annotationEncodedValue.getElements());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ExceptionHandlerRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ExceptionHandlerRewriter.java
new file mode 100644
index 0000000..51df68c
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/ExceptionHandlerRewriter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.BaseExceptionHandler;
+import org.jf.dexlib2.iface.ExceptionHandler;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class ExceptionHandlerRewriter implements Rewriter<ExceptionHandler> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public ExceptionHandlerRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public ExceptionHandler rewrite(@Nonnull ExceptionHandler value) {
+ return new RewrittenExceptionHandler(value);
+ }
+
+ protected class RewrittenExceptionHandler extends BaseExceptionHandler {
+ @Nonnull protected ExceptionHandler exceptionHandler;
+
+ public RewrittenExceptionHandler(@Nonnull ExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ @Override @Nullable public String getExceptionType() {
+ return RewriterUtils.rewriteNullable(rewriters.getTypeRewriter(), exceptionHandler.getExceptionType());
+ }
+
+ @Override public int getHandlerCodeAddress() {
+ return exceptionHandler.getHandlerCodeAddress();
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldReferenceRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldReferenceRewriter.java
new file mode 100644
index 0000000..41b5093
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldReferenceRewriter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.reference.BaseFieldReference;
+import org.jf.dexlib2.iface.reference.FieldReference;
+
+import javax.annotation.Nonnull;
+
+public class FieldReferenceRewriter implements Rewriter<FieldReference> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public FieldReferenceRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public FieldReference rewrite(@Nonnull FieldReference fieldReference) {
+ return new RewrittenFieldReference(fieldReference);
+ }
+
+ protected class RewrittenFieldReference extends BaseFieldReference {
+ @Nonnull protected FieldReference fieldReference;
+
+ public RewrittenFieldReference(@Nonnull FieldReference fieldReference) {
+ this.fieldReference = fieldReference;
+ }
+
+ @Override @Nonnull public String getDefiningClass() {
+ return rewriters.getTypeRewriter().rewrite(fieldReference.getDefiningClass());
+ }
+
+ @Override @Nonnull public String getName() {
+ return fieldReference.getName();
+ }
+
+ @Override @Nonnull public String getType() {
+ return rewriters.getTypeRewriter().rewrite(fieldReference.getType());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldRewriter.java
new file mode 100644
index 0000000..1e5eb6d
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/FieldRewriter.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.reference.BaseFieldReference;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.Field;
+import org.jf.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Set;
+
+public class FieldRewriter implements Rewriter<Field> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public FieldRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public Field rewrite(@Nonnull Field field) {
+ return new RewrittenField(field);
+ }
+
+ protected class RewrittenField extends BaseFieldReference implements Field {
+ @Nonnull protected Field field;
+
+ public RewrittenField(@Nonnull Field field) {
+ this.field = field;
+ }
+
+ @Override @Nonnull public String getDefiningClass() {
+ return rewriters.getFieldReferenceRewriter().rewrite(field).getDefiningClass();
+ }
+
+ @Override @Nonnull public String getName() {
+ return rewriters.getFieldReferenceRewriter().rewrite(field).getName();
+ }
+
+ @Override @Nonnull public String getType() {
+ return rewriters.getFieldReferenceRewriter().rewrite(field).getType();
+ }
+
+ public int getAccessFlags() {
+ return field.getAccessFlags();
+ }
+
+ @Nullable public EncodedValue getInitialValue() {
+ return RewriterUtils.rewriteNullable(rewriters.getEncodedValueRewriter(), field.getInitialValue());
+ }
+
+ @Nonnull public Set<? extends Annotation> getAnnotations() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), field.getAnnotations());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/InstructionRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/InstructionRewriter.java
new file mode 100644
index 0000000..c7da8ca
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/InstructionRewriter.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.Opcode;
+import org.jf.dexlib2.ReferenceType;
+import org.jf.dexlib2.iface.instruction.Instruction;
+import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
+import org.jf.dexlib2.iface.instruction.formats.*;
+import org.jf.dexlib2.iface.reference.FieldReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+import org.jf.dexlib2.iface.reference.Reference;
+import org.jf.dexlib2.iface.reference.TypeReference;
+
+import javax.annotation.Nonnull;
+
+public class InstructionRewriter implements Rewriter<Instruction> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public InstructionRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public Instruction rewrite(@Nonnull Instruction instruction) {
+ if (instruction instanceof ReferenceInstruction) {
+ switch (instruction.getOpcode().format) {
+ case Format20bc:
+ return new RewrittenInstruction20bc((Instruction20bc)instruction);
+ case Format21c:
+ return new RewrittenInstruction21c((Instruction21c)instruction);
+ case Format22c:
+ return new RewrittenInstruction22c((Instruction22c)instruction);
+ case Format31c:
+ return new RewrittenInstruction31c((Instruction31c)instruction);
+ case Format35c:
+ return new RewrittenInstruction35c((Instruction35c)instruction);
+ case Format3rc:
+ return new RewrittenInstruction3rc((Instruction3rc)instruction);
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+ return instruction;
+ }
+
+ protected class BaseRewrittenReferenceInstruction<T extends ReferenceInstruction>
+ implements ReferenceInstruction {
+ @Nonnull protected T instruction;
+
+ protected BaseRewrittenReferenceInstruction(@Nonnull T instruction) {
+ this.instruction = instruction;
+ }
+
+ @Override @Nonnull public Reference getReference() {
+ switch (getReferenceType()) {
+ case ReferenceType.TYPE:
+ return RewriterUtils.rewriteTypeReference(rewriters.getTypeRewriter(),
+ (TypeReference)instruction.getReference());
+ case ReferenceType.FIELD:
+ return rewriters.getFieldReferenceRewriter().rewrite((FieldReference)instruction.getReference());
+ case ReferenceType.METHOD:
+ return rewriters.getMethodReferenceRewriter().rewrite((MethodReference)instruction.getReference());
+ case ReferenceType.STRING:
+ return instruction.getReference();
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override public int getReferenceType() {
+ return instruction.getReferenceType();
+ }
+
+ @Override public Opcode getOpcode() {
+ return instruction.getOpcode();
+ }
+
+ @Override public int getCodeUnits() {
+ return instruction.getCodeUnits();
+ }
+ }
+
+ protected class RewrittenInstruction20bc extends BaseRewrittenReferenceInstruction<Instruction20bc>
+ implements Instruction20bc {
+ public RewrittenInstruction20bc(@Nonnull Instruction20bc instruction) {
+ super(instruction);
+ }
+
+ @Override public int getVerificationError() {
+ return instruction.getVerificationError();
+ }
+ }
+
+ protected class RewrittenInstruction21c extends BaseRewrittenReferenceInstruction<Instruction21c>
+ implements Instruction21c {
+ public RewrittenInstruction21c(@Nonnull Instruction21c instruction) {
+ super(instruction);
+ }
+
+ public int getRegisterA() {
+ return instruction.getRegisterA();
+ }
+ }
+
+ protected class RewrittenInstruction22c extends BaseRewrittenReferenceInstruction<Instruction22c>
+ implements Instruction22c {
+ public RewrittenInstruction22c(@Nonnull Instruction22c instruction) {
+ super(instruction);
+ }
+
+ public int getRegisterA() {
+ return instruction.getRegisterA();
+ }
+
+ public int getRegisterB() {
+ return instruction.getRegisterB();
+ }
+ }
+
+ protected class RewrittenInstruction31c extends BaseRewrittenReferenceInstruction<Instruction31c>
+ implements Instruction31c {
+ public RewrittenInstruction31c(@Nonnull Instruction31c instruction) {
+ super(instruction);
+ }
+
+ public int getRegisterA() {
+ return instruction.getRegisterA();
+ }
+ }
+
+ protected class RewrittenInstruction35c extends BaseRewrittenReferenceInstruction<Instruction35c>
+ implements Instruction35c {
+ public RewrittenInstruction35c(@Nonnull Instruction35c instruction) {
+ super(instruction);
+ }
+
+ public int getRegisterC() {
+ return instruction.getRegisterC();
+ }
+
+ public int getRegisterE() {
+ return instruction.getRegisterE();
+ }
+
+ public int getRegisterG() {
+ return instruction.getRegisterG();
+ }
+
+ public int getRegisterCount() {
+ return instruction.getRegisterCount();
+ }
+
+ public int getRegisterD() {
+ return instruction.getRegisterD();
+ }
+
+ public int getRegisterF() {
+ return instruction.getRegisterF();
+ }
+ }
+
+ protected class RewrittenInstruction3rc extends BaseRewrittenReferenceInstruction<Instruction3rc>
+ implements Instruction3rc {
+ public RewrittenInstruction3rc(@Nonnull Instruction3rc instruction) {
+ super(instruction);
+ }
+
+ public int getStartRegister() {
+ return instruction.getStartRegister();
+ }
+
+ public int getRegisterCount() {
+ return instruction.getRegisterCount();
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodImplementationRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodImplementationRewriter.java
new file mode 100644
index 0000000..4c90e5a
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodImplementationRewriter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.iface.ExceptionHandler;
+import org.jf.dexlib2.iface.MethodImplementation;
+import org.jf.dexlib2.iface.TryBlock;
+import org.jf.dexlib2.iface.debug.DebugItem;
+import org.jf.dexlib2.iface.instruction.Instruction;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+
+public class MethodImplementationRewriter implements Rewriter<MethodImplementation> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public MethodImplementationRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public MethodImplementation rewrite(@Nonnull MethodImplementation methodImplementation) {
+ return new RewrittenMethodImplementation(methodImplementation);
+ }
+
+ protected class RewrittenMethodImplementation implements MethodImplementation {
+ @Nonnull protected MethodImplementation methodImplementation;
+
+ public RewrittenMethodImplementation(@Nonnull MethodImplementation methodImplementation) {
+ this.methodImplementation = methodImplementation;
+ }
+
+ @Override public int getRegisterCount() {
+ return methodImplementation.getRegisterCount();
+ }
+
+ @Override @Nonnull public Iterable<? extends Instruction> getInstructions() {
+ return RewriterUtils.rewriteIterable(rewriters.getInstructionRewriter(),
+ methodImplementation.getInstructions());
+ }
+
+ @Override @Nonnull public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks() {
+ return RewriterUtils.rewriteList(rewriters.getTryBlockRewriter(),
+ methodImplementation.getTryBlocks());
+ }
+
+ @Override @Nonnull public Iterable<? extends DebugItem> getDebugItems() {
+ return RewriterUtils.rewriteIterable(rewriters.getDebugItemRewriter(),
+ methodImplementation.getDebugItems());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodParameterRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodParameterRewriter.java
new file mode 100644
index 0000000..1ddc380
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodParameterRewriter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.BaseMethodParameter;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.MethodParameter;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Set;
+
+public class MethodParameterRewriter implements Rewriter<MethodParameter> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public MethodParameterRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public MethodParameter rewrite(@Nonnull MethodParameter methodParameter) {
+ return new RewrittenMethodParameter(methodParameter);
+ }
+
+ protected class RewrittenMethodParameter extends BaseMethodParameter {
+ @Nonnull protected MethodParameter methodParameter;
+
+ public RewrittenMethodParameter(@Nonnull MethodParameter methodParameter) {
+ this.methodParameter = methodParameter;
+ }
+
+ @Override @Nonnull public String getType() {
+ return rewriters.getTypeRewriter().rewrite(methodParameter.getType());
+ }
+
+ @Override @Nonnull public Set<? extends Annotation> getAnnotations() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), methodParameter.getAnnotations());
+ }
+
+ @Override @Nullable public String getName() {
+ return methodParameter.getName();
+ }
+
+ @Override @Nullable public String getSignature() {
+ return methodParameter.getSignature();
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodReferenceRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodReferenceRewriter.java
new file mode 100644
index 0000000..83a9f9a
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodReferenceRewriter.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import org.jf.dexlib2.base.reference.BaseMethodReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+
+public class MethodReferenceRewriter implements Rewriter<MethodReference> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public MethodReferenceRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public MethodReference rewrite(@Nonnull MethodReference methodReference) {
+ return new RewrittenMethodReference(methodReference);
+ }
+
+ protected class RewrittenMethodReference extends BaseMethodReference {
+ @Nonnull protected MethodReference methodReference;
+
+ public RewrittenMethodReference(@Nonnull MethodReference methodReference) {
+ this.methodReference = methodReference;
+ }
+
+ @Override @Nonnull public String getDefiningClass() {
+ return rewriters.getTypeRewriter().rewrite(methodReference.getDefiningClass());
+ }
+
+ @Override @Nonnull public String getName() {
+ return methodReference.getName();
+ }
+
+ @Override @Nonnull public List<? extends CharSequence> getParameterTypes() {
+ return RewriterUtils.rewriteList(rewriters.getTypeRewriter(),
+ Lists.transform(methodReference.getParameterTypes(),
+ new Function<CharSequence, String>() {
+ @Nonnull @Override public String apply(CharSequence input) {
+ return input.toString();
+ }
+ }));
+ }
+
+ @Override @Nonnull public String getReturnType() {
+ return rewriters.getTypeRewriter().rewrite(methodReference.getReturnType());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodRewriter.java
new file mode 100644
index 0000000..01af6e2
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/MethodRewriter.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.reference.BaseMethodReference;
+import org.jf.dexlib2.iface.Annotation;
+import org.jf.dexlib2.iface.Method;
+import org.jf.dexlib2.iface.MethodImplementation;
+import org.jf.dexlib2.iface.MethodParameter;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Set;
+
+public class MethodRewriter implements Rewriter<Method> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public MethodRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public Method rewrite(@Nonnull Method value) {
+ return new RewrittenMethod(value);
+ }
+
+ protected class RewrittenMethod extends BaseMethodReference implements Method {
+ @Nonnull protected Method method;
+
+ public RewrittenMethod(@Nonnull Method method) {
+ this.method = method;
+ }
+
+ @Override @Nonnull public String getDefiningClass() {
+ return rewriters.getMethodReferenceRewriter().rewrite(method).getDefiningClass();
+ }
+
+ @Override @Nonnull public String getName() {
+ return rewriters.getMethodReferenceRewriter().rewrite(method).getName();
+ }
+
+ @Override @Nonnull public List<? extends CharSequence> getParameterTypes() {
+ return rewriters.getMethodReferenceRewriter().rewrite(method).getParameterTypes();
+ }
+
+ @Override @Nonnull public List<? extends MethodParameter> getParameters() {
+ // We can't use the MethodReferenceRewriter to rewrite the parameters, because we would lose
+ // parameter names and annotations. If a method rewrite involves changing parameters, it needs
+ // to be handled here as well as in the MethodReferenceRewriter
+
+ return RewriterUtils.rewriteList(rewriters.getMethodParameterRewriter(), method.getParameters());
+ }
+
+ @Override @Nonnull public String getReturnType() {
+ return rewriters.getMethodReferenceRewriter().rewrite(method).getReturnType();
+ }
+
+ @Override public int getAccessFlags() {
+ return method.getAccessFlags();
+ }
+
+ @Override @Nonnull public Set<? extends Annotation> getAnnotations() {
+ return RewriterUtils.rewriteSet(rewriters.getAnnotationRewriter(), method.getAnnotations());
+ }
+
+ @Override @Nullable public MethodImplementation getImplementation() {
+ return RewriterUtils.rewriteNullable(rewriters.getMethodImplementationRewriter(),
+ method.getImplementation());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriter.java
new file mode 100644
index 0000000..6fc5334
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import javax.annotation.Nonnull;
+
+public interface Rewriter<T> {
+ @Nonnull
+ T rewrite(@Nonnull T value);
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterModule.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterModule.java
new file mode 100644
index 0000000..2913a67
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterModule.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.iface.*;
+import org.jf.dexlib2.iface.debug.DebugItem;
+import org.jf.dexlib2.iface.instruction.Instruction;
+import org.jf.dexlib2.iface.reference.FieldReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+import org.jf.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+
+public class RewriterModule {
+ @Nonnull public Rewriter<ClassDef> getClassDefRewriter(@Nonnull Rewriters rewriters) {
+ return new ClassDefRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<Field> getFieldRewriter(@Nonnull Rewriters rewriters) {
+ return new FieldRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<Method> getMethodRewriter(@Nonnull Rewriters rewriters) {
+ return new MethodRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<MethodParameter> getMethodParameterRewriter(@Nonnull Rewriters rewriters) {
+ return new MethodParameterRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<MethodImplementation> getMethodImplementationRewriter(@Nonnull Rewriters rewriters) {
+ return new MethodImplementationRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<Instruction> getInstructionRewriter(@Nonnull Rewriters rewriters) {
+ return new InstructionRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<TryBlock<? extends ExceptionHandler>> getTryBlockRewriter(@Nonnull Rewriters rewriters) {
+ return new TryBlockRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<ExceptionHandler> getExceptionHandlerRewriter(@Nonnull Rewriters rewriters) {
+ return new ExceptionHandlerRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<DebugItem> getDebugItemRewriter(@Nonnull Rewriters rewriters) {
+ return new DebugItemRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<String> getTypeRewriter(@Nonnull Rewriters rewriters) {
+ return new TypeRewriter();
+ }
+
+ @Nonnull public Rewriter<FieldReference> getFieldReferenceRewriter(@Nonnull Rewriters rewriters) {
+ return new FieldReferenceRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<MethodReference> getMethodReferenceRewriter(@Nonnull Rewriters rewriters) {
+ return new MethodReferenceRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<Annotation> getAnnotationRewriter(@Nonnull Rewriters rewriters) {
+ return new AnnotationRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<AnnotationElement> getAnnotationElementRewriter(@Nonnull Rewriters rewriters) {
+ return new AnnotationElementRewriter(rewriters);
+ }
+
+ @Nonnull public Rewriter<EncodedValue> getEncodedValueRewriter(@Nonnull Rewriters rewriters) {
+ return new EncodedValueRewriter(rewriters);
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterUtils.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterUtils.java
new file mode 100644
index 0000000..d08467a
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/RewriterUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.reference.BaseTypeReference;
+import org.jf.dexlib2.iface.reference.TypeReference;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.*;
+
+public class RewriterUtils {
+ @Nullable
+ public static <T> T rewriteNullable(@Nonnull Rewriter<T> rewriter, @Nullable T value) {
+ return value==null?null:rewriter.rewrite(value);
+ }
+
+ public static <T> Set<T> rewriteSet(@Nonnull final Rewriter<T> rewriter,
+ @Nonnull final Set<? extends T> set) {
+ return new AbstractSet<T>() {
+ @Nonnull @Override public Iterator<T> iterator() {
+ final Iterator<? extends T> iterator = set.iterator();
+ return new Iterator<T>() {
+ @Override public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override public T next() {
+ return rewriteNullable(rewriter, iterator.next());
+ }
+
+ @Override public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+
+ @Override public int size() {
+ return set.size();
+ }
+ };
+ }
+
+ public static <T> List<T> rewriteList(@Nonnull final Rewriter<T> rewriter,
+ @Nonnull final List<? extends T> list) {
+ return new AbstractList<T>() {
+ @Override public T get(int i) {
+ return rewriteNullable(rewriter, list.get(i));
+ }
+
+ @Override public int size() {
+ return list.size();
+ }
+ };
+ }
+
+ public static <T> Iterable<T> rewriteIterable(@Nonnull final Rewriter<T> rewriter,
+ @Nonnull final Iterable<? extends T> iterable) {
+ return new Iterable<T>() {
+ @Override public Iterator<T> iterator() {
+ final Iterator<? extends T> iterator = iterable.iterator();
+ return new Iterator<T>() {
+ @Override public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override public T next() {
+ return rewriteNullable(rewriter, iterator.next());
+ }
+
+ @Override public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+ };
+ }
+
+ public static TypeReference rewriteTypeReference(@Nonnull final Rewriter<String> typeRewriter,
+ @Nonnull final TypeReference typeReference) {
+ return new BaseTypeReference() {
+ @Nonnull @Override public String getType() {
+ return typeRewriter.rewrite(typeReference.getType());
+ }
+ };
+ }
+}
+
+
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriters.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriters.java
new file mode 100644
index 0000000..97fd879
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/Rewriters.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.iface.*;
+import org.jf.dexlib2.iface.debug.DebugItem;
+import org.jf.dexlib2.iface.instruction.Instruction;
+import org.jf.dexlib2.iface.reference.FieldReference;
+import org.jf.dexlib2.iface.reference.MethodReference;
+import org.jf.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+
+public interface Rewriters {
+ @Nonnull Rewriter<ClassDef> getClassDefRewriter();
+ @Nonnull Rewriter<Field> getFieldRewriter();
+
+ @Nonnull Rewriter<Method> getMethodRewriter();
+ @Nonnull Rewriter<MethodParameter> getMethodParameterRewriter();
+ @Nonnull Rewriter<MethodImplementation> getMethodImplementationRewriter();
+ @Nonnull Rewriter<Instruction> getInstructionRewriter();
+ @Nonnull Rewriter<TryBlock<? extends ExceptionHandler>> getTryBlockRewriter();
+ @Nonnull Rewriter<ExceptionHandler> getExceptionHandlerRewriter();
+ @Nonnull Rewriter<DebugItem> getDebugItemRewriter();
+
+ @Nonnull Rewriter<String> getTypeRewriter();
+ @Nonnull Rewriter<FieldReference> getFieldReferenceRewriter();
+ @Nonnull Rewriter<MethodReference> getMethodReferenceRewriter();
+
+ @Nonnull Rewriter<Annotation> getAnnotationRewriter();
+ @Nonnull Rewriter<AnnotationElement> getAnnotationElementRewriter();
+
+ @Nonnull Rewriter<EncodedValue> getEncodedValueRewriter();
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TryBlockRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TryBlockRewriter.java
new file mode 100644
index 0000000..43fed10
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TryBlockRewriter.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import org.jf.dexlib2.base.BaseTryBlock;
+import org.jf.dexlib2.iface.ExceptionHandler;
+import org.jf.dexlib2.iface.TryBlock;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+
+public class TryBlockRewriter implements Rewriter<TryBlock<? extends ExceptionHandler>> {
+ @Nonnull protected final Rewriters rewriters;
+
+ public TryBlockRewriter(@Nonnull Rewriters rewriters) {
+ this.rewriters = rewriters;
+ }
+
+ @Nonnull @Override public TryBlock<? extends ExceptionHandler> rewrite(
+ @Nonnull TryBlock<? extends ExceptionHandler> tryBlock) {
+ return new RewrittenTryBlock(tryBlock);
+ }
+
+ protected class RewrittenTryBlock extends BaseTryBlock<ExceptionHandler> {
+ @Nonnull protected TryBlock<? extends ExceptionHandler> tryBlock;
+
+ public RewrittenTryBlock(@Nonnull TryBlock<? extends ExceptionHandler> tryBlock) {
+ this.tryBlock = tryBlock;
+ }
+
+ @Override public int getStartCodeAddress() {
+ return tryBlock.getStartCodeAddress();
+ }
+
+ @Override public int getCodeUnitCount() {
+ return tryBlock.getCodeUnitCount();
+ }
+
+ @Override @Nonnull public List<? extends ExceptionHandler> getExceptionHandlers() {
+ return RewriterUtils.rewriteList(rewriters.getExceptionHandlerRewriter(), tryBlock.getExceptionHandlers());
+ }
+ }
+}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java
new file mode 100644
index 0000000..9731154
--- /dev/null
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014, 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.rewriter;
+
+import javax.annotation.Nonnull;
+
+public class TypeRewriter implements Rewriter<String> {
+ @Nonnull @Override public String rewrite(@Nonnull String value) {
+ return value;
+ }
+}