Skip to content

Commit 8bbdbfc

Browse files
nitram84skylot
andauthored
feat: generate missing throws declarations, validate exceptions (#2441) (PR #2475)
* fix: generate missing throws declarations, validate exceptions (#2441) * use ClspGraph.isImplements to check base classes, some code improvements --------- Co-authored-by: Skylot <[email protected]>
1 parent fd6cb24 commit 8bbdbfc

15 files changed

+606
-4
lines changed

jadx-core/src/main/java/jadx/core/Consts.java

+2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public class Consts {
1616
public static final String CLASS_STRING = "java.lang.String";
1717
public static final String CLASS_CLASS = "java.lang.Class";
1818
public static final String CLASS_THROWABLE = "java.lang.Throwable";
19+
public static final String CLASS_ERROR = "java.lang.Error";
1920
public static final String CLASS_EXCEPTION = "java.lang.Exception";
21+
public static final String CLASS_RUNTIME_EXCEPTION = "java.lang.RuntimeException";
2022
public static final String CLASS_ENUM = "java.lang.Enum";
2123

2224
public static final String CLASS_STRING_BUILDER = "java.lang.StringBuilder";

jadx-core/src/main/java/jadx/core/Jadx.java

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import jadx.core.dex.visitors.InlineMethods;
3636
import jadx.core.dex.visitors.MarkMethodsForInline;
3737
import jadx.core.dex.visitors.MethodInvokeVisitor;
38+
import jadx.core.dex.visitors.MethodThrowsVisitor;
3839
import jadx.core.dex.visitors.MethodVisitor;
3940
import jadx.core.dex.visitors.ModVisitor;
4041
import jadx.core.dex.visitors.MoveInlineVisitor;
@@ -180,6 +181,8 @@ public static List<IDexTreeVisitor> getRegionsModePasses(JadxArgs args) {
180181
passes.add(new ReturnVisitor());
181182
passes.add(new CleanRegions());
182183

184+
passes.add(new MethodThrowsVisitor());
185+
183186
passes.add(new CodeShrinkVisitor());
184187
passes.add(new MethodInvokeVisitor());
185188
passes.add(new SimplifyVisitor());

jadx-core/src/main/java/jadx/core/dex/attributes/AType.java

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import jadx.core.dex.attributes.nodes.MethodInlineAttr;
2525
import jadx.core.dex.attributes.nodes.MethodOverrideAttr;
2626
import jadx.core.dex.attributes.nodes.MethodReplaceAttr;
27+
import jadx.core.dex.attributes.nodes.MethodThrowsAttr;
2728
import jadx.core.dex.attributes.nodes.MethodTypeVarsAttr;
2829
import jadx.core.dex.attributes.nodes.PhiListAttr;
2930
import jadx.core.dex.attributes.nodes.RegDebugInfoAttr;
@@ -76,6 +77,7 @@ public final class AType<T extends IJadxAttribute> implements IJadxAttrType<T> {
7677
public static final AType<MethodTypeVarsAttr> METHOD_TYPE_VARS = new AType<>();
7778
public static final AType<AttrList<TryCatchBlockAttr>> TRY_BLOCKS_LIST = new AType<>();
7879
public static final AType<CodeFeaturesAttr> METHOD_CODE_FEATURES = new AType<>();
80+
public static final AType<MethodThrowsAttr> METHOD_THROWS = new AType<>();
7981

8082
// region
8183
public static final AType<DeclareVariablesAttr> DECLARE_VARIABLES = new AType<>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package jadx.core.dex.attributes.nodes;
2+
3+
import java.util.Set;
4+
5+
import jadx.api.plugins.input.data.attributes.IJadxAttrType;
6+
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
7+
import jadx.core.dex.attributes.AType;
8+
9+
public class MethodThrowsAttr extends PinnedAttribute {
10+
private final Set<String> list;
11+
12+
private boolean visited;
13+
14+
public MethodThrowsAttr(Set<String> list) {
15+
this.list = list;
16+
}
17+
18+
public boolean isVisited() {
19+
return visited;
20+
}
21+
22+
public void setVisited(boolean visited) {
23+
this.visited = visited;
24+
}
25+
26+
public Set<String> getList() {
27+
return list;
28+
}
29+
30+
@Override
31+
public IJadxAttrType<MethodThrowsAttr> getAttrType() {
32+
return AType.METHOD_THROWS;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return "THROWS:" + list;
38+
}
39+
40+
}

jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java

+2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public abstract class ArgType {
3434
public static final ArgType STRING = objectNoCache(Consts.CLASS_STRING);
3535
public static final ArgType ENUM = objectNoCache(Consts.CLASS_ENUM);
3636
public static final ArgType THROWABLE = objectNoCache(Consts.CLASS_THROWABLE);
37+
public static final ArgType ERROR = objectNoCache(Consts.CLASS_ERROR);
3738
public static final ArgType EXCEPTION = objectNoCache(Consts.CLASS_EXCEPTION);
39+
public static final ArgType RUNTIME_EXCEPTION = objectNoCache(Consts.CLASS_RUNTIME_EXCEPTION);
3840
public static final ArgType OBJECT_ARRAY = array(OBJECT);
3941
public static final ArgType WILDCARD = wildcard();
4042

jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import jadx.core.dex.attributes.AType;
2727
import jadx.core.dex.attributes.nodes.LoopInfo;
2828
import jadx.core.dex.attributes.nodes.MethodOverrideAttr;
29+
import jadx.core.dex.attributes.nodes.MethodThrowsAttr;
2930
import jadx.core.dex.attributes.nodes.NotificationAttrNode;
3031
import jadx.core.dex.info.AccessInfo;
3132
import jadx.core.dex.info.AccessInfo.AFType;
@@ -477,11 +478,15 @@ public int getExceptionHandlersCount() {
477478

478479
@Override
479480
public List<ArgType> getThrows() {
481+
MethodThrowsAttr throwsAttr = get(AType.METHOD_THROWS);
482+
if (throwsAttr != null) {
483+
return Utils.collectionMap(throwsAttr.getList(), ArgType::object);
484+
}
480485
ExceptionsAttr exceptionsAttr = get(JadxAttrType.EXCEPTIONS);
481-
if (exceptionsAttr == null) {
482-
return Collections.emptyList();
486+
if (exceptionsAttr != null) {
487+
return Utils.collectionMap(exceptionsAttr.getList(), ArgType::object);
483488
}
484-
return Utils.collectionMap(exceptionsAttr.getList(), ArgType::object);
489+
return Collections.emptyList();
485490
}
486491

487492
/**

0 commit comments

Comments
 (0)