Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(339)

Side by Side Diff: ppapi/generators/idl_ast.py

Issue 11235016: Change the way we generate versions (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/generators/generator.py ('k') | ppapi/generators/idl_c_header.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Nodes for PPAPI IDL AST.""" 5 """Nodes for PPAPI IDL AST."""
6 6
7 from idl_namespace import IDLNamespace 7 from idl_namespace import IDLNamespace
8 from idl_node import IDLAttribute, IDLFile, IDLNode 8 from idl_node import IDLAttribute, IDLFile, IDLNode
9 from idl_option import GetOption 9 from idl_option import GetOption
10 from idl_visitor import IDLVisitor 10 from idl_visitor import IDLVisitor
11 from idl_release import IDLReleaseList, IDLReleaseMap 11 from idl_release import IDLReleaseList, IDLReleaseMap
12 12
13 # 13 #
14 # IDL Predefined types 14 # IDL Predefined types
15 # 15 #
16 BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', 16 BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t',
17 'uint16_t', 'uint32_t', 'uint64_t', 'double_t', 'float_t', 17 'uint16_t', 'uint32_t', 'uint64_t', 'double_t', 'float_t',
18 'handle_t', 'interface_t', 'char', 'mem_t', 'str_t', 'void']) 18 'handle_t', 'interface_t', 'char', 'mem_t', 'str_t', 'void'])
19 19
20 20
21 # 21 #
22 # IDLNamespaceLabelResolver 22 # IDLLabelResolver
23 # 23 #
24 # Once the AST is build, we need to resolve the namespace and version 24 # A specialized visitor which traverses the AST, building a mapping of
25 # information. 25 # Release names to Versions numbers and calculating a min version.
26 # The mapping is applied to the File nodes within the AST.
26 # 27 #
27 class IDLNamespaceLabelResolver(IDLVisitor): 28 class IDLLabelResolver(IDLVisitor):
29 def Arrive(self, node, ignore):
30 # If we are entering a File, clear the visitor local mapping
31 if node.IsA('File'):
32 self.release_map = None
33 self.filenode = node
34 # For any non AST node, the filenode is the last known file
35 if not node.IsA('AST'):
36 node.filenode = self.filenode
37 return ignore
38
39 def Depart(self, node, ignore, childdata):
40 # Build list of Release=Version
41 if node.IsA('LabelItem'):
42 return (node.GetName(), node.GetProperty('VALUE'))
43
44 # On completion of the Label, apply to the parent File if the
45 # name of the label matches the generation label.
46 if node.IsA('Label') and node.GetName() == GetOption('label'):
47 try:
48 self.release_map = IDLReleaseMap(childdata)
49 node.parent.release_map = self.release_map
50 except Exception as err:
51 node.Error('Unable to build release map: %s' % str(err))
52
53 # For File objects, set the minimum version
54 if node.IsA('File'):
55 file_min, file_max = node.release_map.GetReleaseRange()
56 node.SetMin(file_min)
57
58 return None
59
60
61 #
62 # IDLNamespaceVersionResolver
63 #
64 # A specialized visitor which traverses the AST, building a namespace tree
65 # as it goes. The namespace tree is mapping from a name to a version list.
66 # Labels must already be resolved to use.
67 #
68 class IDLNamespaceVersionResolver(IDLVisitor):
28 NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct']) 69 NamespaceSet = set(['AST', 'Callspec', 'Interface', 'Member', 'Struct'])
29 # 70 #
30 # When we arrive at a node we must assign it a namespace and if the 71 # When we arrive at a node we must assign it a namespace and if the
31 # node is named, then place it in the appropriate namespace. 72 # node is named, then place it in the appropriate namespace.
32 # 73 #
33 def Arrive(self, node, parent_namespace): 74 def Arrive(self, node, parent_namespace):
34 # If we are entering a parent, clear the local Label\ 75 # If we are a File, grab the Min version and replease mapping
35 if node.IsA('File'): self.release_map = None 76 if node.IsA('File'):
77 self.rmin = node.GetMinMax()[0]
78 self.release_map = node.release_map
79
80 # Set the min version on any non Label within the File
81 if not node.IsA('AST', 'File', 'Label', 'LabelItem'):
82 my_min, my_max = node.GetMinMax()
83 if not my_min:
84 node.SetMin(self.rmin)
36 85
37 # If this object is not a namespace aware object, use the parent's one 86 # If this object is not a namespace aware object, use the parent's one
38 if node.cls not in self.NamespaceSet: 87 if node.cls not in self.NamespaceSet:
39 node.namespace = parent_namespace 88 node.namespace = parent_namespace
40 else: 89 else:
41 # otherwise create one. 90 # otherwise create one.
42 node.namespace = IDLNamespace(parent_namespace) 91 node.namespace = IDLNamespace(parent_namespace, node.GetName())
43 node.namespace.name = node.GetName()
44 92
45 # If this node is named, place it in its parent's namespace 93 # If this node is named, place it in its parent's namespace
46 if parent_namespace and node.cls in IDLNode.NamedSet: 94 if parent_namespace and node.cls in IDLNode.NamedSet:
47 # Set version min and max based on properties 95 # Set version min and max based on properties
48 if self.release_map: 96 if self.release_map:
49 vmin = node.GetProperty('version') 97 vmin = node.GetProperty('version')
50 vmax = node.GetProperty('deprecate') 98 vmax = node.GetProperty('deprecate')
51 rmin = self.release_map.GetRelease(vmin) 99 # If no min is available, the use the parent File's min
100 if vmin == None:
101 rmin = self.rmin
102 else:
103 rmin = self.release_map.GetRelease(vmin)
52 rmax = self.release_map.GetRelease(vmax) 104 rmax = self.release_map.GetRelease(vmax)
53 node.SetReleaseRange(rmin, rmax) 105 node.SetReleaseRange(rmin, rmax)
54 parent_namespace.AddNode(node) 106 parent_namespace.AddNode(node)
55 107
56 # Pass this namespace to each child in case they inherit it 108 # Pass this namespace to each child in case they inherit it
57 return node.namespace 109 return node.namespace
58 110
59 #
60 # As we return from a node, if the node is a LabelItem we pass back
61 # the key=value pair representing the mapping of release to version.
62 # If the node is a Label take the lists of mapping and generate a
63 # version map which is assigned to the Labels parent as a property.
64 #
65 def Depart(self, node, data, childdata):
66 if node.IsA('LabelItem'):
67 return (node.GetName(), node.GetProperty('VALUE'))
68 if node.IsA('Label') and node.GetName() == GetOption('label'):
69 try:
70 self.release_map = IDLReleaseMap(childdata)
71 node.parent.release_map = self.release_map
72 except Exception as err:
73 node.Error('Unable to build release map: %s' % str(err))
74 return None
75 111
76 112 #
113 # IDLFileTypeRessolver
114 #
115 # A specialized visitor which traverses the AST and sets a FILE property
116 # on all file nodes. In addition, searches the namespace resolving all
117 # type references. The namespace tree must already have been populated
118 # before this visitor is used.
119 #
77 class IDLFileTypeResolver(IDLVisitor): 120 class IDLFileTypeResolver(IDLVisitor):
78 def VisitFilter(self, node, data): 121 def VisitFilter(self, node, data):
79 return not node.IsA('Comment', 'Copyright') 122 return not node.IsA('Comment', 'Copyright')
80 123
81 def Arrive(self, node, filenode): 124 def Arrive(self, node, filenode):
82 # Track the file node to update errors 125 # Track the file node to update errors
83 if node.IsA('File'): 126 if node.IsA('File'):
84 node.SetProperty('FILE', node) 127 node.SetProperty('FILE', node)
128 filenode = node
129
130 if not node.IsA('AST'):
131 file_min, file_max = filenode.release_map.GetReleaseRange()
132 if not file_min:
133 print 'Resetting min on %s to %s' % (node, file_min)
134 node.SetMinRange(file_min)
85 135
86 # If this node has a TYPEREF, resolve it to a version list 136 # If this node has a TYPEREF, resolve it to a version list
87 typeref = node.property_node.GetPropertyLocal('TYPEREF') 137 typeref = node.property_node.GetPropertyLocal('TYPEREF')
88 if typeref: 138 if typeref:
89 node.typelist = node.parent.namespace.FindList(typeref) 139 node.typelist = node.parent.namespace.FindList(typeref)
90 if not node.typelist: 140 if not node.typelist:
91 node.Error('Could not resolve %s.' % typeref) 141 node.Error('Could not resolve %s.' % typeref)
92 else: 142 else:
93 node.typelist = None 143 node.typelist = None
94 return filenode 144 return filenode
95 145
146 #
147 # IDLReleaseResolver
148 #
149 # A specialized visitor which will traverse the AST, and generate a mapping
150 # from any release to the first release in which that version of the object
151 # was generated. Types must already be resolved to use.
152 #
153 class IDLReleaseResolver(IDLVisitor):
154 def Arrive(self, node, releases):
155 node.BuildReleaseMap(releases)
156 return releases
157
96 158
97 # 159 #
98 # IDLAst 160 # IDLAst
99 # 161 #
100 # A specialized version of the IDLNode for containing the whole of the 162 # A specialized version of the IDLNode for containing the whole of the
101 # AST. The specialized BuildTree function pulls the per file namespaces 163 # AST. Construction of the AST object will cause resolution of the
102 # into the global AST namespace and checks for collisions. 164 # tree including versions, types, etc... Errors counts will be collected
165 # both per file, and on the AST itself.
103 # 166 #
104 class IDLAst(IDLNode): 167 class IDLAst(IDLNode):
105 def __init__(self, children): 168 def __init__(self, children):
106 IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, children) 169 IDLNode.__init__(self, 'AST', 'BuiltIn', 1, 0, children)
107 self.Resolve() 170 self.Resolve()
108 171
109 def Resolve(self): 172 def Resolve(self):
110 self.namespace = IDLNamespace(None) 173 # Set the appropriate Release=Version mapping for each File
111 self.namespace.name = 'AST' 174 IDLLabelResolver().Visit(self, None)
112 IDLNamespaceLabelResolver().Visit(self, self.namespace) 175
176 # Generate the Namesapce Tree
177 self.namespace = IDLNamespace(None, 'AST')
178 IDLNamespaceVersionResolver().Visit(self, self.namespace)
179
180 # Using the namespace, resolve type references
113 IDLFileTypeResolver().Visit(self, None) 181 IDLFileTypeResolver().Visit(self, None)
114 182
115 # Build an ordered list of all releases 183 # Build an ordered list of all releases
116 self.releases = set() 184 releases = set()
117 for filenode in self.GetListOf('File'): 185 for filenode in self.GetListOf('File'):
118 self.releases |= set(filenode.release_map.GetReleases()) 186 releases |= set(filenode.release_map.GetReleases())
119 self.releases = sorted(self.releases)
120 187
121 def SetTypeInfo(self, name, properties): 188 # Generate a per node list of releases and release mapping
122 node = self.namespace[name] 189 IDLReleaseResolver().Visit(self, sorted(releases))
123 for prop in properties: 190
124 node.properties[prop] = properties[prop] 191 for filenode in self.GetListOf('File'):
192 self.errors += int(filenode.GetProperty('ERRORS', 0))
193
194
OLDNEW
« no previous file with comments | « ppapi/generators/generator.py ('k') | ppapi/generators/idl_c_header.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698