| OLD | NEW |
| 1 #! /usr/bin/env python |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 4 | 5 |
| 6 import json |
| 5 import os.path | 7 import os.path |
| 6 import sys | 8 import sys |
| 7 | 9 |
| 8 # This file is a peer to json_schema.py. Each of these files understands a | 10 # This file is a peer to json_schema.py. Each of these files understands a |
| 9 # certain format describing APIs (either JSON or IDL), reads files written | 11 # certain format describing APIs (either JSON or IDL), reads files written |
| 10 # in that format into memory, and emits them as a Python array of objects | 12 # in that format into memory, and emits them as a Python array of objects |
| 11 # corresponding to those APIs, where the objects are formatted in a way that | 13 # corresponding to those APIs, where the objects are formatted in a way that |
| 12 # the JSON schema compiler understands. compiler.py drives both idl_schema.py | 14 # the JSON schema compiler understands. compiler.py drives both idl_schema.py |
| 13 # and json_schema.py. | 15 # and json_schema.py. |
| 14 | 16 |
| 15 # idl_parser expects to be able to import certain files in its directory, | 17 # idl_parser expects to be able to import certain files in its directory, |
| 16 # so let's set things up the way it wants. | 18 # so let's set things up the way it wants. |
| 17 idl_generators_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), | 19 idl_generators_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), |
| 18 os.pardir, os.pardir, 'ppapi', 'generators') | 20 os.pardir, os.pardir, 'ppapi', 'generators') |
| 19 if idl_generators_path not in sys.path: | 21 if idl_generators_path not in sys.path: |
| 20 sys.path.insert(0, idl_generators_path) | 22 sys.path.insert(0, idl_generators_path) |
| 21 import idl_parser | 23 import idl_parser |
| 22 | 24 |
| 23 class Callspec(object): | 25 class Callspec(object): |
| 24 ''' | 26 ''' |
| 25 Given a Callspec node representing an IDL function declaration, converts into | 27 Given a Callspec node representing an IDL function declaration, converts into |
| 26 a name/value pair where the value is a list of function parameters. | 28 a name/value pair where the value is a list of function parameters. |
| 27 ''' | 29 ''' |
| 28 def __init__(self, callspec_node): | 30 def __init__(self, callspec_node): |
| 29 self.node = callspec_node | 31 self.node = callspec_node |
| 30 | 32 |
| 31 def process(self, refs): | 33 def process(self, callbacks): |
| 32 parameters = [] | 34 parameters = [] |
| 33 for node in self.node.children: | 35 for node in self.node.children: |
| 34 parameters.append(Param(node).process(refs)) | 36 parameters.append(Param(node).process(callbacks)) |
| 35 return self.node.GetName(), parameters | 37 return self.node.GetName(), parameters |
| 36 | 38 |
| 37 class Param(object): | 39 class Param(object): |
| 38 ''' | 40 ''' |
| 39 Given a Param node representing a function parameter, converts into a Python | 41 Given a Param node representing a function parameter, converts into a Python |
| 40 dictionary that the JSON schema compiler expects to see. | 42 dictionary that the JSON schema compiler expects to see. |
| 41 ''' | 43 ''' |
| 42 def __init__(self, param_node): | 44 def __init__(self, param_node): |
| 43 self.node = param_node | 45 self.node = param_node |
| 44 | 46 |
| 45 def process(self, refs): | 47 def process(self, callbacks): |
| 46 return Typeref(self.node.GetProperty( 'TYPEREF'), | 48 return Typeref(self.node.GetProperty( 'TYPEREF'), |
| 47 self.node, | 49 self.node, |
| 48 { 'name': self.node.GetName() }).process(refs) | 50 { 'name': self.node.GetName() }).process(callbacks) |
| 49 | 51 |
| 50 class Dictionary(object): | 52 class Dictionary(object): |
| 51 ''' | 53 ''' |
| 52 Given an IDL Dictionary node, converts into a Python dictionary that the JSON | 54 Given an IDL Dictionary node, converts into a Python dictionary that the JSON |
| 53 schema compiler expects to see. | 55 schema compiler expects to see. |
| 54 ''' | 56 ''' |
| 55 def __init__(self, dictionary_node): | 57 def __init__(self, dictionary_node): |
| 56 self.node = dictionary_node | 58 self.node = dictionary_node |
| 57 | 59 |
| 58 def process(self, refs): | 60 def process(self, callbacks): |
| 59 properties = {} | 61 properties = {} |
| 60 for node in self.node.children: | 62 for node in self.node.children: |
| 61 if node.cls == 'Member': | 63 if node.cls == 'Member': |
| 62 k, v = Member(node).process(refs) | 64 k, v = Member(node).process(callbacks) |
| 63 properties[k] = v | 65 properties[k] = v |
| 64 return { 'id': self.node.GetName(), | 66 return { 'id': self.node.GetName(), |
| 65 'properties': properties, | 67 'properties': properties, |
| 66 'type': 'object' } | 68 'type': 'object' } |
| 67 | 69 |
| 68 class Member(object): | 70 class Member(object): |
| 69 ''' | 71 ''' |
| 70 Given an IDL dictionary or interface member, converts into a name/value pair | 72 Given an IDL dictionary or interface member, converts into a name/value pair |
| 71 where the value is a Python dictionary that the JSON schema compiler expects | 73 where the value is a Python dictionary that the JSON schema compiler expects |
| 72 to see. | 74 to see. |
| 73 ''' | 75 ''' |
| 74 def __init__(self, member_node): | 76 def __init__(self, member_node): |
| 75 self.node = member_node | 77 self.node = member_node |
| 76 | 78 |
| 77 def process(self, refs): | 79 def process(self, callbacks): |
| 78 properties = {} | 80 properties = {} |
| 79 name = self.node.GetName() | 81 name = self.node.GetName() |
| 80 if self.node.GetProperty('OPTIONAL'): | 82 if self.node.GetProperty('OPTIONAL'): |
| 81 properties['optional'] = True | 83 properties['optional'] = True |
| 82 if self.node.GetProperty('nodoc'): | 84 if self.node.GetProperty('nodoc'): |
| 83 properties['nodoc'] = True | 85 properties['nodoc'] = True |
| 84 is_function = False | 86 is_function = False |
| 85 for node in self.node.children: | 87 for node in self.node.children: |
| 86 if node.cls == 'Callspec': | 88 if node.cls == 'Callspec': |
| 87 is_function = True | 89 is_function = True |
| 88 name, parameters = Callspec(node).process(refs) | 90 name, parameters = Callspec(node).process(callbacks) |
| 89 properties['parameters'] = parameters | 91 properties['parameters'] = parameters |
| 90 properties['name'] = name | 92 properties['name'] = name |
| 91 if is_function: | 93 if is_function: |
| 92 properties['type'] = 'function' | 94 properties['type'] = 'function' |
| 93 else: | 95 else: |
| 94 properties = Typeref(self.node.GetProperty('TYPEREF'), | 96 properties = Typeref(self.node.GetProperty('TYPEREF'), |
| 95 self.node, properties).process(refs) | 97 self.node, properties).process(callbacks) |
| 96 return name, properties | 98 return name, properties |
| 97 | 99 |
| 98 class Typeref(object): | 100 class Typeref(object): |
| 99 ''' | 101 ''' |
| 100 Given a TYPEREF property representing the type of dictionary member or | 102 Given a TYPEREF property representing the type of dictionary member or |
| 101 function parameter, converts into a Python dictionary that the JSON schema | 103 function parameter, converts into a Python dictionary that the JSON schema |
| 102 compiler expects to see. | 104 compiler expects to see. |
| 103 ''' | 105 ''' |
| 104 def __init__(self, typeref, parent, additional_properties={}): | 106 def __init__(self, typeref, parent, additional_properties={}): |
| 105 self.typeref = typeref | 107 self.typeref = typeref |
| 106 self.parent = parent | 108 self.parent = parent |
| 107 self.additional_properties = additional_properties | 109 self.additional_properties = additional_properties |
| 108 | 110 |
| 109 def process(self, refs): | 111 def process(self, callbacks): |
| 110 properties = self.additional_properties | 112 properties = self.additional_properties |
| 111 result = properties | 113 result = properties |
| 112 | 114 |
| 113 if self.parent.GetProperty('OPTIONAL', False): | 115 if self.parent.GetProperty('OPTIONAL', False): |
| 114 properties['optional'] = True | 116 properties['optional'] = True |
| 115 | 117 |
| 116 # The IDL parser denotes array types by adding a child 'Array' node onto | 118 # The IDL parser denotes array types by adding a child 'Array' node onto |
| 117 # the Param node in the Callspec. | 119 # the Param node in the Callspec. |
| 118 for sibling in self.parent.GetChildren(): | 120 for sibling in self.parent.GetChildren(): |
| 119 if sibling.cls == 'Array' and sibling.GetName() == self.parent.GetName(): | 121 if sibling.cls == 'Array' and sibling.GetName() == self.parent.GetName(): |
| (...skipping 14 matching lines...) Expand all Loading... |
| 134 properties['type'] = 'object' | 136 properties['type'] = 'object' |
| 135 if 'additionalProperties' not in properties: | 137 if 'additionalProperties' not in properties: |
| 136 properties['additionalProperties'] = {} | 138 properties['additionalProperties'] = {} |
| 137 properties['additionalProperties']['type'] = 'any' | 139 properties['additionalProperties']['type'] = 'any' |
| 138 instance_of = self.parent.GetProperty('instanceOf') | 140 instance_of = self.parent.GetProperty('instanceOf') |
| 139 if instance_of: | 141 if instance_of: |
| 140 properties['isInstanceOf'] = instance_of | 142 properties['isInstanceOf'] = instance_of |
| 141 elif self.typeref is None: | 143 elif self.typeref is None: |
| 142 properties['type'] = 'function' | 144 properties['type'] = 'function' |
| 143 else: | 145 else: |
| 144 try: | 146 if self.typeref in callbacks: |
| 145 result = refs[self.typeref] | 147 properties.update(callbacks[self.typeref]) |
| 146 except KeyError, e: | 148 else: |
| 147 properties['$ref'] = self.typeref | 149 properties['$ref'] = self.typeref |
| 148 | 150 |
| 149 return result | 151 return result |
| 150 | 152 |
| 151 class Namespace(object): | 153 class Namespace(object): |
| 152 ''' | 154 ''' |
| 153 Given an IDLNode representing an IDL namespace, converts into a Python | 155 Given an IDLNode representing an IDL namespace, converts into a Python |
| 154 dictionary that the JSON schema compiler expects to see. | 156 dictionary that the JSON schema compiler expects to see. |
| 155 ''' | 157 ''' |
| 156 | 158 |
| 157 def __init__(self, namespace_node, nodoc=False): | 159 def __init__(self, namespace_node, nodoc=False): |
| 158 self.namespace = namespace_node | 160 self.namespace = namespace_node |
| 159 self.nodoc = nodoc | 161 self.nodoc = nodoc |
| 160 self.events = [] | 162 self.events = [] |
| 161 self.functions = [] | 163 self.functions = [] |
| 162 self.types = [] | 164 self.types = [] |
| 163 self.refs = {} | 165 self.callbacks = {} |
| 164 | 166 |
| 165 def process(self): | 167 def process(self): |
| 166 for node in self.namespace.children: | 168 for node in self.namespace.children: |
| 167 cls = node.cls | 169 cls = node.cls |
| 168 if cls == "Dictionary": | 170 if cls == "Dictionary": |
| 169 self.types.append(Dictionary(node).process(self.refs)) | 171 self.types.append(Dictionary(node).process(self.callbacks)) |
| 170 elif cls == "Callback": | 172 elif cls == "Callback": |
| 171 k, v = Member(node).process(self.refs) | 173 k, v = Member(node).process(self.callbacks) |
| 172 self.refs[k] = v | 174 self.callbacks[k] = v |
| 173 elif cls == "Interface" and node.GetName() == "Functions": | 175 elif cls == "Interface" and node.GetName() == "Functions": |
| 174 self.functions = self.process_interface(node) | 176 self.functions = self.process_interface(node) |
| 175 elif cls == "Interface" and node.GetName() == "Events": | 177 elif cls == "Interface" and node.GetName() == "Events": |
| 176 self.events = self.process_interface(node) | 178 self.events = self.process_interface(node) |
| 177 else: | 179 else: |
| 178 sys.exit("Did not process %s %s" % (node.cls, node)) | 180 sys.exit("Did not process %s %s" % (node.cls, node)) |
| 179 | 181 |
| 180 return { 'events': self.events, | 182 return { 'events': self.events, |
| 181 'functions': self.functions, | 183 'functions': self.functions, |
| 182 'types': self.types, | 184 'types': self.types, |
| 183 'namespace': self.namespace.GetName(), | 185 'namespace': self.namespace.GetName(), |
| 184 'nodoc': self.nodoc } | 186 'nodoc': self.nodoc } |
| 185 | 187 |
| 186 def process_interface(self, node): | 188 def process_interface(self, node): |
| 187 members = [] | 189 members = [] |
| 188 for member in node.children: | 190 for member in node.children: |
| 189 if member.cls == 'Member': | 191 if member.cls == 'Member': |
| 190 name, properties = Member(member).process(self.refs) | 192 name, properties = Member(member).process(self.callbacks) |
| 191 members.append(properties) | 193 members.append(properties) |
| 192 return members | 194 return members |
| 193 | 195 |
| 194 class IDLSchema(object): | 196 class IDLSchema(object): |
| 195 ''' | 197 ''' |
| 196 Given a list of IDLNodes and IDLAttributes, converts into a Python list | 198 Given a list of IDLNodes and IDLAttributes, converts into a Python list |
| 197 of api_defs that the JSON schema compiler expects to see. | 199 of api_defs that the JSON schema compiler expects to see. |
| 198 ''' | 200 ''' |
| 199 | 201 |
| 200 def __init__(self, idl): | 202 def __init__(self, idl): |
| (...skipping 26 matching lines...) Expand all Loading... |
| 227 Python dictionary in a format that the JSON schema compiler expects to see. | 229 Python dictionary in a format that the JSON schema compiler expects to see. |
| 228 ''' | 230 ''' |
| 229 | 231 |
| 230 f = open(filename, 'r') | 232 f = open(filename, 'r') |
| 231 contents = f.read() | 233 contents = f.read() |
| 232 f.close() | 234 f.close() |
| 233 | 235 |
| 234 idl = idl_parser.IDLParser().ParseData(contents, filename) | 236 idl = idl_parser.IDLParser().ParseData(contents, filename) |
| 235 idl_schema = IDLSchema(idl) | 237 idl_schema = IDLSchema(idl) |
| 236 return idl_schema.process() | 238 return idl_schema.process() |
| 239 |
| 240 def Main(): |
| 241 ''' |
| 242 Dump a json serialization of parse result for the IDL files whose names |
| 243 were passed in on the command line. |
| 244 ''' |
| 245 for filename in sys.argv[1:]: |
| 246 schema = Load(filename) |
| 247 print json.dumps(schema, indent=2) |
| 248 |
| 249 if __name__ == '__main__': |
| 250 Main() |
| OLD | NEW |