X Tutup
import sys import subprocess def parse_signature(java, jni): if not jni.startswith(' Signature: '): print 'invalid signature' return jni = jni[13:] javas = java.split() if javas[0] in ('public', 'private', 'protected'): javas.pop(0) is_static = False if javas[0] == 'static': javas.pop(0) is_static = True if jni[0] == '(': if javas[0][0] == '{': return if javas[0] in ('public', 'private', 'protected'): javas.pop(0) # method if '(' in javas[0]: # constructor return ('constructor', '', jni) else: javas.pop(0) name = javas[0].split('(')[0] if is_static: return ('staticmethod', name, jni) return ('method', name, jni) else: # field if javas[0] in ('public', 'private', 'protected'): javas.pop(0) name = javas[1].split(';')[0] if is_static: return ('staticfield', name, jni) return ('field', name, jni) def parse(filename): cmd = subprocess.Popen(['javap', '-s', filename], stdout=subprocess.PIPE) stdout = cmd.communicate()[0] lines = stdout.splitlines()[1:] line = lines.pop(0) if not line.startswith('public class') and not line.startswith('class'): print '-> not a public class, exit.' return [] javaclass = line[13:].split('{')[0].split(' ')[0] pythonclass = javaclass.rsplit('.')[-1] members = [] while len(lines) > 2: javasignature = lines.pop(0) jnisignature = lines.pop(0) member = parse_signature(javasignature, jnisignature) if member is None: continue members.append(member) return (javaclass, pythonclass, members) def generate(defs): javaclass, pythonclass, members = defs output = ''' from java import MetaJavaClass, JavaClass, JavaMethod, \\ JavaStaticMethod, JavaField, JavaStaticField class {0!r}(JavaClass): __metaclass__ = MetaJavaClass __javaclass__ = '{1!r}' '''.format(pythonclass, javaclass) pyclasses = { 'method': 'JavaMethod', 'staticmethod': 'JavaStaticMethod', 'field': 'JavaField', 'staticfield': 'JavaStaticField' } for member in members: tp, name, sig = member if tp == 'constructor': output += ' __javaconstructor__ = {0!r}\n'.format(sig) continue cls = pyclasses[tp] output += ' {0} = {1}({2!r})\n'.format(name, cls, sig) return output if __name__ == '__main__': filename = sys.argv[1] if filename.endswith('.class'): filename = filename[:-6] print generate(parse(filename))
X Tutup