1.1 --- a/classfile.py Sun Nov 07 17:42:07 2004 +0100
1.2 +++ b/classfile.py Sun Nov 07 20:53:03 2004 +0100
1.3 @@ -40,6 +40,84 @@
1.4 # Some name indexes are zero to indicate special conditions.
1.5 return None
1.6
1.7 +class NameAndTypeUtils:
1.8 + def get_name(self):
1.9 + if self.name_and_type_index != 0:
1.10 + return self.class_file.constants[self.name_and_type_index - 1].get_name()
1.11 + else:
1.12 + # Some name indexes are zero to indicate special conditions.
1.13 + return None
1.14 +
1.15 + def get_field_descriptor(self):
1.16 + if self.name_and_type_index != 0:
1.17 + return self.class_file.constants[self.name_and_type_index - 1].get_field_descriptor()
1.18 + else:
1.19 + # Some name indexes are zero to indicate special conditions.
1.20 + return None
1.21 +
1.22 + def get_method_descriptor(self):
1.23 + if self.name_and_type_index != 0:
1.24 + return self.class_file.constants[self.name_and_type_index - 1].get_method_descriptor()
1.25 + else:
1.26 + # Some name indexes are zero to indicate special conditions.
1.27 + return None
1.28 +
1.29 +class DescriptorUtils:
1.30 +
1.31 + "Symbol parsing."
1.32 +
1.33 + def _get_method_descriptor(self, s):
1.34 + assert s[0] == "("
1.35 + params = []
1.36 + s = s[1:]
1.37 + while s[0] != ")":
1.38 + parameter_descriptor, s = self._get_parameter_descriptor(s)
1.39 + params.append(parameter_descriptor)
1.40 + if s[1] != "V":
1.41 + return_type, s = self._get_field_type(s[1:])
1.42 + else:
1.43 + return_type, s = None, s[1:]
1.44 + return params, return_type
1.45 +
1.46 + def _get_parameter_descriptor(self, s):
1.47 + return self._get_field_type(s)
1.48 +
1.49 + def _get_field_descriptor(self, s):
1.50 + return self._get_field_type(s)
1.51 +
1.52 + def _get_component_type(self, s):
1.53 + return self._get_field_type(s)
1.54 +
1.55 + def _get_field_type(self, s):
1.56 + base_type, s = self._get_base_type(s)
1.57 + object_type = None
1.58 + array_type = None
1.59 + if base_type == "L":
1.60 + object_type, s = self._get_object_type(s)
1.61 + elif base_type == "[":
1.62 + array_type, s = self._get_array_type(s)
1.63 + return (base_type, object_type, array_type), s
1.64 +
1.65 + def _get_base_type(self, s):
1.66 + if len(s) > 0:
1.67 + return s[0], s[1:]
1.68 + else:
1.69 + return None, s
1.70 +
1.71 + def _get_object_type(self, s):
1.72 + if len(s) > 0:
1.73 + s_end = s.find(";")
1.74 + assert s_end != -1
1.75 + return s[:s_end], s[s_end+1:]
1.76 + else:
1.77 + return None, s
1.78 +
1.79 + def _get_array_type(self, s):
1.80 + if len(s) > 0:
1.81 + return self._get_component_type(s)
1.82 + else:
1.83 + return None, s
1.84 +
1.85 # Constant information.
1.86 # Objects of these classes are not directly aware of the class they reside in.
1.87
1.88 @@ -49,7 +127,7 @@
1.89 self.name_index = u2(data[0:2])
1.90 return data[2:]
1.91
1.92 -class RefInfo:
1.93 +class RefInfo(NameAndTypeUtils):
1.94 def init(self, data, class_file):
1.95 self.class_file = class_file
1.96 self.class_index = u2(data[0:2])
1.97 @@ -57,21 +135,30 @@
1.98 return data[4:]
1.99
1.100 class FieldRefInfo(RefInfo):
1.101 - pass
1.102 + def get_descriptor(self):
1.103 + return RefInfo.get_field_descriptor(self)
1.104
1.105 class MethodRefInfo(RefInfo):
1.106 - pass
1.107 + def get_descriptor(self):
1.108 + return RefInfo.get_method_descriptor(self)
1.109
1.110 class InterfaceMethodRefInfo(RefInfo):
1.111 - pass
1.112 + def get_descriptor(self):
1.113 + return RefInfo.get_method_descriptor(self)
1.114
1.115 -class NameAndTypeInfo(NameUtils):
1.116 +class NameAndTypeInfo(NameUtils, DescriptorUtils):
1.117 def init(self, data, class_file):
1.118 self.class_file = class_file
1.119 self.name_index = u2(data[0:2])
1.120 self.descriptor_index = u2(data[2:4])
1.121 return data[4:]
1.122
1.123 + def get_field_descriptor(self):
1.124 + return self._get_field_descriptor(unicode(self.class_file.constants[self.descriptor_index - 1]))
1.125 +
1.126 + def get_method_descriptor(self):
1.127 + return self._get_method_descriptor(unicode(self.class_file.constants[self.descriptor_index - 1]))
1.128 +
1.129 class Utf8Info:
1.130 def init(self, data, class_file):
1.131 self.class_file = class_file
1.132 @@ -123,7 +210,7 @@
1.133 # Other information.
1.134 # Objects of these classes are generally aware of the class they reside in.
1.135
1.136 -class ItemInfo(NameUtils):
1.137 +class ItemInfo(NameUtils, DescriptorUtils):
1.138 def init(self, data, class_file):
1.139 self.class_file = class_file
1.140 self.access_flags = u2(data[0:2])
1.141 @@ -132,60 +219,6 @@
1.142 self.attributes, data = self.class_file._get_attributes(data[6:])
1.143 return data
1.144
1.145 - # Symbol parsing.
1.146 -
1.147 - def _get_method_descriptor(self, s):
1.148 - assert s[0] == "("
1.149 - params = []
1.150 - s = s[1:]
1.151 - while s[0] != ")":
1.152 - parameter_descriptor, s = self._get_parameter_descriptor(s)
1.153 - params.append(parameter_descriptor)
1.154 - if s[1] != "V":
1.155 - return_type, s = self._get_field_type(s[1:])
1.156 - else:
1.157 - return_type, s = None, s[1:]
1.158 - return params, return_type
1.159 -
1.160 - def _get_parameter_descriptor(self, s):
1.161 - return self._get_field_type(s)
1.162 -
1.163 - def _get_field_descriptor(self, s):
1.164 - return self._get_field_type(s)
1.165 -
1.166 - def _get_component_type(self, s):
1.167 - return self._get_field_type(s)
1.168 -
1.169 - def _get_field_type(self, s):
1.170 - base_type, s = self._get_base_type(s)
1.171 - object_type = None
1.172 - array_type = None
1.173 - if base_type == "L":
1.174 - object_type, s = self._get_object_type(s)
1.175 - elif base_type == "[":
1.176 - array_type, s = self._get_array_type(s)
1.177 - return (base_type, object_type, array_type), s
1.178 -
1.179 - def _get_base_type(self, s):
1.180 - if len(s) > 0:
1.181 - return s[0], s[1:]
1.182 - else:
1.183 - return None, s
1.184 -
1.185 - def _get_object_type(self, s):
1.186 - if len(s) > 0:
1.187 - s_end = s.find(";")
1.188 - assert s_end != -1
1.189 - return s[:s_end], s[s_end+1:]
1.190 - else:
1.191 - return None, s
1.192 -
1.193 - def _get_array_type(self, s):
1.194 - if len(s) > 0:
1.195 - return self._get_component_type(s)
1.196 - else:
1.197 - return None, s
1.198 -
1.199 class FieldInfo(ItemInfo):
1.200 def get_descriptor(self):
1.201 return self._get_field_descriptor(unicode(self.class_file.constants[self.descriptor_index - 1]))