Property definitions

nitc :: typing $ AExpr :: accept_typing
	private fun accept_typing(v: TypeVisitor)
	do
		v.error(self, "no implemented accept_typing for {self.class_name}")
	end
src/semantize/typing.nit:1009,2--1012,4

nitc :: typing $ ABlockExpr :: accept_typing
	redef fun accept_typing(v)
	do
		for e in self.n_expr do v.visit_stmt(e)
		self.is_typed = true
	end
src/semantize/typing.nit:1056,2--1060,4

nitc :: typing $ AVardeclExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var variable = self.variable
		if variable == null then return # Skip error

		var ntype = self.n_type
		var mtype: nullable MType
		if ntype == null then
			mtype = null
		else
			mtype = v.resolve_mtype(ntype)
			if mtype == null then return # Skip error
		end

		var nexpr = self.n_expr
		if nexpr != null then
			if mtype != null then
				var etype = v.visit_expr_subtype(nexpr, mtype)
				if etype == mtype then
					assert ntype != null
					v.modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition for variable `{variable.name}`")
				end
			else
				mtype = v.visit_expr(nexpr)
				if mtype == null then return # Skip error
			end
		end

		var decltype = mtype
		if mtype == null or mtype isa MNullType then
			var objclass = v.get_mclass(self, "Object")
			if objclass == null then return # skip error
			decltype = objclass.mclass_type.as_nullable
			if mtype == null then mtype = decltype
		end

		variable.declared_type = decltype
		v.set_variable(self, variable, mtype)

		#debug("var {variable}: {mtype}")

		self.mtype = mtype
		self.is_typed = true
	end
src/semantize/typing.nit:1071,2--1114,4

nitc :: typing $ AAbortExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.is_typed = true
	end
src/semantize/typing.nit:1256,2--1259,4

nitc :: typing $ AIfExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)

		v.visit_stmt(n_then)
		v.visit_stmt(n_else)

		self.is_typed = true

		if n_then != null and n_else == null then
			self.mtype = n_then.mtype
		end
	end
src/semantize/typing.nit:1263,2--1275,4

nitc :: typing $ AIfexprExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)

		var t1 = v.visit_expr(n_then)
		var t2 = v.visit_expr(n_else)

		if t1 == null or t2 == null then
			return # Skip error
		end

		var t = v.merge_types(self, [t1, t2])
		if t == null then
			v.error(self, "Type Error: ambiguous type `{t1}` vs `{t2}`.")
		end
		self.mtype = t
	end
src/semantize/typing.nit:1279,2--1295,4

nitc :: typing $ AAssertExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)

		v.visit_stmt(n_else)
		self.is_typed = true
	end
src/semantize/typing.nit:1493,2--1499,4

nitc :: typing $ AIntegerExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var mclass: nullable MClass = null
		if value isa Byte then
			mclass = v.get_mclass(self, "Byte")
		else if value isa Int then
			mclass = v.get_mclass(self, "Int")
		else if value isa Int8 then
			mclass = v.get_mclass(self, "Int8")
		else if value isa Int16 then
			mclass = v.get_mclass(self, "Int16")
		else if value isa UInt16 then
			mclass = v.get_mclass(self, "UInt16")
		else if value isa Int32 then
			mclass = v.get_mclass(self, "Int32")
		else if value isa UInt32 then
			mclass = v.get_mclass(self, "UInt32")
		end
		if mclass == null then return # Forward error
		self.mtype = mclass.mclass_type
	end
src/semantize/typing.nit:1593,2--1613,4

nitc :: typing $ AFloatExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var mclass = v.get_mclass(self, "Float")
		if mclass == null then return # Forward error
		self.mtype = mclass.mclass_type
	end
src/semantize/typing.nit:1617,2--1622,4

nitc :: typing $ AArrayExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var mtype: nullable MType = null
		var ntype = self.n_type
		if ntype != null then
			mtype = v.resolve_mtype(ntype)
			if mtype == null then return # Skip error
		end
		var mtypes = new Array[nullable MType]
		var useless = false
		for e in self.n_exprs do
			var t = v.visit_expr(e)
			if t == null then
				return # Skip error
			end
			set_comprehension(e)
			if mtype != null then
				if v.check_subtype(e, t, mtype, false) == null then return # Forward error
				if t == mtype then useless = true
			else
				mtypes.add(t)
			end
		end
		if mtype == null then
			# Ensure monotony for type adaptation on loops
			if self.element_mtype != null then mtypes.add self.element_mtype
			mtype = v.merge_types(self, mtypes)
		end
		if mtype == null or mtype isa MNullType then
			v.error(self, "Type Error: ambiguous array type {mtypes.join(" ")}")
			return
		end
		if useless then
			assert ntype != null
			v.display_warning(ntype, "useless-type", "Warning: useless type declaration `{mtype}` in literal Array since it can be inferred from the elements type.")
		end

		self.element_mtype = mtype

		var mclass = v.get_mclass(self, "Array")
		if mclass == null then return # Forward error
		var array_mtype = mclass.get_mtype([mtype])

		with_capacity_callsite = v.build_callsite_by_name(self, array_mtype, "with_capacity", false)
		push_callsite = v.build_callsite_by_name(self, array_mtype, "push", false)

		self.mtype = array_mtype
	end
src/semantize/typing.nit:1726,2--1773,4

nitc :: typing $ ANullExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.mtype = v.mmodule.model.null_type
	end
src/semantize/typing.nit:1815,2--1818,4

nitc :: typing $ AParExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.mtype = v.visit_expr(self.n_expr)
	end
src/semantize/typing.nit:1913,2--1916,4

nitc :: typing $ AOnceExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.mtype = v.visit_expr(self.n_expr)
	end
src/semantize/typing.nit:1920,2--1923,4

nitc :: typing $ ASendExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var nrecv = self.n_expr
		var recvtype = v.visit_expr(nrecv)

		if nrecv isa ASafeExpr then
			# Has the receiver the form `x?.foo`?
			# For parsing "reasons" the `?` is in the receiver node, not the call node.
			is_safe = true
		end

		var name = self.property_name
		var node = self.property_node

		if recvtype == null then return # Forward error

		var callsite = null
		var unsafe_type = v.anchor_to(recvtype)
		var mproperty = v.try_get_mproperty_by_name2(node, unsafe_type, name)
		if mproperty == null and nrecv isa AImplicitSelfExpr then
			# Special fall-back search in `sys` when noting found in the implicit receiver.
			var sysclass = v.try_get_mclass(node, "Sys")
			if sysclass != null then
				var systype = sysclass.mclass_type
				mproperty = v.try_get_mproperty_by_name2(node, systype, name)
				if mproperty != null then
					callsite = v.build_callsite_by_name(node, systype, name, false)
					if callsite == null then return # Forward error
					# Update information, we are looking at `sys` now, not `self`
					nrecv.is_sys = true
					nrecv.its_variable = null
					nrecv.mtype = systype
					recvtype = systype
				end
			end
		end
		if callsite == null then
			# If still nothing, just exit
			callsite = v.build_callsite_by_name(node, recvtype, name, nrecv isa ASelfExpr)
			if callsite == null then return
		end

		self.callsite = callsite
		var msignature = callsite.msignature

		var args = compute_raw_arguments

		if not self isa ACallrefExpr then callsite.check_signature(v, node, args)

		if callsite.mproperty.is_init then
			var vmpropdef = v.mpropdef
			if not (vmpropdef isa MMethodDef and vmpropdef.mproperty.is_init) then
				v.error(node, "Error: an `init` can only be called from another `init`.")
			end
			if vmpropdef isa MMethodDef and vmpropdef.mproperty.is_root_init and not callsite.mproperty.is_root_init then
				v.error(node, "Error: `{vmpropdef}` cannot call a factory `{callsite.mproperty}`.")
			end
		end

		var ret = msignature.return_mtype
		if ret != null then
			if is_safe then
				# A safe receiver makes that the call is not executed and returns null
				ret = ret.as_nullable
			end
			self.mtype = ret
		else
			self.is_typed = true
		end
	end
src/semantize/typing.nit:1967,2--2036,4

nitc :: typing $ ASuperExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var anchor = v.anchor
		var recvtype = v.get_variable(self, v.selfvariable)
		assert recvtype != null
		var mproperty = v.mpropdef.mproperty
		if not mproperty isa MMethod then
			v.error(self, "Error: `super` only usable in a `method`.")
			return
		end
		var superprops = mproperty.lookup_super_definitions(v.mmodule, anchor)
		if superprops.length == 0 then
			if mproperty.is_init and v.mpropdef.is_intro then
				process_superinit(v)
				return
			end
			v.error(self, "Error: no super method to call for `{mproperty}`.")
			return
		end
		# FIXME: covariance of return type in linear extension?
		var superprop = superprops.first

		var msignature = superprop.msignature.as(not null)
		msignature = v.resolve_for(msignature, recvtype, true).as(MSignature)
		var args = self.n_args.to_a
		if args.length > 0 then
			signaturemap = v.check_signature(self, args, mproperty, msignature)
		end
		self.mtype = msignature.return_mtype
		self.is_typed = true
		v.mpropdef.has_supercall = true
		mpropdef = v.mpropdef.as(MMethodDef)
	end
src/semantize/typing.nit:2275,2--2307,4

nitc :: typing $ ANewExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var recvtype = v.resolve_mtype(self.n_type)
		if recvtype == null then return

		if not recvtype isa MClassType then
			if recvtype isa MNullableType then
				v.error(self, "Type Error: cannot instantiate the nullable type `{recvtype}`.")
				return
			else if recvtype isa MFormalType then
				v.error(self, "Type Error: cannot instantiate the formal type `{recvtype}`.")
				return
			else
				v.error(self, "Type Error: cannot instantiate the type `{recvtype}`.")
				return
			end
		end

		self.recvtype = recvtype
		var kind = recvtype.mclass.kind

		var name: String
		var nqid = self.n_qid
		var node: ANode
		if nqid != null then
			name = nqid.n_id.text
			node = nqid
		else
			name = "new"
			node = self.n_kwnew
		end
		if name == "intern" then
			if kind != concrete_kind then
				v.error(self, "Type Error: cannot instantiate {kind} {recvtype}.")
				return
			end
			if n_args.n_exprs.not_empty then
				v.error(n_args, "Type Error: the intern constructor expects no arguments.")
				return
			end
			# Our job is done
			self.mtype = recvtype
			return
		end

		var callsite = v.build_callsite_by_name(node, recvtype, name, false)
		if callsite == null then return

		if not callsite.mproperty.is_new then
			if kind != concrete_kind then
				v.error(self, "Type Error: cannot instantiate {kind} `{recvtype}`.")
				return
			end
			self.mtype = recvtype
		else
			self.mtype = callsite.msignature.return_mtype
			assert self.mtype != null
		end

		self.callsite = callsite

		if not callsite.mproperty.is_init_for(recvtype.mclass) then
			v.error(self, "Error: `{name}` is not a constructor.")
			return
		end

		var args = n_args.to_a
		callsite.check_signature(v, node, args)
	end
src/semantize/typing.nit:2406,2--2474,4

nitc :: typing $ AVarargExpr :: accept_typing
	redef fun accept_typing(v)
	do
		# This kind of pseudo-expression can be only processed trough a signature
		# See `check_signature`
		# Other cases are a syntax error.
		v.error(self, "Syntax Error: unexpected `...`.")
	end
src/semantize/typing.nit:2607,2--2613,4

nitc :: typing $ ASafeExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var mtype = v.visit_expr(n_expr)
		if mtype == null then return # Skip error

		if mtype isa MNullType then
			# While `null?.foo` is semantically well defined and should not execute `foo` and just return `null`,
			# currently `null.foo` is forbidden so it seems coherent to also forbid `null?.foo`
			v.modelbuilder.error(self, "Error: safe operator `?` on `null`.")
			return
		end

		self.mtype = mtype.as_notnull

		if not v.can_be_null(mtype) then
			v.display_warning(self, "useless-safe", "Warning: useless safe operator `?` on non-nullable value.")
			return
		end
	end
src/semantize/typing.nit:2585,2--2603,4

nitc :: typing $ ADebugTypeExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var expr = v.visit_expr(self.n_expr)
		if expr == null then return
		var unsafe = v.anchor_to(expr)
		var ntype = self.n_type
		var mtype = v.resolve_mtype(ntype)
		if mtype != null and mtype != expr then
			var umtype = v.anchor_to(mtype)
			v.display_warning(self, "debug", "Found type {expr} (-> {unsafe}), expected {mtype} (-> {umtype})")
		end
		self.is_typed = true
	end
src/semantize/typing.nit:2619,2--2631,4

nitc :: typing $ ARangeExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var discrete_class = v.get_mclass(self, "Discrete")
		if discrete_class == null then return # Forward error
		var discrete_type = discrete_class.intro.bound_mtype
		var t1 = v.visit_expr_subtype(self.n_expr, discrete_type)
		var t2 = v.visit_expr_subtype(self.n_expr2, discrete_type)
		if t1 == null or t2 == null then return
		var mclass = v.get_mclass(self, "Range")
		if mclass == null then return # Forward error
		var mtype
		if v.is_subtype(t1, t2) then
			mtype = mclass.get_mtype([t2])
		else if v.is_subtype(t2, t1) then
			mtype = mclass.get_mtype([t1])
		else
			v.error(self, "Type Error: cannot create range: `{t1}` vs `{t2}`.")
			return
		end

		self.mtype = mtype

		# get the constructor
		var callsite
		if self isa ACrangeExpr then
			callsite = v.build_callsite_by_name(self, mtype, "defaultinit", false)
		else if self isa AOrangeExpr then
			callsite = v.build_callsite_by_name(self, mtype, "without_last", false)
		else
			abort
		end
		init_callsite = callsite
	end
src/semantize/typing.nit:1779,2--1811,4

nitc :: typing $ AVarExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var variable = self.variable
		if variable == null then return # Skip error

		var mtype = v.get_variable(self, variable)
		if mtype != null then
			#debug("{variable} is {mtype}")
		else
			#debug("{variable} is untyped")
		end

		self.mtype = mtype
	end
src/semantize/typing.nit:1119,2--1132,4

nitc :: typing $ ANotExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1530,2--1534,4

nitc :: typing $ ACharExpr :: accept_typing
	redef fun accept_typing(v) do
		var mclass: nullable MClass = null
		if is_code_point then
			mclass = v.get_mclass(self, "Int")
		else
			mclass = v.get_mclass(self, "Char")
		end
		if mclass == null then return # Forward error
		self.mtype = mclass.mclass_type
	end
src/semantize/typing.nit:1626,2--1635,4

nitc :: typing $ AugmentedStringFormExpr :: accept_typing
	redef fun accept_typing(v) do
		var mclass = v.get_mclass(self, "String")
		if mclass == null then return # Forward error
		if is_bytestring then
			to_bytes_with_copy = v.build_callsite_by_name(self, v.mmodule.c_string_type, "to_bytes_with_copy", false)
			mclass = v.get_mclass(self, "Bytes")
		else if is_re then
			to_re = v.build_callsite_by_name(self, mclass.mclass_type, "to_re", false)
			for i in suffix.chars do
				mclass = v.get_mclass(self, "Regex")
				if mclass == null then
					v.error(self, "Error: `Regex` class unknown")
					return
				end
				var service = ""
				if i == 'i' then
					service = "ignore_case="
					ignore_case = v.build_callsite_by_name(self, mclass.mclass_type, service, false)
				else if i == 'm' then
					service = "newline="
					newline = v.build_callsite_by_name(self, mclass.mclass_type, service, false)
				else if i == 'b' then
					service = "extended="
					extended = v.build_callsite_by_name(self, mclass.mclass_type, service, false)
				else
					v.error(self, "Type Error: Unrecognized suffix {i} in prefixed Regex")
					abort
				end
			end
		end
		if mclass == null then return # Forward error
		mtype = mclass.mclass_type
	end
src/semantize/typing.nit:1652,2--1684,4

nitc :: typing $ ATrueExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1579,2--1582,4

nitc :: typing $ AFalseExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1586,2--1589,4

nitc :: typing $ AIsaExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr(n_expr)

		var mtype = v.resolve_mtype(n_type)

		self.cast_type = mtype

		var variable = self.n_expr.its_variable
		if variable != null then
			var orig = self.n_expr.mtype
			#var from = if orig != null then orig.to_s else "invalid"
			#var to = if mtype != null then mtype.to_s else "invalid"
			#debug("adapt {variable}: {from} -> {to}")

			var thentype = v.intersect_types(self, orig, mtype)
			if thentype != orig then
				self.after_flow_context.when_true.set_var(v, variable, thentype)
				#debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> then {thentype or else "?"}"
			end

			var elsetype = v.diff_types(self, orig, mtype)
			if elsetype != orig then
				self.after_flow_context.when_false.set_var(v, variable, elsetype)
				#debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> else {elsetype or else "?"}"
			end
		end

		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1825,2--1854,4

nitc :: typing $ AAsCastExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr(n_expr)

		self.mtype = v.resolve_mtype(n_type)
	end
src/semantize/typing.nit:1873,2--1878,4

nitc :: typing $ AAsNotnullExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var mtype = v.visit_expr(self.n_expr)
		if mtype == null then return # Forward error

		if mtype isa MNullType then
			v.error(self, "Type Error: `as(not null)` on `null`.")
			return
		end

		if v.can_be_null(mtype) then
			mtype = mtype.as_notnull
		end

		self.mtype = mtype
	end
src/semantize/typing.nit:1887,2--1902,4

nitc :: typing $ AAttrExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.resolve_property(v)
		self.mtype = self.attr_type
	end
src/semantize/typing.nit:2537,2--2541,4

nitc :: typing $ AIssetAttrExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.resolve_property(v)
		var mtype = self.attr_type
		if mtype == null then return # Skip error

		var recvtype = self.n_expr.mtype.as(not null)
		var bound = v.resolve_for(mtype, recvtype, false)
		if bound isa MNullableType then
			v.error(n_id, "Type Error: `isset` on a nullable attribute.")
		end
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:2569,2--2581,4

nitc :: typing $ AVarAssignExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var variable = self.variable
		assert variable != null

		var mtype = v.visit_expr_subtype(n_value, variable.declared_type)

		v.set_variable(self, variable, mtype)

		self.is_typed = true
	end
src/semantize/typing.nit:1136,2--1146,4

nitc :: typing $ AVarReassignExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var variable = self.variable
		assert variable != null

		var readtype = v.get_variable(self, variable)
		if readtype == null then return

		read_type = readtype

		var writetype = variable.declared_type
		if writetype == null then return

		var rettype = self.resolve_reassignment(v, readtype, writetype)

		v.set_variable(self, variable, rettype)

		self.is_typed = rettype != null
	end
src/semantize/typing.nit:1183,2--1201,4

nitc :: typing $ AOrElseExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var t1 = v.visit_expr(n_expr)
		var t2 = v.visit_expr(n_expr2)

		if t1 == null or t2 == null then
			return # Skip error
		end

		if t1 isa MNullType then
			self.mtype = t2
			return
		else if v.can_be_null(t1) then
			t1 = t1.as_notnull
		end

		var t = v.merge_types(self, [t1, t2])
		if t == null then
			var c = v.get_mclass(self, "Object")
			if c == null then return # forward error
			t = c.mclass_type
			if v.can_be_null(t2) then
				t = t.as_nullable
			end
			#v.error(self, "Type Error: ambiguous type {t1} vs {t2}")
		end
		self.mtype = t
	end
src/semantize/typing.nit:1538,2--1565,4

nitc :: typing $ ASuperstringExpr :: accept_typing
	redef fun accept_typing(v)
	do
		super
		var objclass = v.get_mclass(self, "Object")
		if objclass == null then return # Forward error
		var objtype = objclass.mclass_type
		for nexpr in self.n_exprs do
			v.visit_expr_subtype(nexpr, objtype)
		end
	end
src/semantize/typing.nit:1688,2--1697,4

nitc :: typing $ ACallrefExpr :: accept_typing
	redef fun accept_typing(v)
	do
		super # do the job as if it was a real call
		var res = callsite.mproperty

                var msignature = callsite.mpropdef.msignature
                var recv = callsite.recv
                assert msignature != null
                var arity = msignature.mparameters.length

                var routine_type_name = "ProcRef"
                if msignature.return_mtype != null then
                        routine_type_name = "FunRef"
                end

                var target_routine_class = "{routine_type_name}{arity}"
                var routine_mclass = v.get_mclass(self, target_routine_class)

                if routine_mclass == null then
                        v.error(self, "Error: missing functional types, try `import functional`")
                        return
                end

                var types_list = new Array[MType]
                for param in msignature.mparameters do
                        if param.is_vararg then
                                types_list.push(v.mmodule.array_type(param.mtype))
                        else
                                types_list.push(param.mtype)
                        end
                end
                if msignature.return_mtype != null then
                        types_list.push(msignature.return_mtype.as(not null))
                end

                # Why we need an anchor :
                #
                # ~~~~nitish
                # class A[E]
                #       def toto(x: E) do print "{x}"
                # end
                #
                # var a = new A[Int]
                # var f = &a.toto # without anchor : ProcRef1[E]
                #		  # with anchor : ProcRef[Int]
                # ~~~~
		# However, we can only anchor if we can resolve every formal
		# parameter, here's an example where we can't.
		# ~~~~nitish
		# class A[E]
		#	fun bar: A[E] do return self
		#	fun foo: Fun0[A[E]] do return &bar # here we can't anchor
		# end
		# var f1 = a1.foo # when this expression will be evaluated,
		#		  # `a1` will anchor `&bar` returned by `foo`.
		# print f1.call
		# ~~~~
		var routine_type = routine_mclass.get_mtype(types_list)
		if not recv.need_anchor then
			routine_type = routine_type.anchor_to(v.mmodule, recv.as(MClassType))
		end
                is_typed = true
		self.mtype = routine_type
	end
src/semantize/typing.nit:2194,2--2257,4

nitc :: typing $ ASendReassignFormExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var recvtype = v.visit_expr(self.n_expr)
		var name = self.property_name
		var node = self.property_node

		if recvtype == null then return # Forward error

		var for_self = self.n_expr isa ASelfExpr
		var callsite = v.build_callsite_by_name(node, recvtype, name, for_self)

		if callsite == null then return
		self.callsite = callsite

		var args = compute_raw_arguments

		callsite.check_signature(v, node, args)

		var readtype = callsite.msignature.return_mtype
		if readtype == null then
			v.error(node, "Error: `{name}` is not a function.")
			return
		end

		var wcallsite = v.build_callsite_by_name(node, recvtype, name + "=", self.n_expr isa ASelfExpr)
		if wcallsite == null then return
		self.write_callsite = wcallsite

		var wtype = self.resolve_reassignment(v, readtype, wcallsite.msignature.mparameters.last.mtype)
		if wtype == null then return

		args = args.to_a # duplicate so raw_arguments keeps only the getter args
		args.add(self.n_value)
		wcallsite.check_signature(v, node, args)

		self.is_typed = true
	end
src/semantize/typing.nit:2133,2--2169,4

nitc :: typing $ AAttrAssignExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.resolve_property(v)
		var mtype = self.attr_type

		v.visit_expr_subtype(self.n_value, mtype)
		self.is_typed = mtype != null
	end
src/semantize/typing.nit:2545,2--2552,4

nitc :: typing $ AAttrReassignExpr :: accept_typing
	redef fun accept_typing(v)
	do
		self.resolve_property(v)
		var mtype = self.attr_type
		if mtype == null then return # Skip error

		var rettype = self.resolve_reassignment(v, mtype, mtype)

		self.is_typed = rettype != null
	end
src/semantize/typing.nit:2556,2--2565,4

nitc :: typing $ AReturnExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var nexpr = self.n_expr
		var ret_type
		var mpropdef = v.mpropdef
		if mpropdef isa MMethodDef then
			ret_type = mpropdef.msignature.return_mtype
		else if mpropdef isa MAttributeDef then
			ret_type = mpropdef.static_mtype
		else
			abort
		end
		if nexpr != null then
			if ret_type != null then
				v.visit_expr_subtype(nexpr, ret_type)
			else
				v.visit_expr(nexpr)
				v.error(nexpr, "Error: `return` with value in a procedure.")
				return
			end
		else if ret_type != null then
			v.error(self, "Error: `return` without value in a function.")
			return
		end
		self.is_typed = true
	end
src/semantize/typing.nit:1227,2--1252,4

nitc :: typing $ ABreakExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var nexpr = self.n_expr
		if nexpr != null then
			v.visit_expr(nexpr)
		end
		self.is_typed = true
	end
src/semantize/typing.nit:1216,2--1223,4

nitc :: typing $ AContinueExpr :: accept_typing
	redef fun accept_typing(v)
	do
		var nexpr = self.n_expr
		if nexpr != null then
			v.visit_expr(nexpr)
		end
		self.is_typed = true
	end
src/semantize/typing.nit:1205,2--1212,4

nitc :: typing $ ADoExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_stmt(n_block)
		v.visit_stmt(n_catch)
		self.is_typed = true
	end
src/semantize/typing.nit:1299,2--1304,4

nitc :: typing $ AWhileExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.has_loop = true
		v.visit_expr_bool(n_expr)
		v.visit_stmt(n_block)
		self.is_typed = true
	end
src/semantize/typing.nit:1308,2--1314,4

nitc :: typing $ ALoopExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.has_loop = true
		v.visit_stmt(n_block)
		self.is_typed = true
	end
src/semantize/typing.nit:1318,2--1323,4

nitc :: typing $ AForExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.has_loop = true

		for g in n_groups do
			var mtype = v.visit_expr(g.n_expr)
			if mtype == null then return
			g.do_type_iterator(v, mtype)
			if g.is_broken then is_broken = true
		end

		v.visit_stmt(n_block)

		self.mtype = n_block.mtype
		self.is_typed = true
	end
src/semantize/typing.nit:1327,2--1342,4

nitc :: typing $ AOrExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)
		v.visit_expr_bool(n_expr2)
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1503,2--1508,4

nitc :: typing $ AImpliesExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)
		v.visit_expr_bool(n_expr2)
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1512,2--1517,4

nitc :: typing $ AAndExpr :: accept_typing
	redef fun accept_typing(v)
	do
		v.visit_expr_bool(n_expr)
		v.visit_expr_bool(n_expr2)
		self.mtype = v.type_bool(self)
	end
src/semantize/typing.nit:1521,2--1526,4

nitc :: typing $ AEqFormExpr :: accept_typing
	redef fun accept_typing(v)
	do
		super
		v.null_test(self)
	end
src/semantize/typing.nit:2069,2--2073,4