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

refactor: use enum for wildcard bounds instead of int

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