Merge: More robustness in keep going
[nit.git] / src / loader.nit
index e50f562..fb1801b 100644 (file)
@@ -352,10 +352,12 @@ redef class ModelBuilder
                end
 
                # Fast track, the path is already known
-               var pn = path.basename(".nit")
+               if identified_files_by_path.has_key(path) then return identified_files_by_path[path]
                var rp = module_absolute_path(path)
                if identified_files_by_path.has_key(rp) then return identified_files_by_path[rp]
 
+               var pn = path.basename(".nit")
+
                # Search for a group
                var mgrouppath = path.join_path("..").simplify_path
                var mgroup = get_mgroup(mgrouppath)
@@ -380,6 +382,7 @@ redef class ModelBuilder
                mgroup.module_paths.add(res)
 
                identified_files_by_path[rp] = res
+               identified_files_by_path[path] = res
                identified_files.add(res)
                return res
        end
@@ -393,10 +396,15 @@ redef class ModelBuilder
        # Note: `paths` is also used to look for mgroups
        fun get_mgroup(dirpath: String): nullable MGroup
        do
-               if not dirpath.file_exists then do
+               var stat = dirpath.file_stat
+
+               if stat == null then do
+                       # search dirless directories in known -I paths
+                       if dirpath.chars.has('/') then return null
                        for p in paths do
                                var try = p / dirpath
-                               if try.file_exists then
+                               stat = try.file_stat
+                               if stat != null then
                                        dirpath = try
                                        break label
                                end
@@ -404,20 +412,19 @@ redef class ModelBuilder
                        return null
                end label
 
+               # Filter out non-directories
+               if not stat.is_dir then
+                       return null
+               end
+
+               # Fast track, the path is already known
                var rdp = module_absolute_path(dirpath)
                if mgroups.has_key(rdp) then
                        return mgroups[rdp]
                end
 
-               # Filter out non-directories
-               var stat = dirpath.file_stat
-               if stat == null or not stat.is_dir then
-                       mgroups[rdp] = null
-                       return null
-               end
-
                # By default, the name of the package or group is the base_name of the directory
-               var pn = rdp.basename(".nit")
+               var pn = rdp.basename
 
                # Check `package.ini` that indicate a package
                var ini = null
@@ -525,16 +532,17 @@ redef class ModelBuilder
                        var fp = p/f
                        var g = get_mgroup(fp)
                        # Recursively scan for groups of the same package
-                       if g != null and g.mpackage == mgroup.mpackage then
+                       if g == null then
+                               identify_file(fp)
+                       else if g.mpackage == mgroup.mpackage then
                                scan_group(g)
                        end
-                       identify_file(fp)
                end
        end
 
        # Transform relative paths (starting with '../') into absolute paths
        private fun module_absolute_path(path: String): String do
-               return getcwd.join_path(path).simplify_path
+               return path.realpath
        end
 
        # Try to load a module AST using a path.
@@ -811,11 +819,13 @@ redef class ModelBuilder
                        # Load the imported module
                        var suppath = seach_module_by_amodule_name(aimport.n_name, mmodule.mgroup)
                        if suppath == null then
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                                continue # Skip error
                        end
                        var sup = load_module_path(suppath)
                        if sup == null then
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                                continue # Skip error
                        end
@@ -824,16 +834,20 @@ redef class ModelBuilder
                        imported_modules.add(sup)
                        var mvisibility = aimport.n_visibility.mvisibility
                        if mvisibility == protected_visibility then
+                               mmodule.is_broken = true
                                error(aimport.n_visibility, "Error: only properties can be protected.")
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                                return
                        end
                        if sup == mmodule then
                                error(aimport.n_name, "Error: dependency loop in module {mmodule}.")
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                        end
                        if sup.in_importation < mmodule then
                                error(aimport.n_name, "Error: dependency loop between modules {mmodule} and {sup}.")
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                                return
                        end
@@ -843,6 +857,7 @@ redef class ModelBuilder
                        var mod_name = "core"
                        var sup = self.get_mmodule_by_name(nmodule, null, mod_name)
                        if sup == null then
+                               mmodule.is_broken = true
                                nmodule.mmodule = null # invalidate the module
                        else # Skip error
                                imported_modules.add(sup)