javaclass

Change of classfile.py

2:928489775f5d
classfile.py
     1.1 --- a/classfile.py	Sat Oct 23 21:34:47 2004 +0200
     1.2 +++ b/classfile.py	Mon Oct 25 20:53:58 2004 +0200
     1.3 @@ -18,16 +18,28 @@
     1.4  def u4(data):
     1.5      return struct.unpack(">L", data[0:4])[0]
     1.6  
     1.7 +# Useful mix-ins.
     1.8 +
     1.9 +class NameUtils:
    1.10 +    def get_name(self):
    1.11 +        if self.name_index != 0:
    1.12 +            return unicode(self.class_file.constants[self.name_index - 1])
    1.13 +        else:
    1.14 +            # Some name indexes are zero to indicate special conditions.
    1.15 +            return None
    1.16 +
    1.17  # Constant information.
    1.18  # Objects of these classes are not directly aware of the class they reside in.
    1.19  
    1.20 -class ClassInfo:
    1.21 -    def init(self, data):
    1.22 +class ClassInfo(NameUtils):
    1.23 +    def init(self, data, class_file):
    1.24 +        self.class_file = class_file
    1.25          self.name_index = u2(data[0:2])
    1.26          return data[2:]
    1.27  
    1.28  class RefInfo:
    1.29 -    def init(self, data):
    1.30 +    def init(self, data, class_file):
    1.31 +        self.class_file = class_file
    1.32          self.class_index = u2(data[0:2])
    1.33          self.name_and_type_index = u2(data[2:4])
    1.34          return data[4:]
    1.35 @@ -41,14 +53,16 @@
    1.36  class InterfaceMethodRefInfo(RefInfo):
    1.37      pass
    1.38  
    1.39 -class NameAndTypeInfo:
    1.40 -    def init(self, data):
    1.41 +class NameAndTypeInfo(NameUtils):
    1.42 +    def init(self, data, class_file):
    1.43 +        self.class_file = class_file
    1.44          self.name_index = u2(data[0:2])
    1.45          self.descriptor_index = u2(data[2:4])
    1.46          return data[4:]
    1.47  
    1.48  class Utf8Info:
    1.49 -    def init(self, data):
    1.50 +    def init(self, data, class_file):
    1.51 +        self.class_file = class_file
    1.52          self.length = u2(data[0:2])
    1.53          self.bytes = data[2:2+self.length]
    1.54          return data[2+self.length:]
    1.55 @@ -60,12 +74,14 @@
    1.56          return unicode(self.bytes, "utf-8")
    1.57  
    1.58  class StringInfo:
    1.59 -    def init(self, data):
    1.60 +    def init(self, data, class_file):
    1.61 +        self.class_file = class_file
    1.62          self.string_index = u2(data[0:2])
    1.63          return data[2:]
    1.64  
    1.65  class SmallNumInfo:
    1.66 -    def init(self, data):
    1.67 +    def init(self, data, class_file):
    1.68 +        self.class_file = class_file
    1.69          self.bytes = u4(data[0:4])
    1.70          return data[4:]
    1.71  
    1.72 @@ -76,7 +92,8 @@
    1.73      pass
    1.74  
    1.75  class LargeNumInfo:
    1.76 -    def init(self, data):
    1.77 +    def init(self, data, class_file):
    1.78 +        self.class_file = class_file
    1.79          self.high_bytes = u4(data[0:4])
    1.80          self.low_bytes = u4(data[4:8])
    1.81          return data[8:]
    1.82 @@ -90,7 +107,7 @@
    1.83  # Other information.
    1.84  # Objects of these classes are generally aware of the class they reside in.
    1.85  
    1.86 -class ItemInfo:
    1.87 +class ItemInfo(NameUtils):
    1.88      def init(self, data, class_file):
    1.89          self.class_file = class_file
    1.90          self.access_flags = u2(data[0:2])
    1.91 @@ -153,11 +170,6 @@
    1.92          else:
    1.93              return None, s
    1.94  
    1.95 -    # Processed details.
    1.96 -
    1.97 -    def get_name(self):
    1.98 -        return unicode(self.class_file.constants[self.name_index - 1])
    1.99 -
   1.100  class FieldInfo(ItemInfo):
   1.101      def get_descriptor(self):
   1.102          return self._get_field_descriptor(unicode(self.class_file.constants[self.descriptor_index - 1]))
   1.103 @@ -174,8 +186,12 @@
   1.104  
   1.105  # NOTE: Decode the different attribute formats.
   1.106  
   1.107 -class SourceFileAttributeInfo(AttributeInfo):
   1.108 -    pass
   1.109 +class SourceFileAttributeInfo(AttributeInfo, NameUtils):
   1.110 +    def init(self, data, class_file):
   1.111 +        self.class_file = class_file
   1.112 +        self.attribute_length = u4(data[0:4])
   1.113 +        # Permit the NameUtils mix-in.
   1.114 +        self.name_index = self.sourcefile_index = u2(data[4:6])
   1.115  
   1.116  class ConstantValueAttributeInfo(AttributeInfo):
   1.117      def init(self, data, class_file):
   1.118 @@ -199,6 +215,7 @@
   1.119          for i in range(0, self.exception_table_length):
   1.120              exception = ExceptionInfo()
   1.121              data = exception.init(data)
   1.122 +            self.exception_table.append(exception)
   1.123          self.attributes, data = self.class_file._get_attributes(data)
   1.124          return data
   1.125  
   1.126 @@ -219,24 +236,53 @@
   1.127          return self.class_file.constants[exception_index - 1]
   1.128  
   1.129  class InnerClassesAttributeInfo(AttributeInfo):
   1.130 -    pass
   1.131 +    def init(self, data, class_file):
   1.132 +        self.class_file = class_file
   1.133 +        self.attribute_length = u4(data[0:4])
   1.134 +        self.number_of_classes = u2(data[4:6])
   1.135 +        self.classes = []
   1.136 +        data = data[6:]
   1.137 +        for i in range(0, self.number_of_classes):
   1.138 +            inner_class = InnerClassInfo()
   1.139 +            data = inner_class.init(data, self.class_file)
   1.140 +            self.classes.append(inner_class)
   1.141 +        return data
   1.142  
   1.143  class SyntheticAttributeInfo(AttributeInfo):
   1.144      pass
   1.145  
   1.146  class LineNumberAttributeInfo(AttributeInfo):
   1.147 -    pass
   1.148 +    def init(self, data, class_file):
   1.149 +        self.class_file = class_file
   1.150 +        self.attribute_length = u4(data[0:4])
   1.151 +        self.line_number_table_length = u2(data[4:6])
   1.152 +        self.line_number_table = []
   1.153 +        data = data[6:]
   1.154 +        for i in range(0, self.line_number_table_length):
   1.155 +            line_number = LineNumberInfo()
   1.156 +            data = line_number.init(data)
   1.157 +            self.line_number_table.append(line_number)
   1.158 +        return data
   1.159  
   1.160  class LocalVariableAttributeInfo(AttributeInfo):
   1.161 -    pass
   1.162 +    def init(self, data, class_file):
   1.163 +        self.class_file = class_file
   1.164 +        self.attribute_length = u4(data[0:4])
   1.165 +        self.local_variable_table_length = u2(data[4:6])
   1.166 +        self.local_variable_table = []
   1.167 +        data = data[6:]
   1.168 +        for i in range(0, self.local_variable_table_length):
   1.169 +            local_variable = LocalVariableInfo()
   1.170 +            data = local_variable.init(data)
   1.171 +            self.local_variable_table.append(local_variable)
   1.172 +        return data
   1.173  
   1.174  class DeprecatedAttributeInfo(AttributeInfo):
   1.175      pass
   1.176  
   1.177 +# Child classes of the attribute information classes.
   1.178 +
   1.179  class ExceptionInfo:
   1.180 -    def __init__(self):
   1.181 -        self.start_pc, self.end_pc, self.handler_pc, self.catch_type = None, None, None, None
   1.182 -
   1.183      def init(self, data):
   1.184          self.start_pc = u2(data[0:2])
   1.185          self.end_pc = u2(data[2:4])
   1.186 @@ -244,6 +290,37 @@
   1.187          self.catch_type = u2(data[6:8])
   1.188          return data[8:]
   1.189  
   1.190 +class InnerClassInfo(NameUtils):
   1.191 +    def init(self, data, class_file):
   1.192 +        self.class_file = class_file
   1.193 +        self.inner_class_info_index = u2(data[0:2])
   1.194 +        self.outer_class_info_index = u2(data[2:4])
   1.195 +        # Permit the NameUtils mix-in.
   1.196 +        self.name_index = self.inner_name_index = u2(data[4:6])
   1.197 +        self.inner_class_access_flags = u2(data[6:8])
   1.198 +        return data[8:]
   1.199 +
   1.200 +class LineNumberInfo:
   1.201 +    def init(self, data):
   1.202 +        self.start_pc = u2(data[0:2])
   1.203 +        self.line_number = u2(data[2:4])
   1.204 +        return data[4:]
   1.205 +
   1.206 +class LocalVariableInfo(NameUtils):
   1.207 +    def init(self, data, class_file):
   1.208 +        self.class_file = class_file
   1.209 +        self.start_pc = u2(data[0:2])
   1.210 +        self.length = u2(data[2:4])
   1.211 +        self.name_index = u2(data[4:6])
   1.212 +        self.descriptor_index = u2(data[6:8])
   1.213 +        self.index = u2(data[8:10])
   1.214 +        return data[10:]
   1.215 +
   1.216 +    def get_descriptor(self):
   1.217 +        return self._get_field_descriptor(unicode(self.class_file.constants[self.descriptor_index - 1]))
   1.218 +
   1.219 +# Exceptions.
   1.220 +
   1.221  class UnknownTag(Exception):
   1.222      pass
   1.223  
   1.224 @@ -298,7 +375,10 @@
   1.225              const = NameAndTypeInfo()
   1.226          else:
   1.227              raise UnknownTag, tag
   1.228 -        s = const.init(s[1:])
   1.229 +
   1.230 +        # Initialise the constant object.
   1.231 +
   1.232 +        s = const.init(s[1:], self)
   1.233          return const, s
   1.234  
   1.235      def _get_constants_from_table(self, count, s):