javaclass

Change of classhook.py

85:85e3410a7de9
classhook.py
     1.1 --- a/classhook.py	Thu Dec 09 20:51:18 2004 +0100
     1.2 +++ b/classhook.py	Fri Dec 10 01:04:59 2004 +0100
     1.3 @@ -260,11 +260,6 @@
     1.4              global_names = module.__dict__
     1.5              global_names["__builtins__"] = __builtins__
     1.6  
     1.7 -            # Process each class file, producing a genuine Python class.
     1.8 -
     1.9 -            class_files = []
    1.10 -            classes = []
    1.11 -
    1.12              # Get the real filename.
    1.13  
    1.14              filename = self._get_path_in_archive(filename)
    1.15 @@ -312,27 +307,69 @@
    1.16  
    1.17                  position += 1
    1.18  
    1.19 -            class_files = [class_files[class_name] for class_name in class_file_index]
    1.20 +            # Process each class file, producing a genuine Python class.
    1.21 +            # Create the classes, but establish a proper initialisation order.
    1.22  
    1.23 -            for class_file in class_files:
    1.24 +            class_file_init_index = []
    1.25 +            class_file_init = {}
    1.26 +
    1.27 +            for class_name in class_file_index:
    1.28 +                print "* Class", class_name
    1.29 +                class_file = class_files[class_name]
    1.30                  translator = bytecode.ClassTranslator(class_file)
    1.31                  cls, external_names = translator.process(global_names)
    1.32                  module.__dict__[cls.__name__] = cls
    1.33 -                classes.append((cls, class_file))
    1.34 +
    1.35 +                # Process external names.
    1.36  
    1.37 -                # Import the local names.
    1.38 +                this_class_name_parts = class_file.this_class.get_python_name().split(".")
    1.39 +                this_class_module, this_class_name = this_class_name_parts[:-1], this_class_name_parts[-1]
    1.40  
    1.41                  for external_name in external_names:
    1.42 +                    print "* Name", external_name
    1.43                      external_name_parts = external_name.split(".")
    1.44 -                    if len(external_name_parts) > 1:
    1.45 -                        external_module_name = ".".join(external_name_parts[:-1])
    1.46 +                    external_class_module, external_class_name = external_name_parts[:-1], external_name_parts[-1]
    1.47 +
    1.48 +                    # Names not local to this package need importing.
    1.49 +
    1.50 +                    if len(external_name_parts) > 1 and this_class_module != external_class_module:
    1.51 +
    1.52 +                        external_module_name = ".".join(external_class_module)
    1.53                          print "* Importing", external_module_name
    1.54                          obj = __import__(external_module_name, global_names, {}, [])
    1.55                          global_names[external_name_parts[0]] = obj
    1.56  
    1.57 +                    # Names local to this package may affect initialisation order.
    1.58 +
    1.59 +                    elif external_class_name not in class_file_init_index:
    1.60 +                        try:
    1.61 +                            this_class_name_index = class_file_init_index.index(this_class_name)
    1.62 +
    1.63 +                            # Either insert this name before the current class's
    1.64 +                            # name.
    1.65 +
    1.66 +                            print "* Inserting", external_class_name
    1.67 +                            class_file_init_index.insert(this_class_name_index, external_class_name)
    1.68 +
    1.69 +                        except ValueError:
    1.70 +
    1.71 +                            # Or add this name in anticipation of the current
    1.72 +                            # class's name appearing.
    1.73 +
    1.74 +                            print "* Including", external_class_name
    1.75 +                            class_file_init_index.append(external_class_name)
    1.76 +
    1.77 +                # Add this class name to the initialisation index.
    1.78 +
    1.79 +                if class_name not in class_file_init_index:
    1.80 +                    class_file_init_index.append(this_class_name)
    1.81 +                class_file_init[this_class_name] = (cls, class_file)
    1.82 +
    1.83              # Finally, call __clinit__ methods for all relevant classes.
    1.84  
    1.85 -            for cls, class_file in classes:
    1.86 +            print "** Initialisation order", class_file_init_index
    1.87 +            for class_name in class_file_init_index:
    1.88 +                cls, class_file = class_file_init[class_name]
    1.89                  print "**", cls, class_file
    1.90                  if hasattr(cls, "__clinit__"):
    1.91                      eval(cls.__clinit__.func_code, global_names)