Use CallSite to resolve and type some implicit services.
Subsequent phases will like them!
Currenlty: all the AFor and ARange services are converted and tools updated.
TODO: Array and SuperString
Pull-Request: #370
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
var cl = v.expr(self.n_expr, null)
var it_meth = self.method_iterator
assert it_meth != null
- var it = v.send(it_meth, [cl])
+ var it = v.compile_callsite(it_meth, [cl])
assert it != null
v.add("for(;;) \{")
var isok_meth = self.method_is_ok
assert isok_meth != null
- var ok = v.send(isok_meth, [it])
+ var ok = v.compile_callsite(isok_meth, [it])
assert ok != null
v.add("if(!{ok}) break;")
if self.variables.length == 1 then
var item_meth = self.method_item
assert item_meth != null
- var i = v.send(item_meth, [it])
+ var i = v.compile_callsite(item_meth, [it])
assert i != null
v.assign(v.variable(variables.first), i)
else if self.variables.length == 2 then
var key_meth = self.method_key
assert key_meth != null
- var i = v.send(key_meth, [it])
+ var i = v.compile_callsite(key_meth, [it])
assert i != null
v.assign(v.variable(variables[0]), i)
var item_meth = self.method_item
assert item_meth != null
- i = v.send(item_meth, [it])
+ i = v.compile_callsite(item_meth, [it])
assert i != null
v.assign(v.variable(variables[1]), i)
else
v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
var next_meth = self.method_next
assert next_meth != null
- v.send(next_meth, [it])
+ v.compile_callsite(next_meth, [it])
v.add("\}")
v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
end
var i2 = v.expr(self.n_expr2, null)
var mtype = self.mtype.as(MClassType)
var res = v.init_instance(mtype)
- var it = v.send(v.get_property("init", res.mtype), [res, i1, i2])
+ var it = v.compile_callsite(init_callsite.as(not null), [res, i1, i2])
return res
end
end
var i2 = v.expr(self.n_expr2, null)
var mtype = self.mtype.as(MClassType)
var res = v.init_instance(mtype)
- var it = v.send(v.get_property("without_last", res.mtype), [res, i1, i2])
+ var it = v.compile_callsite(init_callsite.as(not null), [res, i1, i2])
return res
end
end
if col.mtype isa MNullType then fatal(v, "Receiver is null")
#self.debug("col {col}")
- var iter = v.send(v.force_get_primitive_method("iterator", col.mtype), [col]).as(not null)
+ var iter = v.callsite(method_iterator, [col]).as(not null)
#self.debug("iter {iter}")
loop
- var isok = v.send(v.force_get_primitive_method("is_ok", iter.mtype), [iter]).as(not null)
+ var isok = v.callsite(method_is_ok, [iter]).as(not null)
if not isok.is_true then return
if self.variables.length == 1 then
- var item = v.send(v.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
+ var item = v.callsite(method_item, [iter]).as(not null)
#self.debug("item {item}")
v.frame.map[self.variables.first] = item
else if self.variables.length == 2 then
- var key = v.send(v.force_get_primitive_method("key", iter.mtype), [iter]).as(not null)
+ var key = v.callsite(method_key, [iter]).as(not null)
v.frame.map[self.variables[0]] = key
- var item = v.send(v.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
+ var item = v.callsite(method_item, [iter]).as(not null)
v.frame.map[self.variables[1]] = item
else
abort
if v.is_break(self.escapemark) then return
v.is_continue(self.escapemark) # Clear the break
if v.is_escaping then return
- v.send(v.force_get_primitive_method("next", iter.mtype), [iter])
+ v.callsite(method_next, [iter])
end
end
end
var mtype = v.unanchor_type(self.mtype.as(not null))
var res = new MutableInstance(mtype)
v.init_instance(res)
- v.send(v.force_get_primitive_method("init", mtype), [res, e1, e2])
+ v.callsite(init_callsite, [res, e1, e2])
return res
end
end
var mtype = v.unanchor_type(self.mtype.as(not null))
var res = new MutableInstance(mtype)
v.init_instance(res)
- v.send(v.force_get_primitive_method("without_last", mtype), [res, e1, e2])
+ v.callsite(init_callsite, [res, e1, e2])
return res
end
end
do
var mtype = self.mtype.as(MClassType)
v.add_type(mtype)
- var prop = v.get_method(mtype, "init")
- v.add_monomorphic_send(mtype, prop)
+ v.add_callsite(init_callsite)
end
end
do
var mtype = self.mtype.as(MClassType)
v.add_type(mtype)
- var prop = v.get_method(mtype, "without_last")
- v.add_monomorphic_send(mtype, prop)
+ v.add_callsite(init_callsite)
end
end
redef class AForExpr
redef fun accept_rapid_type_visitor(v)
do
- var recvtype = self.n_expr.mtype.as(not null)
- var colltype = self.coltype.as(not null)
- var itmeth = v.get_method(colltype, "iterator")
- v.add_send(recvtype, itmeth)
- var iteratortype = itmeth.intro.msignature.return_mtype.as(MClassType).mclass.intro.bound_mtype
- var objtype = v.get_class("Object").mclass_type
- v.add_send(objtype, v.get_method(iteratortype, "is_ok"))
+ v.add_callsite(self.method_iterator)
+ v.add_callsite(self.method_is_ok)
if self.variables.length == 1 then
- v.add_send(objtype, v.get_method(iteratortype, "item"))
+ v.add_callsite(self.method_item)
else if self.variables.length == 2 then
- v.add_send(objtype, v.get_method(iteratortype, "key"))
- v.add_send(objtype, v.get_method(iteratortype, "item"))
+ v.add_callsite(self.method_key)
+ v.add_callsite(self.method_item)
else
abort
end
- v.add_send(objtype, v.get_method(iteratortype, "next"))
+ v.add_callsite(self.method_next)
end
end
redef fun accept_transform_visitor(v)
do
var mtype = self.mtype.as(MClassType)
- var meth = v.get_method(self, "init", mtype.mclass)
-
- replace_with(v.builder.make_new(mtype, meth, [n_expr, n_expr2]))
+ replace_with(v.builder.make_new(mtype, init_callsite.mproperty, [n_expr, n_expr2]))
end
end
redef fun accept_transform_visitor(v)
do
var mtype = self.mtype.as(MClassType)
- var meth = v.get_method(self, "without_last", mtype.mclass)
-
- replace_with(v.builder.make_new(mtype, meth, [n_expr, n_expr2]))
+ replace_with(v.builder.make_new(mtype, init_callsite.mproperty, [n_expr, n_expr2]))
end
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
+ var method_iterator: nullable CallSite
+ var method_is_ok: nullable CallSite
+ var method_item: nullable CallSite
+ var method_next: nullable CallSite
+ var method_key: nullable CallSite
private fun do_type_iterator(v: TypeVisitor, mtype: MType)
do
if objcla == null then return
# check iterator method
- var unsafe_type = v.anchor_to(mtype)
- if v.try_get_mproperty_by_name2(self, unsafe_type, "iterator") == null then
- if v.try_get_mproperty_by_name2(self, unsafe_type, "iterate") == null then
- v.error(self, "Type Error: 'for' expects a type providing 'iterator' method, got '{mtype}'.")
- else
- v.modelbuilder.error(self, "NOT YET IMPLEMENTED: Do 'for' on {mtype}")
- end
- return
- end
-
var itdef = v.get_method(self, mtype, "iterator", true)
if itdef == null then
v.error(self, "Type Error: 'for' expects a type providing 'iterator' method, got '{mtype}'.")
return
end
- self.method_iterator = itdef.mproperty
+ self.method_iterator = itdef
# check that iterator return something
var ittype = itdef.msignature.return_mtype
v.error(self, "Type Error: 'for' expects a method 'is_ok' in 'Iterator' type {ittype}.")
return
end
- self.method_is_ok = ikdef.mproperty
+ self.method_is_ok = ikdef
var itemdef = v.get_method(self, ittype, "item", false)
if itemdef == null then
v.error(self, "Type Error: 'for' expects a method 'item' in 'Iterator' type {ittype}.")
return
end
- self.method_item = itemdef.mproperty
+ self.method_item = itemdef
var nextdef = v.get_method(self, ittype, "next", false)
if nextdef == null then
v.error(self, "Type Error: 'for' expects a method 'next' in 'Iterator' type {ittype}.")
return
end
- self.method_next = nextdef.mproperty
+ self.method_next = nextdef
if is_map then
var keydef = v.get_method(self, ittype, "key", false)
v.error(self, "Type Error: 'for' expects a method 'key' in 'Iterator' type {ittype}.")
return
end
- self.method_key = keydef.mproperty
+ self.method_key = keydef
end
end
end
redef class ARangeExpr
+ var init_callsite: nullable CallSite
+
redef fun accept_typing(v)
do
var discrete_class = v.get_mclass(self, "Discrete")
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
- self.mtype = mclass.get_mtype([t2])
+ mtype = mclass.get_mtype([t2])
else if v.is_subtype(t2, t1) then
- self.mtype = mclass.get_mtype([t1])
+ 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.get_method(self, mtype, "init", false)
+ else if self isa AOrangeExpr then
+ callsite = v.get_method(self, mtype, "without_last", false)
+ else
+ abort
end
+ init_callsite = callsite
end
end
base_iterator3.nit:35,1--25: Type Error: 'for' expects method 'iterator' to return an 'Iterator' or 'MapIterator' type'.
base_iterator3.nit:39,1--25: Type Error: 'for' expects method 'iterator' to return an 'Iterator' or 'MapIterator' type'.
+base_iterator3.nit:43,1--25: Error: Method or variable 'iterator' unknown in Test3.
base_iterator3.nit:43,1--25: Type Error: 'for' expects a type providing 'iterator' method, got 'Test3'.
base_iterator3.nit:46,1--48: Type Error: 'for' expects only one variable when using 'Iterator'.
base_iterator3.nit:47,1--47: Type Error: 'for' expects two variables when using 'MapIterator'.
alt/error_expr_not_ok_alt4.nit:67,1--18: Warning: use 'loop' instead of 'while true do'.
alt/error_expr_not_ok_alt4.nit:69,24: Type error: expected A, got Int
alt/error_expr_not_ok_alt4.nit:69,1--25: Type Error: 'for' expects a type providing 'iterator' method, got 'Int'.
+alt/error_expr_not_ok_alt4.nit:69,1--25: Error: Method or variable 'iterator' unknown in Int.
alt/error_expr_not_ok_alt4.nit:71,8--11: Type error: expected Bool, got Int
alt/error_expr_not_ok_alt4.nit:72,7--15: Type error: expected A, got Int
alt/error_expr_not_ok_alt4.nit:73,7--10: Type error: expected Bool, got Int
alt/error_expr_not_ok_alt5.nit:67,1--18: Warning: use 'loop' instead of 'while true do'.
alt/error_expr_not_ok_alt5.nit:69,24: Type error: expected A, got Int
alt/error_expr_not_ok_alt5.nit:69,1--25: Type Error: 'for' expects a type providing 'iterator' method, got 'Int'.
+alt/error_expr_not_ok_alt5.nit:69,1--25: Error: Method or variable 'iterator' unknown in Int.
alt/error_expr_not_ok_alt5.nit:71,8--11: Type error: expected Bool, got Int
alt/error_expr_not_ok_alt5.nit:72,7--15: Type error: expected A, got Int
alt/error_expr_not_ok_alt5.nit:73,7--10: Type error: expected Bool, got Int
alt/error_expr_not_ok_alt6.nit:67,1--18: Warning: use 'loop' instead of 'while true do'.
alt/error_expr_not_ok_alt6.nit:69,24: Type error: expected A, got Int
alt/error_expr_not_ok_alt6.nit:69,1--25: Type Error: 'for' expects a type providing 'iterator' method, got 'Int'.
+alt/error_expr_not_ok_alt6.nit:69,1--25: Error: Method or variable 'iterator' unknown in Int.
alt/error_expr_not_ok_alt6.nit:71,8--11: Type error: expected Bool, got Int
alt/error_expr_not_ok_alt6.nit:72,7--15: Type error: expected A, got Int
alt/error_expr_not_ok_alt6.nit:73,7--10: Type error: expected Bool, got Int
+error_for_coll.nit:17,1--18,3: Error: Method or variable 'iterator' unknown in Int.
error_for_coll.nit:17,1--18,3: Type Error: 'for' expects a type providing 'iterator' method, got 'Int'.
alt/error_needed_method_alt2.nit:47,10--27: Cannot instantiate interface Collection[Int].
+alt/error_needed_method_alt2.nit:47,1--40: Error: Method or variable 'iterator' unknown in Collection[Int].
alt/error_needed_method_alt2.nit:47,1--40: Type Error: 'for' expects a type providing 'iterator' method, got 'Collection[Int]'.
-alt/error_needed_method_alt6.nit:51,9--15: Fatal Error: Range must have a property named without_last.
+alt/error_needed_method_alt6.nit:51,9--15: Error: Method 'without_last' doesn't exists in Range[Int].
+alt/error_needed_types_alt8.nit:21,1--22,3: Error: Method or variable 'iterator' unknown in L.
alt/error_needed_types_alt8.nit:21,1--22,3: Type Error: 'for' expects a type providing 'iterator' method, got 'L'.