core: use own immutable list

This commit is contained in:
Skylot
2018-07-28 22:07:39 +03:00
parent 7e462e800f
commit 6e358d3eab
4 changed files with 243 additions and 24 deletions
@@ -15,6 +15,8 @@ import jadx.core.utils.BlockUtils;
import jadx.core.utils.EmptyBitSet;
import jadx.core.utils.InsnUtils;
import static jadx.core.utils.Utils.lockList;
public class BlockNode extends AttrNode implements IBlock {
private int id;
@@ -70,13 +72,6 @@ public class BlockNode extends AttrNode implements IBlock {
dominatesOn = lockList(dominatesOn);
}
List<BlockNode> lockList(List<BlockNode> list) {
if (list.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(list);
}
/**
* Return all successor which are not exception handler or followed by loop back edge
*/
@@ -43,6 +43,8 @@ import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.utils.Utils.lockList;
public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
private static final Logger LOG = LoggerFactory.getLogger(MethodNode.class);
@@ -154,10 +156,10 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
blocks = null;
enterBlock = null;
exitBlocks = null;
exceptionHandlers.clear();
exceptionHandlers = Collections.emptyList();
sVars.clear();
region = null;
loops.clear();
loops = Collections.emptyList();
}
private boolean parseSignature() {
@@ -407,21 +409,10 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
}
public void finishBasicBlocks() {
trimList(blocks);
trimList(exitBlocks);
blocks = Collections.unmodifiableList(blocks);
exitBlocks = Collections.unmodifiableList(exitBlocks);
for (BlockNode block : blocks) {
block.lock();
}
}
private void trimList(List<BlockNode> blocks) {
if (blocks instanceof ArrayList) {
((ArrayList<BlockNode>)blocks).trimToSize();
}
blocks = lockList(blocks);
exitBlocks = lockList(exitBlocks);
loops = lockList(loops);
blocks.forEach(BlockNode::lock);
}
public List<BlockNode> getBasicBlocks() {
@@ -0,0 +1,220 @@
package jadx.core.utils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import java.util.RandomAccess;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import org.jetbrains.annotations.NotNull;
/**
* Simple immutable list implementation
* Warning: some methods not implemented!
*/
public final class ImmutableList<E> implements List<E>, RandomAccess {
private final E[] arr;
@SuppressWarnings("unchecked")
public ImmutableList(Object[] arr) {
this.arr = (E[]) Objects.requireNonNull(arr);
}
@Override
public int size() {
return arr.length;
}
@Override
public boolean isEmpty() {
return arr.length == 0;
}
@Override
public E get(int index) {
return arr[index];
}
@Override
public int indexOf(Object o) {
int len = arr.length;
for (int i = 0; i < len; i++) {
E e = arr[i];
if (Objects.equals(e, o)) {
return i;
}
}
return -1;
}
@Override
public int lastIndexOf(Object o) {
for (int i = arr.length - 1; i > 0; i--) {
E e = arr[i];
if (Objects.equals(e, o)) {
return i;
}
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public boolean containsAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private int index = 0;
private int len = arr.length;
@Override
public boolean hasNext() {
return index < len;
}
@Override
public E next() {
return arr[index++];
}
};
}
@Override
public void forEach(Consumer<? super E> action) {
for (E e : arr) {
action.accept(e);
}
}
@NotNull
@Override
public Object[] toArray() {
return arr;
}
@NotNull
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(@NotNull T[] a) {
return (T[]) arr;
}
@Override
public boolean add(E e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(@NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(int index, @NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
@Override
public E remove(int index) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public ListIterator<E> listIterator() {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public ListIterator<E> listIterator(int index) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public List<E> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ImmutableList<?> that = (ImmutableList<?>) o;
return Arrays.equals(arr, that.arr);
}
@Override
public int hashCode() {
return Arrays.hashCode(arr);
}
@Override
public String toString() {
return "ImmutableList{" + Arrays.toString(arr) + '}';
}
}
@@ -3,7 +3,9 @@ package jadx.core.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import jadx.api.JadxDecompiler;
@@ -107,4 +109,15 @@ public class Utils {
th.setStackTrace(Arrays.copyOfRange(stackTrace, 0, cutIndex));
}
}
@SuppressWarnings("unchecked")
public static <T> List<T> lockList(List<T> list) {
if (list.isEmpty()) {
return Collections.emptyList();
}
if (list.size() == 1) {
return Collections.singletonList(list.get(0));
}
return new ImmutableList<>(list.toArray());
}
}