changeset 122:1f55b68e19b0

Implemented rewriting of parameter annotations. * dex/AnnotationsDirectory.java: Tested parameter annotation parsing now. * rewriter/DexRewriter.java (visitParameterAnnotation): Implemented. * rewriter/AnnotationTest.java: Extended test case accordingly.
author Michael Starzinger <michi@complang.tuwien.ac.at>
date Fri, 08 Apr 2011 18:41:22 +0200
parents 03ad7dd3dec1
children 3ec98ede8a06
files src/main/java/org/icedrobot/daneel/dex/AnnotationsDirectory.java src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java src/test/java/org/icedrobot/daneel/rewriter/AnnotationTest.java
diffstat 3 files changed, 29 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/dex/AnnotationsDirectory.java	Fri Apr 08 16:47:50 2011 +0200
+++ b/src/main/java/org/icedrobot/daneel/dex/AnnotationsDirectory.java	Fri Apr 08 18:41:22 2011 +0200
@@ -43,6 +43,7 @@
 
 import org.icedrobot.daneel.dex.EncodedValue.AnnotationValue;
 import org.icedrobot.daneel.dex.EncodedValue.AnnotationVisitable;
+import org.icedrobot.daneel.util.BufferUtil;
 
 /**
  * A parser class capable of parsing {@code annotations_directory_item}
@@ -107,7 +108,7 @@
         // structures in parameter_annotations array.
         parameterAnnotations = new HashMap<MethodId, Annotation[][]>();
         for (int i = 0; i < parametersSize; i++) {
-            /*int methodIdx = buffer.getInt();
+            int methodIdx = buffer.getInt();
             int annotationsOff = buffer.getInt();
             ByteBuffer buf = dex.getDataBuffer(annotationsOff);
             int size = buf.getInt();
@@ -117,8 +118,7 @@
                 buf = dex.getDataBuffer(list[j]);
                 annotationSet[j] = parseAnnotations(buf, dex);
             }
-            parameterAnnotations.put(dex.getMethodId(methodIdx), annotationSet);*/
-            throw new UnsupportedOperationException("Not yet tested!");
+            parameterAnnotations.put(dex.getMethodId(methodIdx), annotationSet);
         }
     }
 
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Fri Apr 08 16:47:50 2011 +0200
+++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Fri Apr 08 18:41:22 2011 +0200
@@ -344,7 +344,13 @@
         @Override
         public DexAnnotationVisitor visitParameterAnnotation(int parameter,
                 int visibility, String type) {
-            // XXX Ignore annotations for now.
+            if (visibility == DexAnnotationVisitor.VISIBILITY_RUNTIME) {
+                AnnotationVisitor av = mv.visitParameterAnnotation(parameter,
+                        type, true);
+                if (av == null)
+                    return null;
+                return new AnnotationRewriter(av);
+            }
             return null;
         }
 
--- a/src/test/java/org/icedrobot/daneel/rewriter/AnnotationTest.java	Fri Apr 08 16:47:50 2011 +0200
+++ b/src/test/java/org/icedrobot/daneel/rewriter/AnnotationTest.java	Fri Apr 08 18:41:22 2011 +0200
@@ -45,6 +45,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.lang.reflect.Method;
 
 import org.icedrobot.daneel.DexifyingRunner;
 import org.junit.Test;
@@ -74,6 +75,16 @@
         assertSame(TestAnnotationC.class, a[0].annotationType());
     }
 
+    @Test
+    public void testParameterAnnotation() throws Exception {
+        Method m = DEXCode.class.getMethod("params", int.class, int.class);
+        Annotation[][] a = m.getParameterAnnotations();
+        assertEquals(2, a.length);
+        assertEquals(0, a[0].length);
+        assertEquals(1, a[1].length);
+        assertSame(TestAnnotationD.class, a[1][0].annotationType());
+    }
+
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ ElementType.TYPE })
     private static @interface TestAnnotationA {
@@ -89,6 +100,11 @@
     private static @interface TestAnnotationC {
     };
 
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ ElementType.PARAMETER })
+    private static @interface TestAnnotationD {
+    };
+
     // Keep this class named "DEXCode" to push it through Daneel.
     @TestAnnotationA
     public static class DEXCode {
@@ -99,5 +115,8 @@
         @TestAnnotationC
         public void method() {
         }
+
+        public void params(int param1, @TestAnnotationD int param2) {
+        }
     };
 }