X-Git-Url: http://nitlanguage.org diff --git a/src/modelbuilder.nit b/src/modelbuilder.nit index dcff009..1ae7e45 100644 --- a/src/modelbuilder.nit +++ b/src/modelbuilder.nit @@ -31,16 +31,16 @@ private import more_collections redef class ToolContext # Option --path - var opt_path: OptionArray = new OptionArray("Set include path for loaders (may be used more than once)", "-I", "--path") + var opt_path = new OptionArray("Set include path for loaders (may be used more than once)", "-I", "--path") # Option --only-metamodel - var opt_only_metamodel: OptionBool = new OptionBool("Stop after meta-model processing", "--only-metamodel") + var opt_only_metamodel = new OptionBool("Stop after meta-model processing", "--only-metamodel") # Option --only-parse - var opt_only_parse: OptionBool = new OptionBool("Only proceed to parse step of loaders", "--only-parse") + var opt_only_parse = new OptionBool("Only proceed to parse step of loaders", "--only-parse") # Option --ignore-visibility - var opt_ignore_visibility: OptionBool = new OptionBool("Do not check, and produce errors, on visibility issues.", "--ignore-visibility") + var opt_ignore_visibility = new OptionBool("Do not check, and produce errors, on visibility issues.", "--ignore-visibility") redef init do @@ -48,11 +48,13 @@ redef class ToolContext option_context.add_option(opt_path, opt_only_parse, opt_only_metamodel, opt_ignore_visibility) end + # The modelbuilder 1-to-1 associated with the toolcontext fun modelbuilder: ModelBuilder do return modelbuilder_real.as(not null) + 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 @@ -60,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) @@ -116,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 @@ -132,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. @@ -216,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 @@ -273,7 +284,7 @@ class ModelBuilder return res end - private var try_get_mproperty_by_name2_cache: HashMap3[MModule, MType, String, nullable MProperty] = new HashMap3[MModule, MType, String, nullable MProperty] + private var try_get_mproperty_by_name2_cache = new HashMap3[MModule, MType, String, nullable MProperty] # Alias for try_get_mproperty_by_name2(anode, mclassdef.mmodule, mclassdef.mtype, name) @@ -288,7 +299,7 @@ class ModelBuilder # * the NIT_PATH environment variable # * `toolcontext.nit_dir` # Path can be added (or removed) by the client - var paths: Array[String] = new Array[String] + var paths = new Array[String] # Like (an used by) `get_mmodule_by_name` but just return the ModulePath private fun search_mmodule_by_name(anode: ANode, mgroup: nullable MGroup, name: String): nullable ModulePath @@ -539,7 +550,6 @@ class ModelBuilder var parser = new Parser(lexer) var tree = parser.parse file.close - var mod_name = filename.basename(".nit") # Handle lexer and parser error var nmodule = tree.n_base @@ -586,6 +596,8 @@ class ModelBuilder return nmodule end + # Injection of a new module without source. + # Used by the interpreted fun load_rt_module(parent: nullable MModule, nmodule: AModule, mod_name: String): nullable AModule do # Create the module @@ -693,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 @@ -707,11 +726,11 @@ class ModelBuilder end # All the loaded modules - var nmodules: Array[AModule] = new Array[AModule] + 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: HashMap[MModule, AModule] = new HashMap[MModule, AModule] + var mmodule2nmodule = new HashMap[MModule, AModule] # Helper function to display an error on a node. # Alias for `self.toolcontext.error(n.hot_location, text)` @@ -735,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