From fbdc6cb9cbb0401d1212b0a8e7de661a1b2f7325 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 28 Apr 2013 12:58:29 -0700 Subject: [PATCH] Clean up how the annotation directory items are written --- .../org/jf/dexlib2/writer/ClassSection.java | 2 + .../java/org/jf/dexlib2/writer/DexWriter.java | 274 +----------------- .../org/jf/dexlib2/writer/pool/ClassPool.java | 8 + .../jf/dexlib2/writer/pool/PoolClassDef.java | 2 +- 4 files changed, 27 insertions(+), 259 deletions(-) diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/ClassSection.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/ClassSection.java index 4f50cd34..42abb9d8 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/ClassSection.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/ClassSection.java @@ -57,8 +57,10 @@ public interface ClassSection getSortedStaticFields(@Nonnull ClassKey key); @Nonnull Collection getSortedInstanceFields(@Nonnull ClassKey key); + @Nonnull Collection getSortedFields(@Nonnull ClassKey key); @Nonnull Collection getSortedDirectMethods(@Nonnull ClassKey key); @Nonnull Collection getSortedVirtualMethods(@Nonnull ClassKey key); + @Nonnull Collection getSortedMethods(@Nonnull ClassKey key); int getFieldAccessFlags(@Nonnull FieldKey key); int getMethodAccessFlags(@Nonnull MethodKey key); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index 2458d196..f56f51b9 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -634,272 +634,30 @@ public abstract class DexWriter< int methodAnnotations = 0; int parameterAnnotations = 0; - // the following logic for merging fields/methods is rather verbose and repetitive, but it's intentionally - // so, for efficiency (rather than adding yet another layer of indirection, to simplify it) - { - Iterator staticIterator = staticFields.iterator(); - Iterator instanceIterator = instanceFields.iterator(); - - FieldKey nextStaticField; - int nextStaticFieldIndex = 0; - AnnotationSetKey nextStaticFieldAnnotationSetKey = null; - FieldKey nextInstanceField; - int nextInstanceFieldIndex = 0; - AnnotationSetKey nextInstanceFieldAnnotationSetKey = null; - - try { - do { - nextStaticField = staticIterator.next(); - nextStaticFieldIndex = fieldSection.getItemIndex(nextStaticField); - nextStaticFieldAnnotationSetKey = classSection.getFieldAnnotations(nextStaticField); - } while (nextStaticFieldAnnotationSetKey == null); - } catch (NoSuchElementException ex) { - nextStaticField = null; - } - try { - do { - nextInstanceField = instanceIterator.next(); - nextInstanceFieldIndex = fieldSection.getItemIndex(nextInstanceField); - nextInstanceFieldAnnotationSetKey = - classSection.getFieldAnnotations(nextInstanceField); - } while (nextInstanceFieldAnnotationSetKey == null); - } catch (NoSuchElementException ex) { - nextInstanceField = null; - } - - while (true) { - int nextFieldIndex; - AnnotationSetKey nextFieldAnnotationSetKey; - - if (nextStaticField == null) { - if (nextInstanceField == null) { - break; - } - - nextFieldIndex = nextInstanceFieldIndex; - nextFieldAnnotationSetKey = nextInstanceFieldAnnotationSetKey; - try { - do { - nextInstanceField = instanceIterator.next(); - nextInstanceFieldIndex = fieldSection.getItemIndex(nextInstanceField); - nextInstanceFieldAnnotationSetKey = - classSection.getFieldAnnotations(nextInstanceField); - } while (nextInstanceFieldAnnotationSetKey == null); - } catch (NoSuchElementException ex) { - nextInstanceField = null; - } - } else { - if (nextInstanceField == null || nextStaticFieldIndex < nextInstanceFieldIndex) { - nextFieldIndex = nextStaticFieldIndex; - nextFieldAnnotationSetKey = nextStaticFieldAnnotationSetKey; - try { - do { - nextStaticField = staticIterator.next(); - nextStaticFieldIndex = fieldSection.getItemIndex(nextStaticField); - nextStaticFieldAnnotationSetKey = - classSection.getFieldAnnotations(nextStaticField); - } while (nextStaticFieldAnnotationSetKey == null); - } catch (NoSuchElementException ex) { - nextStaticField = null; - } - } else { - nextFieldIndex = nextInstanceFieldIndex; - nextFieldAnnotationSetKey = nextInstanceFieldAnnotationSetKey; - try { - do { - nextInstanceField = instanceIterator.next(); - nextInstanceFieldIndex = fieldSection.getItemIndex(nextInstanceField); - nextInstanceFieldAnnotationSetKey = - classSection.getFieldAnnotations(nextInstanceField); - } while (nextInstanceFieldAnnotationSetKey == null); - } catch (NoSuchElementException ex) { - nextInstanceField = null; - } - } - } - + for (FieldKey field: classSection.getSortedFields(key)) { + AnnotationSetKey fieldAnnotationsKey = classSection.getFieldAnnotations(field); + if (fieldAnnotationsKey != null) { fieldAnnotations++; - tempBuffer.putInt(nextFieldIndex); - tempBuffer.putInt(annotationSetSection.getItemOffset(nextFieldAnnotationSetKey)); + tempBuffer.putInt(fieldSection.getItemIndex(field)); + tempBuffer.putInt(annotationSetSection.getItemOffset(fieldAnnotationsKey)); } } - { - // weeee! now do it all again, except for methods this time - Iterator directIterator = classSection.getSortedDirectMethods(key).iterator(); - Iterator virtualIterator = classSection.getSortedVirtualMethods(key).iterator(); - - MethodKey nextDirectMethod; - int nextDirectMethodIndex = 0; - AnnotationSetKey nextDirectMethodAnnotationKey = null; - MethodKey nextVirtualMethod; - int nextVirtualMethodIndex = 0; - AnnotationSetKey nextVirtualMethodAnnotationKey = null; - - try { - do { - nextDirectMethod = directIterator.next(); - nextDirectMethodIndex = methodSection.getItemIndex(nextDirectMethod); - nextDirectMethodAnnotationKey = classSection.getMethodAnnotations(nextDirectMethod); - } while (nextDirectMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextDirectMethod = null; - } - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getMethodAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - - while (true) { - int nextMethodIndex; - AnnotationSetKey nextAnnotationKey; - - if (nextDirectMethod == null) { - if (nextVirtualMethod == null) { - break; - } - - nextMethodIndex = nextVirtualMethodIndex; - nextAnnotationKey = nextVirtualMethodAnnotationKey; - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getMethodAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - } else { - if (nextVirtualMethod == null || nextDirectMethodIndex < nextVirtualMethodIndex) { - nextMethodIndex = nextDirectMethodIndex; - nextAnnotationKey = nextDirectMethodAnnotationKey; - try { - do { - nextDirectMethod = directIterator.next(); - nextDirectMethodIndex = methodSection.getItemIndex(nextDirectMethod); - nextDirectMethodAnnotationKey = - classSection.getMethodAnnotations(nextDirectMethod); - } while (nextDirectMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextDirectMethod = null; - } - } else { - nextMethodIndex = nextVirtualMethodIndex; - nextAnnotationKey = nextVirtualMethodAnnotationKey; - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getMethodAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - } - } - + for (MethodKey method: classSection.getSortedMethods(key)) { + AnnotationSetKey methodAnnotationsKey = classSection.getMethodAnnotations(method); + if (methodAnnotationsKey != null) { methodAnnotations++; - tempBuffer.putInt(nextMethodIndex); - tempBuffer.putInt(annotationSetSection.getItemOffset(nextAnnotationKey)); + tempBuffer.putInt(methodSection.getItemIndex(method)); + tempBuffer.putInt(annotationSetSection.getItemOffset(methodAnnotationsKey)); } } - { - // AAAAAAAAAAAnd one final time, for parameter annotations - Iterator directIterator = classSection.getSortedDirectMethods(key).iterator(); - Iterator virtualIterator = classSection.getSortedVirtualMethods(key).iterator(); - - MethodKey nextDirectMethod; - int nextDirectMethodIndex = 0; - AnnotationSetRefKey nextDirectMethodAnnotationKey = null; - MethodKey nextVirtualMethod; - int nextVirtualMethodIndex = 0; - AnnotationSetRefKey nextVirtualMethodAnnotationKey = null; - - try { - do { - nextDirectMethod = directIterator.next(); - nextDirectMethodIndex = methodSection.getItemIndex(nextDirectMethod); - nextDirectMethodAnnotationKey = - classSection.getParameterAnnotations(nextDirectMethod); - } while (nextDirectMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextDirectMethod = null; - } - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getParameterAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - - while (true) { - int nextMethodIndex; - AnnotationSetRefKey nextAnnotationKey; - - if (nextDirectMethod == null) { - if (nextVirtualMethod == null) { - break; - } - - nextMethodIndex = nextVirtualMethodIndex; - nextAnnotationKey = nextVirtualMethodAnnotationKey; - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getParameterAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - } else { - if (nextVirtualMethod == null || nextDirectMethodIndex < nextVirtualMethodIndex) { - nextMethodIndex = nextDirectMethodIndex; - nextAnnotationKey = nextDirectMethodAnnotationKey; - try { - do { - nextDirectMethod = directIterator.next(); - nextDirectMethodIndex = methodSection.getItemIndex(nextDirectMethod); - nextDirectMethodAnnotationKey = - classSection.getParameterAnnotations(nextDirectMethod); - } while (nextDirectMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextDirectMethod = null; - } - } else { - nextMethodIndex = nextVirtualMethodIndex; - nextAnnotationKey = nextVirtualMethodAnnotationKey; - try { - do { - nextVirtualMethod = virtualIterator.next(); - nextVirtualMethodIndex = methodSection.getItemIndex(nextVirtualMethod); - nextVirtualMethodAnnotationKey = - classSection.getParameterAnnotations(nextVirtualMethod); - } while (nextVirtualMethodAnnotationKey == null); - } catch (NoSuchElementException ex) { - nextVirtualMethod = null; - } - } - } - - parameterAnnotations++; - tempBuffer.putInt(nextMethodIndex); - tempBuffer.putInt(annotationSetRefSection.getItemOffset(nextAnnotationKey)); + for (MethodKey method: classSection.getSortedMethods(key)) { + AnnotationSetRefKey parameterAnnotationsKey = classSection.getParameterAnnotations(method); + if (parameterAnnotationsKey != null) { + methodAnnotations++; + tempBuffer.putInt(methodSection.getItemIndex(method)); + tempBuffer.putInt(annotationSetRefSection.getItemOffset(parameterAnnotationsKey)); } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ClassPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ClassPool.java index ee50d98f..b44d2670 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ClassPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ClassPool.java @@ -305,6 +305,10 @@ public class ClassPool implements ClassSection getSortedFields(@Nonnull PoolClassDef classDef) { + return classDef.getFields(); + } + @Nonnull @Override public Collection getSortedDirectMethods(@Nonnull PoolClassDef classDef) { return classDef.getDirectMethods(); } @@ -313,6 +317,10 @@ public class ClassPool implements ClassSection getSortedMethods(@Nonnull PoolClassDef classDef) { + return classDef.getMethods(); + } + @Override public int getFieldAccessFlags(@Nonnull Field field) { return field.getAccessFlags(); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolClassDef.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolClassDef.java index 3d112467..8aa65a94 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolClassDef.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolClassDef.java @@ -119,7 +119,7 @@ class PoolClassDef extends BaseTypeReference implements ClassDef { return virtualMethods; } - @Nonnull @Override public Iterable getMethods() { + @Nonnull @Override public Collection getMethods() { return new AbstractCollection() { @Nonnull @Override public Iterator iterator() { return Iterators.mergeSorted(