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

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

Powered by Google App Engine
This is Rietveld 408576698