Return the most specific property definitions defined or inherited by a type.

The selection knows that refinement is stronger than specialization; however, in case of conflict more than one property are returned. If mtype does not know mproperty then an empty array is returned.

If you want the really most specific property, then look at lookup_first_definition

REQUIRE: not mtype.need_anchor to simplify the API (no anchor parameter)

ENSURE: not mtype.has_mproperty(mmodule, self) == result.is_empty

Property definitions

nitc $ MProperty :: lookup_definitions
	# Return the most specific property definitions defined or inherited by a type.
	# The selection knows that refinement is stronger than specialization;
	# however, in case of conflict more than one property are returned.
	# If mtype does not know mproperty then an empty array is returned.
	#
	# If you want the really most specific property, then look at `lookup_first_definition`
	#
	# REQUIRE: `not mtype.need_anchor` to simplify the API (no `anchor` parameter)
	# ENSURE: `not mtype.has_mproperty(mmodule, self) == result.is_empty`
	fun lookup_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF]
	do
		assert not mtype.need_anchor
		mtype = mtype.undecorate

		var cache = self.lookup_definitions_cache[mmodule, mtype]
		if cache != null then return cache

		#print "select prop {mproperty} for {mtype} in {self}"
		# First, select all candidates
		var candidates = new Array[MPROPDEF]

		# Here we have two strategies: iterate propdefs or iterate classdefs.
		var mpropdefs = self.mpropdefs
		if mpropdefs.length <= 1 or mpropdefs.length < mtype.collect_mclassdefs(mmodule).length then
			# Iterate on all definitions of `self`, keep only those inherited by `mtype` in `mmodule`
			for mpropdef in mpropdefs do
				# If the definition is not imported by the module, then skip
				if not mmodule.in_importation <= mpropdef.mclassdef.mmodule then continue
				# If the definition is not inherited by the type, then skip
				if not mtype.is_subtype(mmodule, null, mpropdef.mclassdef.bound_mtype) then continue
				# Else, we keep it
				candidates.add(mpropdef)
			end
		else
			# Iterate on all super-classdefs of `mtype`, keep only the definitions of `self`, if any.
			for mclassdef in mtype.collect_mclassdefs(mmodule) do
				var p = mclassdef.mpropdefs_by_property.get_or_null(self)
				if p != null then candidates.add p
			end
		end

		# Fast track for only one candidate
		if candidates.length <= 1 then
			self.lookup_definitions_cache[mmodule, mtype] = candidates
			return candidates
		end

		# Second, filter the most specific ones
		return select_most_specific(mmodule, candidates)
	end
src/model/model.nit:2220,2--2269,4