Property definitions

nitc $ MSignature :: defaultinit
# A signature of a method
class MSignature
	super MType

	# The each parameter (in order)
	var mparameters: Array[MParameter]

	# Returns a parameter named `name`, if any.
	fun mparameter_by_name(name: String): nullable MParameter
	do
		for p in mparameters do
			if p.name == name then return p
		end
		return null
	end

	# The return type (null for a procedure)
	var return_mtype: nullable MType

	redef fun depth
	do
		var dmax = 0
		var t = self.return_mtype
		if t != null then dmax = t.depth
		for p in mparameters do
			var d = p.mtype.depth
			if d > dmax then dmax = d
		end
		return dmax + 1
	end

	redef fun length
	do
		var res = 1
		var t = self.return_mtype
		if t != null then res += t.length
		for p in mparameters do
			res += p.mtype.length
		end
		return res
	end

	# REQUIRE: 1 <= mparameters.count p -> p.is_vararg
	init
	do
		var vararg_rank = -1
		for i in [0..mparameters.length[ do
			var parameter = mparameters[i]
			if parameter.is_vararg then
				if vararg_rank >= 0 then
					# If there is more than one vararg,
					# consider that additional arguments cannot be mapped.
					vararg_rank = -1
					break
				end
				vararg_rank = i
			end
		end
		self.vararg_rank = vararg_rank
	end

	# The rank of the main ellipsis (`...`) for vararg (starting from 0).
	# value is -1 if there is no vararg.
	# Example: for "(a: Int, b: Bool..., c: Char)" #-> vararg_rank=1
	#
	# From a model POV, a signature can contain more than one vararg parameter,
	# the `vararg_rank` just indicates the one that will receive the additional arguments.
	# However, currently, if there is more that one vararg parameter, no one will be the main one,
	# and additional arguments will be refused.
	var vararg_rank: Int is noinit

	# The number of parameters
	fun arity: Int do return mparameters.length

	redef fun to_s
	do
		var b = new FlatBuffer
		if not mparameters.is_empty then
			b.append("(")
			var last_mtype = null
			for i in [0..mparameters.length[ do
				var mparameter = mparameters[i]

				# Group types that are common to contiguous parameters
				if mparameter.mtype != last_mtype and last_mtype != null then
					b.append(": ")
					b.append(last_mtype.to_s)
				end

				if i > 0 then b.append(", ")
				b.append(mparameter.name)

				if mparameter.is_vararg then
					b.append(": ")
					b.append(mparameter.mtype.to_s)
					b.append("...")
					last_mtype = null
				else
					last_mtype = mparameter.mtype
				end
			end

			if last_mtype != null then
				b.append(": ")
				b.append(last_mtype.to_s)
			end

			b.append(")")
		end
		var ret = self.return_mtype
		if ret != null then
			b.append(": ")
			b.append(ret.to_s)
		end
		return b.to_s
	end

	redef fun resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule, cleanup_virtual: Bool): MSignature
	do
		var params = new Array[MParameter]
		for p in self.mparameters do
			params.add(p.resolve_for(mtype, anchor, mmodule, cleanup_virtual))
		end
		var ret = self.return_mtype
		if ret != null then
			ret = ret.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
		end
		var res = new MSignature(params, ret)
		return res
	end
end
src/model/model.nit:1964,1--2094,3