Skip to content

Instantly share code, notes, and snippets.

@nfalliere
Created October 25, 2022 16:37
Show Gist options
  • Save nfalliere/f484a7df0d306656da1d4fbf1261bb23 to your computer and use it in GitHub Desktop.
Save nfalliere/f484a7df0d306656da1d4fbf1261bb23 to your computer and use it in GitHub Desktop.
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