Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: lib/dom/scripts/generator.py

Issue 10517004: Move splitting operations with optional arguments to generator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: . Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/dom/scripts/databasebuilder.py ('k') | lib/dom/scripts/idlnode.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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))
OLDNEW
« no previous file with comments | « lib/dom/scripts/databasebuilder.py ('k') | lib/dom/scripts/idlnode.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698