Created
October 25, 2022 16:37
-
-
Save nfalliere/f484a7df0d306656da1d4fbf1261bb23 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
letterToPrim = { | |
'Z': 'boolean', | |
'B': 'byte', | |
'C': 'char', | |
'S': 'short', | |
'I': 'int', | |
'J': 'long', | |
'F': 'float', | |
'D': 'double', | |
} | |
# s: type signature of a class or interface type, e.g. Lcom/foo/Bar; | |
def getSimpleType(s): | |
assert len(s) >= 3 | |
assert s[0] == 'L' and s[-1] == ';' | |
pos = s.rfind('/') | |
if pos < 0: pos = 0 | |
s = s[pos + 1:-1] | |
return s | |
# s: string of appended internal type signatures, e.g. IJ[B[[DLjava/lang/String;[LFoo; | |
def parseTypes(s, allowVoid=False): | |
types = [] | |
i = 0 | |
dimcnt = 0 | |
while i < len(s): | |
ch = s[i] | |
if ch == '[': | |
dimcnt += 1 | |
i += 1 | |
continue | |
if ch == 'L': | |
pos = s.find(';', i) | |
t = s[i:pos+1] | |
t = getSimpleType(t) | |
i = pos + 1 | |
elif ch == 'V': | |
if not allowVoid: raise Exception() | |
t = 'void' | |
i += 1 | |
else: | |
t = letterToPrim.get(ch) | |
if not t: raise Exception() | |
i += 1 | |
if dimcnt != 0: | |
t += ('[]' * dimcnt) | |
dimcnt = 0 | |
types.append(t) | |
return types | |
# s: full method internal signature, e.g. LA/B/C;->func1(IJ[B[[DLjava/lang/String;[LFoo;)V | |
# will return a user-friendly string consisting of the method name and arguments and return types | |
def generateUserFriendlyMethodSignature(s): | |
pos = s.find('->') | |
p0, p1 = s[:pos], s[pos+2:] | |
pos = p1.find('(') | |
mname = p1[:pos] | |
pos2 = p1.find(')', pos) | |
_argtypes = p1[pos+1:pos2] | |
_rettype = p1[pos2+1:] | |
argtypes = parseTypes(_argtypes, False) | |
rettype = parseTypes(_rettype, True)[0] | |
r = '%s %s(%s)' % (rettype, mname, ', '.join(argtypes)) | |
return r | |
# simple test case | |
if __name__ == '__main__': | |
s = 'LA/B/C;->func1(IJ[B[[DLjava/lang/String;[LFoo;)V' | |
print('%s => %s' % (s, generateUserFriendlyMethodSignature(s))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment