OLD | NEW |
---|---|
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import json | 6 import json |
7 import os.path | 7 import os.path |
8 import re | 8 import re |
9 import sys | 9 import sys |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... | |
30 Given the string from a Comment node, parse it into a tuple that looks | 30 Given the string from a Comment node, parse it into a tuple that looks |
31 like: | 31 like: |
32 ( | 32 ( |
33 "The processed comment, minus all |parameter| mentions.", | 33 "The processed comment, minus all |parameter| mentions.", |
34 { | 34 { |
35 'parameter_name_1': "The comment that followed |parameter_name_1|:", | 35 'parameter_name_1': "The comment that followed |parameter_name_1|:", |
36 ... | 36 ... |
37 } | 37 } |
38 ) | 38 ) |
39 ''' | 39 ''' |
40 # Find all the parameter comments of the form "|name|: comment". | 40 # Find all the parameter comments of the form '|name|: comment'. |
41 parameter_comments = re.findall(r'\n *\|([^|]*)\| *: *(.*)', comment) | 41 parameter_comments = re.findall(r'\n *\|([^|]*)\| *: *(.*)', comment) |
42 # Get the parent comment (everything before the first parameter comment. | 42 # Get the parent comment (everything before the first parameter comment. |
43 parent_comment = re.sub(r'\n *\|.*', '', comment) | 43 parent_comment = re.sub(r'\n *\|.*', '', comment) |
44 parent_comment = parent_comment.replace('\n', '').strip() | 44 parent_comment = parent_comment.replace('\n', '').strip() |
45 | 45 |
46 parsed = {} | 46 parsed = {} |
47 for (name, comment) in parameter_comments: | 47 for (name, comment) in parameter_comments: |
48 parsed[name] = comment.replace('\n', '').strip() | 48 parsed[name] = comment.replace('\n', '').strip() |
49 return (parent_comment, parsed) | 49 return (parent_comment, parsed) |
50 | 50 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 properties[k] = v | 95 properties[k] = v |
96 return { 'id': self.node.GetName(), | 96 return { 'id': self.node.GetName(), |
97 'properties': properties, | 97 'properties': properties, |
98 'type': 'object' } | 98 'type': 'object' } |
99 | 99 |
100 class Enum(object): | 100 class Enum(object): |
101 ''' | 101 ''' |
102 Given an IDL Enum node, converts into a Python dictionary that the JSON | 102 Given an IDL Enum node, converts into a Python dictionary that the JSON |
103 schema compiler expects to see. | 103 schema compiler expects to see. |
104 ''' | 104 ''' |
105 def __init__(self, enum_node): | 105 def __init__(self, enum_node): |
not at google - send to devlin
2012/06/04 04:16:49
please get asargent@ to look at the contents of th
benjhayden
2012/06/04 20:33:15
Done.
| |
106 self.node = enum_node | 106 self.node = enum_node |
107 self.description = '' | |
107 | 108 |
108 def process(self, callbacks): | 109 def process(self, callbacks): |
109 enum = [] | 110 enum = [] |
111 enum_type = 'integer' | |
110 for node in self.node.children: | 112 for node in self.node.children: |
111 if node.cls == 'EnumItem': | 113 if node.cls == 'EnumItem': |
112 name = node.GetName() | 114 value = node.GetProperty('VALUE') |
113 enum.append(name) | 115 if value: |
116 try: | |
117 value = int(value) | |
118 except ValueError: | |
119 try: | |
120 value = float(value) | |
121 enum_type = 'double' | |
122 except ValueError: | |
123 enum_type = 'string' | |
124 else: | |
125 value = node.GetName() | |
126 enum_type = 'string' | |
127 enum.append(value) | |
128 elif node.cls == 'Comment': | |
129 self.description = ProcessComment(node.GetName())[0] | |
114 else: | 130 else: |
115 sys.exit("Did not process %s %s" % (node.cls, node)) | 131 sys.exit('Did not process %s %s' % (node.cls, node)) |
116 return { "id" : self.node.GetName(), | 132 return {'id' : self.node.GetName(), |
117 'enum': enum, | 133 'description': self.description, |
118 'type': 'string' } | 134 'type': enum_type, |
119 | 135 'enum': enum} |
120 | 136 |
121 | 137 |
122 class Member(object): | 138 class Member(object): |
123 ''' | 139 ''' |
124 Given an IDL dictionary or interface member, converts into a name/value pair | 140 Given an IDL dictionary or interface member, converts into a name/value pair |
125 where the value is a Python dictionary that the JSON schema compiler expects | 141 where the value is a Python dictionary that the JSON schema compiler expects |
126 to see. | 142 to see. |
127 ''' | 143 ''' |
128 def __init__(self, member_node): | 144 def __init__(self, member_node): |
129 self.node = member_node | 145 self.node = member_node |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 properties['$ref'] = self.typeref | 225 properties['$ref'] = self.typeref |
210 | 226 |
211 return result | 227 return result |
212 | 228 |
213 class Namespace(object): | 229 class Namespace(object): |
214 ''' | 230 ''' |
215 Given an IDLNode representing an IDL namespace, converts into a Python | 231 Given an IDLNode representing an IDL namespace, converts into a Python |
216 dictionary that the JSON schema compiler expects to see. | 232 dictionary that the JSON schema compiler expects to see. |
217 ''' | 233 ''' |
218 | 234 |
219 def __init__(self, namespace_node, nodoc=False): | 235 def __init__(self, namespace_node, description='', nodoc=False, |
236 permissions=None): | |
220 self.namespace = namespace_node | 237 self.namespace = namespace_node |
221 self.nodoc = nodoc | 238 self.nodoc = nodoc |
239 self.description = description | |
222 self.events = [] | 240 self.events = [] |
223 self.functions = [] | 241 self.functions = [] |
224 self.types = [] | 242 self.types = [] |
225 self.callbacks = {} | 243 self.callbacks = {} |
244 self.permissions = permissions or [] | |
226 | 245 |
227 def process(self): | 246 def process(self): |
228 for node in self.namespace.children: | 247 for node in self.namespace.children: |
229 cls = node.cls | 248 cls = node.cls |
230 if cls == "Dictionary": | 249 if cls == 'Dictionary': |
231 self.types.append(Dictionary(node).process(self.callbacks)) | 250 self.types.append(Dictionary(node).process(self.callbacks)) |
232 elif cls == "Callback": | 251 elif cls == 'Callback': |
233 k, v = Member(node).process(self.callbacks) | 252 k, v = Member(node).process(self.callbacks) |
234 self.callbacks[k] = v | 253 self.callbacks[k] = v |
235 elif cls == "Interface" and node.GetName() == "Functions": | 254 elif cls == 'Interface' and node.GetName() == 'Functions': |
236 self.functions = self.process_interface(node) | 255 self.functions = self.process_interface(node) |
237 elif cls == "Interface" and node.GetName() == "Events": | 256 elif cls == 'Interface' and node.GetName() == 'Events': |
238 self.events = self.process_interface(node) | 257 self.events = self.process_interface(node) |
239 elif cls == "Enum": | 258 elif cls == 'Enum': |
240 self.types.append(Enum(node).process(self.callbacks)) | 259 self.types.append(Enum(node).process(self.callbacks)) |
260 elif cls == 'Member': | |
261 name, properties = Member(node).process(self.callbacks) | |
262 self.functions.append(properties) | |
241 else: | 263 else: |
242 sys.exit("Did not process %s %s" % (node.cls, node)) | 264 sys.exit('Did not process %s %s' % (node.cls, node)) |
243 | 265 |
244 return { 'events': self.events, | 266 return {'namespace': self.namespace.GetName(), |
245 'functions': self.functions, | 267 'documentation_permissions_required': self.permissions, |
246 'types': self.types, | 268 'nodoc': self.nodoc, |
247 'namespace': self.namespace.GetName(), | 269 'description': self.description, |
248 'nodoc': self.nodoc } | 270 'types': self.types, |
271 'events': self.events, | |
272 'functions': self.functions} | |
249 | 273 |
250 def process_interface(self, node): | 274 def process_interface(self, node): |
251 members = [] | 275 members = [] |
252 for member in node.children: | 276 for member in node.children: |
253 if member.cls == 'Member': | 277 if member.cls == 'Member': |
254 name, properties = Member(member).process(self.callbacks) | 278 name, properties = Member(member).process(self.callbacks) |
255 members.append(properties) | 279 members.append(properties) |
256 return members | 280 return members |
257 | 281 |
258 class IDLSchema(object): | 282 class IDLSchema(object): |
259 ''' | 283 ''' |
260 Given a list of IDLNodes and IDLAttributes, converts into a Python list | 284 Given a list of IDLNodes and IDLAttributes, converts into a Python list |
261 of api_defs that the JSON schema compiler expects to see. | 285 of api_defs that the JSON schema compiler expects to see. |
262 ''' | 286 ''' |
263 | 287 |
264 def __init__(self, idl): | 288 def __init__(self, idl): |
265 self.idl = idl | 289 self.idl = idl |
266 | 290 |
267 def process(self): | 291 def process(self): |
268 namespaces = [] | 292 namespaces = [] |
293 description = '' | |
294 nodoc = False | |
295 permissions = None | |
269 for node in self.idl: | 296 for node in self.idl: |
270 nodoc = False | |
271 cls = node.cls | 297 cls = node.cls |
272 if cls == 'Namespace': | 298 if cls == 'Namespace': |
273 namespace = Namespace(node, nodoc) | 299 namespace = Namespace(node, description, nodoc, permissions) |
274 namespaces.append(namespace.process()) | 300 namespaces.append(namespace.process()) |
275 elif cls == 'Copyright': | 301 elif cls == 'Copyright': |
276 continue | 302 continue |
277 elif cls == 'Comment': | 303 elif cls == 'Comment': |
304 description = ProcessComment(node.GetName())[0] | |
278 continue | 305 continue |
279 elif cls == 'ExtAttribute': | 306 elif cls == 'ExtAttribute': |
280 if node.name == 'nodoc': | 307 if node.name == 'nodoc': |
281 nodoc = bool(node.value) | 308 nodoc = bool(node.value) |
309 elif node.name == 'permissions': | |
310 permissions = node.value.split(',') | |
282 else: | 311 else: |
283 continue | 312 continue |
284 else: | 313 else: |
285 sys.exit("Did not process %s %s" % (node.cls, node)) | 314 sys.exit('Did not process %s %s' % (node.cls, node)) |
286 schema_util.PrefixSchemasWithNamespace(namespaces) | 315 schema_util.PrefixSchemasWithNamespace(namespaces) |
287 return namespaces | 316 return namespaces |
288 | 317 |
289 def Load(filename): | 318 def Load(filename): |
290 ''' | 319 ''' |
291 Given the filename of an IDL file, parses it and returns an equivalent | 320 Given the filename of an IDL file, parses it and returns an equivalent |
292 Python dictionary in a format that the JSON schema compiler expects to see. | 321 Python dictionary in a format that the JSON schema compiler expects to see. |
293 ''' | 322 ''' |
294 | 323 |
295 f = open(filename, 'r') | 324 f = open(filename, 'r') |
296 contents = f.read() | 325 contents = f.read() |
297 f.close() | 326 f.close() |
298 | 327 |
299 idl = idl_parser.IDLParser().ParseData(contents, filename) | 328 idl = idl_parser.IDLParser().ParseData(contents, filename) |
300 idl_schema = IDLSchema(idl) | 329 idl_schema = IDLSchema(idl) |
301 return idl_schema.process() | 330 return idl_schema.process() |
302 | 331 |
303 def Main(): | 332 def Main(): |
304 ''' | 333 ''' |
305 Dump a json serialization of parse result for the IDL files whose names | 334 Dump a json serialization of parse result for the IDL files whose names |
306 were passed in on the command line. | 335 were passed in on the command line. |
307 ''' | 336 ''' |
308 for filename in sys.argv[1:]: | 337 for filename in sys.argv[1:]: |
309 schema = Load(filename) | 338 schema = Load(filename) |
310 print json.dumps(schema, indent=2) | 339 print json.dumps(schema, indent=2) |
311 | 340 |
312 if __name__ == '__main__': | 341 if __name__ == '__main__': |
313 Main() | 342 Main() |
OLD | NEW |