From 56eac437f1ce55db336235ba0994a5ba980ffd62 Mon Sep 17 00:00:00 2001 From: Skylot Date: Thu, 2 May 2013 18:14:43 +0400 Subject: [PATCH] Fix errors in AttributesList, refactoring --- .../jadx/dex/attributes/AttributeType.java | 21 ++++++- .../jadx/dex/attributes/AttributesList.java | 59 ++++++++++++++----- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/main/java/jadx/dex/attributes/AttributeType.java b/src/main/java/jadx/dex/attributes/AttributeType.java index 78c7a0570..33e19a789 100644 --- a/src/main/java/jadx/dex/attributes/AttributeType.java +++ b/src/main/java/jadx/dex/attributes/AttributeType.java @@ -8,12 +8,10 @@ public enum AttributeType { // blocks LOOP(false), - CATCH_BLOCK(false), + EXC_HANDLER(true), - SPLITTER_BLOCK(true), - FORCE_RETURN(true), // fields @@ -32,8 +30,25 @@ public enum AttributeType { DECLARE_VARIABLE(true); + private static final int notUniqCount; private final boolean uniq; + static { + // place all not unique attributes at first + int last = -1; + AttributeType[] vals = AttributeType.values(); + for (int i = 0; i < vals.length; i++) { + AttributeType type = vals[i]; + if (type.notUniq()) + last = i; + } + notUniqCount = last + 1; + } + + public static int getNotUniqCount() { + return notUniqCount; + } + private AttributeType(boolean isUniq) { this.uniq = isUniq; } diff --git a/src/main/java/jadx/dex/attributes/AttributesList.java b/src/main/java/jadx/dex/attributes/AttributesList.java index a505d844e..0cf0d942a 100644 --- a/src/main/java/jadx/dex/attributes/AttributesList.java +++ b/src/main/java/jadx/dex/attributes/AttributesList.java @@ -14,6 +14,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +/** + * Storage for different attribute types: + * 1. flags - boolean attribute (set or not) + * 2. attribute - class instance associated for attribute type, + * only one attached to node for unique attributes, multiple for others + */ public class AttributesList { private final Set flags; @@ -24,16 +30,11 @@ public class AttributesList { public AttributesList() { flags = EnumSet.noneOf(AttributeFlag.class); uniqAttr = new EnumMap(AttributeType.class); - attributes = new ArrayList(1); - attrCount = new int[AttributeType.values().length]; + attributes = new ArrayList(0); + attrCount = new int[AttributeType.getNotUniqCount()]; } - public void add(IAttribute attr) { - if (attr.getType().isUniq()) - uniqAttr.put(attr.getType(), attr); - else - addMultiAttribute(attr); - } + // Flags public void add(AttributeFlag flag) { flags.add(flag); @@ -47,12 +48,21 @@ public class AttributesList { flags.remove(flag); } + // Attributes + + public void add(IAttribute attr) { + if (attr.getType().isUniq()) + uniqAttr.put(attr.getType(), attr); + else + addMultiAttribute(attr); + } + private void addMultiAttribute(IAttribute attr) { attributes.add(attr); attrCount[attr.getType().ordinal()]++; } - private int getCountInternal(AttributeType type) { + private int getMultiCountInternal(AttributeType type) { return attrCount[type.ordinal()]; } @@ -67,15 +77,14 @@ public class AttributesList { if (type.isUniq()) return uniqAttr.containsKey(type); else - return getCountInternal(type) != 0; + return getMultiCountInternal(type) != 0; } public IAttribute get(AttributeType type) { if (type.isUniq()) { return uniqAttr.get(type); } else { - int count = getCountInternal(type); - if (count != 0) { + if (getMultiCountInternal(type) != 0) { for (IAttribute attr : attributes) if (attr.getType() == type) return attr; @@ -86,9 +95,9 @@ public class AttributesList { public int getCount(AttributeType type) { if (type.isUniq()) { - return 0; + return uniqAttr.containsKey(type) ? 1 : 0; } else { - return getCountInternal(type); + return getMultiCountInternal(type); } } @@ -103,7 +112,7 @@ public class AttributesList { public List getAll(AttributeType type) { assert type.notUniq(); - int count = getCountInternal(type); + int count = getMultiCountInternal(type); if (count == 0) { return Collections.emptyList(); } else { @@ -129,6 +138,26 @@ public class AttributesList { } } + public void remove(IAttribute attr) { + AttributeType type = attr.getType(); + if (type.isUniq()) { + IAttribute a = uniqAttr.get(type); + if (a == attr) + uniqAttr.remove(type); + } else { + if (getMultiCountInternal(type) == 0) + return; + + for (Iterator it = attributes.iterator(); it.hasNext();) { + IAttribute a = it.next(); + if (a == attr) { + it.remove(); + attrCount[type.ordinal()]--; + } + } + } + } + public void clear() { flags.clear(); uniqAttr.clear();