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

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

Issue 8045001: Update the IDL Generator to use Release instead of Version (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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/idl_lint.py ('k') | ppapi/generators/idl_node.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 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """ 7 """
8 IDLNamespace for PPAPI 8 IDLNamespace for PPAPI
9 9
10 This file defines the behavior of the AST namespace which allows for resolving 10 This file defines the behavior of the AST namespace which allows for resolving
11 a symbol as one or more AST nodes given a version or range of versions. 11 a symbol as one or more AST nodes given a release or range of releases.
12 """ 12 """
13 13
14 import sys 14 import sys
15 15
16 from idl_option import GetOption, Option, ParseOptions 16 from idl_option import GetOption, Option, ParseOptions
17 from idl_log import ErrOut, InfoOut, WarnOut 17 from idl_log import ErrOut, InfoOut, WarnOut
18 from idl_version import IDLVersion 18 from idl_release import IDLRelease, IDLReleaseList
19 19
20 Option('label', 'Use the specifed label blocks.', default='Chrome') 20 Option('label', 'Use the specifed label blocks.', default='Chrome')
21 Option('namespace_debug', 'Use the specified version') 21 Option('namespace_debug', 'Use the specified release')
22
23
24 #
25 # IDLVersionList
26 #
27 # IDLVersionList is a list based container for holding IDLVersion
28 # objects in order. The IDLVersionList can be added to, and searched by
29 # range. Objects are stored in order, and must be added in order.
30 #
31 class IDLVersionList(object):
32 def __init__(self):
33 self.nodes = []
34
35 def FindVersion(self, version):
36 assert type(version) == float
37
38 for node in self.nodes:
39 if node.IsVersion(version):
40 return node
41 return None
42
43 def FindRange(self, vmin, vmax):
44 assert type(vmin) == float
45 assert type(vmax) == float
46 assert vmin != vmax
47
48 out = []
49 for node in self.nodes:
50 if node.InRange(vmin, vmax):
51 out.append(node)
52 return out
53
54 def AddNode(self, node):
55 if GetOption('version_debug'):
56 InfoOut.Log('\nAdding %s %s' % (node.Location(), node))
57 last = None
58
59 # Check current versions in that namespace
60 for cver in self.nodes:
61 if GetOption('version_debug'): InfoOut.Log(' Checking %s' % cver)
62
63 # We should only be missing a 'version' tag for the first item.
64 if not node.vmin:
65 raise RuntimeError('Missing version')
66 node.Error('Missing version on overload of previous %s.' %
67 cver.Location())
68 return False
69
70 # If the node has no max, then set it to this one
71 if not cver.vmax:
72 cver.vmax = node.vmin
73 if GetOption('version_debug'): InfoOut.Log(' Update %s' % cver)
74
75 # if the max and min overlap, than's an error
76 if cver.vmax > node.vmin:
77 if node.vmax and cver.vmin >= node.vmax:
78 node.Error('Declarations out of order.')
79 else:
80 node.Error('Overlap in versions.')
81 return False
82 last = cver
83
84 # Otherwise, the previous max and current min should match
85 # unless this is the unlikely case of something being only
86 # temporarily deprecated.
87 if last and last.vmax != node.vmin:
88 node.Warn('Gap in version numbers.')
89
90 # If we made it here, this new node must be the 'newest'
91 # and does not overlap with anything previously added, so
92 # we can add it to the end of the list.
93 if GetOption('version_debug'): InfoOut.Log('Done %s' % node)
94 self.nodes.append(node)
95 return True
96
97 #
98 # IDLVersionMap
99 #
100 # A version map, can map from an float interface version, to a global
101 # release string.
102 #
103 class IDLVersionMap(object):
104 def __init__(self):
105 self.version_to_release = {}
106 self.release_to_version = {}
107 self.versions = []
108 self.releases = []
109
110 def AddReleaseVersionMapping(self, release, version):
111 self.version_to_release[version] = release
112 self.release_to_version[release] = version
113 self.versions = sorted(self.version_to_release.keys())
114 self.releases = sorted(self.release_to_version.keys())
115
116 def GetRelease(self, version):
117 # Check for exact match
118 if version in self.versions:
119 return self.version_to_release[version]
120
121 def GetVersion(self, release):
122 if release > self.releases[-1]:
123 release = self.releases[-1]
124 elif release < self.releases[0]:
125 release = self.releases[0]
126 return self.release_to_version[release]
127
128 22
129 23
130 # 24 #
131 # IDLNamespace 25 # IDLNamespace
132 # 26 #
133 # IDLNamespace provides a mapping between a symbol name and an IDLVersionList 27 # IDLNamespace provides a mapping between a symbol name and an IDLReleaseList
134 # which contains IDLVersion objects. It provides an interface for fetching 28 # which contains IDLRelease objects. It provides an interface for fetching
135 # one or more IDLNodes based on a version or range of versions. 29 # one or more IDLNodes based on a release or range of releases.
136 # 30 #
137 class IDLNamespace(object): 31 class IDLNamespace(object):
138 def __init__(self, parent): 32 def __init__(self, parent):
139 self.namespace = {} 33 self.namespace = {}
140 self.parent = parent 34 self.parent = parent
141 35
142 def Dump(self): 36 def Dump(self):
143 for name in self.namespace: 37 for name in self.namespace:
144 InfoOut.Log('NAME=%s' % name) 38 InfoOut.Log('NAME=%s' % name)
145 for cver in self.namespace[name]: 39 for cver in self.namespace[name].nodes:
146 InfoOut.Log(' %s' % cver) 40 InfoOut.Log(' %s' % cver)
147 InfoOut.Log('') 41 InfoOut.Log('')
148 42
149 def FindVersion(self, name, version): 43 def FindRelease(self, name, release):
150 verlist = self.namespace.get(name, None) 44 verlist = self.namespace.get(name, None)
151 if verlist == None: 45 if verlist == None:
152 if self.parent: 46 if self.parent:
153 return self.parent.FindVersion(name, version) 47 return self.parent.FindRelease(name, release)
154 else: 48 else:
155 return None 49 return None
156 return verlist.FindVersion(version) 50 return verlist.FindRelease(release)
157 51
158 def FindRange(self, name, vmin, vmax): 52 def FindRange(self, name, rmin, rmax):
159 verlist = self.namespace.get(name, None) 53 verlist = self.namespace.get(name, None)
160 if verlist == None: 54 if verlist == None:
161 if self.parent: 55 if self.parent:
162 return self.parent.FindRange(name, vmin, vmax) 56 return self.parent.FindRange(name, rmin, rmax)
163 else: 57 else:
164 return [] 58 return []
165 return verlist.FindRange(vmin, vmax) 59 return verlist.FindRange(rmin, rmax)
166 60
167 def FindList(self, name): 61 def FindList(self, name):
168 verlist = self.namespace.get(name, None) 62 verlist = self.namespace.get(name, None)
169 if verlist == None: 63 if verlist == None:
170 if self.parent: 64 if self.parent:
171 return self.parent.FindList(name) 65 return self.parent.FindList(name)
172 return verlist 66 return verlist
173 67
174 def AddNode(self, node): 68 def AddNode(self, node):
175 name = node.GetName() 69 name = node.GetName()
176 verlist = self.namespace.setdefault(name,IDLVersionList()) 70 verlist = self.namespace.setdefault(name,IDLReleaseList())
177 if GetOption('namespace_debug'): 71 if GetOption('namespace_debug'):
178 print "Adding to namespace: %s" % node 72 print "Adding to namespace: %s" % node
179 return verlist.AddNode(node) 73 return verlist.AddNode(node)
180 74
181 75
182 76
183 # 77 #
184 # Testing Code 78 # Testing Code
185 # 79 #
186 80
187 # 81 #
188 # MockNode 82 # MockNode
189 # 83 #
190 # Mocks the IDLNode to support error, warning handling, and string functions. 84 # Mocks the IDLNode to support error, warning handling, and string functions.
191 # 85 #
192 class MockNode(IDLVersion): 86 class MockNode(IDLRelease):
193 def __init__(self, name, vmin, vmax): 87 def __init__(self, name, rmin, rmax):
194 self.name = name 88 self.name = name
195 self.vmin = vmin 89 self.rmin = rmin
196 self.vmax = vmax 90 self.rmax = rmax
197 self.errors = [] 91 self.errors = []
198 self.warns = [] 92 self.warns = []
199 self.properties = { 93 self.properties = {
200 'NAME': name, 94 'NAME': name,
201 'version': vmin, 95 'release': rmin,
202 'deprecate' : vmax 96 'deprecate' : rmax
203 } 97 }
204 98
205 def __str__(self): 99 def __str__(self):
206 return '%s (%s : %s)' % (self.name, self.vmin, self.vmax) 100 return '%s (%s : %s)' % (self.name, self.rmin, self.rmax)
207 101
208 def GetName(self): 102 def GetName(self):
209 return self.name 103 return self.name
210 104
211 def Error(self, msg): 105 def Error(self, msg):
212 if GetOption('version_debug'): print 'Error: %s' % msg 106 if GetOption('release_debug'): print 'Error: %s' % msg
213 self.errors.append(msg) 107 self.errors.append(msg)
214 108
215 def Warn(self, msg): 109 def Warn(self, msg):
216 if GetOption('version_debug'): print 'Warn: %s' % msg 110 if GetOption('release_debug'): print 'Warn: %s' % msg
217 self.warns.append(msg) 111 self.warns.append(msg)
218 112
219 def GetProperty(self, name): 113 def GetProperty(self, name):
220 return self.properties.get(name, None) 114 return self.properties.get(name, None)
221 115
222 errors = 0 116 errors = 0
223 # 117 #
224 # DumpFailure 118 # DumpFailure
225 # 119 #
226 # Dumps all the information relevant to an add failure. 120 # Dumps all the information relevant to an add failure.
227 def DumpFailure(namespace, node, msg): 121 def DumpFailure(namespace, node, msg):
228 global errors 122 global errors
229 print '\n******************************' 123 print '\n******************************'
230 print 'Failure: %s %s' % (node, msg) 124 print 'Failure: %s %s' % (node, msg)
231 for warn in node.warns: 125 for warn in node.warns:
232 print ' WARN: %s' % warn 126 print ' WARN: %s' % warn
233 for err in node.errors: 127 for err in node.errors:
234 print ' ERROR: %s' % err 128 print ' ERROR: %s' % err
235 print '\n' 129 print '\n'
236 namespace.Dump() 130 namespace.Dump()
237 print '******************************\n' 131 print '******************************\n'
238 errors += 1 132 errors += 1
239 133
240 # Add expecting no errors or warnings 134 # Add expecting no errors or warnings
241 def AddOkay(namespace, node): 135 def AddOkay(namespace, node):
242 okay = namespace.AddNode(node) 136 okay = namespace.AddNode(node)
243 if not okay or node.errors or node.warns: 137 if not okay or node.errors or node.warns:
244 DumpFailure(namespace, node, 'Expected success') 138 DumpFailure(namespace, node, 'Expected success')
245 139
246 # Add expecting a specific warning 140 # Add expecting a specific warning
247 def AddWarn(namespace, node, msg): 141 def AddWarn(namespace, node, msg):
248 okay = namespace.AddNode(node) 142 okay = namespace.AddNode(node)
249 if not okay or node.errors or not node.warns: 143 if not okay or node.errors or not node.warns:
250 DumpFailure(namespace, node, 'Expected warnings') 144 DumpFailure(namespace, node, 'Expected warnings')
251 if msg not in node.warns: 145 if msg not in node.warns:
252 DumpFailure(namespace, node, 'Expected warning: %s' % msg) 146 DumpFailure(namespace, node, 'Expected warning: %s' % msg)
253 147
254 # Add expecting a specific error any any number of warnings 148 # Add expecting a specific error any any number of warnings
255 def AddError(namespace, node, msg): 149 def AddError(namespace, node, msg):
256 okay = namespace.AddNode(node) 150 okay = namespace.AddNode(node)
257 if okay or not node.errors: 151 if okay or not node.errors:
258 DumpFailure(namespace, node, 'Expected errors') 152 DumpFailure(namespace, node, 'Expected errors')
259 if msg not in node.errors: 153 if msg not in node.errors:
260 DumpFailure(namespace, node, 'Expected error: %s' % msg) 154 DumpFailure(namespace, node, 'Expected error: %s' % msg)
155 print ">>%s<<\n>>%s<<\n" % (node.errors[0], msg)
261 156
262 # Verify that a FindVersion call on the namespace returns the expected node. 157 # Verify that a FindRelease call on the namespace returns the expected node.
263 def VerifyFindOne(namespace, name, version, node): 158 def VerifyFindOne(namespace, name, release, node):
264 global errors 159 global errors
265 if (namespace.FindVersion(name, version) != node): 160 if (namespace.FindRelease(name, release) != node):
266 print "Failed to find %s as version %f of %s" % (node, version, name) 161 print "Failed to find %s as release %f of %s" % (node, release, name)
267 namespace.Dump() 162 namespace.Dump()
268 print "\n" 163 print "\n"
269 errors += 1 164 errors += 1
270 165
271 # Verify that a FindRage call on the namespace returns a set of expected nodes. 166 # Verify that a FindRage call on the namespace returns a set of expected nodes.
272 def VerifyFindAll(namespace, name, vmin, vmax, nodes): 167 def VerifyFindAll(namespace, name, rmin, rmax, nodes):
273 global errors 168 global errors
274 out = namespace.FindRange(name, vmin, vmax) 169 out = namespace.FindRange(name, rmin, rmax)
275 if (out != nodes): 170 if (out != nodes):
276 print "Found [%s] instead of[%s] for versions %f to %f of %s" % ( 171 print "Found [%s] instead of[%s] for releases %f to %f of %s" % (
277 ' '.join([str(x) for x in out]), 172 ' '.join([str(x) for x in out]),
278 ' '.join([str(x) for x in nodes]), 173 ' '.join([str(x) for x in nodes]),
279 vmin, 174 rmin,
280 vmax, 175 rmax,
281 name) 176 name)
282 namespace.Dump() 177 namespace.Dump()
283 print "\n" 178 print "\n"
284 errors += 1 179 errors += 1
285 180
286 def Main(args): 181 def Main(args):
287 global errors 182 global errors
288 ParseOptions(args) 183 ParseOptions(args)
289 184
290 InfoOut.SetConsole(True) 185 InfoOut.SetConsole(True)
291 186
292 namespace = IDLNamespace(None) 187 namespace = IDLNamespace(None)
293 188
294 FooXX = MockNode('foo', None, None) 189 FooXX = MockNode('foo', None, None)
295 Foo1X = MockNode('foo', 1.0, None) 190 Foo1X = MockNode('foo', 1.0, None)
296 Foo2X = MockNode('foo', 2.0, None) 191 Foo2X = MockNode('foo', 2.0, None)
297 Foo3X = MockNode('foo', 3.0, None) 192 Foo3X = MockNode('foo', 3.0, None)
298 193
299 # Verify we succeed with undeprecated adds 194 # Verify we succeed with undeprecated adds
300 AddOkay(namespace, FooXX) 195 AddOkay(namespace, FooXX)
301 AddOkay(namespace, Foo1X) 196 AddOkay(namespace, Foo1X)
302 AddOkay(namespace, Foo3X) 197 AddOkay(namespace, Foo3X)
303 # Verify we fail to add a node between undeprecated versions 198 # Verify we fail to add a node between undeprecated releases
304 AddError(namespace, Foo2X, 'Overlap in versions.') 199 AddError(namespace, Foo2X,
200 'Overlap in releases: 3.0 vs 2.0 when adding foo (2.0 : None)')
305 201
306 BarXX = MockNode('bar', None, None) 202 BarXX = MockNode('bar', None, None)
307 Bar12 = MockNode('bar', 1.0, 2.0) 203 Bar12 = MockNode('bar', 1.0, 2.0)
308 Bar23 = MockNode('bar', 2.0, 3.0) 204 Bar23 = MockNode('bar', 2.0, 3.0)
309 Bar34 = MockNode('bar', 3.0, 4.0) 205 Bar34 = MockNode('bar', 3.0, 4.0)
310 206
311 207
312 # Verify we succeed with fully qualified versions 208 # Verify we succeed with fully qualified releases
313 namespace = IDLNamespace(namespace) 209 namespace = IDLNamespace(namespace)
314 AddOkay(namespace, BarXX) 210 AddOkay(namespace, BarXX)
315 AddOkay(namespace, Bar12) 211 AddOkay(namespace, Bar12)
316 # Verify we warn when detecting a gap 212 # Verify we warn when detecting a gap
317 AddWarn(namespace, Bar34, 'Gap in version numbers.') 213 AddWarn(namespace, Bar34, 'Gap in release numbers.')
318 # Verify we fail when inserting into this gap 214 # Verify we fail when inserting into this gap
319 # (NOTE: while this could be legal, it is sloppy so we disallow it) 215 # (NOTE: while this could be legal, it is sloppy so we disallow it)
320 AddError(namespace, Bar23, 'Declarations out of order.') 216 AddError(namespace, Bar23, 'Declarations out of order.')
321 217
322 # Verify local namespace 218 # Verify local namespace
323 VerifyFindOne(namespace, 'bar', 0.0, BarXX) 219 VerifyFindOne(namespace, 'bar', 0.0, BarXX)
324 VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12]) 220 VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12])
325 221
326 # Verify the correct version of the object is found recursively 222 # Verify the correct release of the object is found recursively
327 VerifyFindOne(namespace, 'foo', 0.0, FooXX) 223 VerifyFindOne(namespace, 'foo', 0.0, FooXX)
328 VerifyFindOne(namespace, 'foo', 0.5, FooXX) 224 VerifyFindOne(namespace, 'foo', 0.5, FooXX)
329 VerifyFindOne(namespace, 'foo', 1.0, Foo1X) 225 VerifyFindOne(namespace, 'foo', 1.0, Foo1X)
330 VerifyFindOne(namespace, 'foo', 1.5, Foo1X) 226 VerifyFindOne(namespace, 'foo', 1.5, Foo1X)
331 VerifyFindOne(namespace, 'foo', 3.0, Foo3X) 227 VerifyFindOne(namespace, 'foo', 3.0, Foo3X)
332 VerifyFindOne(namespace, 'foo', 100.0, Foo3X) 228 VerifyFindOne(namespace, 'foo', 100.0, Foo3X)
333 229
334 # Verify the correct range of objects is found 230 # Verify the correct range of objects is found
335 VerifyFindAll(namespace, 'foo', 0.0, 1.0, [FooXX]) 231 VerifyFindAll(namespace, 'foo', 0.0, 1.0, [FooXX])
336 VerifyFindAll(namespace, 'foo', 0.5, 1.0, [FooXX]) 232 VerifyFindAll(namespace, 'foo', 0.5, 1.0, [FooXX])
337 VerifyFindAll(namespace, 'foo', 1.0, 1.1, [Foo1X]) 233 VerifyFindAll(namespace, 'foo', 1.0, 1.1, [Foo1X])
338 VerifyFindAll(namespace, 'foo', 0.5, 1.5, [FooXX, Foo1X]) 234 VerifyFindAll(namespace, 'foo', 0.5, 1.5, [FooXX, Foo1X])
339 VerifyFindAll(namespace, 'foo', 0.0, 3.0, [FooXX, Foo1X]) 235 VerifyFindAll(namespace, 'foo', 0.0, 3.0, [FooXX, Foo1X])
340 VerifyFindAll(namespace, 'foo', 3.0, 100.0, [Foo3X]) 236 VerifyFindAll(namespace, 'foo', 3.0, 100.0, [Foo3X])
341 237
342 FooBar = MockNode('foobar', 1.0, 2.0) 238 FooBar = MockNode('foobar', 1.0, 2.0)
343 namespace = IDLNamespace(namespace) 239 namespace = IDLNamespace(namespace)
344 AddOkay(namespace, FooBar) 240 AddOkay(namespace, FooBar)
345 241
346 if errors: 242 if errors:
347 print 'Test failed with %d errors.' % errors 243 print 'Test failed with %d errors.' % errors
348 else: 244 else:
349 print 'Passed.' 245 print 'Passed.'
350 return errors 246 return errors
351 247
352 if __name__ == '__main__': 248 if __name__ == '__main__':
353 sys.exit(Main(sys.argv[1:])) 249 sys.exit(Main(sys.argv[1:]))
354 250
OLDNEW
« no previous file with comments | « ppapi/generators/idl_lint.py ('k') | ppapi/generators/idl_node.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698