compiler: resolve types when doing new NativeArray
[nit.git] / src / modelbuilder.nit
index 35c273e..1ae7e45 100644 (file)
@@ -53,8 +53,8 @@ redef class ToolContext
 
        private var modelbuilder_real: nullable ModelBuilder = null
 
-       # Run `process_mainmodule` on all phases
-       fun run_global_phases(mmodules: Array[MModule])
+       # Combine module to make a single one if required.
+       fun make_main_module(mmodules: Array[MModule]): MModule
        do
                assert not mmodules.is_empty
                var mainmodule
@@ -62,10 +62,17 @@ redef class ToolContext
                        mainmodule = mmodules.first
                else
                        # We need a main module, so we build it by importing all modules
-                       mainmodule = new MModule(modelbuilder.model, null, mmodules.first.name, new Location(mmodules.first.location.file, 0, 0, 0, 0))
+                       mainmodule = new MModule(modelbuilder.model, null, mmodules.first.name + "-m", new Location(mmodules.first.location.file, 0, 0, 0, 0))
                        mainmodule.is_fictive = true
                        mainmodule.set_imported_mmodules(mmodules)
                end
+               return mainmodule
+       end
+
+       # Run `process_mainmodule` on all phases
+       fun run_global_phases(mmodules: Array[MModule])
+       do
+               var mainmodule = make_main_module(mmodules)
                for phase in phases_list do
                        if phase.disabled then continue
                        phase.process_mainmodule(mainmodule, mmodules)
@@ -118,10 +125,8 @@ class ModelBuilder
 
        # Instantiate a modelbuilder for a model and a toolcontext
        # Important, the options of the toolcontext must be correctly set (parse_option already called)
-       init(model: Model, toolcontext: ToolContext)
+       init
        do
-               self.model = model
-               self.toolcontext = toolcontext
                assert toolcontext.modelbuilder_real == null
                toolcontext.modelbuilder_real = self
 
@@ -134,10 +139,8 @@ class ModelBuilder
                end
 
                var nit_dir = toolcontext.nit_dir
-               if nit_dir != null then
-                       var libname = "{nit_dir}/lib"
-                       if libname.file_exists then paths.add(libname)
-               end
+               var libname = "{nit_dir}/lib"
+               if libname.file_exists then paths.add(libname)
        end
 
        # Load a bunch of modules.
@@ -218,6 +221,12 @@ class ModelBuilder
                for mprop in props do
                        if not mtype.has_mproperty(mmodule, mprop) then continue
                        if not mmodule.is_visible(mprop.intro_mclassdef.mmodule, mprop.visibility) then continue
+
+                       # new-factories are invisible outside of the class
+                       if mprop isa MMethod and mprop.is_new and (not mtype isa MClassType or mprop.intro_mclassdef.mclass != mtype.mclass) then
+                               continue
+                       end
+
                        if res == null then
                                res = mprop
                                continue
@@ -589,20 +598,25 @@ class ModelBuilder
 
        # Injection of a new module without source.
        # Used by the interpreted
-       fun load_rt_module(parent: MModule, nmodule: AModule, mod_name: String): nullable AModule
+       fun load_rt_module(parent: nullable MModule, nmodule: AModule, mod_name: String): nullable AModule
        do
                # Create the module
-               var mmodule = new MModule(model, parent.mgroup, mod_name, nmodule.location)
+
+               var mgroup = null
+               if parent != null then mgroup = parent.mgroup
+               var mmodule = new MModule(model, mgroup, mod_name, nmodule.location)
                nmodule.mmodule = mmodule
                nmodules.add(nmodule)
                self.mmodule2nmodule[mmodule] = nmodule
 
-               var imported_modules = new Array[MModule]
-
-               imported_modules.add(parent)
-               mmodule.set_visibility_for(parent, intrude_visibility)
-
-               mmodule.set_imported_mmodules(imported_modules)
+               if parent!= null then
+                       var imported_modules = new Array[MModule]
+                       imported_modules.add(parent)
+                       mmodule.set_visibility_for(parent, intrude_visibility)
+                       mmodule.set_imported_mmodules(imported_modules)
+               else
+                       build_module_importation(nmodule)
+               end
 
                return nmodule
        end
@@ -691,6 +705,13 @@ class ModelBuilder
                self.toolcontext.info("{mmodule} imports {imported_modules.join(", ")}", 3)
                mmodule.set_imported_mmodules(imported_modules)
 
+               # Force standard to be public if imported
+               for sup in mmodule.in_importation.greaters do
+                       if sup.name == "standard" then
+                               mmodule.set_visibility_for(sup, public_visibility)
+                       end
+               end
+
                # TODO: Correctly check for useless importation
                # It is even doable?
                var directs = mmodule.in_importation.direct_greaters
@@ -733,11 +754,13 @@ class ModelBuilder
        end
 
        # Force to get the primitive method named `name` on the type `recv` or do a fatal error on `n`
-       fun force_get_primitive_method(n: ANode, name: String, recv: MClass, mmodule: MModule): MMethod
+       fun force_get_primitive_method(n: nullable ANode, name: String, recv: MClass, mmodule: MModule): MMethod
        do
                var res = mmodule.try_get_primitive_method(name, recv)
                if res == null then
-                       self.toolcontext.fatal_error(n.hot_location, "Fatal Error: {recv} must have a property named {name}.")
+                       var l = null
+                       if n != null then l = n.hot_location
+                       self.toolcontext.fatal_error(l, "Fatal Error: {recv} must have a property named {name}.")
                        abort
                end
                return res