Commit fef3e55c authored by Jan S's avatar Jan S Committed by skylot

feat(gui): select a class to open via command-line (PR #658)

parent 6f973ca2
......@@ -130,7 +130,7 @@ public class JadxCLIArgs {
* Used to merge saved options and options passed in command line.
*/
public boolean overrideProvided(String[] args) {
JCommanderWrapper<JadxCLIArgs> jcw = new JCommanderWrapper<>(new JadxCLIArgs());
JCommanderWrapper<JadxCLIArgs> jcw = new JCommanderWrapper<>(newInstance());
if (!jcw.parse(args)) {
return false;
}
......@@ -138,6 +138,10 @@ public class JadxCLIArgs {
return process(jcw);
}
protected JadxCLIArgs newInstance() {
return new JadxCLIArgs();
}
private boolean process(JCommanderWrapper<JadxCLIArgs> jcw) {
if (printHelp) {
jcw.printUsage();
......
......@@ -8,8 +8,9 @@ import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.ProgressMonitor;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -133,4 +134,13 @@ public class JadxWrapper {
public JadxArgs getArgs() {
return decompiler.getArgs();
}
/**
* @param fullName Full name of an outer class. Inner classes are not supported.
* @return
*/
public @Nullable JavaClass searchJavaClassByClassName(String fullName) {
return decompiler.getClasses().stream().filter(cls -> cls.getFullName().equals(fullName))
.findFirst().orElse(null);
}
}
......@@ -15,13 +15,15 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.swing.*;
import javax.swing.JFrame;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.beust.jcommander.Parameter;
import jadx.api.JadxArgs;
import jadx.cli.JadxCLIArgs;
import jadx.gui.ui.MainWindow;
......@@ -65,6 +67,10 @@ public class JadxSettings extends JadxCLIArgs {
private int settingsVersion = 0;
@JadxSettingsAdapter.GsonExclude
@Parameter(names = { "-sc", "--select-class" }, description = "GUI: Open the selected class and show the decompiled code")
private String cmdSelectClass = null;
public static JadxSettings makeDefault() {
JadxSettings jadxSettings = new JadxSettings();
jadxSettings.fixOnLoad();
......@@ -96,6 +102,10 @@ public class JadxSettings extends JadxCLIArgs {
}
}
public String getCmdSelectClass() {
return cmdSelectClass;
}
public Path getLastOpenFilePath() {
return lastOpenFilePath;
}
......@@ -412,4 +422,8 @@ public class JadxSettings extends JadxCLIArgs {
sync();
}
@Override
protected JadxCLIArgs newInstance() {
return new JadxSettings();
}
}
package jadx.gui.settings;
import java.awt.Rectangle;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.prefs.Preferences;
......@@ -31,7 +35,8 @@ public class JadxSettingsAdapter {
public boolean shouldSkipField(FieldAttributes f) {
return JadxSettings.SKIP_FIELDS.contains(f.getName())
|| f.hasModifier(Modifier.PUBLIC)
|| f.hasModifier(Modifier.TRANSIENT);
|| f.hasModifier(Modifier.TRANSIENT)
|| (f.getAnnotation(GsonExclude.class) != null);
}
@Override
......@@ -96,4 +101,12 @@ public class JadxSettingsAdapter {
.create()
.fromJson(json, type);
}
/**
* Annotation for specifying fields that should not be be saved/loaded
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface GsonExclude {
}
}
......@@ -67,6 +67,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.JadxArgs;
import jadx.api.JavaNode;
import jadx.api.ResourceFile;
import jadx.gui.JadxWrapper;
import jadx.gui.jobs.BackgroundWorker;
......@@ -178,10 +179,25 @@ public class MainWindow extends JFrame {
}
});
processCommandLineArgs();
}
private void processCommandLineArgs() {
if (settings.getFiles().isEmpty()) {
openFileOrProject();
} else {
open(Paths.get(settings.getFiles().get(0)));
if (settings.getCmdSelectClass() != null) {
JavaNode javaNode = wrapper.searchJavaClassByClassName(settings.getCmdSelectClass());
if (javaNode == null) {
JOptionPane.showMessageDialog(this,
NLS.str("msg.cmd_select_class_error", settings.getCmdSelectClass()),
NLS.str("error_dialog.title"), JOptionPane.ERROR_MESSAGE);
} else {
JNode node = cacheObject.getNodeCache().makeFrom(javaNode);
tabbedPane.codeJump(new JumpPosition(node.getRootClass(), node.getLine()));
}
}
}
}
......
......@@ -32,6 +32,8 @@ tree.sources_title=Source code
tree.resources_title=Resources
tree.loading=Loading...
error_dialog.title=Error
search.previous=Previous
search.next=Next
search.mark_all=Mark All
......@@ -131,6 +133,7 @@ msg.project_error_title=Error
msg.project_error=Project could not be loaded
msg.rename_disabled_title=Rename disabled
msg.rename_disabled=Some of rename settings are disabled, please take this into consideration
msg.cmd_select_class_error=Failed to select the class\n%s\nThe class does not exist.
popup.undo=Undo
popup.redo=Redo
......
......@@ -32,6 +32,8 @@ tree.sources_title=Código fuente
tree.resources_title=Recursos
tree.loading=Cargando...
#error_dialog.title=
search.previous=Anterior
search.next=Siguiente
search.mark_all=Marcar todo
......@@ -131,6 +133,7 @@ msg.index_not_initialized=Índice no inicializado, ¡la bósqueda se desactivar
#msg.project_error=
#msg.rename_disabled_title=
#msg.rename_disabled=
#msg.cmd_select_class_error=
popup.undo=Deshacer
popup.redo=Rehacer
......
......@@ -32,6 +32,8 @@ tree.sources_title=源代码
tree.resources_title=资源文件
tree.loading=稍等...
#error_dialog.title=
search.previous=上一个
search.next=下一个
search.mark_all=标记全部
......@@ -131,6 +133,7 @@ msg.index_not_initialized=索引尚未初始化,无法进行搜索!
#msg.project_error=
#msg.rename_disabled_title=
#msg.rename_disabled=
#msg.cmd_select_class_error=
popup.undo=撤销
popup.redo=重做
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment