Chromium Code Reviews| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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): |
| 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' | |
|
asargent_no_longer_on_chrome
2012/06/07 00:18:08
As I mentioned in another comment, the WebIDL spec
benjhayden
2012/06/08 16:41:52
Done.
| |
| 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, nodoc=False, |
| 236 permissions=None): | |
| 220 self.namespace = namespace_node | 237 self.namespace = namespace_node |
| 221 self.nodoc = nodoc | 238 self.nodoc = nodoc |
| 222 self.events = [] | 239 self.events = [] |
| 223 self.functions = [] | 240 self.functions = [] |
| 224 self.types = [] | 241 self.types = [] |
| 225 self.callbacks = {} | 242 self.callbacks = {} |
| 243 self.permissions = permissions or [] | |
| 226 | 244 |
| 227 def process(self): | 245 def process(self): |
| 228 for node in self.namespace.children: | 246 for node in self.namespace.children: |
| 229 cls = node.cls | 247 cls = node.cls |
| 230 if cls == "Dictionary": | 248 if cls == 'Dictionary': |
| 231 self.types.append(Dictionary(node).process(self.callbacks)) | 249 self.types.append(Dictionary(node).process(self.callbacks)) |
| 232 elif cls == "Callback": | 250 elif cls == 'Callback': |
| 233 k, v = Member(node).process(self.callbacks) | 251 k, v = Member(node).process(self.callbacks) |
| 234 self.callbacks[k] = v | 252 self.callbacks[k] = v |
| 235 elif cls == "Interface" and node.GetName() == "Functions": | 253 elif cls == 'Interface' and node.GetName() == 'Functions': |
| 236 self.functions = self.process_interface(node) | 254 self.functions = self.process_interface(node) |
| 237 elif cls == "Interface" and node.GetName() == "Events": | 255 elif cls == 'Interface' and node.GetName() == 'Events': |
| 238 self.events = self.process_interface(node) | 256 self.events = self.process_interface(node) |
| 239 elif cls == "Enum": | 257 elif cls == 'Enum': |
| 240 self.types.append(Enum(node).process(self.callbacks)) | 258 self.types.append(Enum(node).process(self.callbacks)) |
| 259 elif cls == 'Member': | |
| 260 name, properties = Member(node).process(self.callbacks) | |
| 261 self.functions.append(properties) | |
| 241 else: | 262 else: |
| 242 sys.exit("Did not process %s %s" % (node.cls, node)) | 263 sys.exit('Did not process %s %s' % (node.cls, node)) |
| 243 | 264 |
| 244 return { 'events': self.events, | 265 return {'namespace': self.namespace.GetName(), |
| 245 'functions': self.functions, | 266 'documentation_permissions_required': self.permissions, |
| 246 'types': self.types, | 267 'nodoc': self.nodoc, |
| 247 'namespace': self.namespace.GetName(), | 268 'types': self.types, |
| 248 'nodoc': self.nodoc } | 269 'events': self.events, |
| 270 'functions': self.functions} | |
| 249 | 271 |
| 250 def process_interface(self, node): | 272 def process_interface(self, node): |
| 251 members = [] | 273 members = [] |
| 252 for member in node.children: | 274 for member in node.children: |
| 253 if member.cls == 'Member': | 275 if member.cls == 'Member': |
| 254 name, properties = Member(member).process(self.callbacks) | 276 name, properties = Member(member).process(self.callbacks) |
| 255 members.append(properties) | 277 members.append(properties) |
| 256 return members | 278 return members |
| 257 | 279 |
| 258 class IDLSchema(object): | 280 class IDLSchema(object): |
| 259 ''' | 281 ''' |
| 260 Given a list of IDLNodes and IDLAttributes, converts into a Python list | 282 Given a list of IDLNodes and IDLAttributes, converts into a Python list |
| 261 of api_defs that the JSON schema compiler expects to see. | 283 of api_defs that the JSON schema compiler expects to see. |
| 262 ''' | 284 ''' |
| 263 | 285 |
| 264 def __init__(self, idl): | 286 def __init__(self, idl): |
| 265 self.idl = idl | 287 self.idl = idl |
| 266 | 288 |
| 267 def process(self): | 289 def process(self): |
| 268 namespaces = [] | 290 namespaces = [] |
| 291 nodoc = False | |
| 292 permissions = None | |
| 269 for node in self.idl: | 293 for node in self.idl: |
| 270 nodoc = False | |
| 271 cls = node.cls | 294 cls = node.cls |
| 272 if cls == 'Namespace': | 295 if cls == 'Namespace': |
| 273 namespace = Namespace(node, nodoc) | 296 namespace = Namespace(node, nodoc, permissions) |
| 274 namespaces.append(namespace.process()) | 297 namespaces.append(namespace.process()) |
| 275 elif cls == 'Copyright': | 298 elif cls in ['Copyright', 'Comment']: |
| 276 continue | |
| 277 elif cls == 'Comment': | |
| 278 continue | 299 continue |
| 279 elif cls == 'ExtAttribute': | 300 elif cls == 'ExtAttribute': |
| 280 if node.name == 'nodoc': | 301 if node.name == 'nodoc': |
| 281 nodoc = bool(node.value) | 302 nodoc = bool(node.value) |
| 303 elif node.name == 'permissions': | |
| 304 permissions = node.value.split(',') | |
| 282 else: | 305 else: |
| 283 continue | 306 continue |
| 284 else: | 307 else: |
| 285 sys.exit("Did not process %s %s" % (node.cls, node)) | 308 sys.exit('Did not process %s %s' % (node.cls, node)) |
| 286 schema_util.PrefixSchemasWithNamespace(namespaces) | 309 schema_util.PrefixSchemasWithNamespace(namespaces) |
| 287 return namespaces | 310 return namespaces |
| 288 | 311 |
| 289 def Load(filename): | 312 def Load(filename): |
| 290 ''' | 313 ''' |
| 291 Given the filename of an IDL file, parses it and returns an equivalent | 314 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. | 315 Python dictionary in a format that the JSON schema compiler expects to see. |
| 293 ''' | 316 ''' |
| 294 | 317 |
| 295 f = open(filename, 'r') | 318 f = open(filename, 'r') |
| 296 contents = f.read() | 319 contents = f.read() |
| 297 f.close() | 320 f.close() |
| 298 | 321 |
| 299 idl = idl_parser.IDLParser().ParseData(contents, filename) | 322 idl = idl_parser.IDLParser().ParseData(contents, filename) |
| 300 idl_schema = IDLSchema(idl) | 323 idl_schema = IDLSchema(idl) |
| 301 return idl_schema.process() | 324 return idl_schema.process() |
| 302 | 325 |
| 303 def Main(): | 326 def Main(): |
| 304 ''' | 327 ''' |
| 305 Dump a json serialization of parse result for the IDL files whose names | 328 Dump a json serialization of parse result for the IDL files whose names |
| 306 were passed in on the command line. | 329 were passed in on the command line. |
| 307 ''' | 330 ''' |
| 308 for filename in sys.argv[1:]: | 331 for filename in sys.argv[1:]: |
| 309 schema = Load(filename) | 332 schema = Load(filename) |
| 310 print json.dumps(schema, indent=2) | 333 print json.dumps(schema, indent=2) |
| 311 | 334 |
| 312 if __name__ == '__main__': | 335 if __name__ == '__main__': |
| 313 Main() | 336 Main() |
| OLD | NEW |