# Visit all nodes in order.
# Thus, call `v.enter_visit(e)` for each child `e`
fun visit_all(v: Visitor) is abstract
+
+ # Do a deep search and return an array of tokens that match a given text
+ fun collect_tokens_by_text(text: String): Array[Token]
+ do
+ var v = new CollectTokensByTextVisitor(text)
+ v.enter_visit(self)
+ return v.result
+ end
+
+ # Do a deep search and return an array of node that are annotated
+ # The attached node can be retrieved by two invocations of parent
+ fun collect_annotations_by_name(name: String): Array[AAnnotation]
+ do
+ var v = new CollectAnnotationsByNameVisitor(name)
+ v.enter_visit(self)
+ return v.result
+ end
+end
+
+private class CollectTokensByTextVisitor
+ super Visitor
+ var text: String
+ var result = new Array[Token]
+ redef fun visit(node)
+ do
+ node.visit_all(self)
+ if node isa Token and node.text == text then result.add(node)
+ end
end
+private class CollectAnnotationsByNameVisitor
+ super Visitor
+ var name: String
+ var result = new Array[AAnnotation]
+ redef fun visit(node)
+ do
+ node.visit_all(self)
+ if node isa AAnnotation and node.n_atid.n_id.text == name then result.add(node)
+ end
+end
+
+
# A sequence of nodes
# It is a specific class (instead of using a Array) to track the parent/child relation when nodes are added or removed
class ANodes[E: ANode]
# All the annotations attached directly to the node
var n_annotations: nullable AAnnotations = null is writable
+ # Return all its annotations of a given name in the order of their declaration
+ # Retun an empty array if no such an annotation.
+ fun get_annotations(name: String): Array[AAnnotation]
+ do
+ var res = new Array[AAnnotation]
+ var nas = n_annotations
+ if nas == null then return res
+ for na in nas.n_items do
+ if na.name != name then continue
+ res.add(na)
+ end
+ return res
+ end
+
redef fun replace_with(n: ANode)
do
super
# The initial value, if any
var n_expr: nullable AExpr = null is writable
+
+ var n_block: nullable AExpr = null is writable
+
redef fun hot_location
do
return n_id2.location
var n_label: nullable ALabel = null is writable
end
-# A `break` statement.
-class ABreakExpr
+# A `break` or a `continue`
+abstract class AEscapeExpr
super AExpr
super ALabelable
- var n_kwbreak: TKwbreak is writable, noinit
var n_expr: nullable AExpr = null is writable
end
+# A `break` statement.
+class ABreakExpr
+ super AEscapeExpr
+ var n_kwbreak: TKwbreak is writable, noinit
+end
+
# An `abort` statement
class AAbortExpr
super AExpr
# A `continue` statement
class AContinueExpr
- super AExpr
- super ALabelable
+ super AEscapeExpr
var n_kwcontinue: nullable TKwcontinue = null is writable
- var n_expr: nullable AExpr = null is writable
end
# A `do` statement
# A `once` expression. eg `once x`
class AOnceExpr
- super AProxyExpr
+ super AExpr
var n_kwonce: TKwonce is writable, noinit
+ var n_expr: AExpr is writable, noinit
end
# A polymorphic invocation of a method
# A simple parenthesis. eg `(x)`
class AParExpr
- super AProxyExpr
- var n_opar: TOpar is writable, noinit
- var n_cpar: TCpar is writable, noinit
-end
-
-# Whatever just contains (and mimic) an other expression
-abstract class AProxyExpr
super AExpr
+ var n_opar: TOpar is writable, noinit
var n_expr: AExpr is writable, noinit
+ var n_cpar: TCpar is writable, noinit
end
# A type cast. eg `x.as(T)`
end
# A list of expression separated with commas (arguments for instance)
-abstract class AExprs
- super Prod
+class AManyExpr
+ super AExpr
var n_exprs = new ANodes[AExpr](self)
end
+# A special expression that encapsulates a static type
+# Can only be found in special construction like arguments of annotations.
+class ATypeExpr
+ super AExpr
+ var n_type: AType is writable, noinit
+end
+
+# A special expression that encapsulates a method identifier
+# Can only be found in special construction like arguments of annotations.
+class AMethidExpr
+ super AExpr
+ # The receiver, is any
+ var n_expr: AExpr is writable, noinit
+ var n_id: AMethid is writable, noinit
+end
+
+# A special expression that encapsulate an annotation
+# Can only be found in special construction like arguments of annotations.
+class AAtExpr
+ super AExpr
+end
+
# A special expression to debug types
class ADebugTypeExpr
super AExpr
var n_type: AType is writable, noinit
end
+# A list of expression separated with commas (arguments for instance)
+abstract class AExprs
+ super Prod
+ var n_exprs = new ANodes[AExpr](self)
+end
+
# A simple list of expressions
class AListExprs
super AExprs
var n_visibility: nullable AVisibility is writable
var n_atid: AAtid is writable, noinit
var n_opar: nullable TOpar = null is writable
- var n_args = new ANodes[AAtArg](self)
+ var n_args = new ANodes[AExpr](self)
var n_cpar: nullable TCpar = null is writable
-end
-
-# A single argument of an annotation
-abstract class AAtArg
- super Prod
-end
-
-# A type-like argument of an annotation
-class ATypeAtArg
- super AAtArg
- var n_type: AType is writable, noinit
-end
-
-# An expression-like argument of an annotation
-class AExprAtArg
- super AAtArg
- var n_expr: AExpr is writable, noinit
-end
-# An annotation-like argument of an annotation
-class AAtAtArg
- super AAtArg
+ # The name of the annotation
+ fun name: String
+ do
+ return n_atid.n_id.text
+ end
end
# An annotation name
class Start
super Prod
var n_base: nullable AModule is writable
- var n_eof: EOF is writable, noinit
- init(n_base: nullable AModule, n_eof: EOF)
- do
- self._n_base = n_base
- self._n_eof = n_eof
- end
+ var n_eof: EOF is writable
end