提交 06f26ef8 编写于 作者: S Skylot

refactor: use enum for wildcard bounds instead of int

上级 a71bb7a5
...@@ -274,9 +274,9 @@ public class ClsSet { ...@@ -274,9 +274,9 @@ public class ClsSet {
private static void writeArgType(DataOutputStream out, ArgType argType, Map<String, NClass> names) throws IOException { private static void writeArgType(DataOutputStream out, ArgType argType, Map<String, NClass> names) throws IOException {
if (argType.getWildcardType() != null) { if (argType.getWildcardType() != null) {
out.writeByte(TypeEnum.WILDCARD.ordinal()); out.writeByte(TypeEnum.WILDCARD.ordinal());
int bounds = argType.getWildcardBounds(); ArgType.WildcardBound bound = argType.getWildcardBound();
out.writeByte(bounds); out.writeByte(bound.getNum());
if (bounds != 0) { if (bound != ArgType.WildcardBound.UNBOUND) {
writeArgType(out, argType.getWildcardType(), names); writeArgType(out, argType.getWildcardType(), names);
} }
} else if (argType.isGeneric()) { } else if (argType.isGeneric()) {
...@@ -415,7 +415,7 @@ public class ClsSet { ...@@ -415,7 +415,7 @@ public class ClsSet {
int bounds = in.readByte(); int bounds = in.readByte();
return bounds == 0 return bounds == 0
? ArgType.wildcard() ? ArgType.wildcard()
: ArgType.wildcard(readArgType(in), bounds); : ArgType.wildcard(readArgType(in), ArgType.WildcardBound.getByNum(bounds));
case GENERIC: case GENERIC:
String obj = classes[in.readInt()].getName(); String obj = classes[in.readInt()].getName();
......
...@@ -470,10 +470,9 @@ public class ClassGen { ...@@ -470,10 +470,9 @@ public class ClassGen {
ArgType gt = generics[i]; ArgType gt = generics[i];
ArgType wt = gt.getWildcardType(); ArgType wt = gt.getWildcardType();
if (wt != null) { if (wt != null) {
code.add('?'); ArgType.WildcardBound bound = gt.getWildcardBound();
int bounds = gt.getWildcardBounds(); code.add(bound.getStr());
if (bounds != 0) { if (bound != ArgType.WildcardBound.UNBOUND) {
code.add(bounds == -1 ? " super " : " extends ");
useType(code, wt); useType(code, wt);
} }
} else { } else {
......
...@@ -74,14 +74,14 @@ public abstract class ArgType { ...@@ -74,14 +74,14 @@ public abstract class ArgType {
} }
public static ArgType wildcard() { public static ArgType wildcard() {
return new WildcardType(OBJECT, 0); return new WildcardType(OBJECT, WildcardBound.UNBOUND);
} }
public static ArgType wildcard(ArgType obj, int bounds) { public static ArgType wildcard(ArgType obj, WildcardBound bound) {
return new WildcardType(obj, bounds); return new WildcardType(obj, bound);
} }
public static ArgType generic(String sign) { public static ArgType parseGenericSignature(String sign) {
return new SignatureParser(sign).consumeType(); return new SignatureParser(sign).consumeType();
} }
...@@ -212,14 +212,40 @@ public abstract class ArgType { ...@@ -212,14 +212,40 @@ public abstract class ArgType {
} }
} }
public enum WildcardBound {
EXTENDS(1, "? extends "), // upper bound (? extends A)
UNBOUND(0, "?"), // no bounds (?)
SUPER(-1, "? super "); // lower bound (? super A)
private final int num;
private final String str;
WildcardBound(int val, String str) {
this.num = val;
this.str = str;
}
public int getNum() {
return num;
}
public String getStr() {
return str;
}
public static WildcardBound getByNum(int num) {
return num == 0 ? UNBOUND : (num == 1 ? EXTENDS : SUPER);
}
}
private static final class WildcardType extends ObjectType { private static final class WildcardType extends ObjectType {
private final ArgType type; private final ArgType type;
private final int bounds; private final WildcardBound bound;
public WildcardType(ArgType obj, int bounds) { public WildcardType(ArgType obj, WildcardBound bound) {
super(OBJECT.getObject()); super(OBJECT.getObject());
this.type = obj; this.type = obj;
this.bounds = bounds; this.bound = bound;
} }
@Override @Override
...@@ -232,32 +258,24 @@ public abstract class ArgType { ...@@ -232,32 +258,24 @@ public abstract class ArgType {
return type; return type;
} }
/**
* Return wildcard bounds:
* <ul>
* <li>1 for upper bound (? extends A)</li>
* <li>0 no bounds (?)</li>
* <li>-1 for lower bound (? super A)</li>
* </ul>
*/
@Override @Override
public int getWildcardBounds() { public WildcardBound getWildcardBound() {
return bounds; return bound;
} }
@Override @Override
boolean internalEquals(Object obj) { boolean internalEquals(Object obj) {
return super.internalEquals(obj) return super.internalEquals(obj)
&& bounds == ((WildcardType) obj).bounds && bound == ((WildcardType) obj).bound
&& type.equals(((WildcardType) obj).type); && type.equals(((WildcardType) obj).type);
} }
@Override @Override
public String toString() { public String toString() {
if (bounds == 0) { if (bound == WildcardBound.UNBOUND) {
return "?"; return bound.getStr();
} }
return "? " + (bounds == -1 ? "super" : "extends") + ' ' + type; return bound.getStr() + type;
} }
} }
...@@ -468,11 +486,8 @@ public abstract class ArgType { ...@@ -468,11 +486,8 @@ public abstract class ArgType {
return null; return null;
} }
/** public WildcardBound getWildcardBound() {
* @see WildcardType#getWildcardBounds() return null;
*/
public int getWildcardBounds() {
return 0;
} }
public ArgType getOuterType() { public ArgType getOuterType() {
...@@ -629,6 +644,10 @@ public abstract class ArgType { ...@@ -629,6 +644,10 @@ public abstract class ArgType {
if (isGenericType()) { if (isGenericType()) {
return true; return true;
} }
ArgType wildcardType = getWildcardType();
if (wildcardType != null) {
return wildcardType.containsGenericType();
}
if (isGeneric()) { if (isGeneric()) {
ArgType[] genericTypes = getGenericTypes(); ArgType[] genericTypes = getGenericTypes();
if (genericTypes != null) { if (genericTypes != null) {
...@@ -662,7 +681,7 @@ public abstract class ArgType { ...@@ -662,7 +681,7 @@ public abstract class ArgType {
return new GenericObject(aliasFullName, type.getGenericTypes()); return new GenericObject(aliasFullName, type.getGenericTypes());
} }
if (type instanceof WildcardType) { if (type instanceof WildcardType) {
return new WildcardType(ArgType.object(aliasFullName), type.getWildcardBounds()); return new WildcardType(ArgType.object(aliasFullName), type.getWildcardBound());
} }
} }
return ArgType.object(aliasFullName); return ArgType.object(aliasFullName);
......
...@@ -38,7 +38,8 @@ public class SignatureParser { ...@@ -38,7 +38,8 @@ public class SignatureParser {
if (a == null) { if (a == null) {
return null; return null;
} }
return new SignatureParser(mergeSignature((List<String>) a.getDefaultValue())); String signature = mergeSignature((List<String>) a.getDefaultValue());
return new SignatureParser(signature);
} }
private char next() { private char next() {
...@@ -200,10 +201,10 @@ public class SignatureParser { ...@@ -200,10 +201,10 @@ public class SignatureParser {
type = ArgType.wildcard(); type = ArgType.wildcard();
} else if (lookAhead('+')) { } else if (lookAhead('+')) {
next(); next();
type = ArgType.wildcard(consumeType(), 1); type = ArgType.wildcard(consumeType(), ArgType.WildcardBound.EXTENDS);
} else if (lookAhead('-')) { } else if (lookAhead('-')) {
next(); next();
type = ArgType.wildcard(consumeType(), -1); type = ArgType.wildcard(consumeType(), ArgType.WildcardBound.SUPER);
} else { } else {
type = consumeType(); type = consumeType();
} }
......
...@@ -31,7 +31,7 @@ public final class LocalVar { ...@@ -31,7 +31,7 @@ public final class LocalVar {
this.name = name; this.name = name;
if (sign != null) { if (sign != null) {
try { try {
ArgType gType = ArgType.generic(sign); ArgType gType = ArgType.parseGenericSignature(sign);
if (checkSignature(type, gType)) { if (checkSignature(type, gType)) {
type = gType; type = gType;
} }
......
...@@ -327,7 +327,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor ...@@ -327,7 +327,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
} }
ArgType wildcardType = gType.getWildcardType(); ArgType wildcardType = gType.getWildcardType();
if (wildcardType != null if (wildcardType != null
&& gType.getWildcardBounds() == 1 && gType.getWildcardBound() == ArgType.WildcardBound.EXTENDS
&& ArgType.isInstanceOf(mth.root(), wildcardType, varType)) { && ArgType.isInstanceOf(mth.root(), wildcardType, varType)) {
return true; return true;
} }
......
...@@ -3,6 +3,7 @@ package jadx.core.dex.instructions.args; ...@@ -3,6 +3,7 @@ package jadx.core.dex.instructions.args;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ArgTypeTest { class ArgTypeTest {
...@@ -13,4 +14,14 @@ class ArgTypeTest { ...@@ -13,4 +14,14 @@ class ArgTypeTest {
assertEquals(first, second); assertEquals(first, second);
} }
@Test
void testContainsGenericType() {
ArgType wildcard = ArgType.wildcard(ArgType.genericType("T"), ArgType.WildcardBound.SUPER);
assertTrue(wildcard.containsGenericType());
ArgType type = ArgType.generic("java.lang.List", wildcard);
assertTrue(type.containsGenericType());
}
} }
...@@ -6,6 +6,7 @@ import java.util.List; ...@@ -6,6 +6,7 @@ import java.util.List;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.ArgType.WildcardBound;
import jadx.core.dex.nodes.GenericInfo; import jadx.core.dex.nodes.GenericInfo;
import jadx.core.dex.nodes.parser.SignatureParser; import jadx.core.dex.nodes.parser.SignatureParser;
...@@ -60,10 +61,10 @@ class SignatureParserTest { ...@@ -60,10 +61,10 @@ class SignatureParserTest {
@Test @Test
public void testWildcards() { public void testWildcards() {
checkWildcards("*", wildcard()); checkWildcards("*", wildcard());
checkWildcards("+Lb;", wildcard(object("b"), 1)); checkWildcards("+Lb;", wildcard(object("b"), WildcardBound.EXTENDS));
checkWildcards("-Lb;", wildcard(object("b"), -1)); checkWildcards("-Lb;", wildcard(object("b"), WildcardBound.SUPER));
checkWildcards("+TV;", wildcard(genericType("V"), 1)); checkWildcards("+TV;", wildcard(genericType("V"), WildcardBound.EXTENDS));
checkWildcards("-TV;", wildcard(genericType("V"), -1)); checkWildcards("-TV;", wildcard(genericType("V"), WildcardBound.SUPER));
checkWildcards("**", wildcard(), wildcard()); checkWildcards("**", wildcard(), wildcard());
checkWildcards("*Lb;", wildcard(), object("b")); checkWildcards("*Lb;", wildcard(), object("b"));
...@@ -116,7 +117,7 @@ class SignatureParserTest { ...@@ -116,7 +117,7 @@ class SignatureParserTest {
assertThat(argTypes, hasSize(1)); assertThat(argTypes, hasSize(1));
ArgType argType = argTypes.get(0); ArgType argType = argTypes.get(0);
assertThat(argType.getObject().indexOf('/'), is(-1)); assertThat(argType.getObject().indexOf('/'), is(-1));
assertThat(argType, is(genericInner(generic("La/b/C;", genericType("T")), "d.E", (ArgType[]) null))); assertThat(argType, is(genericInner(generic("La/b/C;", genericType("T")), "d.E", null)));
} }
@Test @Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册