Chromium Code Reviews| Index: lib/dom/scripts/generator.py |
| diff --git a/lib/dom/scripts/generator.py b/lib/dom/scripts/generator.py |
| index b80fb56fe41c39cae09fe82da41e68af98998eeb..875a0004d8a9442fa1e61452bae9d4244b558e4f 100644 |
| --- a/lib/dom/scripts/generator.py |
| +++ b/lib/dom/scripts/generator.py |
| @@ -6,6 +6,7 @@ |
| """This module provides shared functionality for systems to generate |
| Dart APIs from the IDL database.""" |
| +import copy |
| import re |
| _pure_interfaces = set([ |
| @@ -193,7 +194,7 @@ class ParamInfo(object): |
| # Given a list of overloaded arguments, render a dart argument. |
| -def _DartArg(args, interface): |
| +def _DartArg(args, interface, constructor=False): |
| # Given a list of overloaded arguments, choose a suitable name. |
| def OverloadedName(args): |
| return '_OR_'.join(sorted(set(arg.id for arg in args))) |
| @@ -210,15 +211,30 @@ def _DartArg(args, interface): |
| else: |
| return (None, TypeName(type_ids, interface)) |
| + def NeedsDefaultValue(argument): |
|
Anton Muhin
2012/06/04 14:43:13
maybe it should be named IsOptional?
podivilov
2012/06/04 15:12:02
I prefer to use a different name to emphasize the
|
| + if not argument: |
| + return True |
| + if 'Callback' in argument.ext_attrs: |
| + # Callbacks with 'Optional=XXX' are treated as optional arguments. |
| + return 'Optional' in argument.ext_attrs |
| + if constructor: |
| + # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as |
| + # optional arguments. |
| + return 'Optional' in argument.ext_attrs |
| + return False |
| + |
| filtered = filter(None, args) |
| - optional = any(not arg or arg.is_optional for arg in args) |
| + needs_default_value = any(NeedsDefaultValue(arg) for arg in args) |
| (type_id, dart_type) = OverloadedType(filtered) |
| name = OverloadedName(filtered) |
| - if optional: |
| + if needs_default_value: |
| return ParamInfo(name, type_id, dart_type, 'null') |
| else: |
| return ParamInfo(name, type_id, dart_type, None) |
| +def IsOptional(argument): |
| + return ('Optional' in argument.ext_attrs and |
| + argument.ext_attrs['Optional'] == None) |
| def AnalyzeOperation(interface, operations): |
| """Makes operation calling convention decision for a set of overloads. |
| @@ -226,13 +242,23 @@ def AnalyzeOperation(interface, operations): |
| Returns: An OperationInfo object. |
| """ |
| + # split operations with optional args into multiple operations |
| + split_operations = [] |
| + for operation in operations: |
| + for i in range(0, len(operation.arguments)): |
| + if IsOptional(operation.arguments[i]): |
|
Anton Muhin
2012/06/04 14:43:13
controversial:
maybe make it explicit that once w
podivilov
2012/06/04 15:12:02
Current variant has lesser nesting level :)
|
| + new_operation = copy.deepcopy(operation) |
|
Anton Muhin
2012/06/04 14:43:13
are you sure you need deepcopy here?
podivilov
2012/06/04 15:12:02
See the next statement.
|
| + new_operation.arguments = new_operation.arguments[:i] |
| + split_operations.append(new_operation) |
| + split_operations.append(operation) |
| + |
| # Zip together arguments from each overload by position, then convert |
| # to a dart argument. |
| args = map(lambda *args: _DartArg(args, interface), |
| - *(op.arguments for op in operations)) |
| + *(op.arguments for op in split_operations)) |
| info = OperationInfo() |
| - info.overloads = operations |
| + info.overloads = split_operations |
| info.declared_name = operations[0].id |
| info.name = operations[0].ext_attrs.get('DartName', info.declared_name) |
| info.constructor_name = None |
| @@ -248,7 +274,8 @@ def AnalyzeConstructor(interface): |
| Returns None if the interface has no Constructor. |
| """ |
| def GetArgs(func_value): |
| - return map(lambda arg: _DartArg([arg], interface), func_value.arguments) |
| + return map(lambda arg: _DartArg([arg], interface, True), |
| + func_value.arguments) |
| if 'Constructor' in interface.ext_attrs: |
| name = None |