Home | History | Annotate | Download | only in generators
      1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """ Visitor Object for traversing AST """
      6 
      7 #
      8 # IDLVisitor
      9 #
     10 # The IDLVisitor class will traverse an AST truncating portions of the tree
     11 # when 'VisitFilter' returns false.  After the filter returns true, for each
     12 # node, the visitor will call the 'Arrive' member passing in the node and
     13 # and generic data object from the parent call.  The returned value is then
     14 # passed to all children who's results are aggregated into a list.  The child
     15 # results along with the original Arrive result are passed to the Depart
     16 # function which returns the final result of the Visit.  By default this is
     17 # the exact value that was return from the original arrive.
     18 #
     19 
     20 class IDLVisitor(object):
     21   def __init__(self):
     22     self.depth = 0
     23 
     24   # Return TRUE if the node should be visited
     25   def VisitFilter(self, node, data):
     26     return True
     27 
     28   # Return TRUE if data should be added to the childdata list
     29   def AgrigateFilter(self, data):
     30     return data is not None
     31 
     32   def Visit(self, node, data):
     33     self.depth += 1
     34     if not self.VisitFilter(node, data): return None
     35 
     36     childdata = []
     37     newdata = self.Arrive(node, data)
     38     for child in node.GetChildren():
     39       ret = self.Visit(child, newdata)
     40       if self.AgrigateFilter(ret):
     41         childdata.append(ret)
     42     out = self.Depart(node, newdata, childdata)
     43 
     44     self.depth -= 1
     45     return out
     46 
     47   def Arrive(self, node, data):
     48     __pychecker__ = 'unusednames=node'
     49     return data
     50 
     51   def Depart(self, node, data, childdata):
     52     __pychecker__ = 'unusednames=node,childdata'
     53     return data
     54 
     55 
     56 #
     57 # IDLVersionVisitor
     58 #
     59 # The IDLVersionVisitor will only visit nodes with intervals that include the
     60 # version.  It will also optionally filter based on a class list
     61 #
     62 class IDLVersionVisitor(object):
     63   def __init__(self, version, classList):
     64     self.version = version
     65     self.classes = classes
     66 
     67   def Filter(self, node, data):
     68     if self.classList and node.cls not in self.classList: return False
     69     if not node.IsVersion(self.version): return False
     70     return True
     71 
     72 class IDLRangeVisitor(object):
     73   def __init__(self, vmin, vmax, classList):
     74     self.vmin = vmin
     75     self.vmax = vmax
     76     self.classList = classList
     77 
     78   def Filter(self, node, data):
     79     if self.classList and node.cls not in self.classList: return False
     80     if not node.IsVersion(self.version): return False
     81     return True
     82