# The each parameter (in order)
var mparameters: Array[MParameter]
+ var mclosures = new Array[MParameter]
+
# The return type (null for a procedure)
var return_mtype: nullable MType
ret = ret.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
end
var res = new MSignature(params, ret)
+ for p in self.mclosures do
+ res.mclosures.add(p.resolve_for(mtype, anchor, mmodule, cleanup_virtual))
+ end
return res
end
end
if self.ret_type == null then return false # Skip errir
end
+ for nclosure in self.n_closure_decls do
+ if not nclosure.n_signature.visit_signature(modelbuilder, nclassdef) then return false
+ end
+
self.is_visited = true
return true
end
+
+ # Build a visited signature
+ fun build_signature(modelbuilder: ModelBuilder, nclassdef: AClassdef): nullable MSignature
+ do
+ if param_names.length != param_types.length then
+ # Some parameters are typed, other parameters are not typed.
+ modelbuilder.warning(self.n_params[param_types.length], "Error: Untyped parameter `{param_names[param_types.length]}'.")
+ return null
+ 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)
+ mparameters.add(mparameter)
+ end
+
+ var msignature = new MSignature(mparameters, ret_type)
+ return msignature
+ end
end
redef class AMethPropdef
var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank)
mparameters.add(mparameter)
end
+
msignature = new MSignature(mparameters, ret_type)
mpropdef.msignature = msignature
+
+ if nsig != null then
+ for nclosure in nsig.n_closure_decls do
+ var clos_signature = nclosure.n_signature.build_signature(modelbuilder, nclassdef)
+ if clos_signature == null then return
+ var mparameter = new MParameter(nclosure.n_id.text, clos_signature, false)
+ msignature.mclosures.add(mparameter)
+ end
+ end
+
end
redef fun check_signature(modelbuilder, nclassdef)
var variable: nullable ClosureVariable
end
+redef class ASendExpr
+ # The escape mark used with the closures if any
+ var escapemark: nullable EscapeMark
+
+ redef fun accept_scope_visitor(v)
+ do
+ if self.n_closure_defs.length > 0 then
+ var escapemark = v.make_escape_mark(self.n_closure_defs.last.n_label, true)
+ self.escapemark = escapemark
+ end
+ super
+ end
+end
+
redef class AClosureDef
# The automatic variables in order
var variables: nullable Array[Variable]
variables.add(va)
end
- var escapemark = v.make_escape_mark(n_label, true)
- self.escapemark = escapemark
+ self.escapemark = self.parent.as(ASendExpr).escapemark
v.enter_visit_block(self.n_expr, escapemark)
v.scopes.shift
assert variable != null
variable.declared_type = mtype
end
+ for i in [0..mmethoddef.msignature.mclosures.length[ do
+ var mclosure = mmethoddef.msignature.mclosures[i]
+ var variable = self.n_signature.n_closure_decls[i].variable
+ assert variable != null
+ variable.declared_type = mclosure.mtype
+ end
v.visit_stmt(nblock)
if not nblock.after_flow_context.is_unreachable and mmethoddef.msignature.return_mtype != null then
else
self.is_typed = true
end
+
+ if self.n_closure_defs.length == msignature.mclosures.length then
+ for i in [0..self.n_closure_defs.length[ do
+ self.n_closure_defs[i].accept_typing(v, msignature.mclosures[i])
+ end
+ else
+ debug("closure: got {self.n_closure_defs.length}, want {msignature.mclosures.length}")
+ end
end
# The name of the property
redef class AClosureCallExpr
redef fun accept_typing(v)
do
- #TODO
+ var variable = self.variable
+ if variable == null then return # Skip error
+
+ var recvtype = v.nclassdef.mclassdef.bound_mtype
+ var msignature = variable.declared_type.as(MSignature)
+ msignature = v.resolve_signature_for(msignature, recvtype, false)
+
+ var args = n_args.to_a
+ v.check_signature(self, args, variable.name, msignature)
+
+ self.is_typed = true
+ self.mtype = msignature.return_mtype
+ end
+end
+
+redef class AClosureDef
+ var mclosure: nullable MParameter
+
+ private fun accept_typing(v: TypeVisitor, mparameter: MParameter)
+ do
+ var variables = self.variables
+ if variables == null then return
+
+ self.mclosure = mparameter
+ var msignature = mparameter.mtype.as(MSignature)
+
+ if msignature.arity != variables.length then
+ v.error(self, "Type error: closure {mparameter.name} expects {msignature.arity} parameters, {variables.length} given")
+ return
+ end
+
+ for i in [0..variables.length[ do
+ variables[i].declared_type = msignature.mparameters[i].mtype
+ end
+
+ v.visit_stmt(self.n_expr)
end
end