Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 """This module provides shared functionality for systems to generate | 6 """This module provides shared functionality for systems to generate |
| 7 Dart APIs from the IDL database.""" | 7 Dart APIs from the IDL database.""" |
| 8 | 8 |
| 9 import copy | 9 import copy |
| 10 import re | 10 import re |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 return GetIDLTypeInfo(idl_type_name).dart_type() | 172 return GetIDLTypeInfo(idl_type_name).dart_type() |
| 173 | 173 |
| 174 | 174 |
| 175 class ParamInfo(object): | 175 class ParamInfo(object): |
| 176 """Holder for various information about a parameter of a Dart operation. | 176 """Holder for various information about a parameter of a Dart operation. |
| 177 | 177 |
| 178 Attributes: | 178 Attributes: |
| 179 name: Name of parameter. | 179 name: Name of parameter. |
| 180 type_id: Original type id. None for merged types. | 180 type_id: Original type id. None for merged types. |
| 181 dart_type: DartType of parameter. | 181 dart_type: DartType of parameter. |
| 182 default_value: String holding the expression. None for mandatory parameter. | 182 is_optional: Parameter optionality. |
| 183 """ | 183 """ |
| 184 def __init__(self, name, type_id, dart_type, default_value): | 184 def __init__(self, name, type_id, dart_type, is_optional): |
| 185 self.name = name | 185 self.name = name |
| 186 self.type_id = type_id | 186 self.type_id = type_id |
| 187 self.dart_type = dart_type | 187 self.dart_type = dart_type |
| 188 self.default_value = default_value | 188 self.is_optional = is_optional |
| 189 | 189 |
| 190 def __repr__(self): | 190 def __repr__(self): |
| 191 content = 'name = %s, type_id = %s, dart_type = %s, default_value = %s' % ( | 191 content = 'name = %s, type_id = %s, dart_type = %s, is_optional = %s' % ( |
| 192 self.name, self.type_id, self.dart_type, self.default_value) | 192 self.name, self.type_id, self.dart_type, self.is_optional) |
| 193 return '<ParamInfo(%s)>' % content | 193 return '<ParamInfo(%s)>' % content |
| 194 | 194 |
| 195 | 195 |
| 196 # Given a list of overloaded arguments, render a dart argument. | 196 # Given a list of overloaded arguments, render a dart argument. |
| 197 def _DartArg(args, interface, constructor=False): | 197 def _DartArg(args, interface, constructor=False): |
| 198 # Given a list of overloaded arguments, choose a suitable name. | 198 # Given a list of overloaded arguments, choose a suitable name. |
| 199 def OverloadedName(args): | 199 def OverloadedName(args): |
| 200 return '_OR_'.join(sorted(set(arg.id for arg in args))) | 200 return '_OR_'.join(sorted(set(arg.id for arg in args))) |
| 201 | 201 |
| 202 # Given a list of overloaded arguments, choose a suitable type. | 202 # Given a list of overloaded arguments, choose a suitable type. |
| 203 def OverloadedType(args): | 203 def OverloadedType(args): |
| 204 type_ids = sorted(set(arg.type.id for arg in args)) | 204 type_ids = sorted(set(arg.type.id for arg in args)) |
| 205 dart_types = sorted(set(DartType(arg.type.id) for arg in args)) | 205 dart_types = sorted(set(DartType(arg.type.id) for arg in args)) |
| 206 if len(dart_types) == 1: | 206 if len(dart_types) == 1: |
| 207 if len(type_ids) == 1: | 207 if len(type_ids) == 1: |
| 208 return (type_ids[0], dart_types[0]) | 208 return (type_ids[0], dart_types[0]) |
| 209 else: | 209 else: |
| 210 return (None, dart_types[0]) | 210 return (None, dart_types[0]) |
| 211 else: | 211 else: |
| 212 return (None, TypeName(type_ids, interface)) | 212 return (None, TypeName(type_ids, interface)) |
| 213 | 213 |
| 214 def NeedsDefaultValue(argument): | 214 def IsOptional(argument): |
| 215 if not argument: | 215 if not argument: |
| 216 return True | 216 return True |
| 217 if 'Callback' in argument.ext_attrs: | 217 if 'Callback' in argument.ext_attrs: |
| 218 # Callbacks with 'Optional=XXX' are treated as optional arguments. | 218 # Callbacks with 'Optional=XXX' are treated as optional arguments. |
| 219 return 'Optional' in argument.ext_attrs | 219 return 'Optional' in argument.ext_attrs |
| 220 if constructor: | 220 if constructor: |
| 221 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as | 221 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as |
| 222 # optional arguments. | 222 # optional arguments. |
| 223 return 'Optional' in argument.ext_attrs | 223 return 'Optional' in argument.ext_attrs |
| 224 return False | 224 return False |
| 225 | 225 |
| 226 filtered = filter(None, args) | 226 filtered = filter(None, args) |
| 227 needs_default_value = any(NeedsDefaultValue(arg) for arg in args) | 227 is_optional = any(IsOptional(arg) for arg in args) |
| 228 (type_id, dart_type) = OverloadedType(filtered) | 228 (type_id, dart_type) = OverloadedType(filtered) |
| 229 name = OverloadedName(filtered) | 229 name = OverloadedName(filtered) |
| 230 if needs_default_value: | 230 return ParamInfo(name, type_id, dart_type, is_optional) |
| 231 return ParamInfo(name, type_id, dart_type, 'null') | |
| 232 else: | |
| 233 return ParamInfo(name, type_id, dart_type, None) | |
| 234 | 231 |
| 235 def IsOptional(argument): | 232 def IsOptional(argument): |
| 236 return ('Optional' in argument.ext_attrs and | 233 return ('Optional' in argument.ext_attrs and |
| 237 argument.ext_attrs['Optional'] == None) | 234 argument.ext_attrs['Optional'] == None) |
| 238 | 235 |
| 239 def AnalyzeOperation(interface, operations): | 236 def AnalyzeOperation(interface, operations): |
| 240 """Makes operation calling convention decision for a set of overloads. | 237 """Makes operation calling convention decision for a set of overloads. |
| 241 | 238 |
| 242 Returns: An OperationInfo object. | 239 Returns: An OperationInfo object. |
| 243 """ | 240 """ |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 name: A string, the simple name of the operation. | 381 name: A string, the simple name of the operation. |
| 385 constructor_name: A string, the name of the constructor iff the constructor | 382 constructor_name: A string, the name of the constructor iff the constructor |
| 386 is named, e.g. 'fromList' in Int8Array.fromList(list). | 383 is named, e.g. 'fromList' in Int8Array.fromList(list). |
| 387 type_name: A string, the name of the return type of the operation. | 384 type_name: A string, the name of the return type of the operation. |
| 388 param_infos: A list of ParamInfo. | 385 param_infos: A list of ParamInfo. |
| 389 """ | 386 """ |
| 390 | 387 |
| 391 def ParametersInterfaceDeclaration(self): | 388 def ParametersInterfaceDeclaration(self): |
| 392 """Returns a formatted string declaring the parameters for the interface.""" | 389 """Returns a formatted string declaring the parameters for the interface.""" |
| 393 return self._FormatParams( | 390 return self._FormatParams( |
| 394 self.param_infos, True, | 391 self.param_infos, None, |
| 395 lambda param: TypeOrNothing(param.dart_type, param.type_id)) | 392 lambda param: TypeOrNothing(param.dart_type, param.type_id)) |
| 396 | 393 |
| 397 def ParametersImplementationDeclaration(self, rename_type=None): | 394 def ParametersImplementationDeclaration( |
| 395 self, rename_type=None, default_value='null'): | |
|
Anton Muhin
2012/06/06 14:23:18
do you need default value for default_value?
podivilov
2012/06/06 15:11:56
Yes, it is needed for frog generators.
| |
| 398 """Returns a formatted string declaring the parameters for the | 396 """Returns a formatted string declaring the parameters for the |
| 399 implementation. | 397 implementation. |
| 400 | 398 |
| 401 Args: | 399 Args: |
| 402 rename_type: A function that allows the types to be renamed. | 400 rename_type: A function that allows the types to be renamed. |
| 403 The function is applied to the parameter's dart_type. | 401 The function is applied to the parameter's dart_type. |
| 404 """ | 402 """ |
| 405 if rename_type: | 403 if rename_type: |
| 406 def renamer(param_info): | 404 def renamer(param_info): |
| 407 return TypeOrNothing(rename_type(param_info.dart_type)) | 405 return TypeOrNothing(rename_type(param_info.dart_type)) |
| 408 return self._FormatParams(self.param_infos, False, renamer) | 406 return self._FormatParams(self.param_infos, default_value, renamer) |
| 409 else: | 407 else: |
| 410 def type_fn(param_info): | 408 def type_fn(param_info): |
| 411 if param_info.dart_type == 'Dynamic': | 409 if param_info.dart_type == 'Dynamic': |
| 412 if param_info.type_id: | 410 if param_info.type_id: |
| 413 # It is more informative to use a comment IDL type. | 411 # It is more informative to use a comment IDL type. |
| 414 return '/*%s*/' % param_info.type_id | 412 return '/*%s*/' % param_info.type_id |
| 415 else: | 413 else: |
| 416 return 'var' | 414 return 'var' |
| 417 else: | 415 else: |
| 418 return param_info.dart_type | 416 return param_info.dart_type |
| 419 return self._FormatParams( | 417 return self._FormatParams( |
| 420 self.param_infos, False, | 418 self.param_infos, default_value, |
| 421 lambda param: TypeOrNothing(param.dart_type, param.type_id)) | 419 lambda param: TypeOrNothing(param.dart_type, param.type_id)) |
| 422 | 420 |
| 423 def ParametersAsArgumentList(self): | 421 def ParametersAsArgumentList(self): |
| 424 """Returns a string of the parameter names suitable for passing the | 422 """Returns a string of the parameter names suitable for passing the |
| 425 parameters as arguments. | 423 parameters as arguments. |
| 426 """ | 424 """ |
| 427 return ', '.join(map(lambda param_info: param_info.name, self.param_infos)) | 425 return ', '.join(map(lambda param_info: param_info.name, self.param_infos)) |
| 428 | 426 |
| 429 def _FormatParams(self, params, is_interface, type_fn): | 427 def _FormatParams(self, params, default_value, type_fn): |
| 430 def FormatParam(param): | 428 def FormatParam(param): |
| 431 """Returns a parameter declaration fragment for an ParamInfo.""" | 429 """Returns a parameter declaration fragment for an ParamInfo.""" |
| 432 type = type_fn(param) | 430 type = type_fn(param) |
| 433 if is_interface or param.default_value is None: | 431 if param.is_optional and default_value: |
| 434 return '%s%s' % (type, param.name) | 432 return '%s%s = %s' % (type, param.name, default_value) |
| 435 else: | 433 return '%s%s' % (type, param.name) |
| 436 return '%s%s = %s' % (type, param.name, param.default_value) | |
| 437 | 434 |
| 438 required = [] | 435 required = [] |
| 439 optional = [] | 436 optional = [] |
| 440 for param_info in params: | 437 for param_info in params: |
| 441 if param_info.default_value: | 438 if param_info.is_optional: |
| 442 optional.append(param_info) | 439 optional.append(param_info) |
| 443 else: | 440 else: |
| 444 if optional: | 441 if optional: |
| 445 raise Exception('Optional parameters cannot precede required ones: ' | 442 raise Exception('Optional parameters cannot precede required ones: ' |
| 446 + str(args)) | 443 + str(params)) |
| 447 required.append(param_info) | 444 required.append(param_info) |
| 448 argtexts = map(FormatParam, required) | 445 argtexts = map(FormatParam, required) |
| 449 if optional: | 446 if optional: |
| 450 argtexts.append('[' + ', '.join(map(FormatParam, optional)) + ']') | 447 argtexts.append('[' + ', '.join(map(FormatParam, optional)) + ']') |
| 451 return ', '.join(argtexts) | 448 return ', '.join(argtexts) |
| 452 | 449 |
| 453 def IsStatic(self): | 450 def IsStatic(self): |
| 454 is_static = self.overloads[0].is_static | 451 is_static = self.overloads[0].is_static |
| 455 assert any([is_static == o.is_static for o in self.overloads]) | 452 assert any([is_static == o.is_static for o in self.overloads]) |
| 456 return is_static | 453 return is_static |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 '"SVGAnimatedListPropertyTearOff.h"', | 793 '"SVGAnimatedListPropertyTearOff.h"', |
| 797 '"SVGTransformListPropertyTearOff.h"', | 794 '"SVGTransformListPropertyTearOff.h"', |
| 798 '"SVGPathSegListPropertyTearOff.h"', | 795 '"SVGPathSegListPropertyTearOff.h"', |
| 799 ] | 796 ] |
| 800 | 797 |
| 801 def GetIDLTypeInfo(idl_type_name): | 798 def GetIDLTypeInfo(idl_type_name): |
| 802 match = re.match(r'sequence<(\w+)>$', idl_type_name) | 799 match = re.match(r'sequence<(\w+)>$', idl_type_name) |
| 803 if match: | 800 if match: |
| 804 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1))) | 801 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1))) |
| 805 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) | 802 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) |
| OLD | NEW |