Skip to content

Commit

Permalink
feat(gui):improve search and usage dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
MrIkso committed Dec 26, 2024
1 parent a46e35c commit 84fe471
Show file tree
Hide file tree
Showing 27 changed files with 937 additions and 514 deletions.
28 changes: 11 additions & 17 deletions jadx-gui/src/main/java/jadx/gui/search/ISearchMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,19 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public interface ISearchMethod {
int find(String input, String subStr, int start);
MatchingPositions find(String input, int start);

static ISearchMethod build(SearchSettings searchSettings) {
if (searchSettings.isUseRegex()) {
Pattern pattern = searchSettings.getPattern();
return (input, subStr, start) -> {
Matcher matcher = pattern.matcher(input);
if (matcher.find(start)) {
return matcher.start();
}
return -1;
};
}
if (searchSettings.isIgnoreCase()) {
return StringUtils::indexOfIgnoreCase;
}
return String::indexOf;
Pattern pattern = searchSettings.getPattern();
return (input, start) -> {
Matcher matcher = pattern.matcher(input);
if (matcher.find(start)) {
int startIndex = matcher.start();
int endIndex = matcher.end();
return new MatchingPositions(/* lineText, */startIndex, endIndex);
}
return null;
};
}
}
50 changes: 50 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/search/MatchingPositions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package jadx.gui.search;

public class MatchingPositions {
private final String line;
private int startMath;
private int endMath;

private int lineNumber;

public MatchingPositions(String line) {
this.line = line;
}

public MatchingPositions(String line, int lineNumber, int startMath, int endMath) {
this.line = line;
this.lineNumber = lineNumber;
this.startMath = startMath;
this.endMath = endMath;
}

public MatchingPositions(String line, int startMath, int endMath) {
this.line = line;
this.lineNumber = -1;
this.startMath = startMath;
this.endMath = endMath;
}

public MatchingPositions(int startMath, int endMath) {
this.line = null;
this.lineNumber = -1;
this.startMath = startMath;
this.endMath = endMath;
}

public int getLineNumber() {
return lineNumber;
}

public String getLine() {
return line;
}

public int getEndMath() {
return endMath;
}

public int getStartMath() {
return startMath;
}
}
39 changes: 39 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/search/SearchManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package jadx.gui.search;

import java.util.regex.Pattern;

public class SearchManager {
/**
* Generate the good pattern according to the different boolean
*
* @param exp the searched expression
* @param caseSensitive boolean
* @param wholeWord boolean
* @param useRegexp boolean
* @return the pattern
*/
public static Pattern generatePattern(String exp, boolean caseSensitive, boolean wholeWord, boolean useRegexp) {
String word = exp;
if (word != null && !word.isEmpty()) {
if (!useRegexp) {
word = word.replace("\\E", "\\E\\\\E\\Q");
word = "\\Q" + word + "\\E";
if (wholeWord && exp.matches("\\b.*\\b")) {
word = "\\b" + word + "\\b";
}
}

if (!caseSensitive) {
word = "(?i)" + word;
}

if (useRegexp) {
word = "(?m)" + word;
}

return Pattern.compile(word);
} else {
return Pattern.compile("");
}
}
}
28 changes: 10 additions & 18 deletions jadx-gui/src/main/java/jadx/gui/search/SearchSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,36 @@ public class SearchSettings {
private final String searchString;
private final boolean useRegex;
private final boolean ignoreCase;
private final boolean wholeWord;
private final JavaPackage searchPackage;

private JClass activeCls;
private JResource activeResource;
private Pattern regexPattern;
private ISearchMethod searchMethod;

public SearchSettings(String searchString, boolean ignoreCase, boolean useRegex, JavaPackage searchPackage) {
public SearchSettings(String searchString, boolean ignoreCase, boolean wholeWord, boolean useRegex, JavaPackage searchPackage) {
this.searchString = searchString;
this.useRegex = useRegex;
this.ignoreCase = ignoreCase;
this.wholeWord = wholeWord;
this.useRegex = useRegex;
this.searchPackage = searchPackage;
}

@Nullable
public String prepare() {
if (useRegex) {
try {
int flags = ignoreCase ? Pattern.CASE_INSENSITIVE : 0;
this.regexPattern = Pattern.compile(searchString, flags);
} catch (Exception e) {
return "Invalid Regex: " + e.getMessage();
}
try {
this.regexPattern = SearchManager.generatePattern(searchString, ignoreCase, wholeWord, useRegex);
} catch (Exception e) {
return "Invalid Regex: " + e.getMessage();
}

searchMethod = ISearchMethod.build(this);
return null;
}

public boolean isMatch(String searchArea) {
return searchMethod.find(searchArea, this.searchString, 0) != -1;
}

public boolean isUseRegex() {
return this.useRegex;
}

public boolean isIgnoreCase() {
return this.ignoreCase;
return searchMethod.find(searchArea, 0) != null;
}

public JavaPackage getSearchPackage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jadx.core.dex.nodes.ICodeNode;
import jadx.gui.search.ISearchMethod;
import jadx.gui.search.ISearchProvider;
import jadx.gui.search.MatchingPositions;
import jadx.gui.search.SearchSettings;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JNode;
Expand Down Expand Up @@ -41,8 +42,8 @@ public BaseSearchProvider(MainWindow mw, SearchSettings searchSettings, List<Jav
this.searchSettings = searchSettings;
}

protected boolean isMatch(String str) {
return searchMth.find(str, searchStr, 0) != -1;
protected MatchingPositions isMatch(String str) {
return searchMth.find(str, 0);
}

protected JNode convert(JavaNode node) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jadx.api.JavaClass;
import jadx.core.dex.info.ClassInfo;
import jadx.gui.jobs.Cancelable;
import jadx.gui.search.MatchingPositions;
import jadx.gui.search.SearchSettings;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.MainWindow;
Expand All @@ -26,18 +27,34 @@ public ClassSearchProvider(MainWindow mw, SearchSettings searchSettings, List<Ja
return null;
}
JavaClass curCls = classes.get(clsNum++);
if (checkCls(curCls)) {
return convert(curCls);
MatchingPositions matchingPositions = checkCls(curCls);
if (matchingPositions != null) {
JNode node = convert(curCls);
MatchingPositions highlightPositions = isMatch(curCls.getFullName());
node.setHasHighlight(true);
node.setStart(highlightPositions.getStartMath());
node.setEnd(highlightPositions.getEndMath());
return node;
}
}
}

private boolean checkCls(JavaClass cls) {
private MatchingPositions checkCls(JavaClass cls) {
ClassInfo clsInfo = cls.getClassNode().getClassInfo();
return isMatch(clsInfo.getShortName())
|| isMatch(clsInfo.getFullName())
|| isMatch(clsInfo.getAliasFullName())
|| isMatch(clsInfo.getRawName());
MatchingPositions shortMatch = isMatch(clsInfo.getShortName());
MatchingPositions fullMatch = isMatch(clsInfo.getFullName());
MatchingPositions aliasMatch = isMatch(clsInfo.getAliasFullName());
MatchingPositions rawMatch = isMatch(clsInfo.getRawName());
if (shortMatch != null) {
return shortMatch;
}
if (fullMatch != null) {
return fullMatch;
}
if (aliasMatch != null) {
return aliasMatch;
}
return rawMatch;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import jadx.api.utils.CodeUtils;
import jadx.gui.JadxWrapper;
import jadx.gui.jobs.Cancelable;
import jadx.gui.search.MatchingPositions;
import jadx.gui.search.SearchSettings;
import jadx.gui.treemodel.CodeNode;
import jadx.gui.treemodel.JClass;
Expand Down Expand Up @@ -64,18 +65,24 @@ public CodeSearchProvider(MainWindow mw, SearchSettings searchSettings, List<Jav

@Nullable
private JNode searchNext(JavaClass javaClass, String clsCode) {
int newPos = searchMth.find(clsCode, searchStr, pos);
if (newPos == -1) {
MatchingPositions positions = searchMth.find(clsCode, pos);
if (positions == null) {
return null;
}
int newPos = positions.getStartMath();
int lineStart = 1 + CodeUtils.getNewLinePosBefore(clsCode, newPos);
int lineEnd = CodeUtils.getNewLinePosAfter(clsCode, newPos);
int end = lineEnd == -1 ? clsCode.length() : lineEnd;
String line = clsCode.substring(lineStart, end);
String line = clsCode.substring(lineStart, end).trim();
this.pos = end;

// build pos for highlight
MatchingPositions highlightPositions = searchMth.find(line, 0);
int startHighlight = highlightPositions.getStartMath();
int endHighlight = highlightPositions.getEndMath();
JClass rootCls = convert(javaClass);
JNode enclosingNode = getOrElse(getEnclosingNode(javaClass, end), rootCls);
return new CodeNode(rootCls, enclosingNode, line.trim(), newPos);
return new CodeNode(rootCls, enclosingNode, line, newPos, startHighlight, endHighlight);
}

private @Nullable JNode getEnclosingNode(JavaClass javaCls, int pos) {
Expand Down
Loading

0 comments on commit 84fe471

Please sign in to comment.