From dd242aa735b1efa3cf7664a3b64afd32bb5b28dd Mon Sep 17 00:00:00 2001 From: Assaf Date: Wed, 20 Jun 2018 16:14:05 +0300 Subject: [PATCH] Remove code duplication - extract Labels and debugItems from MethodLocation. --- .../jf/dexlib2/builder/BuilderDebugItem.java | 6 +- .../jf/dexlib2/builder/ItemWithLocation.java | 16 ++ .../java/org/jf/dexlib2/builder/Label.java | 9 +- .../jf/dexlib2/builder/LocatedDebugItems.java | 10 ++ .../org/jf/dexlib2/builder/LocatedItems.java | 87 +++++++++ .../org/jf/dexlib2/builder/LocatedLabels.java | 9 + .../jf/dexlib2/builder/MethodLocation.java | 166 ++---------------- 7 files changed, 135 insertions(+), 168 deletions(-) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/ItemWithLocation.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedDebugItems.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedItems.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedLabels.java diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java index 0969a9db..41effa1f 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderDebugItem.java @@ -33,10 +33,7 @@ package org.jf.dexlib2.builder; import org.jf.dexlib2.iface.debug.DebugItem; -import javax.annotation.Nullable; - -public abstract class BuilderDebugItem implements DebugItem { - @Nullable MethodLocation location; +public abstract class BuilderDebugItem extends ItemWithLocation implements DebugItem { public BuilderDebugItem() { } @@ -48,5 +45,4 @@ public abstract class BuilderDebugItem implements DebugItem { } return location.getCodeAddress(); } - } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/ItemWithLocation.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/ItemWithLocation.java new file mode 100644 index 00000000..f6515528 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/ItemWithLocation.java @@ -0,0 +1,16 @@ +package org.jf.dexlib2.builder; + +import javax.annotation.Nullable; + +public abstract class ItemWithLocation { + @Nullable + MethodLocation location; + + public boolean isPlaced() { + return location != null; + } + + public void setLocation(MethodLocation methodLocation) { + location = methodLocation; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/Label.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/Label.java index ef19f91c..35c3f562 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/Label.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/Label.java @@ -32,11 +32,8 @@ package org.jf.dexlib2.builder; import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class Label { - @Nullable MethodLocation location; +public class Label extends ItemWithLocation { Label() { } @@ -55,8 +52,4 @@ public class Label { } return location; } - - public boolean isPlaced() { - return location != null; - } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedDebugItems.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedDebugItems.java new file mode 100644 index 00000000..61403565 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedDebugItems.java @@ -0,0 +1,10 @@ +package org.jf.dexlib2.builder; + +public class LocatedDebugItems extends LocatedItems { + + @Override + protected String addLocatedItemError() { + return "Cannot add a debug item that has already been added to a method." + + "You must remove it from its current location first."; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedItems.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedItems.java new file mode 100644 index 00000000..c4abf9e3 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedItems.java @@ -0,0 +1,87 @@ +package org.jf.dexlib2.builder; + +import com.google.common.collect.ImmutableList; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; + +public abstract class LocatedItems { + // We end up creating and keeping around a *lot* of MethodLocation objects + // when building a new dex file, so it's worth the trouble of lazily creating + // the labels and debugItems lists only when they are needed + @Nullable + private List items = null; + + @Nonnull + private List getMutableItems() { + if (items == null) { + items = new ArrayList<>(1); + } + return items; + } + + @Nonnull + private List getImmutableItems() { + if (items == null) { + return ImmutableList.of(); + } + return items; + } + + public Set getModifiableItems(MethodLocation newItemsLocation) { + return new AbstractSet() { + @Nonnull + @Override public Iterator iterator() { + final Iterator it = getImmutableItems().iterator(); + + return new Iterator() { + private @Nullable + T currentItem = null; + + @Override public boolean hasNext() { + return it.hasNext(); + } + + @Override public T next() { + currentItem = it.next(); + return currentItem; + } + + @Override public void remove() { + if (currentItem != null) { + currentItem.setLocation(null); + } + it.remove(); + } + }; + } + + @Override public int size() { + return getImmutableItems().size(); + } + + @Override public boolean add(@Nonnull T item) { + if (item.isPlaced()) { + throw new IllegalArgumentException(addLocatedItemError()); + } + item.setLocation(newItemsLocation); + getMutableItems().add(item); + return true; + } + }; + } + + protected abstract String addLocatedItemError(); + + public void mergeItemsInto(@Nonnull MethodLocation newLocation, LocatedItems otherLocatedItems) { + if (items != null || otherLocatedItems.items != null) { + List otherItems = otherLocatedItems.getMutableItems(); + for (T item: getImmutableItems()) { + item.setLocation(newLocation); + otherItems.add(item); + } + items = null; + } + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedLabels.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedLabels.java new file mode 100644 index 00000000..2b7823f3 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/LocatedLabels.java @@ -0,0 +1,9 @@ +package org.jf.dexlib2.builder; + +public class LocatedLabels extends LocatedItems