Commit 9c90699c authored by Skylot's avatar Skylot

core: fix parsing of generic signature with inner classes

parent b67cd50e
......@@ -6,7 +6,6 @@ import jadx.core.dex.attributes.annotations.Annotation;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
......@@ -159,7 +158,13 @@ public class SignatureParser {
} while (ch != '<' && ch != ';');
if (ch == ';') {
return ArgType.object(incompleteType ? slice() : inclusiveSlice());
String obj;
if (incompleteType) {
obj = slice().replace('/', '.');
} else {
obj = inclusiveSlice();
}
return ArgType.object(obj);
} else {
// generic type start ('<')
String obj = slice();
......@@ -184,7 +189,7 @@ public class SignatureParser {
}
private ArgType[] consumeGenericArgs() {
List<ArgType> list = new ArrayList<ArgType>(1);
List<ArgType> list = new LinkedList<ArgType>();
ArgType type;
do {
if (lookAhead('*')) {
......
......@@ -16,9 +16,8 @@ public class Utils {
int last = obj.length() - 1;
if (obj.charAt(0) == 'L' && obj.charAt(last) == ';') {
return obj.substring(1, last).replace('/', '.');
} else {
return obj;
}
return obj;
}
public static String makeQualifiedObjectName(String obj) {
......
......@@ -26,12 +26,14 @@ class TestSignatureParser extends Specification {
new SignatureParser(str).consumeType() == result
where:
str | result
"TD;" | genericType("D")
"La<TV;Lb;>;" | generic("La;", genericType("V"), object("b"))
"La<Lb<Lc;>;>;" | generic("La;", generic("Lb;", object("Lc;")))
"La<TD;>.c;" | genericInner(generic("La;", genericType("D")), "c", null)
"La<Lb;>.c<TV;>;" | genericInner(generic("La;", object("Lb;")), "c", genericType("V"))
str | result
"TD;" | genericType("D")
"La<TV;Lb;>;" | generic("La;", genericType("V"), object("b"))
"La<Lb<Lc;>;>;" | generic("La;", generic("Lb;", object("Lc;")))
"La/b/C<Ld/E<Lf/G;>;>;" | generic("La/b/C;", generic("Ld/E;", object("Lf/G;")))
"La<TD;>.c;" | genericInner(generic("La;", genericType("D")), "c", null)
"La<TD;>.c/d;" | genericInner(generic("La;", genericType("D")), "c.d", null)
"La<Lb;>.c<TV;>;" | genericInner(generic("La;", object("Lb;")), "c", genericType("V"))
}
def "inner generic"() {
......@@ -85,6 +87,16 @@ class TestSignatureParser extends Specification {
argTypes.get(0) == generic("Ljava/util/List;", wildcard())
}
def "method args 2"() {
when:
def argTypes = new SignatureParser("(La/b/C<TT;>.d/E;)V").consumeMethodArgs()
then:
argTypes.size() == 1
def argType = argTypes.get(0)
argType.getObject().indexOf('/') == -1
argTypes.get(0) == genericInner(generic("La/b/C;", genericType("T")), "d.E", null)
}
def "generic map: bad signature"() {
when:
def map = new SignatureParser("<A:Ljava/lang/Object;B").consumeGenericMap()
......
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