Source code for jawa.util.descriptor

"""
Methods for parsing standard JVM type descriptors for fields and methods.
"""
from collections import namedtuple


JVMType = namedtuple('JVMType', [
    'base_type',
    'dimensions',
    'name'
])

MethodDescriptor = namedtuple('MethodDescriptor', [
    'returns',
    'args',
    'returns_descriptor',
    'args_descriptor',
    'descriptor'
])


[docs]def method_descriptor(descriptor: str) -> MethodDescriptor: """ Parses a Method descriptor as described in section 4.3.3 of the JVM specification. """ end_para = descriptor.find(')') returns = descriptor[end_para + 1:] args = descriptor[1:end_para] return MethodDescriptor( parse_descriptor(returns)[0], parse_descriptor(args), returns, args, descriptor )
[docs]def field_descriptor(descriptor: str) -> str: """ Parses a Field descriptor as described in section 4.3.2 of the JVM specification. """ return parse_descriptor(descriptor)[0]
# JVM Descriptor "BaseType" characters to their # full simple type. _HUMAN_NAMES = { 'L': 'reference', 'B': 'byte', 'C': 'char', 'D': 'double', 'F': 'float', 'I': 'int', 'J': 'long', 'S': 'short', 'Z': 'boolean', 'V': 'void' }
[docs]def parse_descriptor(descriptor: str) -> list: """ Uses a tiny state machine to parse JVM descriptors. To get useful wrappers around the results, use :py:func:`jawa.core.descriptor.method_descriptor` or :py:func:`jawa.core.descriptor.field_descriptor`. """ # States: # 10 == NORMAL, # 20 == OBJECT REFERENCE state = 10 tokens = [] token = [] dimensions = 0 for char in descriptor: if state == 10 and char == 'L': state = 20 elif state == 10 and char == '[': dimensions += 1 elif state == 10: tokens.append(JVMType(char, dimensions, _HUMAN_NAMES[char])) dimensions = 0 elif state == 20 and char == ';': tokens.append(JVMType('L', dimensions, ''.join(token))) dimensions = 0 state = 10 del token[:] elif state == 20: token.append(char) return tokens