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

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

Issue 10913125: Remove lib/dom directory! (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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
(Empty)
1 #!/usr/bin/python
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
4 # BSD-style license that can be found in the LICENSE file.
5
6 """This module provides shared functionality for systems to generate
7 Dart APIs from the IDL database."""
8
9 import copy
10 import re
11
12 _pure_interfaces = set([
13 # TODO(sra): DOMStringMap should be a class implementing Map<String,String>.
14 'DOMStringMap',
15 'ElementTimeControl',
16 'ElementTraversal',
17 'MediaQueryListListener',
18 'NodeSelector',
19 'SVGExternalResourcesRequired',
20 'SVGFilterPrimitiveStandardAttributes',
21 'SVGFitToViewBox',
22 'SVGLangSpace',
23 'SVGLocatable',
24 'SVGStylable',
25 'SVGTests',
26 'SVGTransformable',
27 'SVGURIReference',
28 'SVGZoomAndPan',
29 'TimeoutHandler'])
30
31 def IsPureInterface(interface_name):
32 return interface_name in _pure_interfaces
33
34 #
35 # Renames for attributes that have names that are not legal Dart names.
36 #
37 _dart_attribute_renames = {
38 'default': 'defaultValue',
39 'final': 'finalValue',
40 }
41
42 #
43 # Interface version of the DOM needs to delegate typed array constructors to a
44 # factory provider.
45 #
46 interface_factories = {
47 'Float32Array': '_TypedArrayFactoryProvider',
48 'Float64Array': '_TypedArrayFactoryProvider',
49 'Int8Array': '_TypedArrayFactoryProvider',
50 'Int16Array': '_TypedArrayFactoryProvider',
51 'Int32Array': '_TypedArrayFactoryProvider',
52 'Uint8Array': '_TypedArrayFactoryProvider',
53 'Uint16Array': '_TypedArrayFactoryProvider',
54 'Uint32Array': '_TypedArrayFactoryProvider',
55 'Uint8ClampedArray': '_TypedArrayFactoryProvider',
56 }
57
58 #
59 # Custom native specs for the dart2js dom.
60 #
61 _dart2js_dom_custom_native_specs = {
62 # Decorate the singleton Console object, if present (workers do not have a
63 # console).
64 'Console': "=(typeof console == 'undefined' ? {} : console)",
65
66 # DOMWindow aliased with global scope.
67 'DOMWindow': '@*DOMWindow',
68 }
69
70 def IsRegisteredType(type_name):
71 return type_name in _idl_type_registry
72
73 def ListImplementationInfo(interface, database):
74 """Returns a tuple (elment_type, requires_indexer).
75 If interface do not have to implement List, element_type is None.
76 Otherwise element_type is list element type and requires_indexer
77 is true iff this interface implementation must have indexer and
78 false otherwise. False means that interface implementation
79 inherits indexer and may just reuse it."""
80 element_type = MaybeListElementType(interface)
81 if element_type:
82 return (element_type, True)
83
84 for parent in interface.parents:
85 if database.HasInterface(parent.type.id):
86 parent_interface = database.GetInterface(parent.type.id)
87 (element_type, _) = ListImplementationInfo(parent_interface, database)
88 if element_type:
89 return (element_type, False)
90
91 return (None, None)
92
93
94 def MaybeListElementTypeName(type_name):
95 """Returns the List element type T from string of form "List<T>", or None."""
96 match = re.match(r'sequence<(\w*)>$', type_name)
97 if match:
98 return match.group(1)
99 return None
100
101 def MaybeListElementType(interface):
102 """Returns the List element type T, or None in interface does not implement
103 List<T>.
104 """
105 for parent in interface.parents:
106 element_type = MaybeListElementTypeName(parent.type.id)
107 if element_type:
108 return element_type
109 return None
110
111 def MaybeTypedArrayElementType(interface):
112 """Returns the typed array element type, or None in interface is not a
113 TypedArray.
114 """
115 # Typed arrays implement ArrayBufferView and List<T>.
116 for parent in interface.parents:
117 if parent.type.id == 'ArrayBufferView':
118 return MaybeListElementType(interface)
119 return None
120
121 def MaybeTypedArrayElementTypeInHierarchy(interface, database):
122 """Returns the typed array element type, or None in interface is not a
123 TypedArray. Checks the whole parent hierarchy.
124 """
125 element_type = MaybeTypedArrayElementType(interface)
126 if element_type:
127 return element_type
128 for parent in interface.parents:
129 if database.HasInterface(parent.type.id):
130 parent_interface = database.GetInterface(parent.type.id)
131 element_type = MaybeTypedArrayElementType(parent_interface)
132 if element_type:
133 return element_type
134
135 return None
136
137 def MakeNativeSpec(javascript_binding_name):
138 if javascript_binding_name in _dart2js_dom_custom_native_specs:
139 return _dart2js_dom_custom_native_specs[javascript_binding_name]
140 else:
141 # Make the class 'hidden' so it is dynamically patched at runtime. This
142 # is useful for browser compat.
143 return '*' + javascript_binding_name
144
145
146 def MatchSourceFilter(thing):
147 return 'WebKit' in thing.annotations or 'Dart' in thing.annotations
148
149
150 def DartType(idl_type_name):
151 if idl_type_name in _idl_type_registry:
152 return _idl_type_registry[idl_type_name].dart_type or idl_type_name
153 return idl_type_name
154
155
156 class ParamInfo(object):
157 """Holder for various information about a parameter of a Dart operation.
158
159 Attributes:
160 name: Name of parameter.
161 type_id: Original type id. None for merged types.
162 dart_type: DartType of parameter.
163 is_optional: Parameter optionality.
164 """
165 def __init__(self, name, type_id, dart_type, is_optional):
166 self.name = name
167 self.type_id = type_id
168 self.dart_type = dart_type
169 self.is_optional = is_optional
170
171 def Copy(self):
172 return ParamInfo(self.name, self.type_id, self.dart_type, self.is_optional)
173
174 def __repr__(self):
175 content = 'name = %s, type_id = %s, dart_type = %s, is_optional = %s' % (
176 self.name, self.type_id, self.dart_type, self.is_optional)
177 return '<ParamInfo(%s)>' % content
178
179
180 # Given a list of overloaded arguments, render a dart argument.
181 def _DartArg(args, interface, constructor=False):
182 # Given a list of overloaded arguments, choose a suitable name.
183 def OverloadedName(args):
184 return '_OR_'.join(sorted(set(arg.id for arg in args)))
185
186 # Given a list of overloaded arguments, choose a suitable type.
187 def OverloadedType(args):
188 type_ids = sorted(set(arg.type.id for arg in args))
189 dart_types = sorted(set(DartType(arg.type.id) for arg in args))
190 if len(dart_types) == 1:
191 if len(type_ids) == 1:
192 return (type_ids[0], type_ids[0])
193 else:
194 return (None, type_ids[0])
195 else:
196 return (None, TypeName(type_ids, interface))
197
198 def IsOptional(argument):
199 if not argument:
200 return True
201 if 'Callback' in argument.ext_attrs:
202 # Callbacks with 'Optional=XXX' are treated as optional arguments.
203 return 'Optional' in argument.ext_attrs
204 if constructor:
205 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as
206 # optional arguments.
207 return 'Optional' in argument.ext_attrs
208 return False
209
210 filtered = filter(None, args)
211 is_optional = any(IsOptional(arg) for arg in args)
212 (type_id, dart_type) = OverloadedType(filtered)
213 name = OverloadedName(filtered)
214 return ParamInfo(name, type_id, dart_type, is_optional)
215
216 def IsOptional(argument):
217 return ('Optional' in argument.ext_attrs and
218 argument.ext_attrs['Optional'] == None)
219
220 def AnalyzeOperation(interface, operations):
221 """Makes operation calling convention decision for a set of overloads.
222
223 Returns: An OperationInfo object.
224 """
225
226 # split operations with optional args into multiple operations
227 split_operations = []
228 for operation in operations:
229 for i in range(0, len(operation.arguments)):
230 if IsOptional(operation.arguments[i]):
231 new_operation = copy.deepcopy(operation)
232 new_operation.arguments = new_operation.arguments[:i]
233 split_operations.append(new_operation)
234 split_operations.append(operation)
235
236 # Zip together arguments from each overload by position, then convert
237 # to a dart argument.
238 args = map(lambda *args: _DartArg(args, interface),
239 *(op.arguments for op in split_operations))
240
241 info = OperationInfo()
242 info.operations = operations
243 info.overloads = split_operations
244 info.declared_name = operations[0].id
245 info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
246 info.constructor_name = None
247 info.js_name = info.declared_name
248 info.type_name = operations[0].type.id # TODO: widen.
249 info.param_infos = args
250 return info
251
252
253 def AnalyzeConstructor(interface):
254 """Returns an OperationInfo object for the constructor.
255
256 Returns None if the interface has no Constructor.
257 """
258 def GetArgs(func_value):
259 return map(lambda arg: _DartArg([arg], interface, True),
260 func_value.arguments)
261
262 if 'Constructor' in interface.ext_attrs:
263 name = None
264 func_value = interface.ext_attrs.get('Constructor')
265 if func_value:
266 # [Constructor(param,...)]
267 args = GetArgs(func_value)
268 idl_args = func_value.arguments
269 else: # [Constructor]
270 args = []
271 idl_args = []
272 else:
273 func_value = interface.ext_attrs.get('NamedConstructor')
274 if func_value:
275 name = func_value.id
276 args = GetArgs(func_value)
277 idl_args = func_value.arguments
278 else:
279 return None
280
281 info = OperationInfo()
282 info.overloads = None
283 info.idl_args = idl_args
284 info.declared_name = name
285 info.name = name
286 info.constructor_name = None
287 info.js_name = name
288 info.type_name = interface.id
289 info.param_infos = args
290 return info
291
292 def IsDartListType(type):
293 return type == 'List' or type.startswith('sequence<')
294
295 def IsDartCollectionType(type):
296 return IsDartListType(type)
297
298 def FindMatchingAttribute(interface, attr1):
299 matches = [attr2 for attr2 in interface.attributes
300 if attr1.id == attr2.id]
301 if matches:
302 assert len(matches) == 1
303 return matches[0]
304 return None
305
306
307 def DartDomNameOfAttribute(attr):
308 """Returns the Dart name for an IDLAttribute.
309
310 attr.id is the 'native' or JavaScript name.
311
312 To ensure uniformity, work with the true IDL name until as late a possible,
313 e.g. translate to the Dart name when generating Dart code.
314 """
315 name = attr.id
316 name = _dart_attribute_renames.get(name, name)
317 name = attr.ext_attrs.get('DartName', None) or name
318 return name
319
320
321 def TypeOrNothing(dart_type, comment=None):
322 """Returns string for declaring something with |dart_type| in a context
323 where a type may be omitted.
324 The string is empty or has a trailing space.
325 """
326 if dart_type == 'Dynamic':
327 if comment:
328 return '/*%s*/ ' % comment # Just a comment foo(/*T*/ x)
329 else:
330 return '' # foo(x) looks nicer than foo(Dynamic x)
331 else:
332 return dart_type + ' '
333
334
335 def TypeOrVar(dart_type, comment=None):
336 """Returns string for declaring something with |dart_type| in a context
337 where if a type is omitted, 'var' must be used instead."""
338 if dart_type == 'Dynamic':
339 if comment:
340 return 'var /*%s*/' % comment # e.g. var /*T*/ x;
341 else:
342 return 'var' # e.g. var x;
343 else:
344 return dart_type
345
346
347 class OperationInfo(object):
348 """Holder for various derived information from a set of overloaded operations.
349
350 Attributes:
351 overloads: A list of IDL operation overloads with the same name.
352 name: A string, the simple name of the operation.
353 constructor_name: A string, the name of the constructor iff the constructor
354 is named, e.g. 'fromList' in Int8Array.fromList(list).
355 type_name: A string, the name of the return type of the operation.
356 param_infos: A list of ParamInfo.
357 """
358
359 def ParametersInterfaceDeclaration(self, rename_type):
360 """Returns a formatted string declaring the parameters for the interface."""
361 return self._FormatParams(
362 self.param_infos, None,
363 lambda param: TypeOrNothing(rename_type(param.dart_type), param.type_id) )
364
365 def ParametersImplementationDeclaration(
366 self, rename_type, default_value='null'):
367 """Returns a formatted string declaring the parameters for the
368 implementation.
369
370 Args:
371 rename_type: A function that allows the types to be renamed.
372 The function is applied to the parameter's dart_type.
373 """
374 return self._FormatParams(
375 self.param_infos, default_value,
376 lambda param: TypeOrNothing(rename_type(param.dart_type)))
377
378 def ParametersAsArgumentList(self):
379 """Returns a string of the parameter names suitable for passing the
380 parameters as arguments.
381 """
382 return ', '.join(map(lambda param_info: param_info.name, self.param_infos))
383
384 def _FormatParams(self, params, default_value, type_fn):
385 def FormatParam(param):
386 """Returns a parameter declaration fragment for an ParamInfo."""
387 type = type_fn(param)
388 if param.is_optional and default_value and default_value != 'null':
389 return '%s%s = %s' % (type, param.name, default_value)
390 return '%s%s' % (type, param.name)
391
392 required = []
393 optional = []
394 for param_info in params:
395 if param_info.is_optional:
396 optional.append(param_info)
397 else:
398 if optional:
399 raise Exception('Optional parameters cannot precede required ones: '
400 + str(params))
401 required.append(param_info)
402 argtexts = map(FormatParam, required)
403 if optional:
404 argtexts.append('[' + ', '.join(map(FormatParam, optional)) + ']')
405 return ', '.join(argtexts)
406
407 def IsStatic(self):
408 is_static = self.overloads[0].is_static
409 assert any([is_static == o.is_static for o in self.overloads])
410 return is_static
411
412 def ConstructorFullName(self):
413 if self.constructor_name:
414 return self.type_name + '.' + self.constructor_name
415 else:
416 return self.type_name
417
418 def CopyAndWidenDefaultParameters(self):
419 """Returns equivalent OperationInfo, but default parameters are Dynamic."""
420 info = copy.copy(self)
421 info.param_infos = [param.Copy() for param in self.param_infos]
422 for param in info.param_infos:
423 if param.is_optional:
424 param.dart_type = 'Dynamic'
425 return info
426
427
428 def ConstantOutputOrder(a, b):
429 """Canonical output ordering for constants."""
430 if a.id < b.id: return -1
431 if a.id > b.id: return 1
432 return 0
433
434
435 def _FormatNameList(names):
436 """Returns JavaScript array literal expression with one name per line."""
437 #names = sorted(names)
438 if len(names) <= 1:
439 expression_string = str(names) # e.g. ['length']
440 else:
441 expression_string = ',\n '.join(str(names).split(','))
442 expression_string = expression_string.replace('[', '[\n ')
443 return expression_string
444
445
446 def IndentText(text, indent):
447 """Format lines of text with indent."""
448 def FormatLine(line):
449 if line.strip():
450 return '%s%s\n' % (indent, line)
451 else:
452 return '\n'
453 return ''.join(FormatLine(line) for line in text.split('\n'))
454
455 # Given a sorted sequence of type identifiers, return an appropriate type
456 # name
457 def TypeName(type_ids, interface):
458 # Dynamically type this field for now.
459 return 'Dynamic'
460
461 # ------------------------------------------------------------------------------
462
463 class Conversion(object):
464 """Represents a way of converting between types."""
465 def __init__(self, name, input_type, output_type):
466 # input_type is the type of the API input (and the argument type of the
467 # conversion function)
468 # output_type is the type of the API output (and the result type of the
469 # conversion function)
470 self.function_name = name
471 self.input_type = input_type
472 self.output_type = output_type
473
474 # TYPE -> "DIRECTION INTERFACE.MEMBER" -> conversion
475 # TYPE -> "DIRECTION INTERFACE.*" -> conversion
476 # TYPE -> "DIRECTION" -> conversion
477 #
478 # where DIRECTION is 'get' for getters and operation return values, 'set' for
479 # setters and operation arguments. INTERFACE and MEMBER are the idl names.
480 #
481 dart2js_conversions = {
482 'IDBKey': {
483 'get':
484 Conversion('_convertNativeToDart_IDBKey', 'Dynamic', 'Dynamic'),
485 'set':
486 Conversion('_convertDartToNative_IDBKey', 'Dynamic', 'Dynamic'),
487 },
488 'ImageData': {
489 'get':
490 Conversion('_convertNativeToDart_ImageData', 'Dynamic', 'ImageData'),
491 'set':
492 Conversion('_convertDartToNative_ImageData', 'ImageData', 'Dynamic')
493 },
494 'Dictionary': {
495 'get':
496 Conversion('_convertNativeToDart_Dictionary', 'Dynamic', 'Map'),
497 'set':
498 Conversion('_convertDartToNative_Dictionary', 'Map', 'Dynamic'),
499 },
500
501 'DOMString[]': {
502 'set':
503 Conversion(
504 '_convertDartToNative_StringArray', 'List<String>', 'List'),
505 },
506
507 'SerializedScriptValue': {
508 'set IDBObjectStore.add':
509 Conversion('_convertDartToNative_SerializedScriptValue',
510 'Dynamic', 'Dynamic'),
511 'set IDBObjectStore.put':
512 Conversion('_convertDartToNative_SerializedScriptValue',
513 'Dynamic', 'Dynamic'),
514 'set IDBCursor.update':
515 Conversion('_convertDartToNative_SerializedScriptValue',
516 'Dynamic', 'Dynamic'),
517 },
518
519
520 # IDBAny is problematic. Some uses are just a union of other IDB types,
521 # which need no conversion.. Others include data values which require
522 # serialized script value processing.
523 'IDBAny': {
524 'get IDBCursorWithValue.value':
525 Conversion('_convertNativeToDart_IDBAny', 'Dynamic', 'Dynamic'),
526
527 # This is problematic. The result property of IDBRequest is used for
528 # all requests. Read requests like IDBDataStore.getObject need
529 # conversion, but other requests like opening a database return
530 # something that does not need conversion.
531 'get IDBRequest.result':
532 Conversion('_convertNativeToDart_IDBAny', 'Dynamic', 'Dynamic'),
533
534 # "source: On getting, returns the IDBObjectStore or IDBIndex that the
535 # cursor is iterating. ...". So we should not try to convert it.
536 'get IDBCursor.source': None,
537
538 # Should be either a DOMString, an Array of DOMStrings or null.
539 'get IDBObjectStore.keyPath': None
540 },
541 }
542
543 def FindConversion(idl_type, direction, interface, member):
544 table = dart2js_conversions.get(idl_type)
545 if table:
546 return (table.get('%s %s.%s' % (direction, interface, member)) or
547 table.get('%s %s.*' % (direction, interface)) or
548 table.get(direction))
549 return None
550
551 # ------------------------------------------------------------------------------
552
553 class IDLTypeInfo(object):
554 def __init__(self, idl_type, data):
555 self._idl_type = idl_type
556 self._data = data
557
558 def idl_type(self):
559 return self._idl_type
560
561 def dart_type(self):
562 return self._data.dart_type or self._idl_type
563
564 def native_type(self):
565 return self._data.native_type or self._idl_type
566
567 def requires_v8_scope(self):
568 return self._data.requires_v8_scope
569
570 def to_native_info(self, idl_node, interface_name):
571 cls = 'Dart%s' % self.idl_type()
572
573 if 'Callback' in idl_node.ext_attrs:
574 return '%s', 'RefPtr<%s>' % self.native_type(), cls, 'create'
575
576 if self.custom_to_native():
577 type = 'RefPtr<%s>' % self.native_type()
578 argument_expression_template = '%s.get()'
579 else:
580 type = '%s*' % self.native_type()
581 if isinstance(self, SVGTearOffIDLTypeInfo) and not interface_name.endswith ('List'):
582 argument_expression_template = '%s->propertyReference()'
583 else:
584 argument_expression_template = '%s'
585 return argument_expression_template, type, cls, 'toNative'
586
587 def custom_to_native(self):
588 return self._data.custom_to_native
589
590 def parameter_type(self):
591 return '%s*' % self.native_type()
592
593 def webcore_includes(self):
594 WTF_INCLUDES = [
595 'ArrayBuffer',
596 'ArrayBufferView',
597 'Float32Array',
598 'Float64Array',
599 'Int8Array',
600 'Int16Array',
601 'Int32Array',
602 'Uint8Array',
603 'Uint16Array',
604 'Uint32Array',
605 'Uint8ClampedArray',
606 ]
607
608 if self._idl_type in WTF_INCLUDES:
609 return ['<wtf/%s.h>' % self.native_type()]
610
611 if not self._idl_type.startswith('SVG'):
612 return ['"%s.h"' % self.native_type()]
613
614 if self._idl_type in ['SVGNumber', 'SVGPoint']:
615 return ['"SVGPropertyTearOff.h"']
616 if self._idl_type.startswith('SVGPathSeg'):
617 include = self._idl_type.replace('Abs', '').replace('Rel', '')
618 else:
619 include = self._idl_type
620 return ['"%s.h"' % include] + _svg_supplemental_includes
621
622 def receiver(self):
623 return 'receiver->'
624
625 def conversion_includes(self):
626 includes = [self._idl_type] + (self._data.conversion_includes or [])
627 return ['"Dart%s.h"' % include for include in includes]
628
629 def to_dart_conversion(self, value, interface_name=None, attributes=None):
630 return 'Dart%s::toDart(%s)' % (self._idl_type, value)
631
632 def custom_to_dart(self):
633 return self._data.custom_to_dart
634
635
636 class InterfaceIDLTypeInfo(IDLTypeInfo):
637 def __init__(self, idl_type, data):
638 super(InterfaceIDLTypeInfo, self).__init__(idl_type, data)
639
640
641 class SequenceIDLTypeInfo(IDLTypeInfo):
642 def __init__(self, idl_type, data, item_info):
643 super(SequenceIDLTypeInfo, self).__init__(idl_type, data)
644 self._item_info = item_info
645
646 def dart_type(self):
647 return 'List<%s>' % self._item_info.dart_type()
648
649 def to_dart_conversion(self, value, interface_name=None, attributes=None):
650 return 'DartDOMWrapper::vectorToDart<Dart%s>(%s)' % (self._item_info.native_ type(), value)
651
652 def conversion_includes(self):
653 return self._item_info.conversion_includes()
654
655
656 class DOMStringArrayTypeInfo(SequenceIDLTypeInfo):
657 def __init__(self, data, item_info):
658 super(DOMStringArrayTypeInfo, self).__init__('DOMString[]', data, item_info)
659
660 def to_native_info(self, idl_node, interface_name):
661 return '%s', 'RefPtr<DOMStringList>', 'DartDOMStringList', 'toNative'
662
663
664 class PrimitiveIDLTypeInfo(IDLTypeInfo):
665 def __init__(self, idl_type, data):
666 super(PrimitiveIDLTypeInfo, self).__init__(idl_type, data)
667
668 def to_native_info(self, idl_node, interface_name):
669 type = self.native_type()
670 if type == 'SerializedScriptValue':
671 type = 'RefPtr<%s>' % type
672 if type == 'String':
673 type = 'DartStringAdapter'
674 return '%s', type, 'DartUtilities', 'dartTo%s' % self._capitalized_native_ty pe()
675
676 def parameter_type(self):
677 if self.native_type() == 'String':
678 return 'const String&'
679 return self.native_type()
680
681 def conversion_includes(self):
682 return []
683
684 def to_dart_conversion(self, value, interface_name=None, attributes=None):
685 function_name = self._capitalized_native_type()
686 function_name = function_name[0].lower() + function_name[1:]
687 function_name = 'DartUtilities::%sToDart' % function_name
688 if attributes and 'TreatReturnedNullStringAs' in attributes:
689 function_name += 'WithNullCheck'
690 return '%s(%s)' % (function_name, value)
691
692 def webcore_getter_name(self):
693 return self._data.webcore_getter_name
694
695 def webcore_setter_name(self):
696 return self._data.webcore_setter_name
697
698 def _capitalized_native_type(self):
699 return re.sub(r'(^| )([a-z])', lambda x: x.group(2).upper(), self.native_typ e())
700
701
702 class SVGTearOffIDLTypeInfo(IDLTypeInfo):
703 def __init__(self, idl_type, data):
704 super(SVGTearOffIDLTypeInfo, self).__init__(idl_type, data)
705
706 def native_type(self):
707 if self._data.native_type:
708 return self._data.native_type
709 tear_off_type = 'SVGPropertyTearOff'
710 if self._idl_type.endswith('List'):
711 tear_off_type = 'SVGListPropertyTearOff'
712 return '%s<%s>' % (tear_off_type, self._idl_type)
713
714 def receiver(self):
715 if self._idl_type.endswith('List'):
716 return 'receiver->'
717 return 'receiver->propertyReference().'
718
719 def to_dart_conversion(self, value, interface_name, attributes):
720 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
721 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
722 conversion_cast = '%s::create(%s)'
723 if interface_name.startswith('SVGAnimated'):
724 conversion_cast = 'static_cast<%s*>(%s)'
725 elif self.idl_type() == 'SVGStringList':
726 conversion_cast = '%s::create(receiver, %s)'
727 elif interface_name.endswith('List'):
728 conversion_cast = 'static_cast<%s*>(%s.get())'
729 elif self.idl_type() in svg_primitive_types:
730 conversion_cast = '%s::create(%s)'
731 else:
732 conversion_cast = 'static_cast<%s*>(%s)'
733 conversion_cast = conversion_cast % (self.native_type(), value)
734 return 'Dart%s::toDart(%s)' % (self._idl_type, conversion_cast)
735
736 def argument_expression(self, name, interface_name):
737 return name if interface_name.endswith('List') else '%s->propertyReference() ' % name
738
739
740 class TypeData(object):
741 def __init__(self, clazz, dart_type=None, native_type=None,
742 custom_to_dart=None, custom_to_native=None,
743 conversion_includes=None,
744 webcore_getter_name='getAttribute',
745 webcore_setter_name='setAttribute',
746 requires_v8_scope=False):
747 self.clazz = clazz
748 self.dart_type = dart_type
749 self.native_type = native_type
750 self.custom_to_dart = custom_to_dart
751 self.custom_to_native = custom_to_native
752 self.conversion_includes = conversion_includes
753 self.webcore_getter_name = webcore_getter_name
754 self.webcore_setter_name = webcore_setter_name
755 self.requires_v8_scope = requires_v8_scope
756
757
758 _idl_type_registry = {
759 'boolean': TypeData(clazz='Primitive', dart_type='bool', native_type='bool',
760 webcore_getter_name='hasAttribute',
761 webcore_setter_name='setBooleanAttribute'),
762 'byte': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
763 'octet': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
764 'short': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
765 'unsigned short': TypeData(clazz='Primitive', dart_type='int',
766 native_type='int'),
767 'int': TypeData(clazz='Primitive', dart_type='int'),
768 'unsigned int': TypeData(clazz='Primitive', dart_type='int',
769 native_type='unsigned'),
770 'long': TypeData(clazz='Primitive', dart_type='int', native_type='int',
771 webcore_getter_name='getIntegralAttribute',
772 webcore_setter_name='setIntegralAttribute'),
773 'unsigned long': TypeData(clazz='Primitive', dart_type='int',
774 native_type='unsigned',
775 webcore_getter_name='getUnsignedIntegralAttribute' ,
776 webcore_setter_name='setUnsignedIntegralAttribute' ),
777 'long long': TypeData(clazz='Primitive', dart_type='int'),
778 'unsigned long long': TypeData(clazz='Primitive', dart_type='int'),
779 'float': TypeData(clazz='Primitive', dart_type='num', native_type='double'),
780 'double': TypeData(clazz='Primitive', dart_type='num'),
781
782 'any': TypeData(clazz='Primitive', dart_type='Object'),
783 'Array': TypeData(clazz='Primitive', dart_type='List'),
784 'custom': TypeData(clazz='Primitive', dart_type='Dynamic'),
785 'Date': TypeData(clazz='Primitive', dart_type='Date', native_type='double'),
786 'DOMObject': TypeData(clazz='Primitive', dart_type='Object', native_type='Sc riptValue'),
787 'DOMString': TypeData(clazz='Primitive', dart_type='String', native_type='St ring'),
788 # TODO(vsm): This won't actually work until we convert the Map to
789 # a native JS Map for JS DOM.
790 'Dictionary': TypeData(clazz='Primitive', dart_type='Map', requires_v8_scope =True),
791 # TODO(sra): Flags is really a dictionary: {create:bool, exclusive:bool}
792 # http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-flags-interfa ce
793 'Flags': TypeData(clazz='Primitive', dart_type='Object'),
794 'DOMTimeStamp': TypeData(clazz='Primitive', dart_type='int', native_type='un signed long long'),
795 'object': TypeData(clazz='Primitive', dart_type='Object', native_type='Scrip tValue'),
796 'ObjectArray': TypeData(clazz='Primitive', dart_type='List'),
797 'PositionOptions': TypeData(clazz='Primitive', dart_type='Object'),
798 # TODO(sra): Come up with some meaningful name so that where this appears in
799 # the documentation, the user is made aware that only a limited subset of
800 # serializable types are actually permitted.
801 'SerializedScriptValue': TypeData(clazz='Primitive', dart_type='Dynamic'),
802 # TODO(sra): Flags is really a dictionary: {create:bool, exclusive:bool}
803 # http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-flags-interfa ce
804 'WebKitFlags': TypeData(clazz='Primitive', dart_type='Object'),
805
806 'sequence': TypeData(clazz='Primitive', dart_type='List'),
807 'void': TypeData(clazz='Primitive', dart_type='void'),
808
809 'CSSRule': TypeData(clazz='Interface', conversion_includes=['CSSImportRule'] ),
810 'DOMException': TypeData(clazz='Interface', native_type='DOMCoreException'),
811 'DOMStringList': TypeData(clazz='Interface', dart_type='List<String>', custo m_to_native=True),
812 'DOMStringMap': TypeData(clazz='Interface', dart_type='Map<String, String>') ,
813 'DOMWindow': TypeData(clazz='Interface', custom_to_dart=True),
814 'Element': TypeData(clazz='Interface', custom_to_dart=True),
815 'EventListener': TypeData(clazz='Interface', custom_to_native=True),
816 'EventTarget': TypeData(clazz='Interface', custom_to_native=True),
817 'HTMLElement': TypeData(clazz='Interface', custom_to_dart=True),
818 'IDBAny': TypeData(clazz='Interface', dart_type='Dynamic', custom_to_native= True),
819 'IDBKey': TypeData(clazz='Interface', dart_type='Dynamic', custom_to_native= True),
820 'MutationRecordArray': TypeData(clazz='Interface', # C++ pass by pointer.
821 native_type='MutationRecordArray',
822 dart_type='List<MutationRecord>'),
823 'StyleSheet': TypeData(clazz='Interface', conversion_includes=['CSSStyleShee t']),
824 'SVGElement': TypeData(clazz='Interface', custom_to_dart=True),
825
826 'SVGAngle': TypeData(clazz='SVGTearOff'),
827 'SVGLength': TypeData(clazz='SVGTearOff'),
828 'SVGLengthList': TypeData(clazz='SVGTearOff'),
829 'SVGMatrix': TypeData(clazz='SVGTearOff'),
830 'SVGNumber': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<fl oat>'),
831 'SVGNumberList': TypeData(clazz='SVGTearOff'),
832 'SVGPathSegList': TypeData(clazz='SVGTearOff', native_type='SVGPathSegListPr opertyTearOff'),
833 'SVGPoint': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<Flo atPoint>'),
834 'SVGPointList': TypeData(clazz='SVGTearOff'),
835 'SVGPreserveAspectRatio': TypeData(clazz='SVGTearOff'),
836 'SVGRect': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<Floa tRect>'),
837 'SVGStringList': TypeData(clazz='SVGTearOff', native_type='SVGStaticListProp ertyTearOff<SVGStringList>'),
838 'SVGTransform': TypeData(clazz='SVGTearOff'),
839 'SVGTransformList': TypeData(clazz='SVGTearOff', native_type='SVGTransformLi stPropertyTearOff'),
840 }
841
842 _svg_supplemental_includes = [
843 '"SVGAnimatedPropertyTearOff.h"',
844 '"SVGAnimatedListPropertyTearOff.h"',
845 '"SVGStaticListPropertyTearOff.h"',
846 '"SVGAnimatedListPropertyTearOff.h"',
847 '"SVGTransformListPropertyTearOff.h"',
848 '"SVGPathSegListPropertyTearOff.h"',
849 ]
850
851 class TypeRegistry(object):
852 def __init__(self, database, renamer=None):
853 self._database = database
854 self._renamer = renamer
855 self._cache = {}
856
857 def TypeInfo(self, type_name):
858 if not type_name in self._cache:
859 self._cache[type_name] = self._TypeInfo(type_name)
860 return self._cache[type_name]
861
862 def DartType(self, type_name):
863 dart_type = self.TypeInfo(type_name).dart_type()
864 if self._database.HasInterface(dart_type):
865 interface = self._database.GetInterface(dart_type)
866 if self._renamer:
867 return self._renamer.RenameInterface(interface)
868 else:
869 return interface.id
870 return dart_type
871
872 def _TypeInfo(self, type_name):
873 match = re.match(r'(?:sequence<(\w+)>|(\w+)\[\])$', type_name)
874 if match:
875 if type_name == 'DOMString[]':
876 return DOMStringArrayTypeInfo(TypeData('Sequence'), self.TypeInfo('DOMSt ring'))
877 item_info = self.TypeInfo(match.group(1) or match.group(2))
878 return SequenceIDLTypeInfo(type_name, TypeData('Sequence'), item_info)
879 if not type_name in _idl_type_registry:
880 return InterfaceIDLTypeInfo(type_name, TypeData('Interface'))
881 type_data = _idl_type_registry.get(type_name)
882 class_name = '%sIDLTypeInfo' % type_data.clazz
883 return globals()[class_name](type_name, type_data)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698