# Path: javadecompiler/Krakatau/classfile.py
# class ClassFile(object):
#     flagVals = {'PUBLIC':0x0001,
#                 'FINAL':0x0010,
#                 'SUPER':0x0020,
#                 'INTERFACE':0x0200,
#                 'ABSTRACT':0x0400,
#                 'SYNTHETIC':0x1000,
#                 'ANNOTATION':0x2000,
#                 'ENUM':0x4000,
# 
#                 # These flags are only used for InnerClasses attributes
#                 'PRIVATE':0x0002,
#                 'PROTECTED':0x0004,
#                 'STATIC':0x0008,
#                 }
# 
#     def __init__(self, bytestream):
#         magic, minor, major = bytestream.get('>LHH')
#         assert(magic == 0xCAFEBABE)
#         self.version = major,minor
# 
#         const_pool_raw = get_cp_raw(bytestream)
#         flags, self.this, self.super = bytestream.get('>HHH')
# 
#         interface_count = bytestream.get('>H')
#         self.interfaces_raw = [bytestream.get('>H') for _ in range(interface_count)]
# 
#         self.fields_raw = get_fields_raw(bytestream)
#         self.methods_raw = get_methods_raw(bytestream)
# 
#         ic_indices = [i for i,x in enumerate(const_pool_raw) if x == (1, ("InnerClasses",))]
#         self.attributes_raw = get_attributes_raw(bytestream, ic_indices)
#         assert(bytestream.size() == 0)
# 
#         self.flags = set(name for name,mask in ClassFile.flagVals.items() if (mask & flags))
#         self.cpool = constant_pool.ConstPool(const_pool_raw)
#         self.name = self.cpool.getArgsCheck('Class', self.this)
#         self.elementsLoaded = False
# 
#         self.env = self.supername = self.hierarchy = None
#         self.fields = self.methods = self.attributes = None
# 
#     def loadSupers(self, env, name, subclasses):
#         self.env = env
#         assert(self.name == name)
# 
#         if self.super:
#             self.supername = self.cpool.getArgsCheck('Class', self.super)
#             # if superclass is cached, we can assume it is free from circular inheritance
#             # since it must have been loaded successfully on a previous run
#             if not self.env.isCached(self.supername):
#                 self.env.getClass(self.supername, subclasses + (name,), partial=True)
#             self.hierarchy = self.env.getSupers(self.supername) + (self.name,)
#         else:
#             assert(name == 'java/lang/Object')
#             self.supername = None
#             self.hierarchy = (self.name,)
# 
#     def loadElements(self, keepRaw=False):
#         if self.elementsLoaded:
#             return
#         self.fields = [field.Field(m, self, keepRaw) for m in self.fields_raw]
#         self.methods = [method.Method(m, self, keepRaw) for m in self.methods_raw]
#         self.attributes = fixAttributeNames(self.attributes_raw, self.cpool)
# 
#         self.fields_raw = self.methods_raw = None
#         if not keepRaw:
#             self.attributes_raw = None
#         self.elementsLoaded = True
# 
#     def getSuperclassHierarchy(self):
#         return self.hierarchy
# 
# Path: javadecompiler/Krakatau/assembler/assembler.py
# class PoolRef(object):
#     def __init__(self, *args, **kwargs):
#         self.index = kwargs.get('index')
#         self.lbl = kwargs.get('lbl')
#         self.args = args
# 
#     def toIndex(self, pool, forbidden=(), **kwargs):
#         if self.index is not None:
#             return self.index
#         if self.lbl:
#             self.index = pool.getLabel(self.lbl, forbidden, **kwargs)
#         else:
#             self.args = [(x.toIndex(pool) if isinstance(x, PoolRef) else x) for x in self.args]
#             self.index = pool.getItem(*self.args, **kwargs)
#         return self.index


import ast, struct
import itertools
    import inspect
from ..classfile import ClassFile
from ..method import Method
from ..field import Field
from .tokenize import tokens, wordget, flags
from .assembler import PoolRef
from .codes import handle_codes
from .codes import newarr_codes
from .codes import et_tags
    from ply import yacc
    from ply import yacc

def p_imethod_notref(p):
    '''interfacemethod_notref : classref nameandtyperef'''
    p[0] = PoolRef('InterfaceMethod', p[1], p[2])

#constant pool types related to InvokeDynamic handled later

for _name in ('utf8','class', 'nameandtype', 'method', 'interfacemethod', 'methodhandle'):
    addRule(assign1, '{}ref'.format(_name), '{}_notref'.format(_name), 'ref')

###############################################################################
def p_classnoend(p):
    '''classnoend : version_opt class_directive_lines classdec superdec interfacedecs class_directive_lines topitems'''
    p[0] = tuple(p[1:])

addRule(assign1, 'classwithend', 'classnoend D_END CLASS sep')
listRule('classwithend')

def p_top(p):
    '''top : sep classwithends classnoend'''
    p[0] = p[2] + [p[3]]
#case where all classes have an end
addRule(assign2, 'top', 'sep classwithends')

def p_version(p):
    '''version_opt : D_VERSION intl intl sep'''
    p[0] = p[2], p[3]
addRule(assign1, 'version_opt', 'empty')

###############################################################################

# Path: javadecompiler/Krakatau/classfile.py
# class ClassFile(object):
#     flagVals = {'PUBLIC':0x0001,
#                 'FINAL':0x0010,
#                 'SUPER':0x0020,
#                 'INTERFACE':0x0200,
#                 'ABSTRACT':0x0400,
#                 'SYNTHETIC':0x1000,
#                 'ANNOTATION':0x2000,
#                 'ENUM':0x4000,
# 
#                 # These flags are only used for InnerClasses attributes
#                 'PRIVATE':0x0002,
#                 'PROTECTED':0x0004,
#                 'STATIC':0x0008,
#                 }
# 
#     def __init__(self, bytestream):
#         magic, minor, major = bytestream.get('>LHH')
#         assert(magic == 0xCAFEBABE)
#         self.version = major,minor
# 
#         const_pool_raw = get_cp_raw(bytestream)
#         flags, self.this, self.super = bytestream.get('>HHH')
# 
#         interface_count = bytestream.get('>H')
#         self.interfaces_raw = [bytestream.get('>H') for _ in range(interface_count)]
# 
#         self.fields_raw = get_fields_raw(bytestream)
#         self.methods_raw = get_methods_raw(bytestream)
# 
#         ic_indices = [i for i,x in enumerate(const_pool_raw) if x == (1, ("InnerClasses",))]
#         self.attributes_raw = get_attributes_raw(bytestream, ic_indices)
#         assert(bytestream.size() == 0)
# 
#         self.flags = set(name for name,mask in ClassFile.flagVals.items() if (mask & flags))
#         self.cpool = constant_pool.ConstPool(const_pool_raw)
#         self.name = self.cpool.getArgsCheck('Class', self.this)
#         self.elementsLoaded = False
# 
#         self.env = self.supername = self.hierarchy = None
#         self.fields = self.methods = self.attributes = None
# 
#     def loadSupers(self, env, name, subclasses):
#         self.env = env
#         assert(self.name == name)
# 
#         if self.super:
#             self.supername = self.cpool.getArgsCheck('Class', self.super)
#             # if superclass is cached, we can assume it is free from circular inheritance
#             # since it must have been loaded successfully on a previous run
#             if not self.env.isCached(self.supername):
#                 self.env.getClass(self.supername, subclasses + (name,), partial=True)
#             self.hierarchy = self.env.getSupers(self.supername) + (self.name,)
#         else:
#             assert(name == 'java/lang/Object')
#             self.supername = None
#             self.hierarchy = (self.name,)
# 
#     def loadElements(self, keepRaw=False):
#         if self.elementsLoaded:
#             return
#         self.fields = [field.Field(m, self, keepRaw) for m in self.fields_raw]
#         self.methods = [method.Method(m, self, keepRaw) for m in self.methods_raw]
#         self.attributes = fixAttributeNames(self.attributes_raw, self.cpool)
# 
#         self.fields_raw = self.methods_raw = None
#         if not keepRaw:
#             self.attributes_raw = None
#         self.elementsLoaded = True
# 
#     def getSuperclassHierarchy(self):
#         return self.hierarchy
# 
# Path: javadecompiler/Krakatau/assembler/assembler.py
# class PoolRef(object):
#     def __init__(self, *args, **kwargs):
#         self.index = kwargs.get('index')
#         self.lbl = kwargs.get('lbl')
#         self.args = args
# 
#     def toIndex(self, pool, forbidden=(), **kwargs):
#         if self.index is not None:
#             return self.index
#         if self.lbl:
#             self.index = pool.getLabel(self.lbl, forbidden, **kwargs)
#         else:
#             self.args = [(x.toIndex(pool) if isinstance(x, PoolRef) else x) for x in self.args]
#             self.index = pool.getItem(*self.args, **kwargs)
#         return self.index


# Path: javadecompiler/Krakatau/assembler/parse.py
import ast, struct
import itertools
    import inspect
from ..classfile import ClassFile
from ..method import Method
from ..field import Field
from .tokenize import tokens, wordget, flags
from .assembler import PoolRef
from .codes import handle_codes
from .codes import newarr_codes
from .codes import et_tags
    from ply import yacc
    from ply import yacc


def p_imethod_notref(p):
    '''interfacemethod_notref : classref nameandtyperef'''
    p[0] = PoolRef('InterfaceMethod', p[1], p[2])

#constant pool types related to InvokeDynamic handled later

for _name in ('utf8','class', 'nameandtype', 'method', 'interfacemethod', 'methodhandle'):
    addRule(assign1, '{}ref'.format(_name), '{}_notref'.format(_name), 'ref')

###############################################################################
def p_classnoend(p):
    '''classnoend : version_opt class_directive_lines classdec superdec interfacedecs class_directive_lines topitems'''
    p[0] = tuple(p[1:])

addRule(assign1, 'classwithend', 'classnoend D_END CLASS sep')
listRule('classwithend')

def p_top(p):
    '''top : sep classwithends classnoend'''
    p[0] = p[2] + [p[3]]
#case where all classes have an end
addRule(assign2, 'top', 'sep classwithends')

def p_version(p):
    '''version_opt : D_VERSION intl intl sep'''
    p[0] = p[2], p[3]
addRule(assign1, 'version_opt', 'empty')

###############################################################################

for c, type_ in zip('cmf', (ClassFile, Method, Field)):