1.1 --- a/javaclass/bytecode.py Sun Feb 13 01:33:26 2005 +0100
1.2 +++ b/javaclass/bytecode.py Sun Feb 13 01:35:44 2005 +0100
1.3 @@ -2041,13 +2041,13 @@
1.4 translator.process(method, writer)
1.5 return translator, writer
1.6
1.7 - def make_method(self, real_method_name, methods, global_names, namespace):
1.8 + def make_method(self, real_method_name, methods, global_names):
1.9
1.10 """
1.11 Make a dispatcher method with the given 'real_method_name', providing
1.12 dispatch to the supplied type-sensitive 'methods', accessing the given
1.13 'global_names' where necessary, and storing the new method in the
1.14 - 'namespace' provided.
1.15 + class's namespace.
1.16 """
1.17
1.18 if real_method_name == "<init>":
1.19 @@ -2059,7 +2059,7 @@
1.20
1.21 if len(methods) == 1:
1.22 method, fn = methods[0]
1.23 - namespace[method_name] = fn
1.24 + self.namespace[method_name] = fn
1.25 return
1.26
1.27 # Write a simple bytecode dispatching mechanism.
1.28 @@ -2224,28 +2224,27 @@
1.29 if method_is_static:
1.30 fn = staticmethod(fn)
1.31
1.32 - namespace[method_name] = fn
1.33 + self.namespace[method_name] = fn
1.34
1.35 def process(self, global_names):
1.36
1.37 """
1.38 Process the class, storing it in the 'global_names' dictionary provided.
1.39 - Return a tuple containing the class and a list of external names
1.40 - referenced by the class's methods.
1.41 + Return a list of external names referenced by the class's methods.
1.42 """
1.43
1.44 - namespace = {}
1.45 + self.namespace = {}
1.46
1.47 # Make the fields.
1.48
1.49 for field in self.class_file.fields:
1.50 if classfile.has_flags(field.access_flags, [classfile.STATIC]):
1.51 field_name = str(field.get_python_name())
1.52 - namespace[field_name] = None
1.53 + self.namespace[field_name] = None
1.54
1.55 # Make the methods.
1.56
1.57 - real_methods = {}
1.58 + self.real_methods = {}
1.59 external_names = []
1.60
1.61 for method in self.class_file.methods:
1.62 @@ -2287,13 +2286,27 @@
1.63
1.64 # Remember the real method name and the corresponding methods produced.
1.65
1.66 - if not real_methods.has_key(real_method_name):
1.67 - real_methods[real_method_name] = []
1.68 - real_methods[real_method_name].append((method, fn))
1.69 + if not self.real_methods.has_key(real_method_name):
1.70 + self.real_methods[real_method_name] = []
1.71 + self.real_methods[real_method_name].append((method, fn))
1.72
1.73 # Add the method to the class's namespace.
1.74
1.75 - namespace[method_name] = fn
1.76 + self.namespace[method_name] = fn
1.77 +
1.78 + # Add the super class as an external name, if appropriate.
1.79 +
1.80 + if self.class_file.super_class is not None:
1.81 + external_names.append(self.class_file.super_class.get_python_name())
1.82 +
1.83 + return external_names
1.84 +
1.85 + def get_class(self, global_names):
1.86 +
1.87 + """
1.88 + Get the Python class representing the underlying Java class, using the
1.89 + given 'global_names' to define dispatcher methods.
1.90 + """
1.91
1.92 # Define superclasses.
1.93
1.94 @@ -2301,18 +2314,18 @@
1.95
1.96 # Define method dispatchers.
1.97
1.98 - for real_method_name, methods in real_methods.items():
1.99 + for real_method_name, methods in self.real_methods.items():
1.100 if real_method_name != "<clinit>":
1.101 - self.make_method(real_method_name, methods, global_names, namespace)
1.102 + self.make_method(real_method_name, methods, global_names)
1.103
1.104 # Use only the last part of the fully qualified name.
1.105
1.106 full_class_name = str(self.class_file.this_class.get_python_name())
1.107 class_name = full_class_name.split(".")[-1]
1.108 - cls = new.classobj(class_name, bases, namespace)
1.109 + cls = new.classobj(class_name, bases, self.namespace)
1.110 global_names[cls.__name__] = cls
1.111
1.112 - return cls, external_names
1.113 + return cls
1.114
1.115 def get_base_classes(self, global_names):
1.116
1.117 @@ -2323,27 +2336,20 @@
1.118 tuple).
1.119 """
1.120
1.121 - original_name = str(self.class_file.super_class.get_name())
1.122 - full_this_class_name = str(self.class_file.this_class.get_python_name())
1.123 - this_class_name_parts = full_this_class_name.split(".")
1.124 - this_class_module_name = ".".join(this_class_name_parts[:-1])
1.125 - full_super_class_name = str(self.class_file.super_class.get_python_name())
1.126 - super_class_name_parts = full_super_class_name.split(".")
1.127 - super_class_name = super_class_name_parts[-1]
1.128 - super_class_module_name = ".".join(super_class_name_parts[:-1])
1.129 - if super_class_module_name == "":
1.130 - obj = global_names[super_class_name]
1.131 - elif super_class_module_name == this_class_module_name:
1.132 - obj = global_names[super_class_name]
1.133 - else:
1.134 - #print "Importing", super_class_module_name, super_class_name
1.135 - obj = __import__(super_class_module_name, global_names, {}, [])
1.136 - for super_class_name_part in super_class_name_parts[1:] or [super_class_name]:
1.137 - #print "*", obj, super_class_name_part
1.138 - try:
1.139 - obj = getattr(obj, super_class_name_part)
1.140 - except AttributeError:
1.141 - raise AttributeError, "Cannot find class '%s' in Java package '%s'" % (super_class_name_part, super_class_module_name)
1.142 + super_class = self.class_file.super_class
1.143 + if super_class is None:
1.144 + return ()
1.145 +
1.146 + super_class_name = super_class.get_python_name()
1.147 + super_class_name_parts = super_class_name.split(".")
1.148 + obj = global_names
1.149 + for super_class_name_part in super_class_name_parts[:-1]:
1.150 + try:
1.151 + obj = obj[super_class_name_part].__dict__
1.152 + except KeyError:
1.153 + raise AttributeError, "Cannot find '%s' when referencing Java class '%s'" % (
1.154 + super_class_name_part, super_class_name)
1.155 + obj = obj[super_class_name_parts[-1]]
1.156 return (obj,)
1.157
1.158 def make_varnames(self, nlocals, method_is_static=0):
1.159 @@ -2378,6 +2384,7 @@
1.160 if __name__ == "__main__":
1.161 import sys
1.162 import dis
1.163 + import java.lang
1.164 global_names = globals()
1.165 #global_names["isinstance"] = _isinstance
1.166 #global_names["map"] = _map
1.167 @@ -2385,6 +2392,7 @@
1.168 f = open(filename, "rb")
1.169 c = classfile.ClassFile(f.read())
1.170 translator = ClassTranslator(c)
1.171 - cls, external_names = translator.process(global_names)
1.172 + external_names = translator.process(global_names)
1.173 + cls = translator.get_class(global_names)
1.174
1.175 # vim: tabstop=4 expandtab shiftwidth=4