Print an error and suggest hints when the class identified by qid in mmodule is not found.

This just print error messages.

Property definitions

nitc $ ModelBuilder :: class_not_found
	# Print an error and suggest hints when the class identified by `qid` in `mmodule` is not found.
	#
	# This just print error messages.
	fun class_not_found(qid: AQclassid, mmodule: MModule)
	do
		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
			if not mmodule.in_importation <= c.intro_mmodule then continue
			if mmodule.is_visible(c.intro_mmodule, c.visibility) then continue
			if not qid.accept(c) then continue
			error(qid, "Error: class `{c.full_name}` not visible in module `{mmodule}`.")
			return
		end

		# Look for not imported but known classes from importable modules
		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
			if c.visibility <= private_visibility then continue
			if not qid.accept(c) then continue
			hints.add "`{c.intro_mmodule.full_name}`"
		end
		if hints.not_empty then
			error(qid, "Error: class `{qname}` not found in module `{mmodule}`. Maybe import {hints.join(",", " or ")}?")
			return
		end

		# Look for classes with an approximative name.
		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 = qname.levenshtein_distance(c.name)
			bests.update(d, c)
			d = qname.levenshtein_distance(c.full_name)
			bests.update(d, c)
		end
		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 `{qname}` not found in module `{mmodule}`.")
	end
src/modelbuilder_base.nit:375,2--443,4