javaclass

Change of javaclass/bytecode.py

166:fed5a5ceb0e6
javaclass/bytecode.py
     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