reformat code and fix sonar warnings
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
package jadx.cli;
|
||||
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
public class JadxCLI {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class);
|
||||
|
||||
@@ -17,7 +17,7 @@ public class JadxCLI {
|
||||
if (processArgs(jadxArgs, args)) {
|
||||
processAndSave(jadxArgs);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
} catch (Exception e) {
|
||||
LOG.error("jadx error: {}", e.getMessage(), e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package jadx.cli;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import jadx.api.IJadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -14,14 +8,19 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import com.beust.jcommander.IStringConverter;
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.ParameterDescription;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.api.IJadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
public class JadxCLIArgs implements IJadxArgs {
|
||||
|
||||
@@ -85,7 +84,7 @@ public class JadxCLIArgs implements IJadxArgs {
|
||||
@Parameter(names = {"-h", "--help"}, description = "print this help", help = true)
|
||||
protected boolean printHelp = false;
|
||||
|
||||
private final List<File> input = new ArrayList<File>(1);
|
||||
private final List<File> input = new ArrayList<>(1);
|
||||
private File outputDir;
|
||||
|
||||
public boolean processArgs(String[] args) {
|
||||
@@ -156,7 +155,7 @@ public class JadxCLIArgs implements IJadxArgs {
|
||||
out.println("options:");
|
||||
|
||||
List<ParameterDescription> params = jc.getParameters();
|
||||
Map<String, ParameterDescription> paramsMap = new LinkedHashMap<String, ParameterDescription>(params.size());
|
||||
Map<String, ParameterDescription> paramsMap = new LinkedHashMap<>(params.size());
|
||||
int maxNamesLen = 0;
|
||||
for (ParameterDescription p : params) {
|
||||
paramsMap.put(p.getParameterized().getName(), p);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package jadx.api;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import jadx.core.Jadx;
|
||||
import jadx.core.ProcessClass;
|
||||
import jadx.core.codegen.CodeGen;
|
||||
@@ -27,6 +26,7 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -54,7 +54,7 @@ public final class JadxDecompiler {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JadxDecompiler.class);
|
||||
|
||||
private final IJadxArgs args;
|
||||
private final List<InputFile> inputFiles = new ArrayList<InputFile>();
|
||||
private final List<InputFile> inputFiles = new ArrayList<>();
|
||||
|
||||
private File outDir;
|
||||
|
||||
@@ -140,12 +140,13 @@ public final class JadxDecompiler {
|
||||
}
|
||||
|
||||
private void save(boolean saveSources, boolean saveResources) {
|
||||
ExecutorService ex = getSaveExecutor(saveSources, saveResources);
|
||||
ex.shutdown();
|
||||
try {
|
||||
ExecutorService ex = getSaveExecutor(saveSources, saveResources);
|
||||
ex.shutdown();
|
||||
ex.awaitTermination(1, TimeUnit.DAYS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new JadxRuntimeException("Save interrupted", e);
|
||||
LOG.error("Save interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,17 +190,14 @@ public final class JadxDecompiler {
|
||||
}
|
||||
}
|
||||
|
||||
private void appendSourcesSave(ExecutorService executor, final File outDir) {
|
||||
for (final JavaClass cls : getClasses()) {
|
||||
private void appendSourcesSave(ExecutorService executor, File outDir) {
|
||||
for (JavaClass cls : getClasses()) {
|
||||
if (cls.getClassNode().contains(AFlag.DONT_GENERATE)) {
|
||||
continue;
|
||||
}
|
||||
executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cls.decompile();
|
||||
SaveCode.save(outDir, args, cls.getClassNode());
|
||||
}
|
||||
executor.execute(() -> {
|
||||
cls.decompile();
|
||||
SaveCode.save(outDir, args, cls.getClassNode());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -210,7 +208,7 @@ public final class JadxDecompiler {
|
||||
}
|
||||
if (classes == null) {
|
||||
List<ClassNode> classNodeList = root.getClasses(false);
|
||||
List<JavaClass> clsList = new ArrayList<JavaClass>(classNodeList.size());
|
||||
List<JavaClass> clsList = new ArrayList<>(classNodeList.size());
|
||||
classesMap.clear();
|
||||
for (ClassNode classNode : classNodeList) {
|
||||
JavaClass javaClass = new JavaClass(classNode, this);
|
||||
@@ -237,28 +235,19 @@ public final class JadxDecompiler {
|
||||
if (classList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<String, List<JavaClass>> map = new HashMap<String, List<JavaClass>>();
|
||||
Map<String, List<JavaClass>> map = new HashMap<>();
|
||||
for (JavaClass javaClass : classList) {
|
||||
String pkg = javaClass.getPackage();
|
||||
List<JavaClass> clsList = map.get(pkg);
|
||||
if (clsList == null) {
|
||||
clsList = new ArrayList<JavaClass>();
|
||||
map.put(pkg, clsList);
|
||||
}
|
||||
List<JavaClass> clsList = map.computeIfAbsent(pkg, k -> new ArrayList<>());
|
||||
clsList.add(javaClass);
|
||||
}
|
||||
List<JavaPackage> packages = new ArrayList<JavaPackage>(map.size());
|
||||
List<JavaPackage> packages = new ArrayList<>(map.size());
|
||||
for (Map.Entry<String, List<JavaClass>> entry : map.entrySet()) {
|
||||
packages.add(new JavaPackage(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
Collections.sort(packages);
|
||||
for (JavaPackage pkg : packages) {
|
||||
Collections.sort(pkg.getClasses(), new Comparator<JavaClass>() {
|
||||
@Override
|
||||
public int compare(JavaClass o1, JavaClass o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
pkg.getClasses().sort(Comparator.comparing(JavaClass::getName));
|
||||
}
|
||||
return Collections.unmodifiableList(packages);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public final class JavaClass implements JavaNode {
|
||||
JadxDecompiler rootDecompiler = getRootDecompiler();
|
||||
int inClsCount = cls.getInnerClasses().size();
|
||||
if (inClsCount != 0) {
|
||||
List<JavaClass> list = new ArrayList<JavaClass>(inClsCount);
|
||||
List<JavaClass> list = new ArrayList<>(inClsCount);
|
||||
for (ClassNode inner : cls.getInnerClasses()) {
|
||||
if (!inner.contains(AFlag.DONT_GENERATE)) {
|
||||
JavaClass javaClass = new JavaClass(inner, this);
|
||||
@@ -86,7 +86,7 @@ public final class JavaClass implements JavaNode {
|
||||
|
||||
int fieldsCount = cls.getFields().size();
|
||||
if (fieldsCount != 0) {
|
||||
List<JavaField> flds = new ArrayList<JavaField>(fieldsCount);
|
||||
List<JavaField> flds = new ArrayList<>(fieldsCount);
|
||||
for (FieldNode f : cls.getFields()) {
|
||||
if (!f.contains(AFlag.DONT_GENERATE)) {
|
||||
JavaField javaField = new JavaField(f, this);
|
||||
@@ -99,7 +99,7 @@ public final class JavaClass implements JavaNode {
|
||||
|
||||
int methodsCount = cls.getMethods().size();
|
||||
if (methodsCount != 0) {
|
||||
List<JavaMethod> mths = new ArrayList<JavaMethod>(methodsCount);
|
||||
List<JavaMethod> mths = new ArrayList<>(methodsCount);
|
||||
for (MethodNode m : cls.getMethods()) {
|
||||
if (!m.contains(AFlag.DONT_GENERATE)) {
|
||||
JavaMethod javaMethod = new JavaMethod(this, m);
|
||||
@@ -134,7 +134,7 @@ public final class JavaClass implements JavaNode {
|
||||
if (map.isEmpty() || decompiler == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<CodePosition, JavaNode> resultMap = new HashMap<CodePosition, JavaNode>(map.size());
|
||||
Map<CodePosition, JavaNode> resultMap = new HashMap<>(map.size());
|
||||
for (Map.Entry<CodePosition, Object> entry : map.entrySet()) {
|
||||
CodePosition codePosition = entry.getKey();
|
||||
Object obj = entry.getValue();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package jadx.api;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ResourceFile {
|
||||
|
||||
public static final class ZipRef {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package jadx.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import jadx.api.ResourceFile.ZipRef;
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.files.InputFile;
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
import jadx.core.xmlgen.ResTableParser;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -15,13 +20,8 @@ import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import jadx.api.ResourceFile.ZipRef;
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.files.InputFile;
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
import jadx.core.xmlgen.ResTableParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static jadx.core.utils.files.FileUtils.READ_BUFFER_SIZE;
|
||||
import static jadx.core.utils.files.FileUtils.close;
|
||||
@@ -40,7 +40,7 @@ public final class ResourcesLoader {
|
||||
}
|
||||
|
||||
List<ResourceFile> load(List<InputFile> inputFiles) {
|
||||
List<ResourceFile> list = new ArrayList<ResourceFile>(inputFiles.size());
|
||||
List<ResourceFile> list = new ArrayList<>(inputFiles.size());
|
||||
for (InputFile file : inputFiles) {
|
||||
loadFile(list, file.getFile());
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public final class ResourcesLoader {
|
||||
public static ResContainer decodeStream(ResourceFile rf, ResourceDecoder decoder) throws JadxException {
|
||||
ZipFile zipFile = null;
|
||||
InputStream inputStream = null;
|
||||
ResContainer result = null;
|
||||
ResContainer result;
|
||||
try {
|
||||
long size;
|
||||
ZipRef zipRef = rf.getZipRef();
|
||||
@@ -87,14 +87,9 @@ public final class ResourcesLoader {
|
||||
return result;
|
||||
}
|
||||
|
||||
static ResContainer loadContent(final JadxDecompiler jadxRef, final ResourceFile rf) {
|
||||
static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf) {
|
||||
try {
|
||||
return decodeStream(rf, new ResourceDecoder() {
|
||||
@Override
|
||||
public ResContainer decode(long size, InputStream is) throws IOException {
|
||||
return loadContent(jadxRef, rf, is, size);
|
||||
}
|
||||
});
|
||||
return decodeStream(rf, (size, is) -> loadContent(jadxRef, rf, is, size));
|
||||
} catch (JadxException e) {
|
||||
LOG.error("Decode error", e);
|
||||
CodeWriter cw = new CodeWriter();
|
||||
|
||||
@@ -46,6 +46,9 @@ import org.slf4j.LoggerFactory;
|
||||
public class Jadx {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Jadx.class);
|
||||
|
||||
private Jadx() {
|
||||
}
|
||||
|
||||
static {
|
||||
if (Consts.DEBUG) {
|
||||
LOG.info("debug enabled");
|
||||
@@ -53,7 +56,7 @@ public class Jadx {
|
||||
}
|
||||
|
||||
public static List<IDexTreeVisitor> getPassesList(IJadxArgs args, File outDir) {
|
||||
List<IDexTreeVisitor> passes = new ArrayList<IDexTreeVisitor>();
|
||||
List<IDexTreeVisitor> passes = new ArrayList<>();
|
||||
if (args.isFallbackMode()) {
|
||||
passes.add(new FallbackModeVisitor());
|
||||
} else {
|
||||
|
||||
@@ -9,8 +9,6 @@ import jadx.core.utils.ErrorsCounter;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static jadx.core.dex.nodes.ProcessState.GENERATED;
|
||||
import static jadx.core.dex.nodes.ProcessState.NOT_LOADED;
|
||||
@@ -19,7 +17,6 @@ import static jadx.core.dex.nodes.ProcessState.STARTED;
|
||||
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
|
||||
|
||||
public final class ProcessClass {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ProcessClass.class);
|
||||
|
||||
private ProcessClass() {
|
||||
}
|
||||
@@ -28,7 +25,7 @@ public final class ProcessClass {
|
||||
if (codeGen == null && cls.getState() == PROCESSED) {
|
||||
return;
|
||||
}
|
||||
synchronized (cls) {
|
||||
synchronized (cls.getClassInfo()) {
|
||||
try {
|
||||
if (cls.getState() == NOT_LOADED) {
|
||||
cls.load();
|
||||
@@ -54,7 +51,7 @@ public final class ProcessClass {
|
||||
}
|
||||
}
|
||||
|
||||
static void processDependencies(ClassNode cls, List<IDexTreeVisitor> passes) {
|
||||
private static void processDependencies(ClassNode cls, List<IDexTreeVisitor> passes) {
|
||||
for (ClassNode depCls : cls.getDependencies()) {
|
||||
process(depCls, passes, null);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class ClsSet {
|
||||
|
||||
public void load(RootNode root) {
|
||||
List<ClassNode> list = root.getClasses(true);
|
||||
Map<String, NClass> names = new HashMap<String, NClass>(list.size());
|
||||
Map<String, NClass> names = new HashMap<>(list.size());
|
||||
int k = 0;
|
||||
for (ClassNode cls : list) {
|
||||
String clsRawName = cls.getRawName();
|
||||
@@ -78,7 +78,7 @@ public class ClsSet {
|
||||
}
|
||||
|
||||
public static NClass[] makeParentsArray(ClassNode cls, Map<String, NClass> names) {
|
||||
List<NClass> parents = new ArrayList<NClass>(1 + cls.getInterfaces().size());
|
||||
List<NClass> parents = new ArrayList<>(1 + cls.getInterfaces().size());
|
||||
ArgType superClass = cls.getSuperClass();
|
||||
if (superClass != null) {
|
||||
NClass c = getCls(superClass.getObject(), names);
|
||||
@@ -105,9 +105,7 @@ public class ClsSet {
|
||||
|
||||
void save(File output) throws IOException {
|
||||
FileUtils.makeDirsForFile(output);
|
||||
|
||||
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(output));
|
||||
try {
|
||||
try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(output))) {
|
||||
String outputName = output.getName();
|
||||
if (outputName.endsWith(CLST_EXTENSION)) {
|
||||
save(outputStream);
|
||||
@@ -122,14 +120,11 @@ public class ClsSet {
|
||||
} else {
|
||||
throw new JadxRuntimeException("Unknown file format: " + outputName);
|
||||
}
|
||||
} finally {
|
||||
close(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(OutputStream output) throws IOException {
|
||||
DataOutputStream out = new DataOutputStream(output);
|
||||
try {
|
||||
try (DataOutputStream out = new DataOutputStream(output)) {
|
||||
out.writeBytes(JADX_CLS_SET_HEADER);
|
||||
out.writeByte(VERSION);
|
||||
|
||||
@@ -145,32 +140,25 @@ public class ClsSet {
|
||||
out.writeInt(parent.getId());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
close(out);
|
||||
}
|
||||
}
|
||||
|
||||
public void load() throws IOException, DecodeException {
|
||||
InputStream input = getClass().getResourceAsStream(CLST_FILENAME);
|
||||
if (input == null) {
|
||||
throw new JadxRuntimeException("Can't load classpath file: " + CLST_FILENAME);
|
||||
}
|
||||
try {
|
||||
try (InputStream input = getClass().getResourceAsStream(CLST_FILENAME)) {
|
||||
if (input == null) {
|
||||
throw new JadxRuntimeException("Can't load classpath file: " + CLST_FILENAME);
|
||||
}
|
||||
load(input);
|
||||
} finally {
|
||||
close(input);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(File input) throws IOException, DecodeException {
|
||||
String name = input.getName();
|
||||
InputStream inputStream = new FileInputStream(input);
|
||||
try {
|
||||
try (InputStream inputStream = new FileInputStream(input)) {
|
||||
if (name.endsWith(CLST_EXTENSION)) {
|
||||
load(inputStream);
|
||||
} else if (name.endsWith(".jar")) {
|
||||
ZipInputStream in = new ZipInputStream(inputStream);
|
||||
try {
|
||||
try (ZipInputStream in = new ZipInputStream(inputStream)) {
|
||||
ZipEntry entry = in.getNextEntry();
|
||||
while (entry != null) {
|
||||
if (entry.getName().endsWith(CLST_EXTENSION)) {
|
||||
@@ -178,20 +166,15 @@ public class ClsSet {
|
||||
}
|
||||
entry = in.getNextEntry();
|
||||
}
|
||||
} finally {
|
||||
close(in);
|
||||
}
|
||||
} else {
|
||||
throw new JadxRuntimeException("Unknown file format: " + name);
|
||||
}
|
||||
} finally {
|
||||
close(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(InputStream input) throws IOException, DecodeException {
|
||||
DataInputStream in = new DataInputStream(input);
|
||||
try {
|
||||
try (DataInputStream in = new DataInputStream(input)) {
|
||||
byte[] header = new byte[JADX_CLS_SET_HEADER.length()];
|
||||
int readHeaderLength = in.read(header);
|
||||
int version = in.readByte();
|
||||
@@ -214,8 +197,6 @@ public class ClsSet {
|
||||
}
|
||||
classes[i].setParents(parents);
|
||||
}
|
||||
} finally {
|
||||
close(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ClspGraph {
|
||||
private final Map<String, Set<String>> ancestorCache = Collections.synchronizedMap(new WeakHashMap<String, Set<String>>());
|
||||
private Map<String, NClass> nameMap;
|
||||
|
||||
private final Set<String> missingClasses = new HashSet<String>();
|
||||
private final Set<String> missingClasses = new HashSet<>();
|
||||
|
||||
public void load() throws IOException, DecodeException {
|
||||
ClsSet set = new ClsSet();
|
||||
@@ -36,7 +36,7 @@ public class ClspGraph {
|
||||
|
||||
public void addClasspath(ClsSet set) {
|
||||
if (nameMap == null) {
|
||||
nameMap = new HashMap<String, NClass>(set.getClassesCount());
|
||||
nameMap = new HashMap<>(set.getClassesCount());
|
||||
set.addToMap(nameMap);
|
||||
} else {
|
||||
throw new JadxRuntimeException("Classpath already loaded");
|
||||
@@ -110,7 +110,7 @@ public class ClspGraph {
|
||||
missingClasses.add(clsName);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
result = new HashSet<String>();
|
||||
result = new HashSet<>();
|
||||
addAncestorsNames(cls, result);
|
||||
if (result.isEmpty()) {
|
||||
result = Collections.emptySet();
|
||||
@@ -133,7 +133,7 @@ public class ClspGraph {
|
||||
}
|
||||
LOG.warn("Found {} references to unknown classes", count);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
List<String> clsNames = new ArrayList<String>(missingClasses);
|
||||
List<String> clsNames = new ArrayList<>(missingClasses);
|
||||
Collections.sort(clsNames);
|
||||
for (String cls : clsNames) {
|
||||
LOG.debug(" {}", cls);
|
||||
|
||||
@@ -30,7 +30,7 @@ public class ConvertToClsSet {
|
||||
}
|
||||
File output = new File(args[0]);
|
||||
|
||||
List<InputFile> inputFiles = new ArrayList<InputFile>(args.length - 1);
|
||||
List<InputFile> inputFiles = new ArrayList<>(args.length - 1);
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
File f = new File(args[i]);
|
||||
if (f.isDirectory()) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ClassGen {
|
||||
private final boolean fallback;
|
||||
private final boolean showInconsistentCode;
|
||||
|
||||
private final Set<ClassInfo> imports = new HashSet<ClassInfo>();
|
||||
private final Set<ClassInfo> imports = new HashSet<>();
|
||||
private int clsDeclLine;
|
||||
|
||||
public ClassGen(ClassNode cls, IJadxArgs jadxArgs) {
|
||||
@@ -89,7 +89,7 @@ public class ClassGen {
|
||||
}
|
||||
int importsCount = imports.size();
|
||||
if (importsCount != 0) {
|
||||
List<String> sortImports = new ArrayList<String>(importsCount);
|
||||
List<String> sortImports = new ArrayList<>(importsCount);
|
||||
for (ClassInfo ic : imports) {
|
||||
sortImports.add(ic.getAlias().getFullName());
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class ClassGen {
|
||||
}
|
||||
|
||||
private static List<MethodNode> sortMethodsByLine(List<MethodNode> methods) {
|
||||
List<MethodNode> out = new ArrayList<MethodNode>(methods);
|
||||
List<MethodNode> out = new ArrayList<>(methods);
|
||||
Collections.sort(out, METHOD_LINE_COMPARATOR);
|
||||
return out;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ public class ClassGen {
|
||||
}
|
||||
annotationGen.addForField(code, f);
|
||||
|
||||
if(f.getFieldInfo().isRenamed()) {
|
||||
if (f.getFieldInfo().isRenamed()) {
|
||||
code.startLine("/* renamed from: ").add(f.getName()).add(" */");
|
||||
}
|
||||
code.startLine(f.getAccessFlags().makeString());
|
||||
|
||||
@@ -16,23 +16,21 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static jadx.core.utils.files.FileUtils.close;
|
||||
|
||||
public class CodeWriter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(CodeWriter.class);
|
||||
|
||||
public static final String NL = System.getProperty("line.separator");
|
||||
public static final String INDENT = " ";
|
||||
public static final String INDENT_STR = " ";
|
||||
|
||||
private static final boolean ADD_LINE_NUMBERS = false;
|
||||
|
||||
private static final String[] INDENT_CACHE = {
|
||||
"",
|
||||
INDENT,
|
||||
INDENT + INDENT,
|
||||
INDENT + INDENT + INDENT,
|
||||
INDENT + INDENT + INDENT + INDENT,
|
||||
INDENT + INDENT + INDENT + INDENT + INDENT,
|
||||
INDENT_STR,
|
||||
INDENT_STR + INDENT_STR,
|
||||
INDENT_STR + INDENT_STR + INDENT_STR,
|
||||
INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR,
|
||||
INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR,
|
||||
};
|
||||
|
||||
private StringBuilder buf = new StringBuilder();
|
||||
@@ -127,7 +125,7 @@ public class CodeWriter {
|
||||
}
|
||||
|
||||
public CodeWriter addIndent() {
|
||||
add(INDENT);
|
||||
add(INDENT_STR);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -148,9 +146,9 @@ public class CodeWriter {
|
||||
if (curIndent < INDENT_CACHE.length) {
|
||||
this.indentStr = INDENT_CACHE[curIndent];
|
||||
} else {
|
||||
StringBuilder s = new StringBuilder(curIndent * INDENT.length());
|
||||
StringBuilder s = new StringBuilder(curIndent * INDENT_STR.length());
|
||||
for (int i = 0; i < curIndent; i++) {
|
||||
s.append(INDENT);
|
||||
s.append(INDENT_STR);
|
||||
}
|
||||
this.indentStr = s.toString();
|
||||
}
|
||||
@@ -209,7 +207,7 @@ public class CodeWriter {
|
||||
|
||||
private Object attachAnnotation(Object obj, CodePosition pos) {
|
||||
if (annotations.isEmpty()) {
|
||||
annotations = new HashMap<CodePosition, Object>();
|
||||
annotations = new HashMap<>();
|
||||
}
|
||||
return annotations.put(pos, obj);
|
||||
}
|
||||
@@ -227,7 +225,7 @@ public class CodeWriter {
|
||||
|
||||
private void attachSourceLine(int decompiledLine, int sourceLine) {
|
||||
if (lineMap.isEmpty()) {
|
||||
lineMap = new TreeMap<Integer, Integer>();
|
||||
lineMap = new TreeMap<>();
|
||||
}
|
||||
lineMap.put(decompiledLine, sourceLine);
|
||||
}
|
||||
@@ -286,15 +284,10 @@ public class CodeWriter {
|
||||
finish();
|
||||
}
|
||||
File outFile = FileUtils.prepareFile(file);
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
out = new PrintWriter(outFile, "UTF-8");
|
||||
try (PrintWriter out = new PrintWriter(outFile, "UTF-8")) {
|
||||
out.println(code);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Save file error", e);
|
||||
} finally {
|
||||
close(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ConditionGen extends InsnGen {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConditionGen.class);
|
||||
|
||||
private static class CondStack {
|
||||
private final Queue<IfCondition> stack = new LinkedList<IfCondition>();
|
||||
private final Queue<IfCondition> stack = new LinkedList<>();
|
||||
|
||||
public Queue<IfCondition> getStack() {
|
||||
return stack;
|
||||
|
||||
@@ -752,7 +752,7 @@ public class InsnGen {
|
||||
}
|
||||
// replace args
|
||||
InsnNode inlCopy = inl.copy();
|
||||
List<RegisterArg> inlArgs = new ArrayList<RegisterArg>();
|
||||
List<RegisterArg> inlArgs = new ArrayList<>();
|
||||
inlCopy.getRegisterArgs(inlArgs);
|
||||
for (RegisterArg r : inlArgs) {
|
||||
int regNum = r.getRegNum();
|
||||
|
||||
@@ -81,7 +81,7 @@ public class MethodGen {
|
||||
ai = ai.remove(AccessFlags.ACC_PUBLIC);
|
||||
}
|
||||
|
||||
if(mth.getMethodInfo().isRenamed()) {
|
||||
if (mth.getMethodInfo().isRenamed()) {
|
||||
code.startLine("/* renamed from: ").add(mth.getName()).add(" */");
|
||||
}
|
||||
code.startLineWithNum(mth.getSourceLine());
|
||||
@@ -133,7 +133,7 @@ public class MethodGen {
|
||||
annotationGen.addForParameter(argsCode, paramsAnnotation, i);
|
||||
}
|
||||
SSAVar argSVar = arg.getSVar();
|
||||
if (argSVar!= null && argSVar.contains(AFlag.FINAL)) {
|
||||
if (argSVar != null && argSVar.contains(AFlag.FINAL)) {
|
||||
argsCode.add("final ");
|
||||
}
|
||||
if (!it.hasNext() && mth.getAccessFlags().isVarArgs()) {
|
||||
|
||||
@@ -26,12 +26,12 @@ public class NameGen {
|
||||
|
||||
private static final Map<String, String> OBJ_ALIAS;
|
||||
|
||||
private final Set<String> varNames = new HashSet<String>();
|
||||
private final Set<String> varNames = new HashSet<>();
|
||||
private final MethodNode mth;
|
||||
private final boolean fallback;
|
||||
|
||||
static {
|
||||
OBJ_ALIAS = new HashMap<String, String>();
|
||||
OBJ_ALIAS = new HashMap<>();
|
||||
OBJ_ALIAS.put(Consts.CLASS_STRING, "str");
|
||||
OBJ_ALIAS.put(Consts.CLASS_CLASS, "cls");
|
||||
OBJ_ALIAS.put(Consts.CLASS_THROWABLE, "th");
|
||||
@@ -164,7 +164,9 @@ public class NameGen {
|
||||
if (vName != null) {
|
||||
return vName;
|
||||
}
|
||||
return StringUtils.escape(shortName.toLowerCase());
|
||||
if (shortName != null) {
|
||||
return StringUtils.escape(shortName.toLowerCase());
|
||||
}
|
||||
}
|
||||
return StringUtils.escape(type.toString());
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ class DeobfPresets {
|
||||
private final Deobfuscator deobfuscator;
|
||||
private final File deobfMapFile;
|
||||
|
||||
private final Map<String, String> clsPresetMap = new HashMap<String, String>();
|
||||
private final Map<String, String> fldPresetMap = new HashMap<String, String>();
|
||||
private final Map<String, String> mthPresetMap = new HashMap<String, String>();
|
||||
private final Map<String, String> clsPresetMap = new HashMap<>();
|
||||
private final Map<String, String> fldPresetMap = new HashMap<>();
|
||||
private final Map<String, String> mthPresetMap = new HashMap<>();
|
||||
|
||||
public DeobfPresets(Deobfuscator deobfuscator, File deobfMapFile) {
|
||||
this.deobfuscator = deobfuscator;
|
||||
@@ -98,7 +98,7 @@ class DeobfPresets {
|
||||
* Saves DefaultDeobfuscator presets
|
||||
*/
|
||||
private void dumpMapping() throws IOException {
|
||||
List<String> list = new ArrayList<String>();
|
||||
List<String> list = new ArrayList<>();
|
||||
// packages
|
||||
for (PackageNode p : deobfuscator.getRootPackage().getInnerPackages()) {
|
||||
for (PackageNode pp : p.getInnerPackages()) {
|
||||
|
||||
@@ -39,15 +39,15 @@ public class Deobfuscator {
|
||||
private final List<DexNode> dexNodes;
|
||||
private final DeobfPresets deobfPresets;
|
||||
|
||||
private final Map<ClassInfo, DeobfClsInfo> clsMap = new HashMap<ClassInfo, DeobfClsInfo>();
|
||||
private final Map<FieldInfo, String> fldMap = new HashMap<FieldInfo, String>();
|
||||
private final Map<MethodInfo, String> mthMap = new HashMap<MethodInfo, String>();
|
||||
private final Map<ClassInfo, DeobfClsInfo> clsMap = new HashMap<>();
|
||||
private final Map<FieldInfo, String> fldMap = new HashMap<>();
|
||||
private final Map<MethodInfo, String> mthMap = new HashMap<>();
|
||||
|
||||
private final Map<MethodInfo, OverridedMethodsNode> ovrdMap = new HashMap<MethodInfo, OverridedMethodsNode>();
|
||||
private final List<OverridedMethodsNode> ovrd = new ArrayList<OverridedMethodsNode>();
|
||||
private final Map<MethodInfo, OverridedMethodsNode> ovrdMap = new HashMap<>();
|
||||
private final List<OverridedMethodsNode> ovrd = new ArrayList<>();
|
||||
|
||||
private final PackageNode rootPackage = new PackageNode("");
|
||||
private final Set<String> pkgSet = new TreeSet<String>();
|
||||
private final Set<String> pkgSet = new TreeSet<>();
|
||||
|
||||
private final int maxLength;
|
||||
private final int minLength;
|
||||
@@ -112,14 +112,14 @@ public class Deobfuscator {
|
||||
for (OverridedMethodsNode o : ovrd) {
|
||||
boolean aliasFromPreset = false;
|
||||
String aliasToUse = null;
|
||||
for(MethodInfo mth : o.getMethods()){
|
||||
if(mth.isAliasFromPreset()) {
|
||||
for (MethodInfo mth : o.getMethods()) {
|
||||
if (mth.isAliasFromPreset()) {
|
||||
aliasToUse = mth.getAlias();
|
||||
aliasFromPreset = true;
|
||||
}
|
||||
}
|
||||
for(MethodInfo mth : o.getMethods()){
|
||||
if(aliasToUse == null) {
|
||||
for (MethodInfo mth : o.getMethods()) {
|
||||
if (aliasToUse == null) {
|
||||
if (mth.isRenamed() && !mth.isAliasFromPreset()) {
|
||||
mth.setAlias(String.format("mo%d%s", id, makeName(mth.getName())));
|
||||
}
|
||||
@@ -201,9 +201,8 @@ public class Deobfuscator {
|
||||
}
|
||||
|
||||
private void resolveOverriding(DexNode dex, ClassNode cls, MethodNode mth) {
|
||||
Set<MethodInfo> overrideSet = new HashSet<MethodInfo>();
|
||||
Set<MethodInfo> overrideSet = new HashSet<>();
|
||||
resolveOverridingInternal(dex, cls, mth.getMethodInfo().makeSignature(false), overrideSet, cls);
|
||||
|
||||
if (overrideSet.size() > 1) {
|
||||
OverridedMethodsNode overrideNode = null;
|
||||
for (MethodInfo _mth : overrideSet) {
|
||||
@@ -212,12 +211,10 @@ public class Deobfuscator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (overrideNode == null) {
|
||||
overrideNode = new OverridedMethodsNode(overrideSet);
|
||||
ovrd.add(overrideNode);
|
||||
}
|
||||
|
||||
for (MethodInfo _mth : overrideSet) {
|
||||
if (!ovrdMap.containsKey(_mth)) {
|
||||
ovrdMap.put(_mth, overrideNode);
|
||||
@@ -228,7 +225,6 @@ public class Deobfuscator {
|
||||
}
|
||||
} else {
|
||||
overrideSet.clear();
|
||||
overrideSet = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,9 +438,9 @@ public class Deobfuscator {
|
||||
parentPkg = parentPkg.getParentPackage();
|
||||
}
|
||||
|
||||
final String pkgName = pkg.getName();
|
||||
String pkgName = pkg.getName();
|
||||
if (!pkg.hasAlias() && shouldRename(pkgName)) {
|
||||
final String pkgAlias = String.format("p%03d%s", pkgIndex++, makeName(pkgName));
|
||||
String pkgAlias = String.format("p%03d%s", pkgIndex++, makeName(pkgName));
|
||||
pkg.setAlias(pkgAlias);
|
||||
}
|
||||
}
|
||||
@@ -501,7 +497,7 @@ public class Deobfuscator {
|
||||
}
|
||||
|
||||
private String getPackageName(String packageName) {
|
||||
final PackageNode pkg = getPackageNode(packageName, false);
|
||||
PackageNode pkg = getPackageNode(packageName, false);
|
||||
if (pkg != null) {
|
||||
return pkg.getFullAlias();
|
||||
}
|
||||
@@ -509,7 +505,7 @@ public class Deobfuscator {
|
||||
}
|
||||
|
||||
private String getClassName(ClassInfo clsInfo) {
|
||||
final DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
|
||||
DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
|
||||
if (deobfClsInfo != null) {
|
||||
return deobfClsInfo.makeNameWithoutPkg();
|
||||
}
|
||||
@@ -521,7 +517,7 @@ public class Deobfuscator {
|
||||
}
|
||||
|
||||
private String getClassFullName(ClassInfo clsInfo) {
|
||||
final DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
|
||||
DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
|
||||
if (deobfClsInfo != null) {
|
||||
return deobfClsInfo.getFullName();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public class NameMapper {
|
||||
private static final Pattern VALID_JAVA_FULL_IDENTIFIER = Pattern.compile(
|
||||
"(" + VALID_JAVA_IDENTIFIER + "\\.)*" + VALID_JAVA_IDENTIFIER);
|
||||
|
||||
private static final Set<String> RESERVED_NAMES = new HashSet<String>(
|
||||
private static final Set<String> RESERVED_NAMES = new HashSet<>(
|
||||
Arrays.asList(new String[]{
|
||||
"abstract",
|
||||
"assert",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package jadx.core.deobf;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class PackageNode {
|
||||
|
||||
@@ -29,11 +30,11 @@ public class PackageNode {
|
||||
|
||||
public String getFullName() {
|
||||
if (cachedPackageFullName == null) {
|
||||
Stack<PackageNode> pp = getParentPackages();
|
||||
Deque<PackageNode> pp = getParentPackages();
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(pp.pop().getName());
|
||||
while (pp.size() > 0) {
|
||||
while (!pp.isEmpty()) {
|
||||
result.append(SEPARATOR_CHAR);
|
||||
result.append(pp.pop().getName());
|
||||
}
|
||||
@@ -59,12 +60,12 @@ public class PackageNode {
|
||||
|
||||
public String getFullAlias() {
|
||||
if (cachedPackageFullAlias == null) {
|
||||
Stack<PackageNode> pp = getParentPackages();
|
||||
Deque<PackageNode> pp = getParentPackages();
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
if (pp.size() > 0) {
|
||||
if (!pp.isEmpty()) {
|
||||
result.append(pp.pop().getAlias());
|
||||
while (pp.size() > 0) {
|
||||
while (!pp.isEmpty()) {
|
||||
result.append(SEPARATOR_CHAR);
|
||||
result.append(pp.pop().getAlias());
|
||||
}
|
||||
@@ -86,7 +87,7 @@ public class PackageNode {
|
||||
|
||||
public void addInnerPackage(PackageNode pkg) {
|
||||
if (innerPackages.isEmpty()) {
|
||||
innerPackages = new ArrayList<PackageNode>();
|
||||
innerPackages = new ArrayList<>();
|
||||
}
|
||||
innerPackages.add(pkg);
|
||||
pkg.parentPackage = this;
|
||||
@@ -114,16 +115,15 @@ public class PackageNode {
|
||||
*
|
||||
* @return stack with parent packages
|
||||
*/
|
||||
private Stack<PackageNode> getParentPackages() {
|
||||
Stack<PackageNode> pp = new Stack<PackageNode>();
|
||||
private Deque<PackageNode> getParentPackages() {
|
||||
Deque<PackageNode> pp = new ArrayDeque<>();
|
||||
|
||||
PackageNode currentP = this;
|
||||
PackageNode parentP = currentP.getParentPackage();
|
||||
|
||||
while (currentP != parentP) {
|
||||
pp.push(currentP);
|
||||
currentP = parentP;
|
||||
parentP = currentP.getParentPackage();
|
||||
PackageNode currentPkg = this;
|
||||
PackageNode parentPkg = currentPkg.getParentPackage();
|
||||
while (currentPkg != parentPkg) {
|
||||
pp.push(currentPkg);
|
||||
currentPkg = parentPkg;
|
||||
parentPkg = currentPkg.getParentPackage();
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
|
||||
@@ -29,25 +29,25 @@ import jadx.core.dex.trycatch.SplitterBlockAttr;
|
||||
*/
|
||||
public class AType<T extends IAttribute> {
|
||||
|
||||
public static final AType<AttrList<JumpInfo>> JUMP = new AType<AttrList<JumpInfo>>();
|
||||
public static final AType<AttrList<LoopInfo>> LOOP = new AType<AttrList<LoopInfo>>();
|
||||
public static final AType<AttrList<EdgeInsnAttr>> EDGE_INSN = new AType<AttrList<EdgeInsnAttr>>();
|
||||
public static final AType<AttrList<JumpInfo>> JUMP = new AType<>();
|
||||
public static final AType<AttrList<LoopInfo>> LOOP = new AType<>();
|
||||
public static final AType<AttrList<EdgeInsnAttr>> EDGE_INSN = new AType<>();
|
||||
|
||||
public static final AType<ExcHandlerAttr> EXC_HANDLER = new AType<ExcHandlerAttr>();
|
||||
public static final AType<CatchAttr> CATCH_BLOCK = new AType<CatchAttr>();
|
||||
public static final AType<SplitterBlockAttr> SPLITTER_BLOCK = new AType<SplitterBlockAttr>();
|
||||
public static final AType<ForceReturnAttr> FORCE_RETURN = new AType<ForceReturnAttr>();
|
||||
public static final AType<FieldInitAttr> FIELD_INIT = new AType<FieldInitAttr>();
|
||||
public static final AType<FieldReplaceAttr> FIELD_REPLACE = new AType<FieldReplaceAttr>();
|
||||
public static final AType<JadxErrorAttr> JADX_ERROR = new AType<JadxErrorAttr>();
|
||||
public static final AType<MethodInlineAttr> METHOD_INLINE = new AType<MethodInlineAttr>();
|
||||
public static final AType<EnumClassAttr> ENUM_CLASS = new AType<EnumClassAttr>();
|
||||
public static final AType<EnumMapAttr> ENUM_MAP = new AType<EnumMapAttr>();
|
||||
public static final AType<AnnotationsList> ANNOTATION_LIST = new AType<AnnotationsList>();
|
||||
public static final AType<MethodParameters> ANNOTATION_MTH_PARAMETERS = new AType<MethodParameters>();
|
||||
public static final AType<PhiListAttr> PHI_LIST = new AType<PhiListAttr>();
|
||||
public static final AType<SourceFileAttr> SOURCE_FILE = new AType<SourceFileAttr>();
|
||||
public static final AType<DeclareVariablesAttr> DECLARE_VARIABLES = new AType<DeclareVariablesAttr>();
|
||||
public static final AType<LoopLabelAttr> LOOP_LABEL = new AType<LoopLabelAttr>();
|
||||
public static final AType<IgnoreEdgeAttr> IGNORE_EDGE = new AType<IgnoreEdgeAttr>();
|
||||
public static final AType<ExcHandlerAttr> EXC_HANDLER = new AType<>();
|
||||
public static final AType<CatchAttr> CATCH_BLOCK = new AType<>();
|
||||
public static final AType<SplitterBlockAttr> SPLITTER_BLOCK = new AType<>();
|
||||
public static final AType<ForceReturnAttr> FORCE_RETURN = new AType<>();
|
||||
public static final AType<FieldInitAttr> FIELD_INIT = new AType<>();
|
||||
public static final AType<FieldReplaceAttr> FIELD_REPLACE = new AType<>();
|
||||
public static final AType<JadxErrorAttr> JADX_ERROR = new AType<>();
|
||||
public static final AType<MethodInlineAttr> METHOD_INLINE = new AType<>();
|
||||
public static final AType<EnumClassAttr> ENUM_CLASS = new AType<>();
|
||||
public static final AType<EnumMapAttr> ENUM_MAP = new AType<>();
|
||||
public static final AType<AnnotationsList> ANNOTATION_LIST = new AType<>();
|
||||
public static final AType<MethodParameters> ANNOTATION_MTH_PARAMETERS = new AType<>();
|
||||
public static final AType<PhiListAttr> PHI_LIST = new AType<>();
|
||||
public static final AType<SourceFileAttr> SOURCE_FILE = new AType<>();
|
||||
public static final AType<DeclareVariablesAttr> DECLARE_VARIABLES = new AType<>();
|
||||
public static final AType<LoopLabelAttr> LOOP_LABEL = new AType<>();
|
||||
public static final AType<IgnoreEdgeAttr> IGNORE_EDGE = new AType<>();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
public class AttrList<T> implements IAttribute {
|
||||
|
||||
private final AType<AttrList<T>> type;
|
||||
private final List<T> list = new LinkedList<T>();
|
||||
private final List<T> list = new LinkedList<>();
|
||||
|
||||
public AttrList(AType<AttrList<T>> type) {
|
||||
this.type = type;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class AttributeStorage {
|
||||
|
||||
public AttributeStorage() {
|
||||
flags = EnumSet.noneOf(AFlag.class);
|
||||
attributes = new IdentityHashMap<AType<?>, IAttribute>();
|
||||
attributes = new IdentityHashMap<>();
|
||||
}
|
||||
|
||||
public void add(AFlag flag) {
|
||||
@@ -38,7 +38,7 @@ public class AttributeStorage {
|
||||
public <T> void add(AType<AttrList<T>> type, T obj) {
|
||||
AttrList<T> list = get(type);
|
||||
if (list == null) {
|
||||
list = new AttrList<T>(type);
|
||||
list = new AttrList<>(type);
|
||||
add(list);
|
||||
}
|
||||
list.getList().add(obj);
|
||||
@@ -84,7 +84,7 @@ public class AttributeStorage {
|
||||
}
|
||||
|
||||
public void remove(IAttribute attr) {
|
||||
AType<?> type = attr.getType();
|
||||
AType<? extends IAttribute> type = attr.getType();
|
||||
IAttribute a = attributes.get(type);
|
||||
if (a == attr) {
|
||||
attributes.remove(type);
|
||||
@@ -101,7 +101,7 @@ public class AttributeStorage {
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> list = new ArrayList<String>(size);
|
||||
List<String> list = new ArrayList<>(size);
|
||||
for (AFlag a : flags) {
|
||||
list.add(a.toString());
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package jadx.core.dex.attributes;
|
||||
|
||||
public interface IAttribute {
|
||||
|
||||
AType<?> getType();
|
||||
|
||||
AType<? extends IAttribute> getType();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public class AnnotationsList implements IAttribute {
|
||||
private final Map<String, Annotation> map;
|
||||
|
||||
public AnnotationsList(List<Annotation> anList) {
|
||||
map = new HashMap<String, Annotation>(anList.size());
|
||||
map = new HashMap<>(anList.size());
|
||||
for (Annotation a : anList) {
|
||||
map.put(a.getAnnotationClass(), a);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public class MethodParameters implements IAttribute {
|
||||
private final List<AnnotationsList> paramList;
|
||||
|
||||
public MethodParameters(int paramCount) {
|
||||
paramList = new ArrayList<AnnotationsList>(paramCount);
|
||||
paramList = new ArrayList<>(paramCount);
|
||||
}
|
||||
|
||||
public List<AnnotationsList> getParamList() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
*/
|
||||
public class DeclareVariablesAttr implements IAttribute {
|
||||
|
||||
private final List<RegisterArg> vars = new LinkedList<RegisterArg>();
|
||||
private final List<RegisterArg> vars = new LinkedList<>();
|
||||
|
||||
public Iterable<RegisterArg> getVars() {
|
||||
return vars;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class EnumClassAttr implements IAttribute {
|
||||
private MethodNode staticMethod;
|
||||
|
||||
public EnumClassAttr(int fieldsCount) {
|
||||
this.fields = new ArrayList<EnumField>(fieldsCount);
|
||||
this.fields = new ArrayList<>(fieldsCount);
|
||||
}
|
||||
|
||||
public List<EnumField> getFields() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.Map;
|
||||
public class EnumMapAttr implements IAttribute {
|
||||
|
||||
public static class KeyValueMap {
|
||||
private final Map<Object, Object> map = new HashMap<Object, Object>();
|
||||
private final Map<Object, Object> map = new HashMap<>();
|
||||
|
||||
public Object get(Object key) {
|
||||
return map.get(key);
|
||||
@@ -21,7 +21,7 @@ public class EnumMapAttr implements IAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<FieldNode, KeyValueMap> fieldsMap = new HashMap<FieldNode, KeyValueMap>();
|
||||
private final Map<FieldNode, KeyValueMap> fieldsMap = new HashMap<>();
|
||||
|
||||
public KeyValueMap getMap(FieldNode field) {
|
||||
return fieldsMap.get(field);
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.Set;
|
||||
|
||||
public class IgnoreEdgeAttr implements IAttribute {
|
||||
|
||||
private final Set<BlockNode> blocks = new HashSet<BlockNode>(3);
|
||||
private final Set<BlockNode> blocks = new HashSet<>(3);
|
||||
|
||||
public Set<BlockNode> getBlocks() {
|
||||
return blocks;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class LoopInfo {
|
||||
* Exit nodes belongs to loop (contains in {@code loopBlocks})
|
||||
*/
|
||||
public Set<BlockNode> getExitNodes() {
|
||||
Set<BlockNode> nodes = new HashSet<BlockNode>();
|
||||
Set<BlockNode> nodes = new HashSet<>();
|
||||
Set<BlockNode> blocks = getLoopBlocks();
|
||||
for (BlockNode block : blocks) {
|
||||
// exit: successor node not from this loop, (don't change to getCleanSuccessors)
|
||||
@@ -60,7 +60,7 @@ public class LoopInfo {
|
||||
* Return loop exit edges.
|
||||
*/
|
||||
public List<Edge> getExitEdges() {
|
||||
List<Edge> edges = new LinkedList<Edge>();
|
||||
List<Edge> edges = new LinkedList<>();
|
||||
Set<BlockNode> blocks = getLoopBlocks();
|
||||
for (BlockNode block : blocks) {
|
||||
for (BlockNode s : block.getSuccessors()) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
public class PhiListAttr implements IAttribute {
|
||||
|
||||
private final List<PhiInsn> list = new LinkedList<PhiInsn>();
|
||||
private final List<PhiInsn> list = new LinkedList<>();
|
||||
|
||||
@Override
|
||||
public AType<PhiListAttr> getType() {
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class ClassInfo {
|
||||
int sep = clsName.lastIndexOf('$');
|
||||
if (canBeInner && sep > 0 && sep != clsName.length() - 1) {
|
||||
String parClsName = pkg + "." + clsName.substring(0, sep);
|
||||
if(pkg.length() == 0) {
|
||||
if (pkg.isEmpty()) {
|
||||
parClsName = clsName.substring(0, sep);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ConstStorage {
|
||||
|
||||
private static final class Values {
|
||||
private final Map<Object, FieldNode> values = new HashMap<Object, FieldNode>();
|
||||
private final Set<Object> duplicates = new HashSet<Object>();
|
||||
private static final class ValueStorage {
|
||||
private final Map<Object, FieldNode> values = new HashMap<>();
|
||||
private final Set<Object> duplicates = new HashSet<>();
|
||||
|
||||
public Map<Object, FieldNode> getValues() {
|
||||
return values;
|
||||
@@ -55,10 +55,10 @@ public class ConstStorage {
|
||||
}
|
||||
|
||||
private final boolean replaceEnabled;
|
||||
private final Values globalValues = new Values();
|
||||
private final Map<ClassNode, Values> classes = new HashMap<ClassNode, Values>();
|
||||
private final ValueStorage globalValues = new ValueStorage();
|
||||
private final Map<ClassNode, ValueStorage> classes = new HashMap<>();
|
||||
|
||||
private Map<Integer, String> resourcesNames = new HashMap<Integer, String>();
|
||||
private Map<Integer, String> resourcesNames = new HashMap<>();
|
||||
|
||||
public ConstStorage(IJadxArgs args) {
|
||||
this.replaceEnabled = args.isReplaceConsts();
|
||||
@@ -90,10 +90,10 @@ public class ConstStorage {
|
||||
}
|
||||
}
|
||||
|
||||
private Values getClsValues(ClassNode cls) {
|
||||
Values classValues = classes.get(cls);
|
||||
private ValueStorage getClsValues(ClassNode cls) {
|
||||
ValueStorage classValues = classes.get(cls);
|
||||
if (classValues == null) {
|
||||
classValues = new Values();
|
||||
classValues = new ValueStorage();
|
||||
classes.put(cls, classValues);
|
||||
}
|
||||
return classValues;
|
||||
@@ -117,7 +117,7 @@ public class ConstStorage {
|
||||
}
|
||||
ClassNode current = cls;
|
||||
while (current != null) {
|
||||
Values classValues = classes.get(current);
|
||||
ValueStorage classValues = classes.get(current);
|
||||
if (classValues != null) {
|
||||
FieldNode field = classValues.get(value);
|
||||
if (field != null) {
|
||||
@@ -161,12 +161,14 @@ public class ConstStorage {
|
||||
return getConstField(cls, literal, Math.abs(literal) > 1000);
|
||||
case FLOAT:
|
||||
float f = Float.intBitsToFloat((int) literal);
|
||||
return getConstField(cls, f, f != 0.0);
|
||||
return getConstField(cls, f, Float.compare(f, 0) == 0);
|
||||
case DOUBLE:
|
||||
double d = Double.longBitsToDouble(literal);
|
||||
return getConstField(cls, d, d != 0);
|
||||
return getConstField(cls, d, Double.compare(d, 0) == 0);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setResourcesNames(Map<Integer, String> resourcesNames) {
|
||||
|
||||
@@ -8,9 +8,9 @@ import java.util.Map;
|
||||
|
||||
public class InfoStorage {
|
||||
|
||||
private final Map<ArgType, ClassInfo> classes = new HashMap<ArgType, ClassInfo>();
|
||||
private final Map<Integer, MethodInfo> methods = new HashMap<Integer, MethodInfo>();
|
||||
private final Map<FieldInfo, FieldInfo> fields = new HashMap<FieldInfo, FieldInfo>();
|
||||
private final Map<ArgType, ClassInfo> classes = new HashMap<>();
|
||||
private final Map<Integer, MethodInfo> methods = new HashMap<>();
|
||||
private final Map<FieldInfo, FieldInfo> fields = new HashMap<>();
|
||||
|
||||
public ClassInfo getCls(ArgType type) {
|
||||
return classes.get(type);
|
||||
@@ -24,16 +24,16 @@ public class InfoStorage {
|
||||
}
|
||||
|
||||
private int generateMethodLookupId(DexNode dex, int mthId) {
|
||||
return (dex.getDexId()<<16)|mthId;
|
||||
return dex.getDexId() << 16 | mthId;
|
||||
}
|
||||
|
||||
public MethodInfo getMethod(DexNode dex, int mtdId) {
|
||||
return methods.get(generateMethodLookupId(dex,mtdId));
|
||||
return methods.get(generateMethodLookupId(dex, mtdId));
|
||||
}
|
||||
|
||||
public MethodInfo putMethod(DexNode dex, int mthId, MethodInfo mth) {
|
||||
synchronized (methods) {
|
||||
MethodInfo prev = methods.put(generateMethodLookupId(dex,mthId), mth);
|
||||
MethodInfo prev = methods.put(generateMethodLookupId(dex, mthId), mth);
|
||||
return prev == null ? mth : prev;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class FillArrayNode extends InsnNode {
|
||||
}
|
||||
|
||||
public List<LiteralArg> getLiteralArgs() {
|
||||
List<LiteralArg> list = new ArrayList<LiteralArg>(size);
|
||||
List<LiteralArg> list = new ArrayList<>(size);
|
||||
Object array = data;
|
||||
if (array instanceof int[]) {
|
||||
for (int b : (int[]) array) {
|
||||
|
||||
@@ -21,7 +21,7 @@ public final class PhiInsn extends InsnNode {
|
||||
|
||||
public PhiInsn(int regNum, int predecessors) {
|
||||
super(InsnType.PHI, predecessors);
|
||||
this.blockBinds = new IdentityHashMap<RegisterArg, BlockNode>(predecessors);
|
||||
this.blockBinds = new IdentityHashMap<>(predecessors);
|
||||
setResult(InsnArg.reg(regNum, ArgType.UNKNOWN));
|
||||
add(AFlag.DONT_INLINE);
|
||||
}
|
||||
|
||||
@@ -140,16 +140,16 @@ public abstract class ArgType {
|
||||
}
|
||||
|
||||
private static class ObjectType extends KnownType {
|
||||
private final String object;
|
||||
private final String objName;
|
||||
|
||||
public ObjectType(String obj) {
|
||||
this.object = Utils.cleanObjectName(obj);
|
||||
this.hash = object.hashCode();
|
||||
this.objName = Utils.cleanObjectName(obj);
|
||||
this.hash = objName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObject() {
|
||||
return object;
|
||||
return objName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,12 +164,12 @@ public abstract class ArgType {
|
||||
|
||||
@Override
|
||||
boolean internalEquals(Object obj) {
|
||||
return object.equals(((ObjectType) obj).object);
|
||||
return objName.equals(((ObjectType) obj).objName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return object;
|
||||
return objName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ public abstract class ArgType {
|
||||
}
|
||||
|
||||
private static final class ArrayArg extends KnownType {
|
||||
public static final PrimitiveType[] ARRAY_POSSIBLES = new PrimitiveType[]{PrimitiveType.ARRAY};
|
||||
private static final PrimitiveType[] ARRAY_POSSIBLES = new PrimitiveType[]{PrimitiveType.ARRAY};
|
||||
private final ArgType arrayElement;
|
||||
|
||||
public ArrayArg(ArgType arrayElement) {
|
||||
@@ -495,7 +495,7 @@ public abstract class ArgType {
|
||||
return null;
|
||||
} else {
|
||||
// both types unknown
|
||||
List<PrimitiveType> types = new ArrayList<PrimitiveType>();
|
||||
List<PrimitiveType> types = new ArrayList<>();
|
||||
for (PrimitiveType type : a.getPossibleTypes()) {
|
||||
if (b.contains(type)) {
|
||||
types.add(type);
|
||||
@@ -622,8 +622,10 @@ public abstract class ArgType {
|
||||
return DOUBLE;
|
||||
case 'V':
|
||||
return VOID;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRegCount() {
|
||||
|
||||
@@ -57,10 +57,7 @@ public final class FieldArg extends RegisterArg {
|
||||
if (!field.equals(fieldArg.field)) {
|
||||
return false;
|
||||
}
|
||||
if (instArg != null ? !instArg.equals(fieldArg.instArg) : fieldArg.instArg != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return instArg != null ? instArg.equals(fieldArg.instArg) : fieldArg.instArg == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -101,7 +101,7 @@ public abstract class InsnArg extends Typed {
|
||||
}
|
||||
|
||||
public static void updateParentInsn(InsnNode fromInsn, InsnNode toInsn) {
|
||||
List<RegisterArg> args = new ArrayList<RegisterArg>();
|
||||
List<RegisterArg> args = new ArrayList<>();
|
||||
fromInsn.getRegisterArgs(args);
|
||||
for (RegisterArg reg : args) {
|
||||
reg.setParentInsn(toInsn);
|
||||
|
||||
@@ -6,12 +6,11 @@ import jadx.core.dex.nodes.DexNode;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.utils.InsnUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RegisterArg extends InsnArg implements Named {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RegisterArg.class);
|
||||
|
||||
protected final int regNum;
|
||||
// not null after SSATransform pass
|
||||
@@ -151,23 +150,13 @@ public class RegisterArg extends InsnArg implements Named {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof RegisterArg)) {
|
||||
return false;
|
||||
}
|
||||
RegisterArg other = (RegisterArg) obj;
|
||||
if (regNum != other.regNum) {
|
||||
return false;
|
||||
}
|
||||
if (!type.equals(other.type)) {
|
||||
return false;
|
||||
}
|
||||
if (sVar != null && !sVar.equals(other.getSVar())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return regNum == other.regNum
|
||||
&& type.equals(other.type)
|
||||
&& Objects.equals(sVar, other.getSVar());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@ public class SSAVar extends AttrNode {
|
||||
|
||||
@NotNull
|
||||
private RegisterArg assign;
|
||||
private final List<RegisterArg> useList = new ArrayList<RegisterArg>(2);
|
||||
private final List<RegisterArg> useList = new ArrayList<>(2);
|
||||
@Nullable
|
||||
private PhiInsn usedInPhi;
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ public class BlockNode extends AttrNode implements IBlock {
|
||||
|
||||
private int id;
|
||||
private final int startOffset;
|
||||
private final List<InsnNode> instructions = new ArrayList<InsnNode>(2);
|
||||
private final List<InsnNode> instructions = new ArrayList<>(2);
|
||||
|
||||
private List<BlockNode> predecessors = new ArrayList<BlockNode>(1);
|
||||
private List<BlockNode> successors = new ArrayList<BlockNode>(1);
|
||||
private List<BlockNode> predecessors = new ArrayList<>(1);
|
||||
private List<BlockNode> successors = new ArrayList<>(1);
|
||||
private List<BlockNode> cleanSuccessors;
|
||||
|
||||
// all dominators
|
||||
@@ -85,7 +85,7 @@ public class BlockNode extends AttrNode implements IBlock {
|
||||
if (sucList.isEmpty()) {
|
||||
return sucList;
|
||||
}
|
||||
List<BlockNode> toRemove = new LinkedList<BlockNode>();
|
||||
List<BlockNode> toRemove = new LinkedList<>();
|
||||
for (BlockNode b : sucList) {
|
||||
if (BlockUtils.isBlockMustBeCleared(b)) {
|
||||
toRemove.add(b);
|
||||
@@ -104,7 +104,7 @@ public class BlockNode extends AttrNode implements IBlock {
|
||||
if (toRemove.isEmpty()) {
|
||||
return sucList;
|
||||
}
|
||||
List<BlockNode> result = new ArrayList<BlockNode>(sucList);
|
||||
List<BlockNode> result = new ArrayList<>(sucList);
|
||||
result.removeAll(toRemove);
|
||||
return result;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class BlockNode extends AttrNode implements IBlock {
|
||||
|
||||
public void addDominatesOn(BlockNode block) {
|
||||
if (dominatesOn.isEmpty()) {
|
||||
dominatesOn = new LinkedList<BlockNode>();
|
||||
dominatesOn = new LinkedList<>();
|
||||
}
|
||||
dominatesOn.add(block);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
private ClassNode parentClass;
|
||||
|
||||
private ProcessState state = ProcessState.NOT_LOADED;
|
||||
private final Set<ClassNode> dependencies = new HashSet<ClassNode>();
|
||||
private final Set<ClassNode> dependencies = new HashSet<>();
|
||||
|
||||
// cache maps
|
||||
private Map<MethodInfo, MethodNode> mthInfoMap = Collections.emptyMap();
|
||||
@@ -74,7 +74,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
} else {
|
||||
this.superClass = dex.getType(cls.getSupertypeIndex());
|
||||
}
|
||||
this.interfaces = new ArrayList<ArgType>(cls.getInterfaces().length);
|
||||
this.interfaces = new ArrayList<>(cls.getInterfaces().length);
|
||||
for (short interfaceIdx : cls.getInterfaces()) {
|
||||
this.interfaces.add(dex.getType(interfaceIdx));
|
||||
}
|
||||
@@ -83,8 +83,8 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
int mthsCount = clsData.getDirectMethods().length + clsData.getVirtualMethods().length;
|
||||
int fieldsCount = clsData.getStaticFields().length + clsData.getInstanceFields().length;
|
||||
|
||||
methods = new ArrayList<MethodNode>(mthsCount);
|
||||
fields = new ArrayList<FieldNode>(fieldsCount);
|
||||
methods = new ArrayList<>(mthsCount);
|
||||
fields = new ArrayList<>(fieldsCount);
|
||||
|
||||
for (Method mth : clsData.getDirectMethods()) {
|
||||
methods.add(new MethodNode(this, mth, false));
|
||||
@@ -268,7 +268,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
}
|
||||
|
||||
private void buildCache() {
|
||||
mthInfoMap = new HashMap<MethodInfo, MethodNode>(methods.size());
|
||||
mthInfoMap = new HashMap<>(methods.size());
|
||||
for (MethodNode mth : methods) {
|
||||
mthInfoMap.put(mth.getMethodInfo(), mth);
|
||||
}
|
||||
@@ -373,7 +373,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
|
||||
public void addInnerClass(ClassNode cls) {
|
||||
if (innerClasses.isEmpty()) {
|
||||
innerClasses = new ArrayList<ClassNode>(3);
|
||||
innerClasses = new ArrayList<>(3);
|
||||
}
|
||||
innerClasses.add(cls);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package jadx.core.dex.nodes;
|
||||
|
||||
import jadx.core.dex.info.ClassInfo;
|
||||
import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.info.InfoStorage;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
@@ -37,8 +36,8 @@ public class DexNode implements IDexNode {
|
||||
private final DexFile file;
|
||||
private final int dexId;
|
||||
|
||||
private final List<ClassNode> classes = new ArrayList<ClassNode>();
|
||||
private final Map<ClassInfo, ClassNode> clsMap = new HashMap<ClassInfo, ClassNode>();
|
||||
private final List<ClassNode> classes = new ArrayList<>();
|
||||
private final Map<ClassInfo, ClassNode> clsMap = new HashMap<>();
|
||||
|
||||
public DexNode(RootNode root, DexFile input, int dexId) {
|
||||
this.root = root;
|
||||
@@ -57,7 +56,7 @@ public class DexNode implements IDexNode {
|
||||
|
||||
void initInnerClasses() {
|
||||
// move inner classes
|
||||
List<ClassNode> inner = new ArrayList<ClassNode>();
|
||||
List<ClassNode> inner = new ArrayList<>();
|
||||
for (ClassNode cls : classes) {
|
||||
if (cls.getClassInfo().isInner()) {
|
||||
inner.add(cls);
|
||||
@@ -185,7 +184,7 @@ public class DexNode implements IDexNode {
|
||||
|
||||
public List<ArgType> readParamList(int parametersOffset) {
|
||||
TypeList paramList = dexBuf.readTypeList(parametersOffset);
|
||||
List<ArgType> args = new ArrayList<ArgType>(paramList.getTypes().length);
|
||||
List<ArgType> args = new ArrayList<>(paramList.getTypes().length);
|
||||
for (short t : paramList.getTypes()) {
|
||||
args.add(getType(t));
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ public interface ILoadable {
|
||||
|
||||
/**
|
||||
* On demand loading
|
||||
*
|
||||
* @throws DecodeException
|
||||
*/
|
||||
void load() throws DecodeException;
|
||||
|
||||
@@ -15,5 +13,4 @@ public interface ILoadable {
|
||||
* Free resources
|
||||
*/
|
||||
void unload();
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class InsnNode extends LineAttrNode {
|
||||
if (argsCount == 0) {
|
||||
this.arguments = Collections.emptyList();
|
||||
} else {
|
||||
this.arguments = new ArrayList<InsnArg>(argsCount);
|
||||
this.arguments = new ArrayList<>(argsCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
}
|
||||
|
||||
public void checkInstructions() {
|
||||
List<RegisterArg> list = new ArrayList<RegisterArg>();
|
||||
List<RegisterArg> list = new ArrayList<>();
|
||||
for (InsnNode insnNode : instructions) {
|
||||
if (insnNode == null) {
|
||||
continue;
|
||||
@@ -216,7 +216,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
argsList = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
argsList = new ArrayList<RegisterArg>(args.size());
|
||||
argsList = new ArrayList<>(args.size());
|
||||
for (ArgType arg : args) {
|
||||
argsList.add(InsnArg.typeImmutableReg(pos, arg));
|
||||
pos += arg.getRegCount();
|
||||
@@ -225,7 +225,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
|
||||
public List<RegisterArg> getArguments(boolean includeThis) {
|
||||
if (includeThis && thisArg != null) {
|
||||
List<RegisterArg> list = new ArrayList<RegisterArg>(argsList.size() + 1);
|
||||
List<RegisterArg> list = new ArrayList<>(argsList.size() + 1);
|
||||
list.add(thisArg);
|
||||
list.addAll(argsList);
|
||||
return list;
|
||||
@@ -259,8 +259,8 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
}
|
||||
|
||||
int hc = 0;
|
||||
Set<Integer> addrs = new HashSet<Integer>();
|
||||
List<TryCatchBlock> catches = new ArrayList<TryCatchBlock>(catchBlocks.length);
|
||||
Set<Integer> addrs = new HashSet<>();
|
||||
List<TryCatchBlock> catches = new ArrayList<>(catchBlocks.length);
|
||||
|
||||
for (CatchHandler handler : catchBlocks) {
|
||||
TryCatchBlock tcBlock = new TryCatchBlock();
|
||||
@@ -399,8 +399,8 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
}
|
||||
|
||||
public void initBasicBlocks() {
|
||||
blocks = new ArrayList<BlockNode>();
|
||||
exitBlocks = new ArrayList<BlockNode>(1);
|
||||
blocks = new ArrayList<>();
|
||||
exitBlocks = new ArrayList<>(1);
|
||||
}
|
||||
|
||||
public void finishBasicBlocks() {
|
||||
@@ -437,7 +437,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
|
||||
public void registerLoop(LoopInfo loop) {
|
||||
if (loops.isEmpty()) {
|
||||
loops = new ArrayList<LoopInfo>(5);
|
||||
loops = new ArrayList<>(5);
|
||||
}
|
||||
loop.setId(loops.size());
|
||||
loops.add(loop);
|
||||
@@ -460,7 +460,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
if (loops.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<LoopInfo> list = new ArrayList<LoopInfo>(loops.size());
|
||||
List<LoopInfo> list = new ArrayList<>(loops.size());
|
||||
for (LoopInfo loop : loops) {
|
||||
if (loop.getLoopBlocks().contains(block)) {
|
||||
list.add(loop);
|
||||
@@ -479,7 +479,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
|
||||
public ExceptionHandler addExceptionHandler(ExceptionHandler handler) {
|
||||
if (exceptionHandlers.isEmpty()) {
|
||||
exceptionHandlers = new ArrayList<ExceptionHandler>(2);
|
||||
exceptionHandlers = new ArrayList<>(2);
|
||||
} else {
|
||||
for (ExceptionHandler h : exceptionHandlers) {
|
||||
if (h == handler || h.getHandleOffset() == handler.getHandleOffset()) {
|
||||
@@ -528,7 +528,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
boolean result = false;
|
||||
if (accFlags.isConstructor() && mthInfo.isConstructor()) {
|
||||
int defaultArgCount = 0;
|
||||
/** workaround for non-static inner class constructor, that has synthetic argument */
|
||||
// workaround for non-static inner class constructor, that has synthetic argument
|
||||
if (parentClass.getClassInfo().isInner()
|
||||
&& !parentClass.getAccessFlags().isStatic()) {
|
||||
ClassNode outerCls = parentClass.getParentClass();
|
||||
@@ -557,7 +557,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
|
||||
public SSAVar makeNewSVar(int regNum, int version, @NotNull RegisterArg assignArg) {
|
||||
SSAVar var = new SSAVar(regNum, version, assignArg);
|
||||
if (sVars.isEmpty()) {
|
||||
sVars = new ArrayList<SSAVar>();
|
||||
sVars = new ArrayList<>();
|
||||
}
|
||||
sVars.add(var);
|
||||
return var;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class RootNode {
|
||||
}
|
||||
|
||||
public void load(List<InputFile> inputFiles) throws DecodeException {
|
||||
dexNodes = new ArrayList<DexNode>();
|
||||
dexNodes = new ArrayList<>();
|
||||
for (InputFile input : inputFiles) {
|
||||
for (DexFile dexFile : input.getDexFiles()) {
|
||||
try {
|
||||
@@ -80,7 +80,7 @@ public class RootNode {
|
||||
LOG.debug("'.arsc' file not found");
|
||||
return;
|
||||
}
|
||||
final ResTableParser parser = new ResTableParser();
|
||||
ResTableParser parser = new ResTableParser();
|
||||
try {
|
||||
ResourcesLoader.decodeStream(arsc, new ResourcesLoader.ResourceDecoder() {
|
||||
@Override
|
||||
@@ -109,7 +109,7 @@ public class RootNode {
|
||||
ClspGraph clsp = new ClspGraph();
|
||||
clsp.load();
|
||||
|
||||
List<ClassNode> classes = new ArrayList<ClassNode>();
|
||||
List<ClassNode> classes = new ArrayList<>();
|
||||
for (DexNode dexNode : dexNodes) {
|
||||
classes.addAll(dexNode.getClasses());
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class RootNode {
|
||||
}
|
||||
|
||||
public List<ClassNode> getClasses(boolean includeInner) {
|
||||
List<ClassNode> classes = new ArrayList<ClassNode>();
|
||||
List<ClassNode> classes = new ArrayList<>();
|
||||
for (DexNode dex : dexNodes) {
|
||||
if (includeInner) {
|
||||
classes.addAll(dex.getClasses());
|
||||
@@ -156,7 +156,7 @@ public class RootNode {
|
||||
}
|
||||
|
||||
public List<ClassNode> searchClassByShortName(String shortName) {
|
||||
List<ClassNode> list = new ArrayList<ClassNode>();
|
||||
List<ClassNode> list = new ArrayList<>();
|
||||
for (DexNode dexNode : dexNodes) {
|
||||
for (ClassNode cls : dexNode.getClasses()) {
|
||||
if (cls.getClassInfo().getShortName().equals(shortName)) {
|
||||
|
||||
@@ -79,7 +79,7 @@ public class AnnotationsParser {
|
||||
if (size == 0) {
|
||||
return AnnotationsList.EMPTY;
|
||||
}
|
||||
List<Annotation> list = new ArrayList<Annotation>(size);
|
||||
List<Annotation> list = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Section anSection = dex.openSection(section.readInt());
|
||||
Annotation a = readAnnotation(dex, anSection, true);
|
||||
@@ -97,7 +97,7 @@ public class AnnotationsParser {
|
||||
}
|
||||
int typeIndex = s.readUleb128();
|
||||
int size = s.readUleb128();
|
||||
Map<String, Object> values = new LinkedHashMap<String, Object>(size);
|
||||
Map<String, Object> values = new LinkedHashMap<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
String name = dex.getString(s.readUleb128());
|
||||
values.put(name, parser.parseValue());
|
||||
|
||||
@@ -83,7 +83,7 @@ public class EncValueParser {
|
||||
|
||||
case ENCODED_ARRAY:
|
||||
int count = Leb128.readUnsignedLeb128(in);
|
||||
List<Object> values = new ArrayList<Object>(count);
|
||||
List<Object> values = new ArrayList<>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
values.add(parseValue());
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class SignatureParser {
|
||||
}
|
||||
|
||||
private ArgType[] consumeGenericArgs() {
|
||||
List<ArgType> list = new LinkedList<ArgType>();
|
||||
List<ArgType> list = new LinkedList<>();
|
||||
ArgType type;
|
||||
do {
|
||||
if (lookAhead('*')) {
|
||||
@@ -220,7 +220,7 @@ public class SignatureParser {
|
||||
if (!lookAhead('<')) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<ArgType, List<ArgType>> map = new LinkedHashMap<ArgType, List<ArgType>>(2);
|
||||
Map<ArgType, List<ArgType>> map = new LinkedHashMap<>(2);
|
||||
consume('<');
|
||||
while (true) {
|
||||
if (lookAhead('>') || next() == STOP_CHAR) {
|
||||
@@ -251,7 +251,7 @@ public class SignatureParser {
|
||||
ArgType argType = consumeType();
|
||||
if (!argType.equals(ArgType.OBJECT)) {
|
||||
if (types.isEmpty()) {
|
||||
types = new LinkedList<ArgType>();
|
||||
types = new LinkedList<>();
|
||||
}
|
||||
types.add(argType);
|
||||
}
|
||||
@@ -269,7 +269,7 @@ public class SignatureParser {
|
||||
consume(')');
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<ArgType> args = new LinkedList<ArgType>();
|
||||
List<ArgType> args = new LinkedList<>();
|
||||
do {
|
||||
args.add(consumeType());
|
||||
} while (!lookAhead(')'));
|
||||
|
||||
@@ -12,7 +12,7 @@ public final class Region extends AbstractRegion {
|
||||
|
||||
public Region(IRegion parent) {
|
||||
super(parent);
|
||||
this.blocks = new ArrayList<IContainer>(1);
|
||||
this.blocks = new ArrayList<>(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,8 +20,8 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
|
||||
public SwitchRegion(IRegion parent, BlockNode header) {
|
||||
super(parent);
|
||||
this.header = header;
|
||||
this.keys = new ArrayList<List<Object>>();
|
||||
this.cases = new ArrayList<IContainer>();
|
||||
this.keys = new ArrayList<>();
|
||||
this.cases = new ArrayList<>();
|
||||
}
|
||||
|
||||
public BlockNode getHeader() {
|
||||
@@ -51,7 +51,7 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
|
||||
|
||||
@Override
|
||||
public List<IContainer> getSubBlocks() {
|
||||
List<IContainer> all = new ArrayList<IContainer>(cases.size() + 2);
|
||||
List<IContainer> all = new ArrayList<>(cases.size() + 2);
|
||||
all.add(header);
|
||||
all.addAll(cases);
|
||||
if (defCase != null) {
|
||||
@@ -62,7 +62,7 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
|
||||
|
||||
@Override
|
||||
public List<IContainer> getBranches() {
|
||||
List<IContainer> branches = new ArrayList<IContainer>(cases.size() + 1);
|
||||
List<IContainer> branches = new ArrayList<>(cases.size() + 1);
|
||||
branches.addAll(cases);
|
||||
branches.add(defCase);
|
||||
return Collections.unmodifiableList(branches);
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.List;
|
||||
public final class SynchronizedRegion extends AbstractRegion {
|
||||
|
||||
private final InsnNode enterInsn;
|
||||
private final List<InsnNode> exitInsns = new LinkedList<InsnNode>();
|
||||
private final List<InsnNode> exitInsns = new LinkedList<>();
|
||||
private final Region region;
|
||||
|
||||
public SynchronizedRegion(IRegion parent, InsnNode insn) {
|
||||
|
||||
@@ -28,7 +28,7 @@ public final class TryCatchRegion extends AbstractRegion implements IBranchRegio
|
||||
public void setTryCatchBlock(TryCatchBlock tryCatchBlock) {
|
||||
this.tryCatchBlock = tryCatchBlock;
|
||||
int count = tryCatchBlock.getHandlersCount();
|
||||
this.catchRegions = new LinkedHashMap<ExceptionHandler, IContainer>(count);
|
||||
this.catchRegions = new LinkedHashMap<>(count);
|
||||
for (ExceptionHandler handler : tryCatchBlock.getHandlers()) {
|
||||
IContainer handlerRegion = handler.getHandlerRegion();
|
||||
if (handlerRegion != null) {
|
||||
@@ -63,7 +63,7 @@ public final class TryCatchRegion extends AbstractRegion implements IBranchRegio
|
||||
|
||||
@Override
|
||||
public List<IContainer> getSubBlocks() {
|
||||
List<IContainer> all = new ArrayList<IContainer>(2 + catchRegions.size());
|
||||
List<IContainer> all = new ArrayList<>(2 + catchRegions.size());
|
||||
all.add(tryRegion);
|
||||
all.addAll(catchRegions.values());
|
||||
if (finallyRegion != null) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class IfCondition {
|
||||
if (c.mode == Mode.COMPARE) {
|
||||
this.args = Collections.emptyList();
|
||||
} else {
|
||||
this.args = new ArrayList<IfCondition>(c.args);
|
||||
this.args = new ArrayList<>(c.args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public final class IfCondition {
|
||||
case AND:
|
||||
case OR:
|
||||
List<IfCondition> args = cond.getArgs();
|
||||
List<IfCondition> newArgs = new ArrayList<IfCondition>(args.size());
|
||||
List<IfCondition> newArgs = new ArrayList<>(args.size());
|
||||
for (IfCondition arg : args) {
|
||||
newArgs.add(invert(arg));
|
||||
}
|
||||
@@ -154,7 +154,7 @@ public final class IfCondition {
|
||||
IfCondition simpl = simplify(arg);
|
||||
if (simpl != arg) {
|
||||
if (args == null) {
|
||||
args = new ArrayList<IfCondition>(cond.getArgs());
|
||||
args = new ArrayList<>(cond.getArgs());
|
||||
}
|
||||
args.set(i, simpl);
|
||||
}
|
||||
@@ -206,7 +206,7 @@ public final class IfCondition {
|
||||
}
|
||||
|
||||
public List<RegisterArg> getRegisterArgs() {
|
||||
List<RegisterArg> list = new LinkedList<RegisterArg>();
|
||||
List<RegisterArg> list = new LinkedList<>();
|
||||
if (mode == Mode.COMPARE) {
|
||||
compare.getInsn().getRegisterArgs(list);
|
||||
} else {
|
||||
|
||||
@@ -82,7 +82,7 @@ public final class IfRegion extends AbstractRegion implements IBranchRegion {
|
||||
|
||||
@Override
|
||||
public List<IContainer> getSubBlocks() {
|
||||
List<IContainer> all = new ArrayList<IContainer>(3);
|
||||
List<IContainer> all = new ArrayList<>(3);
|
||||
all.add(header);
|
||||
if (thenRegion != null) {
|
||||
all.add(thenRegion);
|
||||
@@ -95,7 +95,7 @@ public final class IfRegion extends AbstractRegion implements IBranchRegion {
|
||||
|
||||
@Override
|
||||
public List<IContainer> getBranches() {
|
||||
List<IContainer> branches = new ArrayList<IContainer>(2);
|
||||
List<IContainer> branches = new ArrayList<>(2);
|
||||
branches.add(thenRegion);
|
||||
branches.add(elseRegion);
|
||||
return Collections.unmodifiableList(branches);
|
||||
|
||||
@@ -136,7 +136,7 @@ public final class LoopRegion extends AbstractRegion {
|
||||
|
||||
@Override
|
||||
public List<IContainer> getSubBlocks() {
|
||||
List<IContainer> all = new ArrayList<IContainer>(3);
|
||||
List<IContainer> all = new ArrayList<>(3);
|
||||
if (preCondition != null) {
|
||||
all.add(preCondition);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public class ExceptionHandler {
|
||||
private final int handleOffset;
|
||||
|
||||
private BlockNode handlerBlock;
|
||||
private final List<BlockNode> blocks = new ArrayList<BlockNode>();
|
||||
private final List<BlockNode> blocks = new ArrayList<>();
|
||||
private IContainer handlerRegion;
|
||||
private InsnArg arg;
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ public class TryCatchBlock {
|
||||
private final CatchAttr attr;
|
||||
|
||||
public TryCatchBlock() {
|
||||
handlers = new LinkedList<ExceptionHandler>();
|
||||
insns = new ArrayList<InsnNode>();
|
||||
handlers = new LinkedList<>();
|
||||
insns = new ArrayList<>();
|
||||
attr = new CatchAttr(this);
|
||||
}
|
||||
|
||||
@@ -68,10 +68,9 @@ public class TryCatchBlock {
|
||||
BlockUtils.skipPredSyntheticPaths(block);
|
||||
block.add(AFlag.SKIP);
|
||||
ExcHandlerAttr excHandlerAttr = block.get(AType.EXC_HANDLER);
|
||||
if (excHandlerAttr != null) {
|
||||
if (excHandlerAttr.getHandler().equals(handler)) {
|
||||
block.remove(AType.EXC_HANDLER);
|
||||
}
|
||||
if (excHandlerAttr != null
|
||||
&& excHandlerAttr.getHandler().equals(handler)) {
|
||||
block.remove(AType.EXC_HANDLER);
|
||||
}
|
||||
SplitterBlockAttr splitter = handler.getHandlerBlock().get(AType.SPLITTER_BLOCK);
|
||||
if (splitter != null) {
|
||||
|
||||
@@ -9,15 +9,17 @@ public class AbstractVisitor implements IDexTreeVisitor {
|
||||
|
||||
@Override
|
||||
public void init(RootNode root) throws JadxException {
|
||||
// no op implementation
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(ClassNode cls) throws JadxException {
|
||||
// no op implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(MethodNode mth) throws JadxException {
|
||||
// no op implementation
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class CodeShrinker extends AbstractVisitor {
|
||||
}
|
||||
|
||||
public static List<RegisterArg> getArgs(InsnNode insn) {
|
||||
List<RegisterArg> args = new LinkedList<RegisterArg>();
|
||||
List<RegisterArg> args = new LinkedList<>();
|
||||
addArgs(insn, args);
|
||||
return args;
|
||||
}
|
||||
@@ -191,11 +191,11 @@ public class CodeShrinker extends AbstractVisitor {
|
||||
}
|
||||
InsnList insnList = new InsnList(block.getInstructions());
|
||||
int insnCount = insnList.size();
|
||||
List<ArgsInfo> argsList = new ArrayList<ArgsInfo>(insnCount);
|
||||
List<ArgsInfo> argsList = new ArrayList<>(insnCount);
|
||||
for (int i = 0; i < insnCount; i++) {
|
||||
argsList.add(new ArgsInfo(insnList.get(i), argsList, i));
|
||||
}
|
||||
List<WrapInfo> wrapList = new ArrayList<WrapInfo>();
|
||||
List<WrapInfo> wrapList = new ArrayList<>();
|
||||
for (ArgsInfo argsInfo : argsList) {
|
||||
List<RegisterArg> args = argsInfo.getArgs();
|
||||
if (args.isEmpty()) {
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
if (mth.isNoCode()) {
|
||||
return;
|
||||
}
|
||||
List<InsnNode> toRemove = new ArrayList<InsnNode>();
|
||||
List<InsnNode> toRemove = new ArrayList<>();
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
toRemove.clear();
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
@@ -99,7 +99,7 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
|
||||
private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
|
||||
SSAVar sVar = constInsn.getResult().getSVar();
|
||||
List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
|
||||
List<RegisterArg> use = new ArrayList<>(sVar.getUseList());
|
||||
int replaceCount = 0;
|
||||
for (RegisterArg arg : use) {
|
||||
InsnNode useInsn = arg.getParentInsn();
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package jadx.core.dex.visitors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
@@ -14,6 +11,9 @@ import jadx.core.utils.ErrorsCounter;
|
||||
import jadx.core.utils.exceptions.DecodeException;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DebugInfoVisitor extends AbstractVisitor {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DebugInfoVisitor.class);
|
||||
@@ -26,7 +26,7 @@ public class DebugInfoVisitor extends AbstractVisitor {
|
||||
processDebugInfo(mth, debugOffset);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error in debug info parser: " + ErrorsCounter.formatErrorMsg(mth, e.getMessage()), e);
|
||||
LOG.error("Error in debug info parser: {}", ErrorsCounter.formatErrorMsg(mth, e.getMessage()), e);
|
||||
} finally {
|
||||
mth.unloadInsnArr();
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
+ "(" + Utils.listToString(mth.getArguments(true)) + ") "));
|
||||
|
||||
String attrs = attributesString(mth);
|
||||
if (attrs.length() != 0) {
|
||||
if (!attrs.isEmpty()) {
|
||||
dot.add(" | ").add(attrs);
|
||||
}
|
||||
dot.add("}\"];");
|
||||
@@ -122,7 +122,7 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
processRegion(mth, h.getHandlerRegion());
|
||||
}
|
||||
}
|
||||
Set<IBlock> regionsBlocks = new HashSet<IBlock>(mth.getBasicBlocks().size());
|
||||
Set<IBlock> regionsBlocks = new HashSet<>(mth.getBasicBlocks().size());
|
||||
RegionUtils.getAllRegionBlocks(mth.getRegion(), regionsBlocks);
|
||||
for (ExceptionHandler handler : mth.getExceptionHandlers()) {
|
||||
IContainer handlerRegion = handler.getHandlerRegion();
|
||||
@@ -143,7 +143,7 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
dot.startLine("subgraph " + makeName(region) + " {");
|
||||
dot.startLine("label = \"").add(r.toString());
|
||||
String attrs = attributesString(r);
|
||||
if (attrs.length() != 0) {
|
||||
if (!attrs.isEmpty()) {
|
||||
dot.add(" | ").add(attrs);
|
||||
}
|
||||
dot.add("\";");
|
||||
@@ -171,11 +171,11 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
dot.add("label=\"{");
|
||||
dot.add(String.valueOf(block.getId())).add("\\:\\ ");
|
||||
dot.add(InsnUtils.formatOffset(block.getStartOffset()));
|
||||
if (attrs.length() != 0) {
|
||||
if (!attrs.isEmpty()) {
|
||||
dot.add('|').add(attrs);
|
||||
}
|
||||
String insns = insertInsns(mth, block);
|
||||
if (insns.length() != 0) {
|
||||
if (!insns.isEmpty()) {
|
||||
dot.add('|').add(insns);
|
||||
}
|
||||
dot.add("}\"];");
|
||||
@@ -208,11 +208,11 @@ public class DotGraphVisitor extends AbstractVisitor {
|
||||
dot.add("color=red,");
|
||||
}
|
||||
dot.add("label=\"{");
|
||||
if (attrs.length() != 0) {
|
||||
if (!attrs.isEmpty()) {
|
||||
dot.add(attrs);
|
||||
}
|
||||
String insns = insertInsns(mth, block);
|
||||
if (insns.length() != 0) {
|
||||
if (!insns.isEmpty()) {
|
||||
dot.add('|').add(insns);
|
||||
}
|
||||
dot.add("}\"];");
|
||||
|
||||
@@ -64,7 +64,7 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
String valuesMethod = "values()" + TypeGen.signature(ArgType.array(clsType));
|
||||
|
||||
// collect enum fields, remove synthetic
|
||||
List<FieldNode> enumFields = new ArrayList<FieldNode>();
|
||||
List<FieldNode> enumFields = new ArrayList<>();
|
||||
for (FieldNode f : cls.getFields()) {
|
||||
if (f.getAccessFlags().isEnum()) {
|
||||
enumFields.add(f);
|
||||
@@ -101,7 +101,7 @@ public class EnumVisitor extends AbstractVisitor {
|
||||
|
||||
// move enum specific instruction from static method to separate list
|
||||
BlockNode staticBlock = staticMethod.getBasicBlocks().get(0);
|
||||
List<InsnNode> enumPutInsns = new ArrayList<InsnNode>();
|
||||
List<InsnNode> enumPutInsns = new ArrayList<>();
|
||||
List<InsnNode> list = staticBlock.getInstructions();
|
||||
int size = list.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
@@ -102,7 +102,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
|
||||
private static class InitInfo {
|
||||
private final MethodNode constrMth;
|
||||
private final List<InsnNode> putInsns = new ArrayList<InsnNode>();
|
||||
private final List<InsnNode> putInsns = new ArrayList<>();
|
||||
|
||||
private InitInfo(MethodNode constrMth) {
|
||||
this.constrMth = constrMth;
|
||||
@@ -122,7 +122,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
if (constrList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<InitInfo> infoList = new ArrayList<InitInfo>(constrList.size());
|
||||
List<InitInfo> infoList = new ArrayList<>(constrList.size());
|
||||
for (MethodNode constrMth : constrList) {
|
||||
if (constrMth.isNoCode() || constrMth.getBasicBlocks().isEmpty()) {
|
||||
return;
|
||||
@@ -151,7 +151,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
if (common == null) {
|
||||
return;
|
||||
}
|
||||
Set<FieldInfo> fields = new HashSet<FieldInfo>();
|
||||
Set<FieldInfo> fields = new HashSet<>();
|
||||
for (InsnNode insn : common.getPutInsns()) {
|
||||
FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) insn).getIndex();
|
||||
FieldNode field = cls.dex().resolveField(fieldInfo);
|
||||
@@ -200,7 +200,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
} else {
|
||||
return arg.isLiteral() || arg.isThis();
|
||||
}
|
||||
Set<RegisterArg> regs = new HashSet<RegisterArg>();
|
||||
Set<RegisterArg> regs = new HashSet<>();
|
||||
insn.getRegisterArgs(regs);
|
||||
if (!regs.isEmpty()) {
|
||||
for (RegisterArg reg : regs) {
|
||||
@@ -213,7 +213,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static List<MethodNode> getConstructorsList(ClassNode cls) {
|
||||
List<MethodNode> list = new ArrayList<MethodNode>();
|
||||
List<MethodNode> list = new ArrayList<>();
|
||||
for (MethodNode mth : cls.getMethods()) {
|
||||
AccessInfo accFlags = mth.getAccessFlags();
|
||||
if (!accFlags.isStatic() && accFlags.isConstructor()) {
|
||||
@@ -230,7 +230,7 @@ public class ExtractFieldInit extends AbstractVisitor {
|
||||
if (mth.isNoCode()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<InsnNode> assignInsns = new ArrayList<InsnNode>();
|
||||
List<InsnNode> assignInsns = new ArrayList<>();
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == putInsn) {
|
||||
|
||||
@@ -19,14 +19,11 @@ public interface IDexTreeVisitor {
|
||||
* Visit class
|
||||
*
|
||||
* @return false for disable child methods and inner classes traversal
|
||||
* @throws JadxException
|
||||
*/
|
||||
boolean visit(ClassNode cls) throws JadxException;
|
||||
|
||||
/**
|
||||
* Visit method
|
||||
*
|
||||
* @throws JadxException
|
||||
*/
|
||||
void visit(MethodNode mth) throws JadxException;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
break;
|
||||
|
||||
case MOVE_EXCEPTION:
|
||||
processMoveException(mth, block, insn, remover);
|
||||
processMoveException(block, insn, remover);
|
||||
break;
|
||||
|
||||
case ARITH:
|
||||
@@ -216,7 +216,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
RegisterArg resultArg = co.getResult();
|
||||
if (!resultArg.equals(instArg)) {
|
||||
// replace all usages of 'instArg' with result of this constructor instruction
|
||||
for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) {
|
||||
for (RegisterArg useArg : new ArrayList<>(instArg.getSVar().getUseList())) {
|
||||
RegisterArg dup = resultArg.duplicate();
|
||||
InsnNode parentInsn = useArg.getParentInsn();
|
||||
parentInsn.replaceArg(useArg, dup);
|
||||
@@ -284,7 +284,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode callMthNode, ConstructorInsn co) {
|
||||
Map<InsnArg, FieldNode> map = new LinkedHashMap<InsnArg, FieldNode>();
|
||||
Map<InsnArg, FieldNode> map = new LinkedHashMap<>();
|
||||
ClassNode parentClass = callMthNode.getParentClass();
|
||||
List<RegisterArg> argList = callMthNode.getArguments(false);
|
||||
int startArg = parentClass.getAccessFlags().isStatic() ? 0 : 1;
|
||||
@@ -360,10 +360,10 @@ public class ModVisitor extends AbstractVisitor {
|
||||
ArgType insnArrayType = insn.getResult().getType();
|
||||
ArgType insnElementType = insnArrayType.getArrayElement();
|
||||
ArgType elType = insn.getElementType();
|
||||
if (!elType.isTypeKnown() && insnElementType.isPrimitive()) {
|
||||
if (elType.contains(insnElementType.getPrimitiveType())) {
|
||||
elType = insnElementType;
|
||||
}
|
||||
if (!elType.isTypeKnown()
|
||||
&& insnElementType.isPrimitive()
|
||||
&& elType.contains(insnElementType.getPrimitiveType())) {
|
||||
elType = insnElementType;
|
||||
}
|
||||
if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
|
||||
ErrorsCounter.methodError(mth,
|
||||
@@ -429,8 +429,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void processMoveException(MethodNode mth, BlockNode block, InsnNode insn,
|
||||
InstructionRemover remover) {
|
||||
private static void processMoveException(BlockNode block, InsnNode insn, InstructionRemover remover) {
|
||||
ExcHandlerAttr excHandlerAttr = block.get(AType.EXC_HANDLER);
|
||||
if (excHandlerAttr == null) {
|
||||
return;
|
||||
|
||||
@@ -65,7 +65,8 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
return processNewArray(mth, instructions, i, remover);
|
||||
|
||||
case SWITCH:
|
||||
return processEnumSwitch(mth, (SwitchNode) insn);
|
||||
processEnumSwitch(mth, (SwitchNode) insn);
|
||||
return null;
|
||||
|
||||
default:
|
||||
return null;
|
||||
@@ -104,43 +105,43 @@ public class ReSugarCode extends AbstractVisitor {
|
||||
return filledArr;
|
||||
}
|
||||
|
||||
private static InsnNode processEnumSwitch(MethodNode mth, SwitchNode insn) {
|
||||
private static void processEnumSwitch(MethodNode mth, SwitchNode insn) {
|
||||
InsnArg arg = insn.getArg(0);
|
||||
if (!arg.isInsnWrap()) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
|
||||
if (wrapInsn.getType() != InsnType.AGET) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
EnumMapInfo enumMapInfo = checkEnumMapAccess(mth, wrapInsn);
|
||||
if (enumMapInfo == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
FieldNode enumMapField = enumMapInfo.getMapField();
|
||||
InsnArg invArg = enumMapInfo.getArg();
|
||||
|
||||
EnumMapAttr.KeyValueMap valueMap = getEnumMap(mth, enumMapField);
|
||||
if (valueMap == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
Object[] keys = insn.getKeys();
|
||||
for (Object key : keys) {
|
||||
Object newKey = valueMap.get(key);
|
||||
if (newKey == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// replace confirmed
|
||||
if (!insn.replaceArg(arg, invArg)) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
keys[i] = valueMap.get(keys[i]);
|
||||
}
|
||||
enumMapField.add(AFlag.DONT_GENERATE);
|
||||
checkAndHideClass(enumMapField.getParentClass());
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
private static EnumMapAttr.KeyValueMap getEnumMap(MethodNode mth, FieldNode field) {
|
||||
|
||||
@@ -40,9 +40,9 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
return;
|
||||
}
|
||||
InputFile firstInputFile = dexNodes.get(0).getDexFile().getInputFile();
|
||||
final String firstInputFileName = firstInputFile.getFile().getAbsolutePath();
|
||||
final String inputPath = FilenameUtils.getFullPathNoEndSeparator(firstInputFileName);
|
||||
final String inputName = FilenameUtils.getBaseName(firstInputFileName);
|
||||
String firstInputFileName = firstInputFile.getFile().getAbsolutePath();
|
||||
String inputPath = FilenameUtils.getFullPathNoEndSeparator(firstInputFileName);
|
||||
String inputName = FilenameUtils.getBaseName(firstInputFileName);
|
||||
|
||||
File deobfMapFile = new File(inputPath, inputName + ".jobf");
|
||||
deobfuscator = new Deobfuscator(args, dexNodes, deobfMapFile);
|
||||
@@ -64,7 +64,7 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private void checkClasses(RootNode root) {
|
||||
Set<String> clsNames = new HashSet<String>();
|
||||
Set<String> clsNames = new HashSet<>();
|
||||
for (ClassNode cls : root.getClasses(true)) {
|
||||
checkClassName(cls);
|
||||
if (!CASE_SENSITIVE_FS) {
|
||||
@@ -101,7 +101,7 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private void checkFields(ClassNode cls) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
Set<String> names = new HashSet<>();
|
||||
for (FieldNode field : cls.getFields()) {
|
||||
FieldInfo fieldInfo = field.getFieldInfo();
|
||||
if (!names.add(fieldInfo.getAlias())) {
|
||||
@@ -111,7 +111,7 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private void checkMethods(ClassNode cls) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
Set<String> names = new HashSet<>();
|
||||
for (MethodNode mth : cls.getMethods()) {
|
||||
if (mth.contains(AFlag.DONT_GENERATE)) {
|
||||
continue;
|
||||
|
||||
@@ -298,7 +298,7 @@ public class SimplifyVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static List<InsnNode> flattenInsnChain(InsnNode insn) {
|
||||
List<InsnNode> chain = new ArrayList<InsnNode>();
|
||||
List<InsnNode> chain = new ArrayList<>();
|
||||
InsnArg i = insn.getArg(0);
|
||||
while (i.isInsnWrap()) {
|
||||
InsnNode wrapInsn = ((InsnWrapArg) i).getWrapInsn();
|
||||
|
||||
+17
-15
@@ -29,6 +29,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -93,7 +94,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
private static boolean extractFinally(MethodNode mth, ExceptionHandler handler) {
|
||||
int count = handler.getBlocks().size();
|
||||
BitSet bs = new BitSet(count);
|
||||
List<BlockNode> blocks = new ArrayList<BlockNode>(count);
|
||||
List<BlockNode> blocks = new ArrayList<>(count);
|
||||
for (BlockNode block : handler.getBlocks()) {
|
||||
List<InsnNode> insns = block.getInstructions();
|
||||
if (!insns.isEmpty()) {
|
||||
@@ -108,8 +109,8 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<BlocksRemoveInfo> removes = new LinkedList<BlocksRemoveInfo>();
|
||||
Set<BlockNode> splitters = new HashSet<BlockNode>();
|
||||
List<BlocksRemoveInfo> removes = new LinkedList<>();
|
||||
Set<BlockNode> splitters = new HashSet<>();
|
||||
|
||||
// remove 'finally' from handlers
|
||||
TryCatchBlock tryBlock = handler.getTryBlock();
|
||||
@@ -238,7 +239,6 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
if (!processed.get(fromRegNum)) {
|
||||
boolean liveFromBefore = laBefore.isLive(insertBlockBefore, fromRegNum);
|
||||
boolean liveFromAfter = laAfter.isLive(insertBlock, fromRegNum);
|
||||
// boolean liveToBefore = laBefore.isLive(insertBlock, toRegNum);
|
||||
boolean liveToAfter = laAfter.isLive(insertBlock, toRegNum);
|
||||
if (liveToAfter && liveFromBefore) {
|
||||
// merge 'to' and 'from' registers
|
||||
@@ -308,7 +308,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static boolean mergeReturns(MethodNode mth, Set<BlocksPair> outs) {
|
||||
Set<BlockNode> rightOuts = new HashSet<BlockNode>();
|
||||
Set<BlockNode> rightOuts = new HashSet<>();
|
||||
boolean allReturns = true;
|
||||
for (BlocksPair outPair : outs) {
|
||||
BlockNode first = outPair.getFirst();
|
||||
@@ -346,7 +346,8 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
/**
|
||||
* 'Finally' instructions can start in the middle of the first block.
|
||||
*/
|
||||
private static BlocksRemoveInfo isStartBlock(BlockNode remBlock, BlockNode startBlock) {
|
||||
private static @Nullable
|
||||
BlocksRemoveInfo isStartBlock(BlockNode remBlock, BlockNode startBlock) {
|
||||
List<InsnNode> remInsns = remBlock.getInstructions();
|
||||
List<InsnNode> startInsns = startBlock.getInstructions();
|
||||
if (remInsns.size() < startInsns.size()) {
|
||||
@@ -400,8 +401,8 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean checkBlocksTree(BlockNode remBlock, BlockNode startBlock, BlocksRemoveInfo removeInfo,
|
||||
BitSet bs) {
|
||||
private static boolean checkBlocksTree(BlockNode remBlock, BlockNode startBlock,
|
||||
@NotNull BlocksRemoveInfo removeInfo, BitSet bs) {
|
||||
// skip check on start block
|
||||
if (!removeInfo.getProcessed().isEmpty()
|
||||
&& !sameBlocks(remBlock, startBlock, removeInfo)) {
|
||||
@@ -434,7 +435,8 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean sameBlocks(BlockNode remBlock, BlockNode finallyBlock, BlocksRemoveInfo removeInfo) {
|
||||
private static boolean sameBlocks(BlockNode remBlock, BlockNode finallyBlock,
|
||||
@NotNull BlocksRemoveInfo removeInfo) {
|
||||
List<InsnNode> first = remBlock.getInstructions();
|
||||
List<InsnNode> second = finallyBlock.getInstructions();
|
||||
if (first.size() < second.size()) {
|
||||
@@ -453,7 +455,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean sameInsns(InsnNode remInsn, InsnNode fInsn, BlocksRemoveInfo removeInfo) {
|
||||
private static boolean sameInsns(InsnNode remInsn, InsnNode fInsn, @Nullable BlocksRemoveInfo removeInfo) {
|
||||
if (!remInsn.isSame(fInsn)) {
|
||||
return false;
|
||||
}
|
||||
@@ -541,7 +543,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
if (filtPreds.size() > 1) {
|
||||
BlockNode pred = sOut.getPredecessors().get(0);
|
||||
BlockNode newPred = BlockSplitter.insertBlockBetween(mth, pred, sOut);
|
||||
for (BlockNode predBlock : new ArrayList<BlockNode>(sOut.getPredecessors())) {
|
||||
for (BlockNode predBlock : new ArrayList<>(sOut.getPredecessors())) {
|
||||
if (predBlock != newPred) {
|
||||
removeConnection(predBlock, sOut);
|
||||
connect(predBlock, newPred);
|
||||
@@ -566,7 +568,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
}
|
||||
|
||||
// redirect input edges
|
||||
for (BlockNode pred : new ArrayList<BlockNode>(remBlock.getPredecessors())) {
|
||||
for (BlockNode pred : new ArrayList<>(remBlock.getPredecessors())) {
|
||||
BlockNode middle = insertBlockBetween(mth, pred, remBlock);
|
||||
removeConnection(middle, remBlock);
|
||||
connect(middle, startBlock);
|
||||
@@ -593,7 +595,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
BlockNode newBlock = BlockSplitter.startNewBlock(mth, -1);
|
||||
|
||||
newBlock.getSuccessors().addAll(block.getSuccessors());
|
||||
for (BlockNode s : new ArrayList<BlockNode>(block.getSuccessors())) {
|
||||
for (BlockNode s : new ArrayList<>(block.getSuccessors())) {
|
||||
removeConnection(block, s);
|
||||
connect(newBlock, s);
|
||||
}
|
||||
@@ -684,7 +686,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
if (edgeAttr == null) {
|
||||
return;
|
||||
}
|
||||
List<BlockNode> merge = new LinkedList<BlockNode>();
|
||||
List<BlockNode> merge = new LinkedList<>();
|
||||
for (BlockNode blockNode : pred.getSuccessors()) {
|
||||
if (blockNode.contains(AFlag.RETURN)) {
|
||||
merge.add(blockNode);
|
||||
@@ -718,7 +720,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
|
||||
}
|
||||
|
||||
private static void mergeSyntheticPredecessors(MethodNode mth, BlockNode block) {
|
||||
List<BlockNode> preds = new ArrayList<BlockNode>(block.getPredecessors());
|
||||
List<BlockNode> preds = new ArrayList<>(block.getPredecessors());
|
||||
Iterator<BlockNode> it = preds.iterator();
|
||||
while (it.hasNext()) {
|
||||
BlockNode predBlock = it.next();
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BlockFinish extends AbstractVisitor {
|
||||
if (handlerBlock.getPredecessors().size() < 2) {
|
||||
return;
|
||||
}
|
||||
Map<BlockNode, SplitterBlockAttr> splitters = new HashMap<BlockNode, SplitterBlockAttr>();
|
||||
Map<BlockNode, SplitterBlockAttr> splitters = new HashMap<>();
|
||||
for (BlockNode pred : handlerBlock.getPredecessors()) {
|
||||
pred = BlockUtils.skipSyntheticPredecessor(pred);
|
||||
SplitterBlockAttr splitterAttr = pred.get(AType.SPLITTER_BLOCK);
|
||||
|
||||
@@ -292,7 +292,7 @@ public class BlockProcessor extends AbstractVisitor {
|
||||
BlockNode loopEnd = loop.getEnd();
|
||||
if (loopEnd.getPredecessors().size() > 1) {
|
||||
boolean change = false;
|
||||
List<BlockNode> nodes = new ArrayList<BlockNode>(loopEnd.getPredecessors());
|
||||
List<BlockNode> nodes = new ArrayList<>(loopEnd.getPredecessors());
|
||||
for (BlockNode pred : nodes) {
|
||||
if (!pred.contains(AFlag.SYNTHETIC)) {
|
||||
BlockSplitter.insertBlockBetween(mth, pred, loopEnd);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class BlockSplitter extends AbstractVisitor {
|
||||
|
||||
private static void splitBasicBlocks(MethodNode mth) {
|
||||
InsnNode prevInsn = null;
|
||||
Map<Integer, BlockNode> blocksMap = new HashMap<Integer, BlockNode>();
|
||||
Map<Integer, BlockNode> blocksMap = new HashMap<>();
|
||||
BlockNode curBlock = startNewBlock(mth, 0);
|
||||
mth.setEnterBlock(curBlock);
|
||||
|
||||
|
||||
+3
-3
@@ -11,9 +11,9 @@ import java.util.Set;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class BlocksRemoveInfo {
|
||||
private final Set<BlocksPair> processed = new HashSet<BlocksPair>();
|
||||
private final Set<BlocksPair> outs = new HashSet<BlocksPair>();
|
||||
private final Map<RegisterArg, RegisterArg> regMap = new HashMap<RegisterArg, RegisterArg>();
|
||||
private final Set<BlocksPair> processed = new HashSet<>();
|
||||
private final Set<BlocksPair> outs = new HashSet<>();
|
||||
private final Map<RegisterArg, RegisterArg> regMap = new HashMap<>();
|
||||
|
||||
private BlocksPair start;
|
||||
private BlocksPair end;
|
||||
|
||||
@@ -29,7 +29,7 @@ public class CheckRegions extends AbstractVisitor {
|
||||
}
|
||||
|
||||
// check if all blocks included in regions
|
||||
final Set<BlockNode> blocksInRegions = new HashSet<BlockNode>();
|
||||
Set<BlockNode> blocksInRegions = new HashSet<>();
|
||||
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
|
||||
@Override
|
||||
public void processBlock(MethodNode mth, IBlock container) {
|
||||
|
||||
@@ -49,8 +49,8 @@ public class IfMakerHelper {
|
||||
}
|
||||
|
||||
static IfInfo restructureIf(MethodNode mth, BlockNode block, IfInfo info) {
|
||||
final BlockNode thenBlock = info.getThenBlock();
|
||||
final BlockNode elseBlock = info.getElseBlock();
|
||||
BlockNode thenBlock = info.getThenBlock();
|
||||
BlockNode elseBlock = info.getElseBlock();
|
||||
|
||||
// select 'then', 'else' and 'exit' blocks
|
||||
if (thenBlock.contains(AFlag.RETURN) && elseBlock.contains(AFlag.RETURN)) {
|
||||
|
||||
@@ -110,7 +110,7 @@ public class IfRegionVisitor extends AbstractVisitor implements IRegionVisitor,
|
||||
private static void moveReturnToThenBlock(MethodNode mth, IfRegion ifRegion) {
|
||||
if (!mth.getReturnType().equals(ArgType.VOID)
|
||||
&& hasSimpleReturnBlock(ifRegion.getElseRegion())
|
||||
/*&& insnsCount(ifRegion.getThenRegion()) < 2*/) {
|
||||
/*&& insnsCount(ifRegion.getThenRegion()) < 2*/) {
|
||||
invertIfRegion(ifRegion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
|
||||
return false;
|
||||
}
|
||||
// can't make loop if argument from increment instruction is assign in loop
|
||||
List<RegisterArg> args = new LinkedList<RegisterArg>();
|
||||
List<RegisterArg> args = new LinkedList<>();
|
||||
incrInsn.getRegisterArgs(args);
|
||||
for (RegisterArg iArg : args) {
|
||||
if (assignOnlyInLoop(mth, loopRegion, iArg)) {
|
||||
@@ -230,7 +230,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
|
||||
|| !checkInvoke(nextCall, "java.util.Iterator", "next()Ljava/lang/Object;", 0)) {
|
||||
return false;
|
||||
}
|
||||
List<InsnNode> toSkip = new LinkedList<InsnNode>();
|
||||
List<InsnNode> toSkip = new LinkedList<>();
|
||||
RegisterArg iterVar = nextCall.getResult();
|
||||
if (iterVar == null) {
|
||||
return false;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<BlockNode, TryCatchBlock> tryBlocksMap = new HashMap<BlockNode, TryCatchBlock>(2);
|
||||
Map<BlockNode, TryCatchBlock> tryBlocksMap = new HashMap<>(2);
|
||||
searchTryCatchDominators(mth, tryBlocksMap);
|
||||
|
||||
IRegionIterativeVisitor visitor = new IRegionIterativeVisitor() {
|
||||
@@ -55,7 +55,7 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
|
||||
}
|
||||
|
||||
private static void searchTryCatchDominators(MethodNode mth, Map<BlockNode, TryCatchBlock> tryBlocksMap) {
|
||||
Set<TryCatchBlock> tryBlocks = new HashSet<TryCatchBlock>();
|
||||
Set<TryCatchBlock> tryBlocks = new HashSet<>();
|
||||
// collect all try/catch blocks
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
CatchAttr c = block.get(AType.CATCH_BLOCK);
|
||||
|
||||
@@ -72,8 +72,8 @@ public class ProcessVariables extends AbstractVisitor {
|
||||
private RegisterArg arg;
|
||||
private VarName varName;
|
||||
private IRegion argRegion;
|
||||
private final Set<IRegion> usage = new HashSet<IRegion>(2);
|
||||
private final Set<IRegion> assigns = new HashSet<IRegion>(2);
|
||||
private final Set<IRegion> usage = new HashSet<>(2);
|
||||
private final Set<IRegion> assigns = new HashSet<>(2);
|
||||
|
||||
public void setArg(RegisterArg arg) {
|
||||
this.arg = arg;
|
||||
@@ -119,7 +119,7 @@ public class ProcessVariables extends AbstractVisitor {
|
||||
|
||||
public CollectUsageRegionVisitor(Map<Variable, Usage> usageMap) {
|
||||
this.usageMap = usageMap;
|
||||
args = new ArrayList<RegisterArg>();
|
||||
args = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -177,7 +177,7 @@ public class ProcessVariables extends AbstractVisitor {
|
||||
if (mth.isNoCode()) {
|
||||
return;
|
||||
}
|
||||
final Map<Variable, Usage> usageMap = new LinkedHashMap<Variable, Usage>();
|
||||
Map<Variable, Usage> usageMap = new LinkedHashMap<>();
|
||||
for (RegisterArg arg : mth.getArguments(true)) {
|
||||
addToUsageMap(arg, usageMap);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ public class ProcessVariables extends AbstractVisitor {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<IContainer, Integer> regionsOrder = new HashMap<IContainer, Integer>();
|
||||
Map<IContainer, Integer> regionsOrder = new HashMap<>();
|
||||
calculateOrder(mth.getRegion(), regionsOrder, 0, true);
|
||||
|
||||
for (Iterator<Entry<Variable, Usage>> it = usageMap.entrySet().iterator(); it.hasNext(); ) {
|
||||
|
||||
@@ -158,7 +158,7 @@ public class RegionMaker {
|
||||
|
||||
// set exit blocks scan order priority
|
||||
// this can help if loop have several exits (after using 'break' or 'return' in loop)
|
||||
List<BlockNode> exitBlocks = new ArrayList<BlockNode>(exitBlocksSet.size());
|
||||
List<BlockNode> exitBlocks = new ArrayList<>(exitBlocksSet.size());
|
||||
BlockNode nextStart = getNextBlock(loopStart);
|
||||
if (nextStart != null && exitBlocksSet.remove(nextStart)) {
|
||||
exitBlocks.add(nextStart);
|
||||
@@ -511,8 +511,8 @@ public class RegionMaker {
|
||||
synchRegion.getSubBlocks().add(block);
|
||||
curRegion.getSubBlocks().add(synchRegion);
|
||||
|
||||
Set<BlockNode> exits = new HashSet<BlockNode>();
|
||||
Set<BlockNode> cacheSet = new HashSet<BlockNode>();
|
||||
Set<BlockNode> exits = new HashSet<>();
|
||||
Set<BlockNode> cacheSet = new HashSet<>();
|
||||
traverseMonitorExits(synchRegion, insn.getArg(0), block, exits, cacheSet);
|
||||
|
||||
for (InsnNode exitInsn : synchRegion.getExitInsns()) {
|
||||
@@ -691,19 +691,19 @@ public class RegionMaker {
|
||||
|
||||
int len = insn.getTargets().length;
|
||||
// sort by target
|
||||
Map<Integer, List<Object>> casesMap = new LinkedHashMap<Integer, List<Object>>(len);
|
||||
Map<Integer, List<Object>> casesMap = new LinkedHashMap<>(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object key = insn.getKeys()[i];
|
||||
int targ = insn.getTargets()[i];
|
||||
List<Object> keys = casesMap.get(targ);
|
||||
if (keys == null) {
|
||||
keys = new ArrayList<Object>(2);
|
||||
keys = new ArrayList<>(2);
|
||||
casesMap.put(targ, keys);
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
|
||||
Map<BlockNode, List<Object>> blocksMap = new LinkedHashMap<BlockNode, List<Object>>(len);
|
||||
Map<BlockNode, List<Object>> blocksMap = new LinkedHashMap<>(len);
|
||||
for (Map.Entry<Integer, List<Object>> entry : casesMap.entrySet()) {
|
||||
BlockNode c = getBlockByOffset(entry.getKey(), block.getSuccessors());
|
||||
if (c == null) {
|
||||
@@ -717,7 +717,7 @@ public class RegionMaker {
|
||||
}
|
||||
LoopInfo loop = mth.getLoopForBlock(block);
|
||||
|
||||
Map<BlockNode, BlockNode> fallThroughCases = new LinkedHashMap<BlockNode, BlockNode>();
|
||||
Map<BlockNode, BlockNode> fallThroughCases = new LinkedHashMap<>();
|
||||
|
||||
List<BlockNode> basicBlocks = mth.getBasicBlocks();
|
||||
BitSet outs = new BitSet(basicBlocks.size());
|
||||
@@ -753,14 +753,13 @@ public class RegionMaker {
|
||||
stack.addExits(BlockUtils.bitSetToBlocks(mth, outs));
|
||||
|
||||
// check cases order if fall through case exists
|
||||
if (!fallThroughCases.isEmpty()) {
|
||||
if (!fallThroughCases.isEmpty()
|
||||
&& isBadCasesOrder(blocksMap, fallThroughCases)) {
|
||||
LOG.debug("Fixing incorrect switch cases order, method: {}", mth);
|
||||
blocksMap = reOrderSwitchCases(blocksMap, fallThroughCases);
|
||||
if (isBadCasesOrder(blocksMap, fallThroughCases)) {
|
||||
LOG.debug("Fixing incorrect switch cases order, method: {}", mth);
|
||||
blocksMap = reOrderSwitchCases(blocksMap, fallThroughCases);
|
||||
if (isBadCasesOrder(blocksMap, fallThroughCases)) {
|
||||
LOG.error("Can't fix incorrect switch cases order, method: {}", mth);
|
||||
mth.add(AFlag.INCONSISTENT_CODE);
|
||||
}
|
||||
LOG.error("Can't fix incorrect switch cases order, method: {}", mth);
|
||||
mth.add(AFlag.INCONSISTENT_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,8 +844,8 @@ public class RegionMaker {
|
||||
return out;
|
||||
}
|
||||
|
||||
private boolean isBadCasesOrder(final Map<BlockNode, List<Object>> blocksMap,
|
||||
final Map<BlockNode, BlockNode> fallThroughCases) {
|
||||
private boolean isBadCasesOrder(Map<BlockNode, List<Object>> blocksMap,
|
||||
Map<BlockNode, BlockNode> fallThroughCases) {
|
||||
BlockNode nextCaseBlock = null;
|
||||
for (BlockNode caseBlock : blocksMap.keySet()) {
|
||||
if (nextCaseBlock != null && !caseBlock.equals(nextCaseBlock)) {
|
||||
@@ -858,8 +857,8 @@ public class RegionMaker {
|
||||
}
|
||||
|
||||
private Map<BlockNode, List<Object>> reOrderSwitchCases(Map<BlockNode, List<Object>> blocksMap,
|
||||
final Map<BlockNode, BlockNode> fallThroughCases) {
|
||||
List<BlockNode> list = new ArrayList<BlockNode>(blocksMap.size());
|
||||
Map<BlockNode, BlockNode> fallThroughCases) {
|
||||
List<BlockNode> list = new ArrayList<>(blocksMap.size());
|
||||
list.addAll(blocksMap.keySet());
|
||||
Collections.sort(list, new Comparator<BlockNode>() {
|
||||
@Override
|
||||
@@ -876,7 +875,7 @@ public class RegionMaker {
|
||||
}
|
||||
});
|
||||
|
||||
Map<BlockNode, List<Object>> newBlocksMap = new LinkedHashMap<BlockNode, List<Object>>(blocksMap.size());
|
||||
Map<BlockNode, List<Object>> newBlocksMap = new LinkedHashMap<>(blocksMap.size());
|
||||
for (BlockNode key : list) {
|
||||
newBlocksMap.put(key, blocksMap.get(key));
|
||||
}
|
||||
@@ -902,13 +901,13 @@ public class RegionMaker {
|
||||
}
|
||||
|
||||
public IRegion processTryCatchBlocks(MethodNode mth) {
|
||||
Set<TryCatchBlock> tcs = new HashSet<TryCatchBlock>();
|
||||
Set<TryCatchBlock> tcs = new HashSet<>();
|
||||
for (ExceptionHandler handler : mth.getExceptionHandlers()) {
|
||||
tcs.add(handler.getTryBlock());
|
||||
}
|
||||
for (TryCatchBlock tc : tcs) {
|
||||
List<BlockNode> blocks = new ArrayList<BlockNode>(tc.getHandlersCount());
|
||||
Set<BlockNode> splitters = new HashSet<BlockNode>();
|
||||
List<BlockNode> blocks = new ArrayList<>(tc.getHandlersCount());
|
||||
Set<BlockNode> splitters = new HashSet<>();
|
||||
for (ExceptionHandler handler : tc.getHandlers()) {
|
||||
BlockNode handlerBlock = handler.getHandlerBlock();
|
||||
if (handlerBlock != null) {
|
||||
@@ -918,7 +917,7 @@ public class RegionMaker {
|
||||
LOG.debug(ErrorsCounter.formatErrorMsg(mth, "No exception handler block: " + handler));
|
||||
}
|
||||
}
|
||||
Set<BlockNode> exits = new HashSet<BlockNode>();
|
||||
Set<BlockNode> exits = new HashSet<>();
|
||||
for (BlockNode splitter : splitters) {
|
||||
for (BlockNode handler : blocks) {
|
||||
List<BlockNode> s = splitter.getSuccessors();
|
||||
@@ -944,10 +943,10 @@ public class RegionMaker {
|
||||
* Search handlers successor blocks not included in any region.
|
||||
*/
|
||||
protected IRegion processHandlersOutBlocks(MethodNode mth, Set<TryCatchBlock> tcs) {
|
||||
Set<IBlock> allRegionBlocks = new HashSet<IBlock>();
|
||||
Set<IBlock> allRegionBlocks = new HashSet<>();
|
||||
RegionUtils.getAllRegionBlocks(mth.getRegion(), allRegionBlocks);
|
||||
|
||||
Set<IBlock> succBlocks = new HashSet<IBlock>();
|
||||
Set<IBlock> succBlocks = new HashSet<>();
|
||||
for (TryCatchBlock tc : tcs) {
|
||||
for (ExceptionHandler handler : tc.getHandlers()) {
|
||||
IContainer region = handler.getHandlerRegion();
|
||||
|
||||
@@ -113,7 +113,7 @@ public class RegionMakerVisitor extends AbstractVisitor {
|
||||
if (!(c instanceof Region)) {
|
||||
continue;
|
||||
}
|
||||
Set<IBlock> blocks = new HashSet<IBlock>();
|
||||
Set<IBlock> blocks = new HashSet<>();
|
||||
RegionUtils.getAllRegionBlocks(c, blocks);
|
||||
if (blocks.isEmpty()) {
|
||||
addBreakToContainer((Region) c);
|
||||
@@ -151,7 +151,7 @@ public class RegionMakerVisitor extends AbstractVisitor {
|
||||
if (RegionUtils.hasExitEdge(c)) {
|
||||
return;
|
||||
}
|
||||
List<InsnNode> insns = new ArrayList<InsnNode>(1);
|
||||
List<InsnNode> insns = new ArrayList<>(1);
|
||||
insns.add(new InsnNode(InsnType.BREAK, 0));
|
||||
c.add(new InsnContainer(insns));
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ final class RegionStack {
|
||||
IRegion region;
|
||||
|
||||
public State() {
|
||||
exits = new HashSet<BlockNode>(4);
|
||||
exits = new HashSet<>(4);
|
||||
}
|
||||
|
||||
private State(State c) {
|
||||
exits = new HashSet<BlockNode>(c.exits);
|
||||
exits = new HashSet<>(c.exits);
|
||||
}
|
||||
|
||||
public State copy() {
|
||||
@@ -55,7 +55,7 @@ final class RegionStack {
|
||||
if (DEBUG) {
|
||||
LOG.debug("New RegionStack: {}", mth);
|
||||
}
|
||||
this.stack = new ArrayDeque<State>();
|
||||
this.stack = new ArrayDeque<>();
|
||||
this.curState = new State();
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ public class TernaryMod {
|
||||
if (tPhi == null || ePhi == null || tPhi != ePhi) {
|
||||
return false;
|
||||
}
|
||||
Map<Integer, Integer> map = new HashMap<Integer, Integer>(tPhi.getArgsCount());
|
||||
Map<Integer, Integer> map = new HashMap<>(tPhi.getArgsCount());
|
||||
for (InsnArg arg : tPhi.getArguments()) {
|
||||
if (!arg.isRegister()) {
|
||||
continue;
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.Deque;
|
||||
|
||||
public abstract class TracedRegionVisitor implements IRegionVisitor {
|
||||
|
||||
protected final Deque<IRegion> regionStack = new ArrayDeque<IRegion>();
|
||||
protected final Deque<IRegion> regionStack = new ArrayDeque<>();
|
||||
|
||||
@Override
|
||||
public boolean enterRegion(MethodNode mth, IRegion region) {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SSATransform extends AbstractVisitor {
|
||||
int blocksCount = blocks.size();
|
||||
BitSet hasPhi = new BitSet(blocksCount);
|
||||
BitSet processed = new BitSet(blocksCount);
|
||||
Deque<BlockNode> workList = new LinkedList<BlockNode>();
|
||||
Deque<BlockNode> workList = new LinkedList<>();
|
||||
|
||||
BitSet assignBlocks = la.getAssignBlocks(regNum);
|
||||
for (int id = assignBlocks.nextSetBit(0); id >= 0; id = assignBlocks.nextSetBit(id + 1)) {
|
||||
@@ -221,11 +221,10 @@ public class SSATransform extends AbstractVisitor {
|
||||
InsnNode parentInsn = arg.getAssignInsn();
|
||||
if (parentInsn != null
|
||||
&& parentInsn.getResult() != null
|
||||
&& parentInsn.contains(AFlag.TRY_LEAVE)) {
|
||||
if (phi.removeArg(arg)) {
|
||||
argsCount--;
|
||||
continue;
|
||||
}
|
||||
&& parentInsn.contains(AFlag.TRY_LEAVE)
|
||||
&& phi.removeArg(arg)) {
|
||||
argsCount--;
|
||||
continue;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
@@ -256,7 +255,7 @@ public class SSATransform extends AbstractVisitor {
|
||||
|
||||
private static boolean fixUselessPhi(MethodNode mth) {
|
||||
boolean changed = false;
|
||||
List<PhiInsn> insnToRemove = new ArrayList<PhiInsn>();
|
||||
List<PhiInsn> insnToRemove = new ArrayList<>();
|
||||
for (SSAVar var : mth.getSVars()) {
|
||||
// phi result not used
|
||||
if (var.getUseCount() == 0) {
|
||||
@@ -385,7 +384,7 @@ public class SSATransform extends AbstractVisitor {
|
||||
return false;
|
||||
}
|
||||
List<RegisterArg> useList = resVar.getUseList();
|
||||
for (RegisterArg useArg : new ArrayList<RegisterArg>(useList)) {
|
||||
for (RegisterArg useArg : new ArrayList<>(useList)) {
|
||||
InsnNode useInsn = useArg.getParentInsn();
|
||||
if (useInsn == null || useInsn == phi) {
|
||||
return false;
|
||||
|
||||
@@ -149,5 +149,4 @@ public class PostTypeInference {
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public class ExportGradleProject {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExportGradleProject.class);
|
||||
|
||||
private static final Set<String> IGNORE_CLS_NAMES = new HashSet<String>(Arrays.asList(
|
||||
private static final Set<String> IGNORE_CLS_NAMES = new HashSet<>(Arrays.asList(
|
||||
"R",
|
||||
"BuildConfig"
|
||||
));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package jadx.core.export;
|
||||
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -34,7 +36,7 @@ public class TemplateFile {
|
||||
|
||||
private final String templateName;
|
||||
private final InputStream template;
|
||||
private final Map<String, String> values = new HashMap<String, String>();
|
||||
private final Map<String, String> values = new HashMap<>();
|
||||
|
||||
public static TemplateFile fromResources(String path) throws FileNotFoundException {
|
||||
InputStream res = TemplateFile.class.getResourceAsStream(path);
|
||||
@@ -44,7 +46,7 @@ public class TemplateFile {
|
||||
return new TemplateFile(path, res);
|
||||
}
|
||||
|
||||
private TemplateFile(String name, InputStream in) throws FileNotFoundException {
|
||||
private TemplateFile(String name, InputStream in) {
|
||||
this.templateName = name;
|
||||
this.template = in;
|
||||
}
|
||||
@@ -76,9 +78,7 @@ public class TemplateFile {
|
||||
if (template.available() == 0) {
|
||||
throw new IOException("Template already processed");
|
||||
}
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new BufferedInputStream(template);
|
||||
try (InputStream in = new BufferedInputStream(template)) {
|
||||
ParserState state = new ParserState();
|
||||
while (true) {
|
||||
int ch = in.read();
|
||||
@@ -92,8 +92,6 @@ public class TemplateFile {
|
||||
out.write(ch);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
close(in);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +140,7 @@ public class TemplateFile {
|
||||
return "{" + ch;
|
||||
|
||||
case END:
|
||||
throw new RuntimeException("Expected variable end: '" + parser.curVariable
|
||||
throw new JadxRuntimeException("Expected variable end: '" + parser.curVariable
|
||||
+ "' (missing second '}')");
|
||||
}
|
||||
break;
|
||||
@@ -154,7 +152,7 @@ public class TemplateFile {
|
||||
private String processVar(String varName) {
|
||||
String str = values.get(varName);
|
||||
if (str == null) {
|
||||
throw new RuntimeException("Unknown variable: '" + varName
|
||||
throw new JadxRuntimeException("Unknown variable: '" + varName
|
||||
+ "' in template: " + templateName);
|
||||
}
|
||||
return str;
|
||||
|
||||
@@ -6,24 +6,17 @@ import java.io.IOException;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
import static jadx.core.utils.files.FileUtils.close;
|
||||
|
||||
public class AsmUtils {
|
||||
|
||||
private AsmUtils() {
|
||||
}
|
||||
|
||||
public static String getNameFromClassFile(File file) throws IOException {
|
||||
String className = null;
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
String className;
|
||||
try (FileInputStream in = new FileInputStream(file)) {
|
||||
ClassReader classReader = new ClassReader(in);
|
||||
className = classReader.getClassName();
|
||||
} finally {
|
||||
close(in);
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ public class BlockUtils {
|
||||
if (size == 1) {
|
||||
BlockNode first = blocks.get(0);
|
||||
return first != node ? first : null;
|
||||
} else if (size == 2) {
|
||||
}
|
||||
if (size == 2) {
|
||||
BlockNode first = blocks.get(0);
|
||||
return first != node ? first : blocks.get(1);
|
||||
}
|
||||
@@ -89,7 +90,7 @@ public class BlockUtils {
|
||||
* Remove exception handlers from block nodes list
|
||||
*/
|
||||
private static List<BlockNode> cleanBlockList(List<BlockNode> list) {
|
||||
List<BlockNode> ret = new ArrayList<BlockNode>(list.size());
|
||||
List<BlockNode> ret = new ArrayList<>(list.size());
|
||||
for (BlockNode block : list) {
|
||||
if (!isBlockMustBeCleared(block)) {
|
||||
ret.add(block);
|
||||
@@ -117,12 +118,10 @@ public class BlockUtils {
|
||||
*/
|
||||
public static List<BlockNode> filterPredecessors(BlockNode block) {
|
||||
List<BlockNode> predecessors = block.getPredecessors();
|
||||
List<BlockNode> list = new ArrayList<BlockNode>(predecessors.size());
|
||||
List<BlockNode> list = new ArrayList<>(predecessors.size());
|
||||
for (BlockNode pred : predecessors) {
|
||||
IgnoreEdgeAttr edgeAttr = pred.get(AType.IGNORE_EDGE);
|
||||
if (edgeAttr == null) {
|
||||
list.add(pred);
|
||||
} else if (!edgeAttr.contains(block)) {
|
||||
if (edgeAttr == null || !edgeAttr.contains(block)) {
|
||||
list.add(pred);
|
||||
}
|
||||
}
|
||||
@@ -274,7 +273,7 @@ public class BlockUtils {
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<BlockNode> blocks = new ArrayList<BlockNode>(size);
|
||||
List<BlockNode> blocks = new ArrayList<>(size);
|
||||
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
|
||||
BlockNode block = mth.getBasicBlocks().get(i);
|
||||
blocks.add(block);
|
||||
@@ -311,7 +310,7 @@ public class BlockUtils {
|
||||
* Collect blocks from all possible execution paths from 'start' to 'end'
|
||||
*/
|
||||
public static Set<BlockNode> getAllPathsBlocks(BlockNode start, BlockNode end) {
|
||||
Set<BlockNode> set = new HashSet<BlockNode>();
|
||||
Set<BlockNode> set = new HashSet<>();
|
||||
set.add(start);
|
||||
if (start != end) {
|
||||
addPredecessors(set, end, start);
|
||||
@@ -398,9 +397,10 @@ public class BlockUtils {
|
||||
if (!end.isDominator(start)) {
|
||||
return false;
|
||||
}
|
||||
while (start.getCleanSuccessors().size() == 1) {
|
||||
start = start.getCleanSuccessors().get(0);
|
||||
if (start == end) {
|
||||
BlockNode currentNode = start;
|
||||
while (currentNode.getCleanSuccessors().size() == 1) {
|
||||
currentNode = currentNode.getCleanSuccessors().get(0);
|
||||
if (currentNode == end) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -452,14 +452,17 @@ public class BlockUtils {
|
||||
* Collect all block dominated by 'dominator', starting from 'start'
|
||||
*/
|
||||
public static List<BlockNode> collectBlocksDominatedBy(BlockNode dominator, BlockNode start) {
|
||||
List<BlockNode> result = new ArrayList<BlockNode>();
|
||||
List<BlockNode> result = new ArrayList<>();
|
||||
HashSet<BlockNode> visited = new HashSet<BlockNode>();
|
||||
collectWhileDominates(dominator, start, result, visited);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void collectWhileDominates(BlockNode dominator, BlockNode child, List<BlockNode> result, HashSet<BlockNode> visited) {
|
||||
if (visited.contains(child)) return;
|
||||
private static void collectWhileDominates(BlockNode dominator, BlockNode child, List<BlockNode> result,
|
||||
HashSet<BlockNode> visited) {
|
||||
if (visited.contains(child)) {
|
||||
return;
|
||||
}
|
||||
visited.add(child);
|
||||
for (BlockNode node : child.getCleanSuccessors()) {
|
||||
if (node.isDominator(dominator)) {
|
||||
@@ -470,14 +473,18 @@ public class BlockUtils {
|
||||
}
|
||||
|
||||
public static List<BlockNode> buildSimplePath(BlockNode block) {
|
||||
List<BlockNode> list = new LinkedList<BlockNode>();
|
||||
while (block != null
|
||||
&& block.getCleanSuccessors().size() < 2
|
||||
&& block.getPredecessors().size() == 1) {
|
||||
list.add(block);
|
||||
block = getNextBlock(block);
|
||||
List<BlockNode> list = new LinkedList<>();
|
||||
BlockNode currentBlock = block;
|
||||
while (currentBlock != null
|
||||
&& currentBlock.getCleanSuccessors().size() < 2
|
||||
&& currentBlock.getPredecessors().size() == 1) {
|
||||
list.add(currentBlock);
|
||||
currentBlock = getNextBlock(currentBlock);
|
||||
}
|
||||
return list.isEmpty() ? Collections.<BlockNode>emptyList() : list;
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,9 @@ import org.slf4j.LoggerFactory;
|
||||
public class DebugUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DebugUtils.class);
|
||||
|
||||
private DebugUtils() {
|
||||
}
|
||||
|
||||
public static void dump(MethodNode mth) {
|
||||
dump(mth, "");
|
||||
}
|
||||
@@ -46,8 +49,8 @@ public class DebugUtils {
|
||||
DotGraphVisitor.dumpRegions(out).visit(mth);
|
||||
}
|
||||
|
||||
public static void printRegionsWithBlock(MethodNode mth, final BlockNode block) {
|
||||
final Set<IRegion> regions = new LinkedHashSet<IRegion>();
|
||||
public static void printRegionsWithBlock(MethodNode mth, BlockNode block) {
|
||||
Set<IRegion> regions = new LinkedHashSet<>();
|
||||
DepthRegionTraversal.traverse(mth, new TracedRegionVisitor() {
|
||||
@Override
|
||||
public void processBlockTraced(MethodNode mth, IBlock container, IRegion currentRegion) {
|
||||
@@ -126,17 +129,15 @@ public class DebugUtils {
|
||||
}
|
||||
for (RegisterArg useArg : sVar.getUseList()) {
|
||||
InsnNode parentInsn = useArg.getParentInsn();
|
||||
if (parentInsn != null) {
|
||||
if (!parentInsn.containsArg(useArg)) {
|
||||
throw new JadxRuntimeException("Incorrect use info in PHI insn");
|
||||
}
|
||||
if (parentInsn != null && !parentInsn.containsArg(useArg)) {
|
||||
throw new JadxRuntimeException("Incorrect use info in PHI insn");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPHI(MethodNode mth) {
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
List<PhiInsn> phis = new ArrayList<PhiInsn>();
|
||||
List<PhiInsn> phis = new ArrayList<>();
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == InsnType.PHI) {
|
||||
PhiInsn phi = (PhiInsn) insn;
|
||||
|
||||
@@ -86,9 +86,4 @@ public final class EmptyBitSet extends BitSet {
|
||||
public void andNot(BitSet set) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class ErrorsCounter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ErrorsCounter.class);
|
||||
|
||||
private final Set<Object> errorNodes = new HashSet<Object>();
|
||||
private final Set<Object> errorNodes = new HashSet<>();
|
||||
private int errorsCount;
|
||||
|
||||
public int getErrorCount() {
|
||||
@@ -69,7 +69,7 @@ public class ErrorsCounter {
|
||||
public void printReport() {
|
||||
if (getErrorCount() > 0) {
|
||||
LOG.error("{} errors occurred in following nodes:", getErrorCount());
|
||||
List<Object> nodes = new ArrayList<Object>(errorNodes);
|
||||
List<Object> nodes = new ArrayList<>(errorNodes);
|
||||
Collections.sort(nodes, new Comparator<Object>() {
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
|
||||
@@ -37,20 +37,20 @@ public class InsnUtils {
|
||||
return insn.getD();
|
||||
case 4:
|
||||
return insn.getE();
|
||||
default:
|
||||
throw new JadxRuntimeException("Wrong argument number: " + arg);
|
||||
}
|
||||
throw new JadxRuntimeException("Wrong argument number: " + arg);
|
||||
}
|
||||
|
||||
public static String formatOffset(int offset) {
|
||||
if (offset < 0) {
|
||||
return "?";
|
||||
} else {
|
||||
return String.format("0x%04x", offset);
|
||||
}
|
||||
return String.format("0x%04x", offset);
|
||||
}
|
||||
|
||||
public static String insnTypeToString(InsnType type) {
|
||||
return type.toString() + " ";
|
||||
return type + " ";
|
||||
}
|
||||
|
||||
public static String indexToString(Object index) {
|
||||
@@ -59,9 +59,8 @@ public class InsnUtils {
|
||||
}
|
||||
if (index instanceof String) {
|
||||
return "\"" + index + "\"";
|
||||
} else {
|
||||
return index.toString();
|
||||
}
|
||||
return index.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,16 +80,15 @@ public class InsnUtils {
|
||||
case SGET:
|
||||
FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex();
|
||||
FieldNode fieldNode = dex.resolveField(f);
|
||||
if (fieldNode != null) {
|
||||
FieldInitAttr attr = fieldNode.get(AType.FIELD_INIT);
|
||||
if (attr != null) {
|
||||
return attr.getValue();
|
||||
}
|
||||
} else {
|
||||
if (fieldNode == null) {
|
||||
LOG.warn("Field {} not found in dex {}", f, dex);
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
FieldInitAttr attr = fieldNode.get(AType.FIELD_INIT);
|
||||
return attr != null ? attr.getValue() : null;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user