 Chromium Code Reviews
 Chromium Code Reviews Issue 12315074:
  Fix problem with non void return types in extension API IDL.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 12315074:
  Fix problem with non void return types in extension API IDL.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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 itertools | 6 import itertools | 
| 7 import json | 7 import json | 
| 8 import os.path | 8 import os.path | 
| 9 import re | 9 import re | 
| 10 import sys | 10 import sys | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 param_comment_start = cur_param.end() | 81 param_comment_start = cur_param.end() | 
| 82 param_comment_end = next_param.start() if next_param else len(comment) | 82 param_comment_end = next_param.start() if next_param else len(comment) | 
| 83 params[param_name] = (comment[param_comment_start:param_comment_end | 83 params[param_name] = (comment[param_comment_start:param_comment_end | 
| 84 ].strip().replace('\n\n', '<br/><br/>') | 84 ].strip().replace('\n\n', '<br/><br/>') | 
| 85 .replace('\n', '')) | 85 .replace('\n', '')) | 
| 86 return (parent_comment, params) | 86 return (parent_comment, params) | 
| 87 | 87 | 
| 88 class Callspec(object): | 88 class Callspec(object): | 
| 89 ''' | 89 ''' | 
| 90 Given a Callspec node representing an IDL function declaration, converts into | 90 Given a Callspec node representing an IDL function declaration, converts into | 
| 91 a name/value pair where the value is a list of function parameters. | 91 a tuple: | 
| 92 (name, list of function parameters, return type) | |
| 92 ''' | 93 ''' | 
| 93 def __init__(self, callspec_node, comment): | 94 def __init__(self, callspec_node, comment): | 
| 94 self.node = callspec_node | 95 self.node = callspec_node | 
| 95 self.comment = comment | 96 self.comment = comment | 
| 96 | 97 | 
| 97 def process(self, callbacks): | 98 def process(self, callbacks): | 
| 98 parameters = [] | 99 parameters = [] | 
| 100 return_type = None | |
| 101 if self.node.GetProperty('TYPEREF') not in ['void', None]: | |
| 
asargent_no_longer_on_chrome
2013/02/26 06:19:47
tiny nit: I think we typically prefer ('void', Non
 | |
| 102 return_type = Typeref(self.node.GetProperty('TYPEREF'), | |
| 103 self.node, | |
| 104 {'name': self.node.GetName()}).process(callbacks) | |
| 105 # The IDL parser doesn't allow specifying return types as optional. | |
| 106 # Instead we infer any object return values to be optional. | |
| 
asargent_no_longer_on_chrome
2013/02/26 06:19:47
I can whip up a quick CL to add this support to th
 | |
| 107 if return_type.get('type') == 'object' or '$ref' in return_type: | |
| 108 return_type['optional'] = True; | |
| 99 for node in self.node.children: | 109 for node in self.node.children: | 
| 100 parameter = Param(node).process(callbacks) | 110 parameter = Param(node).process(callbacks) | 
| 101 if parameter['name'] in self.comment: | 111 if parameter['name'] in self.comment: | 
| 102 parameter['description'] = self.comment[parameter['name']] | 112 parameter['description'] = self.comment[parameter['name']] | 
| 103 parameters.append(parameter) | 113 parameters.append(parameter) | 
| 104 return self.node.GetName(), parameters | 114 return (self.node.GetName(), parameters, return_type) | 
| 105 | 115 | 
| 106 class Param(object): | 116 class Param(object): | 
| 107 ''' | 117 ''' | 
| 108 Given a Param node representing a function parameter, converts into a Python | 118 Given a Param node representing a function parameter, converts into a Python | 
| 109 dictionary that the JSON schema compiler expects to see. | 119 dictionary that the JSON schema compiler expects to see. | 
| 110 ''' | 120 ''' | 
| 111 def __init__(self, param_node): | 121 def __init__(self, param_node): | 
| 112 self.node = param_node | 122 self.node = param_node | 
| 113 | 123 | 
| 114 def process(self, callbacks): | 124 def process(self, callbacks): | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 if self.node.GetProperty(property_name): | 164 if self.node.GetProperty(property_name): | 
| 155 properties[property_name.lower()] = True | 165 properties[property_name.lower()] = True | 
| 156 is_function = False | 166 is_function = False | 
| 157 parameter_comments = OrderedDict() | 167 parameter_comments = OrderedDict() | 
| 158 for node in self.node.children: | 168 for node in self.node.children: | 
| 159 if node.cls == 'Comment': | 169 if node.cls == 'Comment': | 
| 160 (parent_comment, parameter_comments) = ProcessComment(node.GetName()) | 170 (parent_comment, parameter_comments) = ProcessComment(node.GetName()) | 
| 161 properties['description'] = parent_comment | 171 properties['description'] = parent_comment | 
| 162 elif node.cls == 'Callspec': | 172 elif node.cls == 'Callspec': | 
| 163 is_function = True | 173 is_function = True | 
| 164 name, parameters = Callspec(node, parameter_comments).process(callbacks) | 174 name, parameters, return_type = (Callspec(node, parameter_comments) | 
| 175 .process(callbacks)) | |
| 165 properties['parameters'] = parameters | 176 properties['parameters'] = parameters | 
| 177 if return_type is not None: | |
| 178 properties['returns'] = return_type | |
| 166 properties['name'] = name | 179 properties['name'] = name | 
| 167 if is_function: | 180 if is_function: | 
| 168 properties['type'] = 'function' | 181 properties['type'] = 'function' | 
| 169 else: | 182 else: | 
| 170 properties = Typeref(self.node.GetProperty('TYPEREF'), | 183 properties = Typeref(self.node.GetProperty('TYPEREF'), | 
| 171 self.node, properties).process(callbacks) | 184 self.node, properties).process(callbacks) | 
| 172 enum_values = self.node.GetProperty('legalValues') | 185 enum_values = self.node.GetProperty('legalValues') | 
| 173 if enum_values: | 186 if enum_values: | 
| 174 if properties['type'] == 'integer': | 187 if properties['type'] == 'integer': | 
| 175 enum_values = map(int, enum_values) | 188 enum_values = map(int, enum_values) | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 properties['type'] = 'object' | 232 properties['type'] = 'object' | 
| 220 if 'additionalProperties' not in properties: | 233 if 'additionalProperties' not in properties: | 
| 221 properties['additionalProperties'] = OrderedDict() | 234 properties['additionalProperties'] = OrderedDict() | 
| 222 properties['additionalProperties']['type'] = 'any' | 235 properties['additionalProperties']['type'] = 'any' | 
| 223 instance_of = self.parent.GetProperty('instanceOf') | 236 instance_of = self.parent.GetProperty('instanceOf') | 
| 224 if instance_of: | 237 if instance_of: | 
| 225 properties['isInstanceOf'] = instance_of | 238 properties['isInstanceOf'] = instance_of | 
| 226 elif self.typeref == 'ArrayBuffer': | 239 elif self.typeref == 'ArrayBuffer': | 
| 227 properties['type'] = 'binary' | 240 properties['type'] = 'binary' | 
| 228 properties['isInstanceOf'] = 'ArrayBuffer' | 241 properties['isInstanceOf'] = 'ArrayBuffer' | 
| 242 elif self.typeref == 'FileEntry': | |
| 243 properties['type'] = 'object' | |
| 244 properties['isInstanceOf'] = 'FileEntry' | |
| 245 if 'additionalProperties' not in properties: | |
| 246 properties['additionalProperties'] = OrderedDict() | |
| 247 properties['additionalProperties']['type'] = 'any' | |
| 229 elif self.typeref is None: | 248 elif self.typeref is None: | 
| 230 properties['type'] = 'function' | 249 properties['type'] = 'function' | 
| 231 else: | 250 else: | 
| 232 if self.typeref in callbacks: | 251 if self.typeref in callbacks: | 
| 233 # Do not override name and description if they are already specified. | 252 # Do not override name and description if they are already specified. | 
| 234 name = properties.get('name', None) | 253 name = properties.get('name', None) | 
| 235 description = properties.get('description', None) | 254 description = properties.get('description', None) | 
| 236 properties.update(callbacks[self.typeref]) | 255 properties.update(callbacks[self.typeref]) | 
| 237 if description is not None: | 256 if description is not None: | 
| 238 properties['description'] = description | 257 properties['description'] = description | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 ''' | 392 ''' | 
| 374 Dump a json serialization of parse result for the IDL files whose names | 393 Dump a json serialization of parse result for the IDL files whose names | 
| 375 were passed in on the command line. | 394 were passed in on the command line. | 
| 376 ''' | 395 ''' | 
| 377 for filename in sys.argv[1:]: | 396 for filename in sys.argv[1:]: | 
| 378 schema = Load(filename) | 397 schema = Load(filename) | 
| 379 print json.dumps(schema, indent=2) | 398 print json.dumps(schema, indent=2) | 
| 380 | 399 | 
| 381 if __name__ == '__main__': | 400 if __name__ == '__main__': | 
| 382 Main() | 401 Main() | 
| OLD | NEW |