Merge: Less fixme and todo
authorJean Privat <jean@pryen.org>
Thu, 8 Jan 2015 02:49:52 +0000 (21:49 -0500)
committerJean Privat <jean@pryen.org>
Thu, 8 Jan 2015 02:49:52 +0000 (21:49 -0500)
Looked at http://jenkins.gresil.org/jenkins/job/nit/tasks and did some work.

Pull-Request: #1077
Reviewed-by: Romain Chanoir <chanoir.romain@courrier.uqam.ca>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

1  2 
src/compiler/abstract_compiler.nit
src/compiler/separate_compiler.nit
src/loader.nit
src/nitlight.nit

@@@ -481,10 -481,6 +481,10 @@@ abstract class AbstractCompile
                self.realmainmodule = mainmodule
        end
  
 +      # Do the full code generation of the program `mainmodule`
 +      # It is the main method usually called after the instantiation
 +      fun do_compilation is abstract
 +
        # Force the creation of a new file
        # The point is to avoid contamination between must-be-compiled-separately files
        fun new_file(name: String): CodeFile
@@@ -1462,10 -1458,11 +1462,11 @@@ abstract class AbstractCompilerVisito
                self.require_declaration(s)
        end
  
-       # look for a needed .h and .c file for a given .nit source-file
-       # FIXME: bad API, parameter should be a `MModule`, not its source-file
-       fun add_extern(file: String)
+       # Look for a needed .h and .c file for a given module
+       # This is used for the legacy FFI
+       fun add_extern(mmodule: MModule)
        do
+               var file = mmodule.location.file.filename
                file = file.strip_extension(".nit")
                var tryfile = file + ".nit.h"
                if tryfile.file_exists then
@@@ -2155,16 -2152,13 +2156,13 @@@ redef class AMethPropde
        do
                var externname
                var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
 -              if at != null then
 +              if at != null and at.n_args.length == 1 then
                        externname = at.arg_as_string(v.compiler.modelbuilder)
                        if externname == null then return false
                else
                        return false
                end
-               if location.file != null then
-                       var file = location.file.filename
-                       v.add_extern(file)
-               end
+               v.add_extern(mpropdef.mclassdef.mmodule)
                var res: nullable RuntimeVariable = null
                var ret = mpropdef.msignature.return_mtype
                if ret != null then
                else
                        return false
                end
-               if location.file != null then
-                       var file = location.file.filename
-                       v.add_extern(file)
-               end
+               v.add_extern(mpropdef.mclassdef.mmodule)
                v.adapt_signature(mpropdef, arguments)
                v.unbox_signature_extern(mpropdef, arguments)
                var ret = arguments.first.mtype
@@@ -90,55 -90,12 +90,55 @@@ redef class ModelBuilde
                self.toolcontext.info("*** GENERATING C ***", 1)
  
                var compiler = new SeparateCompiler(mainmodule, self, runtime_type_analysis)
 +              compiler.do_compilation
 +              compiler.display_stats
 +
 +              var time1 = get_time
 +              self.toolcontext.info("*** END GENERATING C: {time1-time0} ***", 2)
 +              write_and_make(compiler)
 +      end
 +
 +      # Count number of invocations by VFT
 +      private var nb_invok_by_tables = 0
 +      # Count number of invocations by direct call
 +      private var nb_invok_by_direct = 0
 +      # Count number of invocations by inlining
 +      private var nb_invok_by_inline = 0
 +end
 +
 +# Singleton that store the knowledge about the separate compilation process
 +class SeparateCompiler
 +      super AbstractCompiler
 +
 +      redef type VISITOR: SeparateCompilerVisitor
 +
 +      # The result of the RTA (used to know live types and methods)
 +      var runtime_type_analysis: nullable RapidTypeAnalysis
 +
 +      private var undead_types: Set[MType] = new HashSet[MType]
 +      private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
 +
 +      private var type_ids: Map[MType, Int] is noinit
 +      private var type_colors: Map[MType, Int] is noinit
 +      private var opentype_colors: Map[MType, Int] is noinit
 +      protected var method_colors: Map[PropertyLayoutElement, Int] is noinit
 +      protected var attr_colors: Map[MAttribute, Int] is noinit
 +
 +      init do
 +              var file = new_file("nit.common")
 +              self.header = new CodeWriter(file)
 +              self.compile_box_kinds
 +      end
 +
 +      redef fun do_compilation
 +      do
 +              var compiler = self
                compiler.compile_header
  
                var c_name = mainmodule.c_name
  
                # compile class structures
 -              self.toolcontext.info("Property coloring", 2)
 +              modelbuilder.toolcontext.info("Property coloring", 2)
                compiler.new_file("{c_name}.classes")
                compiler.do_property_coloring
                for m in mainmodule.in_importation.greaters do
  
                # compile methods
                for m in mainmodule.in_importation.greaters do
 -                      self.toolcontext.info("Generate C for module {m.full_name}", 2)
 +                      modelbuilder.toolcontext.info("Generate C for module {m.full_name}", 2)
                        compiler.new_file("{m.c_name}.sep")
                        compiler.compile_module_to_c(m)
                end
  
                # compile live & cast type structures
 -              self.toolcontext.info("Type coloring", 2)
 +              modelbuilder.toolcontext.info("Type coloring", 2)
                compiler.new_file("{c_name}.types")
 +              compiler.compile_types
 +      end
 +
 +      # Color and compile type structures and cast information
 +      fun compile_types
 +      do
 +              var compiler = self
 +
                var mtypes = compiler.do_type_coloring
                for t in mtypes do
                        compiler.compile_type_to_c(t)
                        compiler.compile_type_to_c(t)
                end
  
 -              compiler.display_stats
 -
 -              var time1 = get_time
 -              self.toolcontext.info("*** END GENERATING C: {time1-time0} ***", 2)
 -              write_and_make(compiler)
 -      end
 -
 -      # Count number of invocations by VFT
 -      private var nb_invok_by_tables = 0
 -      # Count number of invocations by direct call
 -      private var nb_invok_by_direct = 0
 -      # Count number of invocations by inlining
 -      private var nb_invok_by_inline = 0
 -end
 -
 -# Singleton that store the knowledge about the separate compilation process
 -class SeparateCompiler
 -      super AbstractCompiler
 -
 -      redef type VISITOR: SeparateCompilerVisitor
 -
 -      # The result of the RTA (used to know live types and methods)
 -      var runtime_type_analysis: nullable RapidTypeAnalysis
 -
 -      private var undead_types: Set[MType] = new HashSet[MType]
 -      private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
 -
 -      private var type_ids: Map[MType, Int] is noinit
 -      private var type_colors: Map[MType, Int] is noinit
 -      private var opentype_colors: Map[MType, Int] is noinit
 -      protected var method_colors: Map[PropertyLayoutElement, Int] is noinit
 -      protected var attr_colors: Map[MAttribute, Int] is noinit
 -
 -      init do
 -              var file = new_file("nit.common")
 -              self.header = new CodeWriter(file)
 -              self.compile_box_kinds
        end
  
        redef fun compile_header_structs do
@@@ -1077,8 -1063,8 +1077,8 @@@ class SeparateCompilerVisito
        do
                var rta = compiler.runtime_type_analysis
                var mmethod = callsite.mproperty
-               # TODO: Inlining of new-style constructors
-               if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and not mmethod.is_root_init then
+               # TODO: Inlining of new-style constructors with initializers
+               if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and callsite.mpropdef.initializers.is_empty then
                        var tgs = rta.live_targets(callsite)
                        if tgs.length == 1 then
                                # DIRECT CALL
diff --combined src/loader.nit
@@@ -82,61 -82,6 +82,61 @@@ redef class ModelBuilde
  
                if toolcontext.opt_only_parse.value then
                        self.toolcontext.info("*** ONLY PARSE...", 1)
 +                      exit(0)
 +              end
 +
 +              return mmodules.to_a
 +      end
 +
 +      # Load recursively all modules of the group `mgroup`.
 +      # See `parse` for details.
 +      fun parse_group(mgroup: MGroup): Array[MModule]
 +      do
 +              var res = new Array[MModule]
 +              visit_group(mgroup)
 +              for mg in mgroup.in_nesting.smallers do
 +                      for mp in mg.module_paths do
 +                              var nmodule = self.load_module(mp.filepath)
 +                              if nmodule == null then continue # Skip error
 +                              # Load imported module
 +                              build_module_importation(nmodule)
 +
 +                              res.add(nmodule.mmodule.as(not null))
 +                      end
 +              end
 +              return res
 +      end
 +
 +      # Load a bunch of modules and groups.
 +      # Each name can be a module or a group.
 +      # If it is a group then recursively all its modules are parsed.
 +      # See `parse` for details.
 +      fun parse_full(names: Sequence[String]): Array[MModule]
 +      do
 +              var time0 = get_time
 +              # Parse and recursively load
 +              self.toolcontext.info("*** PARSE ***", 1)
 +              var mmodules = new ArraySet[MModule]
 +              for a in names do
 +                      var mgroup = self.get_mgroup(a)
 +                      if mgroup != null then
 +                              mmodules.add_all parse_group(mgroup)
 +                              continue
 +                      end
 +                      var nmodule = self.load_module(a)
 +                      if nmodule == null then continue # Skip error
 +                      # Load imported module
 +                      build_module_importation(nmodule)
 +
 +                      mmodules.add(nmodule.mmodule.as(not null))
 +              end
 +              var time1 = get_time
 +              self.toolcontext.info("*** END PARSE: {time1-time0} ***", 2)
 +
 +              self.toolcontext.check_errors
 +
 +              if toolcontext.opt_only_parse.value then
 +                      self.toolcontext.info("*** ONLY PARSE...", 1)
                        exit(0)
                end
  
        do
                # Check the module name
                var decl = nmodule.n_moduledecl
-               if decl == null then
-                       #warning(nmodule, "Warning: Missing 'module' keyword") #FIXME: NOT YET FOR COMPATIBILITY
-               else
+               if decl != null then
                        var decl_name = decl.n_name.n_id.text
                        if decl_name != mod_name then
                                error(decl.n_name, "Error: module name missmatch; declared {decl_name} file named {mod_name}")
        var nmodules = new Array[AModule]
  
        # Register the nmodule associated to each mmodule
-       # FIXME: why not refine the `MModule` class with a nullable attribute?
-       var mmodule2nmodule = new HashMap[MModule, AModule]
+       #
+       # Public clients need to use `mmodule2node` to access stuff.
+       private var mmodule2nmodule = new HashMap[MModule, AModule]
+       # Retrieve the associated AST node of a mmodule.
+       # This method is used to associate model entity with syntactic entities.
+       #
+       # If the module is not associated with a node, returns null.
+       fun mmodule2node(mmodule: MModule): nullable AModule
+       do
+               return mmodule2nmodule.get_or_null(mmodule)
+       end
  end
  
  # File-system location of a module (file) that is identified but not always loaded.
diff --combined src/nitlight.nit
@@@ -41,7 -41,7 +41,7 @@@ var modelbuilder = new ModelBuilder(mod
  
  var args = toolcontext.option_context.rest
  
 -var mmodules = modelbuilder.parse(args)
 +var mmodules = modelbuilder.parse_full(args)
  modelbuilder.run_phases
  
  if opt_full.value then mmodules = model.mmodules
@@@ -67,7 -67,8 +67,8 @@@ for mm in mmodules d
        if opt_last_line.value != 0 then v.last_line = opt_last_line.value
        if opt_ast.value then v.with_ast = true
        var page = null
-       var m = modelbuilder.mmodule2nmodule[mm]
+       var m = modelbuilder.mmodule2node(mm)
+       assert m != null
        if not opt_fragment.value then
                page = new HTMLTag("html")
                page.add_raw_html """<head>