Standard for
iterate on a single collection.
Multiple for
can iterate on more than one collection at once.
nitc :: AForGroup :: _method_finish
nitc :: AForGroup :: _method_is_ok
nitc :: AForGroup :: _method_item
nitc :: AForGroup :: _method_iterator
nitc :: AForGroup :: _method_key
nitc :: AForGroup :: _method_lt
nitc :: AForGroup :: _method_next
nitc :: AForGroup :: _method_successor
nitc :: AForGroup :: _variables
The automatic variables in ordernitc :: AForGroup :: defaultinit
nitc :: AForGroup :: do_type_iterator
nitc :: AForGroup :: init_aforgroup
nitc :: AForGroup :: method_finish
nitc :: AForGroup :: method_finish=
nitc :: AForGroup :: method_is_ok
nitc :: AForGroup :: method_is_ok=
nitc :: AForGroup :: method_item
nitc :: AForGroup :: method_item=
nitc :: AForGroup :: method_iterator
nitc :: AForGroup :: method_iterator=
nitc :: AForGroup :: method_key
nitc :: AForGroup :: method_key=
nitc :: AForGroup :: method_lt=
nitc :: AForGroup :: method_next
nitc :: AForGroup :: method_next=
nitc :: AForGroup :: method_successor
nitc :: AForGroup :: method_successor=
nitc :: AForGroup :: transform_in
nitc :: AForGroup :: variables=
The automatic variables in ordernitc :: pretty $ AForGroup :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: rapid_type_analysis $ AForGroup :: accept_rapid_type_visitor
nitc :: simple_misc_analysis $ AForGroup :: after_simple_misc
nitc :: htmlight $ AForGroup :: decorate_tag
Add aditionnal information on a child-token and return an additionnal HInfoBox on itnitc :: parser_prod $ AForGroup :: replace_child
Replace a child with an other node in the ASTnitc :: Prod :: _first_location
Location on the first token after the start of a productionnitc :: Prod :: _first_token
The first token of the production in the ASTnitc :: ANode :: _is_broken
The indication that the node did not pass some semantic verifications.nitc :: Prod :: _last_token
The last token of the production in the ASTnitc :: AForGroup :: _method_finish
nitc :: AForGroup :: _method_is_ok
nitc :: AForGroup :: _method_item
nitc :: AForGroup :: _method_iterator
nitc :: AForGroup :: _method_key
nitc :: AForGroup :: _method_lt
nitc :: AForGroup :: _method_next
nitc :: AForGroup :: _method_successor
nitc :: Prod :: _n_annotations
All the annotations attached directly to the nodenitc :: AForGroup :: _variables
The automatic variables in ordernitc :: ANode :: accept_ast_validation
nitc :: ANode :: accept_auto_super_init
nitc :: ANode :: accept_flow_visitor
nitc :: ANode :: accept_forward_analysis
Apply the forward analysisv
to self
.
nitc :: ANode :: accept_literal
nitc :: ANode :: accept_post_typing
nitc :: ANode :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: ANode :: accept_reaching_defs
Apply a ReachingDefsAnalysis toself
.
nitc :: ANode :: accept_regex_visitor
nitc :: ANode :: accept_scope_visitor
nitc :: ANode :: accept_simple_misc
nitc :: ANode :: accept_string_finder
nitc :: ANode :: after_simple_misc
nitc :: ANode :: bad_expr_message
An additional information message to explain the role of a child expression.nitc :: ANode :: check_callsite
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: ANode :: collect_annotations_by_name
Do a deep search and return an array of node that are annotatednitc :: Prod :: collect_comments
Collect allTComment
contained in the production
nitc :: ANode :: collect_length
Collect the length (inChar
) of the node.
nitc :: ANode :: collect_tokens_by_text
Do a deep search and return an array of tokens that match a given textnitc :: ANode :: common_parent
The most specific common parent betweenself
and other
nitc :: ANode :: create_contracts
nitc :: ANode :: decorate_tag
Add aditionnal information on a child-token and return an additionnal HInfoBox on itcore :: Object :: defaultinit
core :: Cloneable :: defaultinit
nitc :: Prod :: defaultinit
nitc :: ANode :: defaultinit
nitc :: AForGroup :: defaultinit
nitc :: ANode :: do_cloneable
nitc :: AForGroup :: do_type_iterator
nitc :: Prod :: first_location
Location on the first token after the start of a productionnitc :: Prod :: first_location=
Location on the first token after the start of a productionnitc :: Prod :: first_token
The first token of the production in the ASTnitc :: Prod :: first_token=
The first token of the production in the ASTnitc :: ANode :: force_block=
Forceself
to be rendered as a block.
nitc :: ANode :: force_inline=
Forceself
to be rendered as a line.
nitc :: ANode :: full_transform_visitor
nitc :: Prod :: get_annotations
Return all its annotations of a given name in the order of their declarationnitc :: Prod :: get_single_annotation
Try to get its single annotation with a given namenitc :: ANode :: hot_location
The location of the important part of the node (identifier or whatever)nitc :: AForGroup :: init_aforgroup
nitc :: ANode :: is_broken=
The indication that the node did not pass some semantic verifications.nitc :: ANode :: is_noserialize
Is this node annotated to not be made serializable?core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: ANode :: is_serialize
Is this node annotated to be made serializable?nitc :: ANode :: is_structural
Isself
a token or a pure-structural production like AQId
?
nitc :: Prod :: last_token
The last token of the production in the ASTnitc :: Prod :: last_token=
The last token of the production in the ASTnitc :: AForGroup :: method_finish
nitc :: AForGroup :: method_finish=
nitc :: AForGroup :: method_is_ok
nitc :: AForGroup :: method_is_ok=
nitc :: AForGroup :: method_item
nitc :: AForGroup :: method_item=
nitc :: AForGroup :: method_iterator
nitc :: AForGroup :: method_iterator=
nitc :: AForGroup :: method_key
nitc :: AForGroup :: method_key=
nitc :: AForGroup :: method_lt=
nitc :: AForGroup :: method_next
nitc :: AForGroup :: method_next=
nitc :: AForGroup :: method_successor
nitc :: AForGroup :: method_successor=
nitc :: ANode :: must_be_block
Doesself
have to be rendered as a block?
nitc :: ANode :: must_be_inline
Doesself
have be rendered as a line?
nitc :: Prod :: n_annotations
All the annotations attached directly to the nodenitc :: Prod :: n_annotations=
All the annotations attached directly to the nodecore :: Object :: native_class_name
The class name of the object in CString format.core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: ANode :: parentize_tokens
Visit the AST and computes advanced AST attributes on Tokens and Prodnitc :: ANode :: replace_child
Replace a child with an other node in the ASTnitc :: ANode :: replace_with
Replace itself with an other node in the ASTnitc :: Prod :: start_token
The token where the production really start (skipping ADoc).nitc :: AForGroup :: transform_in
nitc :: AForGroup :: variables=
The automatic variables in ordernitc :: ANode :: was_inline
Doesself
was written in one line before transformation?
# A collection iterated by a for, its automatic variables and its implicit iterator.
#
# Standard `for` iterate on a single collection.
# Multiple `for` can iterate on more than one collection at once.
class AForGroup
super Prod
# The list of name of the automatic variables
var n_ids = new ANodes[TId](self)
# The `in` keyword
var n_kwin: TKwin is writable, noinit
# The expression used as the collection to iterate on
var n_expr: AExpr is writable, noinit
end
src/parser/parser_nodes.nit:2051,1--2066,3
redef class AForGroup
init init_aforgroup (
n_ids: Collection[Object], # Should be Collection[TId]
n_kwin: nullable TKwin,
n_expr: nullable AExpr
)
do
self.n_ids.unsafe_add_all(n_ids)
_n_kwin = n_kwin.as(not null)
n_kwin.parent = self
_n_expr = n_expr.as(not null)
n_expr.parent = self
end
redef fun replace_child(old_child: ANode, new_child: nullable ANode)
do
if n_ids.replace_child(old_child, new_child) then return
if _n_kwin == old_child then
n_kwin = new_child.as(TKwin)
return
end
if _n_expr == old_child then
n_expr = new_child.as(AExpr)
return
end
end
redef fun n_kwin=(node)
do
_n_kwin = node
node.parent = self
end
redef fun n_expr=(node)
do
_n_expr = node
node.parent = self
end
redef fun visit_all(v: Visitor)
do
n_ids.visit_all(v)
v.enter_visit(_n_kwin)
v.enter_visit(_n_expr)
end
end
src/parser/parser_prod.nit:8003,1--8048,3
redef class AForGroup
redef fun after_simple_misc(v)
do
n_expr.warn_parentheses(v)
end
end
src/frontend/simple_misc_analysis.nit:179,1--184,3
redef class AForGroup
var coltype: nullable MClassType
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
var method_finish: nullable CallSite
var method_lt: nullable CallSite
var method_successor: nullable CallSite
private fun do_type_iterator(v: TypeVisitor, mtype: MType)
do
if mtype isa MNullType then
v.error(self, "Type Error: `for` cannot iterate over `null`.")
return
end
# get obj class
var objcla = v.get_mclass(self, "Object")
if objcla == null then return
# check iterator method
var itdef = v.build_callsite_by_name(self, mtype, "iterator", n_expr isa ASelfExpr)
if itdef == null then
v.error(self, "Type Error: `for` expects a type providing an `iterator` method, got `{mtype}`.")
return
end
self.method_iterator = itdef
# check that iterator return something
var ittype = itdef.msignature.return_mtype
if ittype == null then
v.error(self, "Type Error: `for` expects the method `iterator` to return an `Iterator` or `MapIterator` type.")
return
end
# get iterator type
var colit_cla = v.try_get_mclass(self, "Iterator")
var mapit_cla = v.try_get_mclass(self, "MapIterator")
var is_col = false
var is_map = false
if colit_cla != null and v.is_subtype(ittype, colit_cla.get_mtype([objcla.mclass_type.as_nullable])) then
# Iterator
var coltype = ittype.supertype_to(v.mmodule, v.anchor, colit_cla)
var variables = self.variables
if variables.length != 1 then
v.error(self, "Type Error: `for` expects only one variable when using `Iterator`.")
else
variables.first.declared_type = coltype.arguments.first
end
is_col = true
end
if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then
# Map Iterator
var coltype = ittype.supertype_to(v.mmodule, v.anchor, mapit_cla)
var variables = self.variables
if variables.length != 2 then
v.error(self, "Type Error: `for` expects two variables when using `MapIterator`.")
else
variables[0].declared_type = coltype.arguments[0]
variables[1].declared_type = coltype.arguments[1]
end
is_map = true
end
if not is_col and not is_map then
v.error(self, "Type Error: `for` expects the method `iterator` to return an `Iterator` or `MapIterator` type.")
return
end
# anchor formal and virtual types
if mtype.need_anchor then mtype = v.anchor_to(mtype)
mtype = mtype.undecorate
self.coltype = mtype.as(MClassType)
# get methods is_ok, next, item
var ikdef = v.build_callsite_by_name(self, ittype, "is_ok", false)
if ikdef == null then
v.error(self, "Type Error: `for` expects a method `is_ok` in type `{ittype}`.")
return
end
self.method_is_ok = ikdef
var itemdef = v.build_callsite_by_name(self, ittype, "item", false)
if itemdef == null then
v.error(self, "Type Error: `for` expects a method `item` in type `{ittype}`.")
return
end
self.method_item = itemdef
var nextdef = v.build_callsite_by_name(self, ittype, "next", false)
if nextdef == null then
v.error(self, "Type Error: `for` expects a method `next` in type {ittype}.")
return
end
self.method_next = nextdef
self.method_finish = v.try_build_callsite_by_name(self, ittype, "finish", false)
if is_map then
var keydef = v.build_callsite_by_name(self, ittype, "key", false)
if keydef == null then
v.error(self, "Type Error: `for` expects a method `key` in type `{ittype}`.")
return
end
self.method_key = keydef
end
if self.variables.length == 1 and n_expr isa ARangeExpr then
var variable = variables.first
var vtype = variable.declared_type.as(not null)
if n_expr isa AOrangeExpr then
self.method_lt = v.build_callsite_by_name(self, vtype, "<", false)
else
self.method_lt = v.build_callsite_by_name(self, vtype, "<=", false)
end
self.method_successor = v.build_callsite_by_name(self, vtype, "successor", false)
end
end
end
src/semantize/typing.nit:1345,1--1472,3
redef class AForGroup
redef fun accept_rapid_type_visitor(v)
do
v.add_callsite(self.method_iterator)
v.add_callsite(self.method_is_ok)
if self.variables.length == 1 then
v.add_callsite(self.method_item)
else if self.variables.length == 2 then
v.add_callsite(self.method_key)
v.add_callsite(self.method_item)
else
abort
end
v.add_callsite(self.method_next)
var mf = self.method_finish
if mf != null then v.add_callsite(mf)
end
end
src/rapid_type_analysis.nit:751,1--768,3
redef class AForGroup
private fun transform_in(v: TransformVisitor, before, begin, next, finish: AExpr, escapemark: EscapeMark)
do
var nexpr = n_expr
# Shortcut on explicit range
# Avoid the instantiation of the range and the iterator
if self.variables.length == 1 and nexpr isa ARangeExpr and not v.phase.toolcontext.opt_no_shortcut_range.value then
# Before: evaluate bounds
var variable = variables.first
before.add v.builder.make_var_assign(variable, nexpr.n_expr)
var to = nexpr.n_expr2
before.add to
# Begin: check variable
var is_ok = v.builder.make_call(v.builder.make_var_read(variable, variable.declared_type.as(not null)), method_lt.as(not null), [to.make_var_read])
var nif = v.builder.make_if(is_ok, null)
begin.add nif
nif.n_else.add v.builder.make_break(escapemark)
# Next: increment one
var one = v.builder.make_int(1)
var succ = v.builder.make_call(v.builder.make_var_read(variable, variable.declared_type.as(not null)), method_successor.as(not null), [one])
next.add v.builder.make_var_assign(variable, succ)
return
end
# Before: evaluate expr, make the iterator
before.add nexpr
var iter = v.builder.make_call(nexpr.make_var_read, method_iterator.as(not null), null)
before.add iter
# Begin: check iterator `is_ok`
var is_ok = v.builder.make_call(iter.make_var_read, method_is_ok.as(not null), null)
var nif = v.builder.make_if(is_ok, null)
begin.add nif
nif.n_else.add v.builder.make_break(escapemark)
# Begin: assign automatic variables
if variables.length == 1 then
var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null)
begin.add v.builder.make_var_assign(variables.first, item)
else if variables.length == 2 then
var key = v.builder.make_call(iter.make_var_read, method_key.as(not null), null)
begin.add v.builder.make_var_assign(variables[0], key)
var item = v.builder.make_call(iter.make_var_read, method_item.as(not null), null)
begin.add v.builder.make_var_assign(variables[1], item)
else
abort
end
# Next: call next
next.add v.builder.make_call(iter.make_var_read, method_next.as(not null), null)
# Finish: call finish
var method_finish = method_finish
if method_finish != null then
finish.add v.builder.make_call(iter.make_var_read, method_finish, null)
end
end
end
src/transform.nit:248,1--308,3
redef class AForGroup
# C variable representing the iterator
private var it: RuntimeVariable is noinit
end
src/compiler/abstract_compiler.nit:3989,1--3992,3