- add sources.
[platform/framework/web/crosswalk.git] / src / tools / idl_parser / idl_node.py
1 #!/usr/bin/env python
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.
5
6 import sys
7
8 #
9 # IDL Node
10 #
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.
17 #
18
19
20 #
21 # CopyToList
22 #
23 # Takes an input item, list, or None, and returns a new list of that set.
24 def CopyToList(item):
25   # If the item is 'Empty' make it an empty list
26   if not item:
27     item = []
28
29   # If the item is not a list
30   if type(item) is not type([]):
31     item = [item]
32
33   # Make a copy we can modify
34   return list(item)
35
36
37 # IDLSearch
38 #
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.
41 #
42 class IDLSearch(object):
43   def __init__(self):
44     self.depth = 0
45
46   def Enter(self, node):
47     pass
48
49   def Exit(self, node):
50     pass
51
52
53 # IDLAttribute
54 #
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.
57 #
58 class IDLAttribute(object):
59   def __init__(self, name, value):
60     self._cls = 'Property'
61     self.name = name
62     self.value = value
63
64   def __str__(self):
65     return '%s=%s' % (self.name, self.value)
66
67   def GetClass(self):
68     return self._cls
69
70 #
71 # IDLNode
72 #
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
76 # version aware.
77 #
78 class IDLNode(object):
79   def __init__(self, cls, filename, lineno, pos, children=None):
80     self._cls = cls
81     self._properties = {
82       'ERRORS' : [],
83       'WARNINGS': [],
84       'FILENAME': filename,
85       'LINENO' : lineno,
86       'POSSITION' : pos,
87     }
88
89     self._children = []
90     self._parent = None
91     self.AddChildren(children)
92
93 #
94 #
95 #
96   # Return a string representation of this node
97   def __str__(self):
98     name = self.GetProperty('NAME','')
99     return '%s(%s)' % (self._cls, name)
100
101   def GetLogLine(self, msg):
102     filename, lineno = self.GetFileAndLine()
103     return '%s(%d) : %s\n' % (filename, lineno, msg)
104
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))
109
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))
114
115   # Return file and line number for where node was defined
116   def GetFileAndLine(self):
117     return self.GetProperty('FILENAME'), self.GetProperty('LINENO')
118
119   def GetClass(self):
120     return self._cls
121
122   def GetName(self):
123     return self.GetProperty('NAME')
124
125   def GetParent(self):
126     return self._parent
127
128   def Traverse(self, search, filter_nodes):
129     if self._cls in filter_nodes:
130       return ''
131
132     search.Enter(self)
133     search.depth += 1
134     for child in self._children:
135       child.Traverse(search, filter_nodes)
136     search.depth -= 1
137     search.Exit(self)
138
139
140   def Tree(self, filter_nodes=None, accept_props=None):
141     class DumpTreeSearch(IDLSearch):
142       def __init__(self, props):
143         IDLSearch.__init__(self)
144         self.out = []
145         self.props = props
146
147       def Enter(self, node):
148         tab = ''.rjust(self.depth * 2)
149         self.out.append(tab + str(node))
150         if self.props:
151           proplist = []
152           for key, value in node.GetProperties().iteritems():
153             if key in self.props:
154               proplist.append(tab + '    %s: %s' % (key, str(value)))
155           if proplist:
156             self.out.append(tab + '  PROPERTIES')
157             self.out.extend(proplist)
158
159     if filter_nodes == None:
160       filter_nodes = ['Comment', 'Copyright']
161
162     search = DumpTreeSearch(accept_props)
163     self.Traverse(search, filter_nodes)
164     return search.out
165
166 #
167 # Search related functions
168 #
169   # Check if node is of a given type
170   def IsA(self, *typelist):
171     if self._cls in typelist:
172       return True
173     return False
174
175   # Get a list of all children
176   def GetChildren(self):
177     return self._children
178
179   def GetListOf(self, *keys):
180     out = []
181     for child in self.GetChildren():
182       if child.GetClass() in keys:
183         out.append(child)
184     return out
185
186   def GetOneOf(self, *keys):
187     out = self.GetListOf(*keys)
188     if out:
189       return out[0]
190     return None
191
192   def AddChildren(self, children):
193     children = CopyToList(children)
194     for child in children:
195       if not child:
196         continue
197       if type(child) == IDLAttribute:
198         self.SetProperty(child.name, child.value)
199         continue
200       if type(child) == IDLNode:
201         child._parent = self
202         self._children.append(child)
203         continue
204       raise RuntimeError('Adding child of type .\n' % type(child).__name__)
205
206
207 #
208 # Property Functions
209 #
210   def SetProperty(self, name, val):
211     self._properties[name] = val
212
213   def GetProperty(self, name, default=None):
214     return self._properties.get(name, default)
215
216   def GetProperties(self):
217     return self._properties