core: use own immutable list
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user