2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
11 # IDL Node defines the IDLAttribute and IDLNode objects which are constructed
12 # by the parser as it processes the various 'productions'. The IDLAttribute
13 # objects are assigned to the IDLNode's property dictionary instead of being
14 # applied as children of The IDLNodes, so they do not exist in the final tree.
15 # The AST of IDLNodes is the output from the parsing state and will be used
16 # as the source data by the various generators.
23 # Takes an input item, list, or None, and returns a new list of that set.
25 # If the item is 'Empty' make it an empty list
29 # If the item is not a list
30 if type(item
) is not type([]):
33 # Make a copy we can modify
39 # A temporary object used by the parsing process to hold an Extended Attribute
40 # which will be passed as a child to a standard IDLNode.
42 class IDLSearch(object):
46 def Enter(self
, node
):
55 # A temporary object used by the parsing process to hold an Extended Attribute
56 # which will be passed as a child to a standard IDLNode.
58 class IDLAttribute(object):
59 def __init__(self
, name
, value
):
60 self
._cls
= 'Property'
65 return '%s=%s' % (self
.name
, self
.value
)
73 # This class implements the AST tree, providing the associations between
74 # parents and children. It also contains a namepsace and propertynode to
75 # allow for look-ups. IDLNode is derived from IDLRelease, so it is
78 class IDLNode(object):
79 def __init__(self
, cls
, filename
, lineno
, pos
, children
=None):
91 self
.AddChildren(children
)
96 # Return a string representation of this node
98 name
= self
.GetProperty('NAME','')
99 return '%s(%s)' % (self
._cls
, name
)
101 def GetLogLine(self
, msg
):
102 filename
, lineno
= self
.GetFileAndLine()
103 return '%s(%d) : %s\n' % (filename
, lineno
, msg
)
105 # Log an error for this object
106 def Error(self
, msg
):
107 self
.GetProperty('ERRORS').append(msg
)
108 sys
.stderr
.write(self
.GetLogLine('error: ' + msg
))
110 # Log a warning for this object
111 def Warning(self
, msg
):
112 self
.GetProperty('WARNINGS').append(msg
)
113 sys
.stdout
.write(self
.GetLogLine('warning:' + msg
))
115 # Return file and line number for where node was defined
116 def GetFileAndLine(self
):
117 return self
.GetProperty('FILENAME'), self
.GetProperty('LINENO')
123 return self
.GetProperty('NAME')
128 def Traverse(self
, search
, filter_nodes
):
129 if self
._cls
in filter_nodes
:
134 for child
in self
._children
:
135 child
.Traverse(search
, filter_nodes
)
140 def Tree(self
, filter_nodes
=None, accept_props
=None):
141 class DumpTreeSearch(IDLSearch
):
142 def __init__(self
, props
):
143 IDLSearch
.__init
__(self
)
147 def Enter(self
, node
):
148 tab
= ''.rjust(self
.depth
* 2)
149 self
.out
.append(tab
+ str(node
))
151 for key
, value
in node
.GetProperties().iteritems():
153 if key
in self
.props
:
154 proplist
.append(tab
+ ' %s: %s' % (key
, str(value
)))
156 self
.out
.append(tab
+ ' PROPERTIES')
157 self
.out
.extend(proplist
)
159 if filter_nodes
== None:
160 filter_nodes
= ['Comment', 'Copyright']
162 search
= DumpTreeSearch(accept_props
)
163 self
.Traverse(search
, filter_nodes
)
167 # Search related functions
169 # Check if node is of a given type
170 def IsA(self
, *typelist
):
171 if self
._cls
in typelist
:
175 # Get a list of all children
176 def GetChildren(self
):
177 return self
._children
179 def GetListOf(self
, *keys
):
181 for child
in self
.GetChildren():
182 if child
.GetClass() in keys
:
186 def GetOneOf(self
, *keys
):
187 out
= self
.GetListOf(*keys
)
192 def AddChildren(self
, children
):
193 children
= CopyToList(children
)
194 for child
in children
:
197 if type(child
) == IDLAttribute
:
198 self
.SetProperty(child
.name
, child
.value
)
200 if type(child
) == IDLNode
:
202 self
._children
.append(child
)
204 raise RuntimeError('Adding child of type .\n' % type(child
).__name
__)
210 def SetProperty(self
, name
, val
):
211 self
._properties
[name
] = val
213 def GetProperty(self
, name
, default
=None):
214 return self
._properties
.get(name
, default
)
216 def GetProperties(self
):
217 return self
._properties