Property definitions

nitc :: modelize_property $ APropdef :: build_property
	private fun build_property(modelbuilder: ModelBuilder, mclassdef: MClassDef) do end
src/modelize/modelize_property.nit:586,2--84

nitc :: modelize_property $ AAttrPropdef :: build_property
	redef fun build_property(modelbuilder, mclassdef)
	do
		var mclass = mclassdef.mclass

		var atabstract = self.get_single_annotation("abstract", modelbuilder)

		if atabstract == null then build_attribute_property(modelbuilder, mclassdef)

		# Construction of the read property. If it's not correctly built just return.
		if not build_read_property(modelbuilder, mclassdef) then return

		if atabstract != null then mreadpropdef.is_abstract = true

		has_value = n_expr != null or n_block != null

		if atabstract != null and has_value then
			modelbuilder.error(atabstract, "Error: `abstract` attributes cannot have an initial value.")
			return
		end

		var atnoinit = self.get_single_annotation("noinit", modelbuilder)
		if atnoinit == null then atnoinit = self.get_single_annotation("noautoinit", modelbuilder)
		if atnoinit != null then
			noinit = true
			if has_value then
				modelbuilder.error(atnoinit, "Error: `noautoinit` attributes cannot have an initial value.")
				return
			end
			if atabstract != null then
				modelbuilder.warning(atnoinit, "useless-noautoinit", "Warning: superfluous `noautoinit` on abstract attribute.")
			end
		end

		# Construction of the read property. If it's not correctly built just return.
		if not build_lazy_property(modelbuilder, mclassdef) then return

		var atoptional = self.get_single_annotation("optional", modelbuilder)
		if atoptional != null then
			if not has_value then
				modelbuilder.error(atoptional, "Error: `optional` attributes need a default value.")
			end
			is_optional = true
		end

		var atreadonly = self.get_single_annotation("readonly", modelbuilder)
		if atreadonly != null then
			if not has_value then
				modelbuilder.error(atreadonly, "Error: `readonly` attributes need a value.")
			end
			# No setter, so just leave
			return
		end

		if not mclassdef.is_intro and not has_value and not noinit then
			modelbuilder.advice(self, "attr-in-refinement", "Warning: attributes in refinement need a value or `noautoinit`.")
		end

		# Construction of the read property. If it's not correctly built just return.
		if not build_write_property(modelbuilder, mclassdef, false) then return

		if atabstract != null then mwritepropdef.is_abstract = true

		var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
		if atautoinit != null then
			if has_value then
				modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot have an initial value.")
			else if not mwritepropdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be set on redefinitions.")
			else if not mclassdef.is_intro then
				modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be used in class refinements.")
			else if atabstract == null then
				modelbuilder.warning(atautoinit, "useless-autoinit", "Warning: superfluous `autoinit` on attribute.")
			end
		else if atabstract != null then
			# By default, abstract attribute are not autoinit
			noinit = true
		end
	end
src/modelize/modelize_property.nit:1210,2--1287,4

nitc :: modelize_property $ ATypePropdef :: build_property
	redef fun build_property(modelbuilder, mclassdef)
	do
		var name = self.n_qid.n_id.text
		var mprop = modelbuilder.try_get_mproperty_by_name(self.n_qid, mclassdef, name)
		if mprop == null then
			var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
			mprop = new MVirtualTypeProp(mclassdef, name, self.location, mvisibility)
			for c in name.chars do if c >= 'a' and c<= 'z' then
				modelbuilder.warning(n_qid, "bad-type-name", "Warning: lowercase in the virtual type `{name}`.")
				break
			end
		else
			if mprop.is_broken then return
			assert mprop isa MVirtualTypeProp
			check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
		end

		var mpropdef = new MVirtualTypeDef(mclassdef, mprop, self.location)
		self.mpropdef = mpropdef
		if mpropdef.is_intro then
			modelbuilder.toolcontext.info("{mpropdef} introduces new type {mprop.full_name}", 4)
		else
			modelbuilder.toolcontext.info("{mpropdef} redefines type {mprop.full_name}", 4)
		end
		if not self.check_redef_keyword(modelbuilder, mclassdef, self.n_kwredef, not mpropdef.is_intro, mprop) then
			mpropdef.is_broken =true
		end
		mclassdef.mprop2npropdef[mprop] = self
		modelbuilder.mpropdef2npropdef[mpropdef] = self
		set_doc(mpropdef, modelbuilder)

		var atfixed = get_single_annotation("fixed", modelbuilder)
		if atfixed != null then
			mpropdef.is_fixed = true
		end
	end
src/modelize/modelize_property.nit:1799,2--1834,4

nitc :: modelize_property $ AMethPropdef :: build_property
	redef fun build_property(modelbuilder, mclassdef)
	do
		var n_kwinit = n_kwinit
		var n_kwnew = n_kwnew
		var is_new = n_kwnew != null
		var is_init = n_kwinit != null or is_new
		var name: String
		var amethodid = self.n_methid
		var name_node: ANode
		var is_old_style_init = false
		if amethodid == null then
			if n_kwinit != null then
				name = "init"
				name_node = n_kwinit
				var old_style_annot = get_single_annotation("old_style_init", modelbuilder)
				if  old_style_annot != null or self.n_signature.n_params.not_empty then
					name = "defaultinit"
					if old_style_annot != null then is_old_style_init = true
				end
			else if n_kwnew != null then
				name = "new"
				name_node = n_kwnew
			else
				name = "main"
				name_node = self
			end
		else if amethodid isa AIdMethid then
			name = amethodid.n_id.text
			name_node = amethodid
		else
			# operator, bracket or assign
			name = amethodid.collect_text
			name_node = amethodid

			var arity = self.n_signature.n_params.length
			if name == "+" and arity == 0 then
				name = "unary +"
			else if name == "-" and arity == 0 then
				name = "unary -"
			else if name == "~" and arity == 0 then
				name = "unary ~"
			else
				if amethodid.is_binary and arity != 1 then
					modelbuilder.error(self.n_signature, "Syntax Error: binary operator `{name}` requires exactly one parameter; got {arity}.")
				else if amethodid.min_arity > arity then
					modelbuilder.error(self.n_signature, "Syntax Error: `{name}` requires at least {amethodid.min_arity} parameter(s); got {arity}.")
				end
			end
		end

		var look_like_a_root_init = look_like_a_root_init(modelbuilder, mclassdef)
		var mprop: nullable MMethod = null
		if not is_init or n_kwredef != null or look_like_a_root_init then mprop = modelbuilder.try_get_mproperty_by_name(name_node, mclassdef, name).as(nullable MMethod)
		if mprop == null and look_like_a_root_init then
			mprop = modelbuilder.the_root_init_mmethod
			var nb = n_block
			if nb isa ABlockExpr and nb.n_expr.is_empty and n_doc == null then
				modelbuilder.advice(self, "useless-init", "Warning: useless empty init in {mclassdef}")
			end
		end
		if mprop == null then
			var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
			mprop = new MMethod(mclassdef, name, self.location, mvisibility)
			if look_like_a_root_init and modelbuilder.the_root_init_mmethod == null then
				modelbuilder.the_root_init_mmethod = mprop
				mprop.is_root_init = true
			end
			mprop.is_init = is_init
			mprop.is_new = is_new
			if is_new then mclassdef.mclass.has_new_factory = true
			if name == "sys" then mprop.is_toplevel = true # special case for sys allowed in `new` factories
			if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then
				mprop.is_broken = true
				return
			end
		else
			if mprop.is_broken then return
			if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, not self isa AMainMethPropdef, mprop) then return
			check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
		end

		# Check name conflicts in the local class for constructors.
		if is_init then
			for p, n in mclassdef.mprop2npropdef do
				if p != mprop and p isa MMethod and p.name == name then
					if not check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, p) then
						mprop.is_broken = true
						return
					end
					break
				end
			end
		end

		mclassdef.mprop2npropdef[mprop] = self

		var mpropdef = new MMethodDef(mclassdef, mprop, self.location)
		if mpropdef.name == "defaultinit" and mclassdef.is_intro then
			assert mclassdef.default_init == null
			mpropdef.is_old_style_init = is_old_style_init
			mclassdef.default_init = mpropdef
			# Set the initializers with the mproperty.
			# This point is need when a super class define this own default_init and inherited class use the default_init generated automaticlely.
			mpropdef.initializers.add mprop
			mpropdef.is_calling_init = true
		end

		set_doc(mpropdef, modelbuilder)

		self.mpropdef = mpropdef
		modelbuilder.mpropdef2npropdef[mpropdef] = self
		if mpropdef.is_intro then
			modelbuilder.toolcontext.info("{mpropdef} introduces new method {mprop.full_name}", 4)
		else
			modelbuilder.toolcontext.info("{mpropdef} redefines method {mprop.full_name}", 4)
		end
	end
src/modelize/modelize_property.nit:794,2--910,4