Property definitions

nitc :: modelize_property $ APropdef :: build_signature
	private fun build_signature(modelbuilder: ModelBuilder) do end
src/modelize/modelize_property.nit:587,2--63

nitc :: modelize_property $ AAttrPropdef :: build_signature
	redef fun build_signature(modelbuilder)
	do
		var mreadpropdef = self.mreadpropdef
		var mpropdef = self.mpropdef
		if mreadpropdef == null then return # Error thus skipped
		var mclassdef = mreadpropdef.mclassdef
		var mmodule = mclassdef.mmodule
		var mtype: nullable MType = null


		var ntype = self.n_type
		if ntype != null then
			mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
			if mtype == null then return
		end

		var inherited_type: nullable MType = null
		# Inherit the type from the getter (usually an abstract getter)
		if not mreadpropdef.is_intro then
			var msignature = mreadpropdef.mproperty.intro.msignature
			if msignature == null then return # Error, thus skipped
			inherited_type = msignature.return_mtype
			if inherited_type != null then
				# The inherited type is adapted to use the local formal types, if any.
				inherited_type = inherited_type.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)
				if mtype == null then mtype = inherited_type
			end
		end

		var nexpr = self.n_expr
		if mtype == null then
			if nexpr != null then
				mtype = infer_static_type(modelbuilder, nexpr, mclassdef, mmodule, mreadpropdef)
				if mtype == null then return
			end
		else if ntype != null and inherited_type == mtype then
			if nexpr isa ANewExpr then
				var xmtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
				if xmtype == mtype then
					modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition")
				end
			end
		end

		if mtype == null then
			modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`.")
			return
		end

		self.mtype = mtype

		if mpropdef != null then
			mpropdef.static_mtype = mtype
		end

		build_read_signature

		if self.mwritepropdef != null then build_write_signature

		var mlazypropdef = self.mlazypropdef
		if mlazypropdef != null then
			mlazypropdef.static_mtype = mmodule.bool_type
		end
		check_repeated_types(modelbuilder)
	end
src/modelize/modelize_property.nit:1424,2--1488,4

nitc :: modelize_property $ ATypePropdef :: build_signature
	redef fun build_signature(modelbuilder)
	do
		var mpropdef = self.mpropdef
		if mpropdef == null then return # Error thus skipped
		var mclassdef = mpropdef.mclassdef
		var mtype: nullable MType = null

		var ntype = self.n_type
		mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
		if mtype == null then return

		mpropdef.bound = mtype
		# print "{mpropdef}: {mtype}"
	end
src/modelize/modelize_property.nit:1836,2--1849,4

nitc :: modelize_property $ AMethPropdef :: build_signature
	redef fun build_signature(modelbuilder)
	do
		var mpropdef = self.mpropdef
		if mpropdef == null then return # Error thus skiped
		var mproperty = mpropdef.mproperty
		var mclassdef = mpropdef.mclassdef
		var mmodule = mclassdef.mmodule
		var nsig = self.n_signature

		var accept_special_last_parameter = self.n_methid == null or self.n_methid.accept_special_last_parameter
		var return_is_mandatory = self.n_methid != null and self.n_methid.return_is_mandatory

		# Retrieve info from the signature AST
		var param_names = new Array[String] # Names of parameters from the AST
		var param_types = new Array[MType] # Types of parameters from the AST
		var vararg_rank = -1
		var ret_type: nullable MType = null # Return type from the AST
		if nsig != null then
			if not nsig.visit_signature(modelbuilder, mclassdef) then return
			param_names = nsig.param_names
			param_types = nsig.param_types
			vararg_rank = nsig.vararg_rank
			ret_type = nsig.ret_type
		end

		# Look for some signature to inherit
		# FIXME: do not inherit from the intro, but from the most specific
		var msignature: nullable MSignature = null
		if not mpropdef.is_intro then
			msignature = mproperty.intro.msignature
			if msignature == null then return # Skip error

			# The local signature is adapted to use the local formal types, if any.
			msignature = msignature.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)

			# Check inherited signature arity
			if param_names.length != msignature.arity then
				var node: ANode
				if nsig != null then node = nsig else node = self
				modelbuilder.error(node, "Redef Error: expected {msignature.arity} parameter(s) for `{mproperty.name}{msignature}`; got {param_names.length}. See introduction at `{mproperty.full_name}`.")
				return
			end
		else if mproperty.is_init and not mproperty.is_new then
			# FIXME UGLY: inherit signature from a super-constructor
			for msupertype in mclassdef.supertypes do
				msupertype = msupertype.anchor_to(mmodule, mclassdef.bound_mtype)
				var candidate = modelbuilder.try_get_mproperty_by_name2(self, mmodule, msupertype, mproperty.name)
				if candidate != null then
					if msignature == null then
						msignature = candidate.intro.as(MMethodDef).msignature
					end
				end
			end
		end


		# Inherit the signature
		if msignature != null and param_names.length != param_types.length and param_names.length == msignature.arity and param_types.length == 0 then
			# Parameters are untyped, thus inherit them
			param_types = new Array[MType]
			for mparameter in msignature.mparameters do
				param_types.add(mparameter.mtype)
			end
			vararg_rank = msignature.vararg_rank
		end
		if msignature != null and ret_type == null then
			ret_type = msignature.return_mtype
		end

		if param_names.length != param_types.length then
			# Some parameters are typed, other parameters are not typed.
			modelbuilder.error(nsig.n_params[param_types.length], "Error: untyped parameter `{param_names[param_types.length]}'.")
			return
		end

		var mparameters = new Array[MParameter]
		for i in [0..param_names.length[ do
			var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank)
			if nsig != null then nsig.n_params[i].mparameter = mparameter
			mparameters.add(mparameter)
		end

		# In `new`-factories, the return type is by default the classtype.
		if ret_type == null and mproperty.is_new then ret_type = mclassdef.mclass.mclass_type

		# Special checks for operator methods
		if not accept_special_last_parameter and mparameters.not_empty and mparameters.last.is_vararg then
			modelbuilder.error(self.n_signature.n_params.last, "Error: illegal variadic parameter `{mparameters.last}` for `{mproperty.name}`.")
		end
		if ret_type == null and return_is_mandatory then
			modelbuilder.error(self.n_methid, "Error: mandatory return type for `{mproperty.name}`.")
		end

		msignature = new MSignature(mparameters, ret_type)
		mpropdef.msignature = msignature
		mpropdef.is_abstract = self.get_single_annotation("abstract", modelbuilder) != null
		mpropdef.is_intern = self.get_single_annotation("intern", modelbuilder) != null
		mpropdef.is_extern = self.n_extern_code_block != null or self.get_single_annotation("extern", modelbuilder) != null

		# Check annotations
		var at = self.get_single_annotation("lazy", modelbuilder)
		if at != null then modelbuilder.error(at, "Syntax Error: `lazy` must be used on attributes.")

		var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
		if atautoinit != null then
			if not mpropdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` cannot be set on redefinitions.")
			else if not mclassdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` cannot be used in class refinements.")
			else
				self.is_autoinit = true
			end
		end
	end
src/modelize/modelize_property.nit:912,2--1025,4