src: remove remaining references of subclasses on AMethPropdef
[nit.git] / src / modelbuilder.nit
index 1db6a04..7ccbfa4 100644 (file)
@@ -134,14 +134,11 @@ class ModelBuilder
                        paths.append(path_env.split_with(':'))
                end
 
-               path_env = "NIT_DIR".environ
-               if not path_env.is_empty then
-                       var libname = "{path_env}/lib"
+               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 = "{sys.program_name.dirname}/../lib"
-               if libname.file_exists then paths.add(libname.simplify_path)
        end
 
        # Load a bunch of modules.
@@ -224,28 +221,55 @@ class ModelBuilder
                        if not mmodule.is_visible(mprop.intro_mclassdef.mmodule, mprop.visibility) then continue
                        if res == null then
                                res = mprop
-                       else
+                               continue
+                       end
+
+                       # Two global properties?
+                       # First, special case for init, keep the most specific ones
+                       if res isa MMethod and mprop isa MMethod and res.is_init and mprop.is_init then
                                var restype = res.intro_mclassdef.bound_mtype
                                var mproptype = mprop.intro_mclassdef.bound_mtype
-                               if restype.is_subtype(mmodule, null, mproptype) then
-                                       # we keep res
-                               else if mproptype.is_subtype(mmodule, null, restype) then
+                               if mproptype.is_subtype(mmodule, null, restype) then
+                                       # found a most specific constructor, so keep it
                                        res = mprop
-                               else
-                                       if ress == null then ress = new Array[MProperty]
-                                       ress.add(mprop)
+                                       continue
                                end
                        end
+
+                       # Ok, just keep all prop in the ress table
+                       if ress == null then
+                               ress = new Array[MProperty]
+                               ress.add(res)
+                       end
+                       ress.add(mprop)
                end
-               if ress != null then
+
+               # There is conflict?
+               if ress != null and res isa MMethod and res.is_init then
+                       # special case forinit again
                        var restype = res.intro_mclassdef.bound_mtype
+                       var ress2 = new Array[MProperty]
                        for mprop in ress do
                                var mproptype = mprop.intro_mclassdef.bound_mtype
                                if not restype.is_subtype(mmodule, null, mproptype) then
-                                       self.error(anode, "Ambigous property name '{name}' for {mtype}; conflict between {mprop.full_name} and {res.full_name}")
-                                       return null
+                                       ress2.add(mprop)
+                               else if not mprop isa MMethod or not mprop.is_init then
+                                       ress2.add(mprop)
                                end
                        end
+                       if ress2.is_empty then
+                               ress = null
+                       else
+                               ress = ress2
+                               ress.add(res)
+                       end
+               end
+
+               if ress != null then
+                       assert ress.length > 1
+                       var s = new Array[String]
+                       for mprop in ress do s.add mprop.full_name
+                       self.error(anode, "Ambigous property name '{name}' for {mtype}; conflict between {s.join(" and ")}")
                end
 
                self.try_get_mproperty_by_name2_cache[mmodule, mtype, name] = res
@@ -265,7 +289,7 @@ class ModelBuilder
        # The list is initially set with :
        #   * the toolcontext --path option
        #   * the NIT_PATH environment variable
-       #   * some heuristics including the NIT_DIR environment variable and the progname of the process
+       #   * `toolcontext.nit_dir`
        # Path can be added (or removed) by the client
        var paths: Array[String] = new Array[String]
 
@@ -444,11 +468,20 @@ class ModelBuilder
                        return mgroups[rdp]
                end
 
-               # Hack, a dir is determined by the presence of a honomymous nit file
+               # Hack, a group is determined by:
+               # * the presence of a honomymous nit file
+               # * the fact that the directory is named `src`
                var pn = rdp.basename(".nit")
                var mp = dirpath.join_path(pn + ".nit").simplify_path
 
-               if not mp.file_exists then return null
+               if not mp.file_exists then
+                       if pn == "src" then
+                               # With a src directory, the group name is the name of the parent directory
+                               pn = rdp.dirname.basename("")
+                       else
+                               return null
+                       end
+               end
 
                # check parent directory
                var parentpath = dirpath.join_path("..").simplify_path