| 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 re | 10 import re |
| 10 | 11 |
| 11 _pure_interfaces = set([ | 12 _pure_interfaces = set([ |
| 12 # TODO(sra): DOMStringMap should be a class implementing Map<String,String>. | 13 # TODO(sra): DOMStringMap should be a class implementing Map<String,String>. |
| 13 'DOMStringMap', | 14 'DOMStringMap', |
| 14 'ElementTimeControl', | 15 'ElementTimeControl', |
| 15 'ElementTraversal', | 16 'ElementTraversal', |
| 16 'MediaQueryListListener', | 17 'MediaQueryListListener', |
| 17 'NodeSelector', | 18 'NodeSelector', |
| 18 'SVGExternalResourcesRequired', | 19 'SVGExternalResourcesRequired', |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 self.dart_type = dart_type | 187 self.dart_type = dart_type |
| 187 self.default_value = default_value | 188 self.default_value = default_value |
| 188 | 189 |
| 189 def __repr__(self): | 190 def __repr__(self): |
| 190 content = 'name = %s, type_id = %s, dart_type = %s, default_value = %s' % ( | 191 content = 'name = %s, type_id = %s, dart_type = %s, default_value = %s' % ( |
| 191 self.name, self.type_id, self.dart_type, self.default_value) | 192 self.name, self.type_id, self.dart_type, self.default_value) |
| 192 return '<ParamInfo(%s)>' % content | 193 return '<ParamInfo(%s)>' % content |
| 193 | 194 |
| 194 | 195 |
| 195 # Given a list of overloaded arguments, render a dart argument. | 196 # Given a list of overloaded arguments, render a dart argument. |
| 196 def _DartArg(args, interface): | 197 def _DartArg(args, interface, constructor=False): |
| 197 # Given a list of overloaded arguments, choose a suitable name. | 198 # Given a list of overloaded arguments, choose a suitable name. |
| 198 def OverloadedName(args): | 199 def OverloadedName(args): |
| 199 return '_OR_'.join(sorted(set(arg.id for arg in args))) | 200 return '_OR_'.join(sorted(set(arg.id for arg in args))) |
| 200 | 201 |
| 201 # Given a list of overloaded arguments, choose a suitable type. | 202 # Given a list of overloaded arguments, choose a suitable type. |
| 202 def OverloadedType(args): | 203 def OverloadedType(args): |
| 203 type_ids = sorted(set(arg.type.id for arg in args)) | 204 type_ids = sorted(set(arg.type.id for arg in args)) |
| 204 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)) |
| 205 if len(dart_types) == 1: | 206 if len(dart_types) == 1: |
| 206 if len(type_ids) == 1: | 207 if len(type_ids) == 1: |
| 207 return (type_ids[0], dart_types[0]) | 208 return (type_ids[0], dart_types[0]) |
| 208 else: | 209 else: |
| 209 return (None, dart_types[0]) | 210 return (None, dart_types[0]) |
| 210 else: | 211 else: |
| 211 return (None, TypeName(type_ids, interface)) | 212 return (None, TypeName(type_ids, interface)) |
| 212 | 213 |
| 214 def NeedsDefaultValue(argument): |
| 215 if not argument: |
| 216 return True |
| 217 if 'Callback' in argument.ext_attrs: |
| 218 # Callbacks with 'Optional=XXX' are treated as optional arguments. |
| 219 return 'Optional' in argument.ext_attrs |
| 220 if constructor: |
| 221 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as |
| 222 # optional arguments. |
| 223 return 'Optional' in argument.ext_attrs |
| 224 return False |
| 225 |
| 213 filtered = filter(None, args) | 226 filtered = filter(None, args) |
| 214 optional = any(not arg or arg.is_optional for arg in args) | 227 needs_default_value = any(NeedsDefaultValue(arg) for arg in args) |
| 215 (type_id, dart_type) = OverloadedType(filtered) | 228 (type_id, dart_type) = OverloadedType(filtered) |
| 216 name = OverloadedName(filtered) | 229 name = OverloadedName(filtered) |
| 217 if optional: | 230 if needs_default_value: |
| 218 return ParamInfo(name, type_id, dart_type, 'null') | 231 return ParamInfo(name, type_id, dart_type, 'null') |
| 219 else: | 232 else: |
| 220 return ParamInfo(name, type_id, dart_type, None) | 233 return ParamInfo(name, type_id, dart_type, None) |
| 221 | 234 |
| 235 def IsOptional(argument): |
| 236 return ('Optional' in argument.ext_attrs and |
| 237 argument.ext_attrs['Optional'] == None) |
| 222 | 238 |
| 223 def AnalyzeOperation(interface, operations): | 239 def AnalyzeOperation(interface, operations): |
| 224 """Makes operation calling convention decision for a set of overloads. | 240 """Makes operation calling convention decision for a set of overloads. |
| 225 | 241 |
| 226 Returns: An OperationInfo object. | 242 Returns: An OperationInfo object. |
| 227 """ | 243 """ |
| 228 | 244 |
| 245 # split operations with optional args into multiple operations |
| 246 split_operations = [] |
| 247 for operation in operations: |
| 248 for i in range(0, len(operation.arguments)): |
| 249 if IsOptional(operation.arguments[i]): |
| 250 new_operation = copy.deepcopy(operation) |
| 251 new_operation.arguments = new_operation.arguments[:i] |
| 252 split_operations.append(new_operation) |
| 253 split_operations.append(operation) |
| 254 |
| 229 # Zip together arguments from each overload by position, then convert | 255 # Zip together arguments from each overload by position, then convert |
| 230 # to a dart argument. | 256 # to a dart argument. |
| 231 args = map(lambda *args: _DartArg(args, interface), | 257 args = map(lambda *args: _DartArg(args, interface), |
| 232 *(op.arguments for op in operations)) | 258 *(op.arguments for op in split_operations)) |
| 233 | 259 |
| 234 info = OperationInfo() | 260 info = OperationInfo() |
| 235 info.overloads = operations | 261 info.overloads = split_operations |
| 236 info.declared_name = operations[0].id | 262 info.declared_name = operations[0].id |
| 237 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) | 263 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) |
| 238 info.constructor_name = None | 264 info.constructor_name = None |
| 239 info.js_name = info.declared_name | 265 info.js_name = info.declared_name |
| 240 info.type_name = DartType(operations[0].type.id) # TODO: widen. | 266 info.type_name = DartType(operations[0].type.id) # TODO: widen. |
| 241 info.param_infos = args | 267 info.param_infos = args |
| 242 return info | 268 return info |
| 243 | 269 |
| 244 | 270 |
| 245 def AnalyzeConstructor(interface): | 271 def AnalyzeConstructor(interface): |
| 246 """Returns an OperationInfo object for the constructor. | 272 """Returns an OperationInfo object for the constructor. |
| 247 | 273 |
| 248 Returns None if the interface has no Constructor. | 274 Returns None if the interface has no Constructor. |
| 249 """ | 275 """ |
| 250 def GetArgs(func_value): | 276 def GetArgs(func_value): |
| 251 return map(lambda arg: _DartArg([arg], interface), func_value.arguments) | 277 return map(lambda arg: _DartArg([arg], interface, True), |
| 278 func_value.arguments) |
| 252 | 279 |
| 253 if 'Constructor' in interface.ext_attrs: | 280 if 'Constructor' in interface.ext_attrs: |
| 254 name = None | 281 name = None |
| 255 func_value = interface.ext_attrs.get('Constructor') | 282 func_value = interface.ext_attrs.get('Constructor') |
| 256 if func_value: | 283 if func_value: |
| 257 # [Constructor(param,...)] | 284 # [Constructor(param,...)] |
| 258 args = GetArgs(func_value) | 285 args = GetArgs(func_value) |
| 259 idl_args = func_value.arguments | 286 idl_args = func_value.arguments |
| 260 else: # [Constructor] | 287 else: # [Constructor] |
| 261 args = [] | 288 args = [] |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 '"SVGAnimatedListPropertyTearOff.h"', | 795 '"SVGAnimatedListPropertyTearOff.h"', |
| 769 '"SVGTransformListPropertyTearOff.h"', | 796 '"SVGTransformListPropertyTearOff.h"', |
| 770 '"SVGPathSegListPropertyTearOff.h"', | 797 '"SVGPathSegListPropertyTearOff.h"', |
| 771 ] | 798 ] |
| 772 | 799 |
| 773 def GetIDLTypeInfo(idl_type_name): | 800 def GetIDLTypeInfo(idl_type_name): |
| 774 match = re.match(r'sequence<(\w+)>$', idl_type_name) | 801 match = re.match(r'sequence<(\w+)>$', idl_type_name) |
| 775 if match: | 802 if match: |
| 776 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1))) | 803 return SequenceIDLTypeInfo(idl_type_name, GetIDLTypeInfo(match.group(1))) |
| 777 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) | 804 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) |
| OLD | NEW |