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

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

Issue 10107010: Map IDBAny and IDBKey to Dynamic (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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
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 re 9 import re
10 10
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 # against dart:dom to load in a worker isolate. 122 # against dart:dom to load in a worker isolate.
123 return '*' + javascript_binding_name 123 return '*' + javascript_binding_name
124 124
125 125
126 def MatchSourceFilter(filter, thing): 126 def MatchSourceFilter(filter, thing):
127 if not filter: 127 if not filter:
128 return True 128 return True
129 else: 129 else:
130 return any(token in thing.annotations for token in filter) 130 return any(token in thing.annotations for token in filter)
131 131
132
132 def DartType(idl_type_name): 133 def DartType(idl_type_name):
133 return GetIDLTypeInfo(idl_type_name).dart_type() 134 return GetIDLTypeInfo(idl_type_name).dart_type()
134 135
136
137 class ParamInfo(object):
138 """Holder for various information about a parameter of a Dart operation.
139
140 Attributes:
141 name: Name of parameter.
142 type_id: Original type id. None for merged types.
143 dart_type: DartType of parameter.
144 default_value: String holding the expression. None for mandatory parameter.
145 """
146 def __init__(self, name, type_id, dart_type, default_value):
147 self.name = name
148 self.type_id = type_id
149 self.dart_type = dart_type
150 self.default_value = default_value
151
152
135 # Given a list of overloaded arguments, render a dart argument. 153 # Given a list of overloaded arguments, render a dart argument.
136 def _DartArg(args, interface): 154 def _DartArg(args, interface):
137 # Given a list of overloaded arguments, choose a suitable name. 155 # Given a list of overloaded arguments, choose a suitable name.
138 def OverloadedName(args): 156 def OverloadedName(args):
139 return '_OR_'.join(sorted(set(arg.id for arg in args))) 157 return '_OR_'.join(sorted(set(arg.id for arg in args)))
140 158
141 # Given a list of overloaded arguments, choose a suitable type. 159 # Given a list of overloaded arguments, choose a suitable type.
142 def OverloadedType(args): 160 def OverloadedType(args):
143 typeIds = sorted(set(DartType(arg.type.id) for arg in args)) 161 type_ids = sorted(set(arg.type.id for arg in args))
144 if len(typeIds) == 1: 162 dart_types = sorted(set(DartType(arg.type.id) for arg in args))
145 return typeIds[0] 163 if len(dart_types) == 1:
164 if len(type_ids) == 1:
165 return (type_ids[0], dart_types[0])
166 else:
167 return (None, dart_types[0])
146 else: 168 else:
147 return TypeName(typeIds, interface) 169 return (None, TypeName(type_ids, interface))
148 170
149 filtered = filter(None, args) 171 filtered = filter(None, args)
150 optional = any(not arg or arg.is_optional for arg in args) 172 optional = any(not arg or arg.is_optional for arg in args)
151 type = OverloadedType(filtered) 173 (type_id, dart_type) = OverloadedType(filtered)
152 name = OverloadedName(filtered) 174 name = OverloadedName(filtered)
153 if optional: 175 if optional:
154 return (name, type, 'null') 176 return ParamInfo(name, type_id, dart_type, 'null')
155 else: 177 else:
156 return (name, type, None) 178 return ParamInfo(name, type_id, dart_type, None)
157 179
158 180
159 def AnalyzeOperation(interface, operations): 181 def AnalyzeOperation(interface, operations):
160 """Makes operation calling convention decision for a set of overloads. 182 """Makes operation calling convention decision for a set of overloads.
161 183
162 Returns: An OperationInfo object. 184 Returns: An OperationInfo object.
163 """ 185 """
164 186
165 # Zip together arguments from each overload by position, then convert 187 # Zip together arguments from each overload by position, then convert
166 # to a dart argument. 188 # to a dart argument.
167 args = map(lambda *args: _DartArg(args, interface), 189 args = map(lambda *args: _DartArg(args, interface),
168 *(op.arguments for op in operations)) 190 *(op.arguments for op in operations))
169 191
170 info = OperationInfo() 192 info = OperationInfo()
171 info.overloads = operations 193 info.overloads = operations
172 info.declared_name = operations[0].id 194 info.declared_name = operations[0].id
173 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) 195 info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
174 info.js_name = info.declared_name 196 info.js_name = info.declared_name
175 info.type_name = DartType(operations[0].type.id) # TODO: widen. 197 info.type_name = DartType(operations[0].type.id) # TODO: widen.
176 info.arg_infos = args 198 info.param_infos = args
177 return info 199 return info
178 200
179 201
180 def AnalyzeConstructor(interface): 202 def AnalyzeConstructor(interface):
181 """Returns an OperationInfo object for the constructor. 203 """Returns an OperationInfo object for the constructor.
182 204
183 Returns None if the interface has no Constructor. 205 Returns None if the interface has no Constructor.
184 """ 206 """
185 def GetArgs(func_value): 207 def GetArgs(func_value):
186 return map(lambda arg: _DartArg([arg], interface), func_value.arguments) 208 return map(lambda arg: _DartArg([arg], interface), func_value.arguments)
(...skipping 17 matching lines...) Expand all
204 else: 226 else:
205 return None 227 return None
206 228
207 info = OperationInfo() 229 info = OperationInfo()
208 info.overloads = None 230 info.overloads = None
209 info.idl_args = idl_args 231 info.idl_args = idl_args
210 info.declared_name = name 232 info.declared_name = name
211 info.name = name 233 info.name = name
212 info.js_name = name 234 info.js_name = name
213 info.type_name = interface.id 235 info.type_name = interface.id
214 info.arg_infos = args 236 info.param_infos = args
215 return info 237 return info
216 238
217 239
218 def RecognizeCallback(interface): 240 def RecognizeCallback(interface):
219 """Returns the info for the callback method if the interface smells like a 241 """Returns the info for the callback method if the interface smells like a
220 callback. 242 callback.
221 """ 243 """
222 if 'Callback' not in interface.ext_attrs: return None 244 if 'Callback' not in interface.ext_attrs: return None
223 handlers = [op for op in interface.operations if op.id == 'handleEvent'] 245 handlers = [op for op in interface.operations if op.id == 'handleEvent']
224 if not handlers: return None 246 if not handlers: return None
(...skipping 23 matching lines...) Expand all
248 attr.id is the 'native' or JavaScript name. 270 attr.id is the 'native' or JavaScript name.
249 271
250 To ensure uniformity, work with the true IDL name until as late a possible, 272 To ensure uniformity, work with the true IDL name until as late a possible,
251 e.g. translate to the Dart name when generating Dart code. 273 e.g. translate to the Dart name when generating Dart code.
252 """ 274 """
253 name = attr.id 275 name = attr.id
254 name = _dart_attribute_renames.get(name, name) 276 name = _dart_attribute_renames.get(name, name)
255 name = attr.ext_attrs.get('DartName', None) or name 277 name = attr.ext_attrs.get('DartName', None) or name
256 return name 278 return name
257 279
280
281 def TypeOrNothing(dart_type, comment=None):
282 """Returns string for declaring something with |dart_type| in a context
283 where a type may be omitted.
284 The string is empty or has a trailing space.
285 """
286 if dart_type == 'Dynamic':
287 if comment:
288 return '/*%s*/ ' % comment # Just a comment foo(/*T*/ x)
289 else:
290 return '' # foo(x) looks nicer than foo(Dynamic x)
291 else:
292 return dart_type + ' '
293
294
295 def TypeOrVar(dart_type, comment=None):
296 """Returns string for declaring something with |dart_type| in a context
297 where if a type is omitted, 'var' must be used instead."""
298 if dart_type == 'Dynamic':
299 if comment:
300 return 'var /*%s*/' % comment # e.g. var /*T*/ x;
301 else:
302 return 'var' # e.g. var x;
303 else:
304 return dart_type
305
306
258 class OperationInfo(object): 307 class OperationInfo(object):
259 """Holder for various derived information from a set of overloaded operations. 308 """Holder for various derived information from a set of overloaded operations.
260 309
261 Attributes: 310 Attributes:
262 overloads: A list of IDL operation overloads with the same name. 311 overloads: A list of IDL operation overloads with the same name.
263 name: A string, the simple name of the operation. 312 name: A string, the simple name of the operation.
264 type_name: A string, the name of the return type of the operation. 313 type_name: A string, the name of the return type of the operation.
265 arg_infos: A list of (name, type, default_value) tuples. 314 param_infos: A list of ParamInfo.
266 default_value is None for mandatory arguments.
267 """ 315 """
268 316
269 def ParametersInterfaceDeclaration(self): 317 def ParametersInterfaceDeclaration(self):
270 """Returns a formatted string declaring the parameters for the interface.""" 318 """Returns a formatted string declaring the parameters for the interface."""
271 return self._FormatArgs(self.arg_infos, True) 319 return self._FormatParams(
320 self.param_infos, True,
321 lambda param: TypeOrNothing(param.dart_type, param.type_id))
272 322
273 def ParametersImplementationDeclaration(self, rename_type=None): 323 def ParametersImplementationDeclaration(self, rename_type=None):
274 """Returns a formatted string declaring the parameters for the 324 """Returns a formatted string declaring the parameters for the
275 implementation. 325 implementation.
276 326
277 Args: 327 Args:
278 rename_type: A function that allows the types to be renamed. 328 rename_type: A function that allows the types to be renamed.
329 The function is applied to the parameter's dart_type.
279 """ 330 """
280 args = self.arg_infos
281 if rename_type: 331 if rename_type:
282 args = [(name, rename_type(type), default) 332 def renamer(param_info):
283 for (name, type, default) in args] 333 return TypeOrNothing(rename_type(param_info.dart_type))
284 return self._FormatArgs(args, False) 334 return self._FormatParams(self.param_infos, False, renamer)
335 else:
336 def type_fn(param_info):
337 if param_info.dart_type == 'Dynamic':
338 if param_info.type_id:
339 # It is more informative to use a comment IDL type.
340 return '/*%s*/' % param_info.type_id
341 else:
342 return 'var'
343 else:
344 return param_info.dart_type
345 return self._FormatParams(
346 self.param_infos, False,
347 lambda param: TypeOrNothing(param.dart_type, param.type_id))
285 348
286 def ParametersAsArgumentList(self): 349 def ParametersAsArgumentList(self):
287 """Returns a formatted string declaring the parameters names as an argument 350 """Returns a string of the parameter names suitable for passing the
288 list. 351 parameters as arguments.
289 """ 352 """
290 return ', '.join(map(lambda arg_info: arg_info[0], self.arg_infos)) 353 return ', '.join(map(lambda param_info: param_info.name, self.param_infos))
291 354
292 def _FormatArgs(self, args, is_interface): 355 def _FormatParams(self, params, is_interface, type_fn):
293 def FormatArg(arg_info): 356 def FormatParam(param):
294 """Returns an argument declaration fragment for an argument info tuple.""" 357 """Returns a parameter declaration fragment for an ParamInfo."""
295 (name, type, default) = arg_info 358 type = type_fn(param)
296 if default: 359 if is_interface or param.default_value is None:
297 return '%s %s = %s' % (type, name, default) 360 return '%s%s' % (type, param.name)
298 else: 361 else:
299 return '%s %s' % (type, name) 362 return '%s%s = %s' % (type, param.name, param.default_value)
300 363
301 required = [] 364 required = []
302 optional = [] 365 optional = []
303 for (name, type, default) in args: 366 for param_info in params:
304 if default: 367 if param_info.default_value:
305 if is_interface: 368 optional.append(param_info)
306 optional.append((name, type, None)) # Default values illegal.
307 else:
308 optional.append((name, type, default))
309 else: 369 else:
310 if optional: 370 if optional:
311 raise Exception('Optional arguments cannot precede required ones: ' 371 raise Exception('Optional parameters cannot precede required ones: '
312 + str(args)) 372 + str(args))
313 required.append((name, type, None)) 373 required.append(param_info)
314 argtexts = map(FormatArg, required) 374 argtexts = map(FormatParam, required)
315 if optional: 375 if optional:
316 argtexts.append('[' + ', '.join(map(FormatArg, optional)) + ']') 376 argtexts.append('[' + ', '.join(map(FormatParam, optional)) + ']')
317 return ', '.join(argtexts) 377 return ', '.join(argtexts)
318 378
319 379
320 def AttributeOutputOrder(a, b): 380 def AttributeOutputOrder(a, b):
321 """Canonical output ordering for attributes.""" 381 """Canonical output ordering for attributes."""
322 # Getters before setters: 382 # Getters before setters:
323 if a.id < b.id: return -1 383 if a.id < b.id: return -1
324 if a.id > b.id: return 1 384 if a.id > b.id: return 1
325 if a.is_fc_setter < b.is_fc_setter: return -1 385 if a.is_fc_setter < b.is_fc_setter: return -1
326 if a.is_fc_setter > b.is_fc_setter: return 1 386 if a.is_fc_setter > b.is_fc_setter: return 1
(...skipping 21 matching lines...) Expand all
348 """Format lines of text with indent.""" 408 """Format lines of text with indent."""
349 def FormatLine(line): 409 def FormatLine(line):
350 if line.strip(): 410 if line.strip():
351 return '%s%s\n' % (indent, line) 411 return '%s%s\n' % (indent, line)
352 else: 412 else:
353 return '\n' 413 return '\n'
354 return ''.join(FormatLine(line) for line in text.split('\n')) 414 return ''.join(FormatLine(line) for line in text.split('\n'))
355 415
356 # Given a sorted sequence of type identifiers, return an appropriate type 416 # Given a sorted sequence of type identifiers, return an appropriate type
357 # name 417 # name
358 def TypeName(typeIds, interface): 418 def TypeName(type_ids, interface):
359 # Dynamically type this field for now. 419 # Dynamically type this field for now.
360 return 'var' 420 return 'Dynamic'
361 421
362 # ------------------------------------------------------------------------------ 422 # ------------------------------------------------------------------------------
363 423
364 class IDLTypeInfo(object): 424 class IDLTypeInfo(object):
365 def __init__(self, idl_type, dart_type=None, native_type=None, ref_counted=Tru e, 425 def __init__(self, idl_type, dart_type=None,
426 native_type=None, ref_counted=True,
366 has_dart_wrapper=True, conversion_template=None, 427 has_dart_wrapper=True, conversion_template=None,
367 custom_to_dart=False, conversion_includes=[]): 428 custom_to_dart=False, conversion_includes=[]):
368 self._idl_type = idl_type 429 self._idl_type = idl_type
369 self._dart_type = dart_type 430 self._dart_type = dart_type
370 self._native_type = native_type 431 self._native_type = native_type
371 self._ref_counted = ref_counted 432 self._ref_counted = ref_counted
372 self._has_dart_wrapper = has_dart_wrapper 433 self._has_dart_wrapper = has_dart_wrapper
373 self._conversion_template = conversion_template 434 self._conversion_template = conversion_template
374 self._custom_to_dart = custom_to_dart 435 self._custom_to_dart = custom_to_dart
375 self._conversion_includes = conversion_includes 436 self._conversion_includes = conversion_includes
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 include = self._idl_type.replace('Abs', '').replace('Rel', '') 493 include = self._idl_type.replace('Abs', '').replace('Rel', '')
433 else: 494 else:
434 include = self._idl_type 495 include = self._idl_type
435 return ['"%s.h"' % include] + _svg_supplemental_includes 496 return ['"%s.h"' % include] + _svg_supplemental_includes
436 497
437 def receiver(self): 498 def receiver(self):
438 return 'receiver->' 499 return 'receiver->'
439 500
440 def conversion_includes(self): 501 def conversion_includes(self):
441 def NeededDartTypes(type_name): 502 def NeededDartTypes(type_name):
503 if re.match(r'Dynamic(\/.*)?$', type_name): return []
442 match = re.match(r'List<(\w*)>$', type_name) 504 match = re.match(r'List<(\w*)>$', type_name)
443 if match: 505 if match:
444 return NeededDartTypes(match.group(1)) 506 return NeededDartTypes(match.group(1))
445 return [type_name] 507 return [type_name]
446 508
447 return ['"Dart%s.h"' % include for include in NeededDartTypes(self.dart_type ()) + self._conversion_includes] 509 return ['"Dart%s.h"' % include
510 for include in
511 NeededDartTypes(self.dart_type()) + self._conversion_includes]
448 512
449 def conversion_cast(self, expression): 513 def conversion_cast(self, expression):
450 if self._conversion_template: 514 if self._conversion_template:
451 return self._conversion_template % expression 515 return self._conversion_template % expression
452 return expression 516 return expression
453 517
454 def custom_to_dart(self): 518 def custom_to_dart(self):
455 return self._custom_to_dart 519 return self._custom_to_dart
456 520
457 class PrimitiveIDLTypeInfo(IDLTypeInfo): 521 class PrimitiveIDLTypeInfo(IDLTypeInfo):
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 'sequence': PrimitiveIDLTypeInfo('sequence', dart_type='List'), 628 'sequence': PrimitiveIDLTypeInfo('sequence', dart_type='List'),
565 'void': PrimitiveIDLTypeInfo('void', dart_type='void'), 629 'void': PrimitiveIDLTypeInfo('void', dart_type='void'),
566 630
567 'CSSRule': IDLTypeInfo('CSSRule', conversion_includes=['CSSImportRule']), 631 'CSSRule': IDLTypeInfo('CSSRule', conversion_includes=['CSSImportRule']),
568 'DOMException': IDLTypeInfo('DOMCoreException', dart_type='DOMException'), 632 'DOMException': IDLTypeInfo('DOMCoreException', dart_type='DOMException'),
569 'DOMWindow': IDLTypeInfo('DOMWindow', custom_to_dart=True), 633 'DOMWindow': IDLTypeInfo('DOMWindow', custom_to_dart=True),
570 'Element': IDLTypeInfo('Element', custom_to_dart=True), 634 'Element': IDLTypeInfo('Element', custom_to_dart=True),
571 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False), 635 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False),
572 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False), 636 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False),
573 'HTMLElement': IDLTypeInfo('HTMLElement', custom_to_dart=True), 637 'HTMLElement': IDLTypeInfo('HTMLElement', custom_to_dart=True),
574 'IDBKey': IDLTypeInfo('IDBKey', has_dart_wrapper=False), 638 'IDBAny': IDLTypeInfo('IDBAny', dart_type='Dynamic',
639 native_type='IDBAny',
640 has_dart_wrapper=False,
641 conversion_includes=['IDBAny']),
642 'IDBKey': IDLTypeInfo('IDBKey', dart_type='Dynamic',
643 native_type='IDBKey',
644 has_dart_wrapper=False,
645 conversion_includes=['IDBKey']),
575 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wra pper=False), 646 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wra pper=False),
576 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False), 647 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False),
577 'StyleSheet': IDLTypeInfo('StyleSheet', conversion_includes=['CSSStyleSheet' ]), 648 'StyleSheet': IDLTypeInfo('StyleSheet', conversion_includes=['CSSStyleSheet' ]),
578 'SVGElement': IDLTypeInfo('SVGElement', custom_to_dart=True), 649 'SVGElement': IDLTypeInfo('SVGElement', custom_to_dart=True),
579 650
580 'SVGAngle': SVGTearOffIDLTypeInfo('SVGAngle'), 651 'SVGAngle': SVGTearOffIDLTypeInfo('SVGAngle'),
581 'SVGLength': SVGTearOffIDLTypeInfo('SVGLength'), 652 'SVGLength': SVGTearOffIDLTypeInfo('SVGLength'),
582 'SVGLengthList': SVGTearOffIDLTypeInfo('SVGLengthList', ref_counted=False), 653 'SVGLengthList': SVGTearOffIDLTypeInfo('SVGLengthList', ref_counted=False),
583 'SVGMatrix': SVGTearOffIDLTypeInfo('SVGMatrix'), 654 'SVGMatrix': SVGTearOffIDLTypeInfo('SVGMatrix'),
584 'SVGNumber': SVGTearOffIDLTypeInfo('SVGNumber', native_type='SVGPropertyTear Off<float>'), 655 'SVGNumber': SVGTearOffIDLTypeInfo('SVGNumber', native_type='SVGPropertyTear Off<float>'),
(...skipping 12 matching lines...) Expand all
597 '"SVGAnimatedPropertyTearOff.h"', 668 '"SVGAnimatedPropertyTearOff.h"',
598 '"SVGAnimatedListPropertyTearOff.h"', 669 '"SVGAnimatedListPropertyTearOff.h"',
599 '"SVGStaticListPropertyTearOff.h"', 670 '"SVGStaticListPropertyTearOff.h"',
600 '"SVGAnimatedListPropertyTearOff.h"', 671 '"SVGAnimatedListPropertyTearOff.h"',
601 '"SVGTransformListPropertyTearOff.h"', 672 '"SVGTransformListPropertyTearOff.h"',
602 '"SVGPathSegListPropertyTearOff.h"', 673 '"SVGPathSegListPropertyTearOff.h"',
603 ] 674 ]
604 675
605 def GetIDLTypeInfo(idl_type_name): 676 def GetIDLTypeInfo(idl_type_name):
606 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) 677 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698