Merge: More documentation in src
[nit.git] / src / parser / parser_nodes.nit
index 3db6ebd..289ad53 100644 (file)
@@ -117,8 +117,48 @@ abstract class ANode
        # 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]
@@ -269,6 +309,20 @@ abstract class Prod
        # 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
@@ -2500,6 +2554,12 @@ class AAnnotation
 
        # The closing parenthesis
        var n_cpar: nullable TCpar = null is writable
+
+       # The name of the annotation
+       fun name: String
+       do
+               return n_atid.n_id.text
+       end
 end
 
 # An annotation name