| 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 | 
|---|