X-Git-Url: http://nitlanguage.org diff --git a/src/modelbuilder_base.nit b/src/modelbuilder_base.nit index 7e8f040..5cc235f 100644 --- a/src/modelbuilder_base.nit +++ b/src/modelbuilder_base.nit @@ -348,7 +348,26 @@ class ModelBuilder var name = qid.n_id.text var qname = qid.full_name + if bad_class_names[mmodule].has(qname) then + error(qid, "Error: class `{qname}` not found in module `{mmodule}`.") + return + end + bad_class_names[mmodule].add(qname) + var all_classes = model.get_mclasses_by_name(name) + var hints = new Array[String] + + # Look for conflicting classes. + if all_classes != null then for c in all_classes do + if not mmodule.is_visible(c.intro_mmodule, c.visibility) then continue + if not qid.accept(c) then continue + hints.add "`{c.full_name}`" + end + if hints.length > 1 then + error(qid, "Error: ambiguous class name `{qname}` in module `{mmodule}`. Conflicts are between {hints.join(",", " and ")}.") + return + end + hints.clear # Look for imported but invisible classes. if all_classes != null then for c in all_classes do @@ -360,7 +379,6 @@ class ModelBuilder end # Look for not imported but known classes from importable modules - var hints = new Array[String] if all_classes != null then for c in all_classes do if mmodule.in_importation <= c.intro_mmodule then continue if c.intro_mmodule.in_importation <= mmodule then continue @@ -374,27 +392,28 @@ class ModelBuilder end # Look for classes with an approximative name. - var bestd = name.length / 2 # limit up to 50% name change + var bests = new BestDistance[MClass](qname.length - name.length / 2) # limit up to 50% name change for c in model.mclasses do if not mmodule.in_importation <= c.intro_mmodule then continue if not mmodule.is_visible(c.intro_mmodule, c.visibility) then continue - var d = name.levenshtein_distance(c.name) - if d <= bestd then - if d < bestd then - hints.clear - bestd = d - end - hints.add "`{c.full_name}`" - end + var d = qname.levenshtein_distance(c.name) + bests.update(d, c) + d = qname.levenshtein_distance(c.full_name) + bests.update(d, c) end - if hints.not_empty then + if bests.best_items.not_empty then + for c in bests.best_items do hints.add "`{c.full_name}`" error(qid, "Error: class `{qname}` not found in module `{mmodule}`. Did you mean {hints.join(",", " or ")}?") return end - error(qid, "Error: class `{name}` not found in module `{mmodule}`.") + error(qid, "Error: class `{qname}` not found in module `{mmodule}`.") end + # List of already reported bad class names. + # Used to not perform and repeat hints again and again. + private var bad_class_names = new MultiHashMap[MModule, String] + # Return the static type associated to the node `ntype`. # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types) # In case of problem, an error is displayed on `ntype` and null is returned.