end
end
end
-
v.stmt(self.n_block)
end
redef fun stmt(v)
do
var cl = v.expr(self.n_expr, null)
- var it = v.send(v.get_property("iterator", cl.mtype), [cl])
+ var it_meth = self.method_iterator
+ assert it_meth != null
+ var it = v.send(it_meth, [cl])
assert it != null
v.add("for(;;) \{")
- var ok = v.send(v.get_property("is_ok", it.mtype), [it])
+ var isok_meth = self.method_is_ok
+ assert isok_meth != null
+ var ok = v.send(isok_meth, [it])
assert ok != null
v.add("if(!{ok}) break;")
if self.variables.length == 1 then
- var i = v.send(v.get_property("item", it.mtype), [it])
+ var item_meth = self.method_item
+ assert item_meth != null
+ var i = v.send(item_meth, [it])
assert i != null
v.assign(v.variable(variables.first), i)
else if self.variables.length == 2 then
- var i = v.send(v.get_property("key", it.mtype), [it])
+ var key_meth = self.method_key
+ assert key_meth != null
+ var i = v.send(key_meth, [it])
assert i != null
v.assign(v.variable(variables[0]), i)
- i = v.send(v.get_property("item", it.mtype), [it])
+ var item_meth = self.method_item
+ assert item_meth != null
+ i = v.send(item_meth, [it])
assert i != null
v.assign(v.variable(variables[1]), i)
else
end
v.stmt(self.n_block)
v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
- v.send(v.get_property("next", it.mtype), [it])
+ var next_meth = self.method_next
+ assert next_meth != null
+ v.send(next_meth, [it])
v.add("\}")
v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
end
redef class AForExpr
var coltype: nullable MClassType
+ var method_iterator: nullable MMethod
+ var method_is_ok: nullable MMethod
+ var method_item: nullable MMethod
+ var method_next: nullable MMethod
+ var method_key: nullable MMethod
+
private fun do_type_iterator(v: TypeVisitor, mtype: MType)
do
var objcla = v.get_mclass(self, "Object")
if objcla == null then return
+ var is_col = false
+ var is_map = false
+
var colcla = v.try_get_mclass(self, "Collection")
if colcla != null and v.is_subtype(mtype, colcla.get_mtype([objcla.mclass_type.as_nullable])) then
var coltype = mtype.supertype_to(v.mmodule, v.anchor, colcla)
else
variables.first.declared_type = coltype.arguments.first
end
- return
+ is_col = true
end
var mapcla = v.try_get_mclass(self, "Map")
variables[0].declared_type = coltype.arguments[0]
variables[1].declared_type = coltype.arguments[1]
end
+ is_map = true
+ end
+
+ if is_col or is_map then
+ # get iterator method
+ var coltype = self.coltype.as(not null)
+ var itdef = v.get_method(self, coltype, "iterator", true)
+ var itdefsign = itdef.msignature
+ if itdef == null or itdefsign == null then
+ v.error(self, "Type Error: Expected method 'iterator' in type {coltype}")
+ return
+ end
+ self.method_iterator = itdef.mproperty
+
+ # get iterator type
+ var ittype = v.resolve_signature_for(itdefsign, mtype, false).return_mtype
+ if ittype == null then
+ v.error(self, "Type Error: Expected method 'iterator' to return an Iterator type")
+ return
+ end
+
+ # get methods is_ok, next, item
+ var ikdef = v.get_method(self, ittype, "is_ok", false)
+ if ikdef == null then
+ v.error(self, "Type Error: Expected method 'is_ok' in Iterator type {ittype}")
+ return
+ end
+ self.method_is_ok = ikdef.mproperty
+
+ var itemdef = v.get_method(self, ittype, "item", false)
+ if itemdef == null then
+ v.error(self, "Type Error: Expected method 'item' in Iterator type {ittype}")
+ return
+ end
+ self.method_item = itemdef.mproperty
+
+ var nextdef = v.get_method(self, ittype, "next", false)
+ if nextdef == null then
+ v.error(self, "Type Error: Expected method 'next' in Iterator type {ittype}")
+ return
+ end
+ self.method_next = nextdef.mproperty
+
+ if is_map then
+ var keydef = v.get_method(self, ittype, "key", false)
+ if keydef == null then
+ v.error(self, "Type Error: Expected method 'key' in Iterator type {ittype}")
+ return
+ end
+ self.method_key = keydef.mproperty
+ end
return
end