changeset 27:b0d7f00453ea

Added stable entry point to DEX rewriter. * rewriter/DexRewriter.java (rewrite): The new entry point. * dex/DexFile.java (getClassDef): Removed obsolete method. * ClassTransformerTest.java: Adapted and switched to rewriter.
author Michael Starzinger <michi@complang.tuwien.ac.at>
date Thu, 17 Mar 2011 00:56:23 +0100
parents b27ad11dfcf9
children fe791833f7d8
files src/main/java/org/icedrobot/daneel/dex/DexFile.java src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java src/test/java/org/icedrobot/daneel/ClassTransformerTest.java
diffstat 3 files changed, 24 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/dex/DexFile.java	Wed Mar 16 23:13:52 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/dex/DexFile.java	Thu Mar 17 00:56:23 2011 +0100
@@ -136,15 +136,6 @@
         return methodIds[idx];
     }
 
-    @Deprecated
-    // XXX Direct access of class definition is not allowed, remove me!
-    public ClassDef getClassDef(int idx) {
-        // XXX I know this is hacky, but it is only used by the prototype test.
-        if (idx != 0)
-            throw new DexParseException("You shouldn't have used me!");
-        return classDefs.values().iterator().next();
-    }
-
     /**
      * Provides a buffer for the data area of this DEX file. The buffer is
      * positioned at the given offset and limited to the data area, all attempts
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Wed Mar 16 23:13:52 2011 +0100
+++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Thu Mar 17 00:56:23 2011 +0100
@@ -10,10 +10,12 @@
 import org.icedrobot.daneel.dex.DexClassVisitor;
 import org.icedrobot.daneel.dex.DexFieldVisitor;
 import org.icedrobot.daneel.dex.DexMethodVisitor;
+import org.icedrobot.daneel.dex.DexReader;
 import org.icedrobot.daneel.dex.Label;
 import org.icedrobot.daneel.dex.Opcode;
 import org.icedrobot.daneel.util.TypeUtil;
 import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Type;
@@ -24,6 +26,25 @@
 public class DexRewriter implements DexClassVisitor {
     private final ClassVisitor cv;
 
+    /**
+     * Rewrites a class from Dalvik bytecode into Java bytecode representation.
+     * The source class is given by specifying its name and the DEX source it is
+     * originating from.
+     * 
+     * @param name The name of the class to rewrite as a normal fully qualified
+     *        class name.
+     * @param reader The reader for the DEX source to read from.
+     * @return The Java bytecode for the given class.
+     * @throws ClassNotFoundException In case the source does not define a class
+     *         by that name.
+     */
+    public static byte[] rewrite(String name, DexReader reader)
+            throws ClassNotFoundException {
+        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        reader.accept("L" + name.replace('.', '/') + ";", new DexRewriter(writer));
+        return writer.toByteArray();
+    }
+
     public DexRewriter(ClassVisitor cv) {
         this.cv = cv;
     }
--- a/src/test/java/org/icedrobot/daneel/ClassTransformerTest.java	Wed Mar 16 23:13:52 2011 +0100
+++ b/src/test/java/org/icedrobot/daneel/ClassTransformerTest.java	Thu Mar 17 00:56:23 2011 +0100
@@ -20,16 +20,16 @@
 
 import static org.junit.Assert.assertEquals;
 
-import org.icedrobot.daneel.dex.ClassDef;
 import org.icedrobot.daneel.dex.DexFile;
+import org.icedrobot.daneel.rewriter.DexRewriter;
 import org.junit.Test;
 
 public class ClassTransformerTest extends ClassLoader {
 
     @Test
     public void testTransformClassStaticFields() throws Exception {
-        ClassDef classDef = DexFile.parse(TEST_STATIC_FIELDS).getClassDef(0);
-        byte[] bytecode = ClassTransformer.transformClass(classDef);
+        DexFile dex = DexFile.parse(TEST_STATIC_FIELDS);
+        byte[] bytecode = DexRewriter.rewrite("StaticFieldTest", dex);
         Class<?> cls = defineClass(null, bytecode, 0, bytecode.length);
         assertEquals(7, cls.getFields().length);
         assertEquals("public static byte StaticFieldTest.staticByte",