end
end
+redef class PPropdef
+ redef fun self_var do return _self_var.as(not null)
+ var _self_var: nullable ParamVariable
+end
+
redef class AAttrPropdef
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx.sub(self)
+ _self_var = v.self_var
super
if n_expr != null then
v.check_conform_expr(n_expr.as(not null), prop.signature.return_type.as(not null))
end
redef class AMethPropdef
- redef fun self_var do return _self_var.as(not null)
- var _self_var: nullable ParamVariable
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
v.explicit_super_init_calls = explicit_super_init_calls
v.explicit_other_init_call = false
super
+ end
+
+ redef fun after_typing(v)
+ do
+ super
if v.explicit_other_init_call or method.global.intro != method then
# TODO: something?
else
end
var _stype: nullable MMType
+ redef fun after_typing(v)
+ do
+ # Default behavior is to be happy
+ _is_typed = true
+ end
+
# Is the expression the implicit receiver
fun is_implicit_self: Bool do return false
redef fun after_typing(v)
do
v.variable_ctx.unreash = true
+ _is_typed = true
end
end
_variable = va
v.variable_ctx.add(va)
+ # Process collection
v.enter_visit(n_expr)
if not v.check_conform_expr(n_expr, v.type_collection) then return
if not n_expr.is_self then t = t.not_for_self
va.stype = t
+ # Body evaluation
if n_block != null then v.enter_visit(n_block)
# pop context
do
var old_var_ctx = v.variable_ctx
+ # Process condition
v.enter_visit(n_expr)
+ v.check_conform_expr(n_expr, v.type_bool)
+
+ # Prepare 'then' context
v.use_if_true_variable_ctx(n_expr)
+
+ # Process 'then'
v.enter_visit(n_then)
+
+ # Prepare 'else' context
v.variable_ctx = old_var_ctx
v.use_if_false_variable_ctx(n_expr)
+
+ # Process 'else'
v.enter_visit(n_else)
- v.check_conform_expr(n_expr, v.type_bool)
+ var stype = v.check_conform_multiexpr(null, [n_then, n_else])
+ if stype == null then return
- _stype = v.check_conform_multiexpr(null, [n_then, n_else])
- _is_typed = _stype != null
+ _stype = stype
+ _is_typed = true
end
end
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
+ var stype = v.type_bool
+ _stype = stype
+ # Process left operand
v.enter_visit(n_expr)
+
+ # Prepare right operand context
v.use_if_false_variable_ctx(n_expr)
+ # Process right operand
v.enter_visit(n_expr2)
- if n_expr2.if_false_variable_ctx != null then
+ if n_expr2.if_false_variable_ctx != null then
_if_false_variable_ctx = n_expr2.if_false_variable_ctx
else
_if_false_variable_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx
- v.check_conform_expr(n_expr, v.type_bool)
- v.check_conform_expr(n_expr2, v.type_bool)
- _stype = v.type_bool
+ v.check_conform_expr(n_expr, stype)
+ v.check_conform_expr(n_expr2, stype)
+ _stype = stype
_is_typed = true
end
end
redef fun accept_typing(v)
do
var old_var_ctx = v.variable_ctx
+ var stype = v.type_bool
+ # Process left operand
v.enter_visit(n_expr)
+
+ # Prepare right operand context
v.use_if_true_variable_ctx(n_expr)
+ # Process right operand
v.enter_visit(n_expr2)
- if n_expr2.if_true_variable_ctx != null then
+ if n_expr2.if_true_variable_ctx != null then
_if_true_variable_ctx = n_expr2.if_true_variable_ctx
else
_if_true_variable_ctx = v.variable_ctx
v.variable_ctx = old_var_ctx
- v.check_conform_expr(n_expr, v.type_bool)
- v.check_conform_expr(n_expr2, v.type_bool)
- _stype = v.type_bool
+ v.check_conform_expr(n_expr, stype)
+ v.check_conform_expr(n_expr2, stype)
+ _stype = stype
_is_typed = true
end
end
for c in cs do
if not c.is_optional then min_arity += 1
end
- if cd != null then
- if cs.length == 0 then
- v.error(self, "Error: {name} does not require blocks.")
- else if cd.length > cs.length or cd.length < min_arity then
+ var arity = 0
+ if cd != null then arity = cd.length
+ if cs.length > 0 then
+ if arity == 0 and min_arity > 0 then
+ v.error(self, "Error: {name} requires {cs.length} blocks.")
+ else if arity > cs.length or arity < min_arity then
v.error(self, "Error: {name} requires {cs.length} blocks, {cd.length} found.")
else
# Initialize the break list if a value is required for breaks (ie. if the method is a function)
if t != null then break_list = new Array[ABreakExpr]
# Process each closure definition
- for i in [0..cd.length[ do
+ for i in [0..arity[ do
var csi = cs[i]
var cdi = cd[i]
var esc = new EscapableClosure(cdi, csi, break_list)
t = v.check_conform_multiexpr(t, break_list)
end
end
- else if min_arity != 0 then
- v.error(self, "Error: {name} requires {cs.length} blocks.")
+ else if arity != 0 then
+ v.error(self, "Error: {name} does not require blocks.")
end
return t
end
var name = n_id.to_symbol
var variable = v.variable_ctx[name]
if variable != null then
+ var n: PExpr
if variable isa ClosureVariable then
- var n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
- replace_with(n)
+ n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
n._variable = variable
- n.after_typing(v)
- return
else
if not n_args.is_empty then
v.error(self, "Error: {name} is variable, not a function.")
return
end
- var vform = variable_create(variable)
- vform._variable = variable
- replace_with(vform)
- vform.after_typing(v)
- return
+ n = variable_create(variable)
+ n._variable = variable
end
+ replace_with(n)
+ n.after_typing(v)
+ return
end
end