Flutter Engine
The Flutter Engine
systemnative.py
Go to the documentation of this file.
1#!/usr/bin/env python3
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"""This module provides shared functionality for the systems to generate
6native binding from the IDL database."""
7
8import emitter
9import logging
10import os
11from generator import *
12from htmldartgenerator import *
13from idlnode import IDLArgument, IDLAttribute, IDLEnum, IDLMember
14from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES
15
16_logger = logging.getLogger('systemnative')
17
18# TODO(vsm): This should be recoverable from IDL, but we appear to not
19# track the necessary info.
20_url_utils = [
21 'hash', 'host', 'hostname', 'origin', 'password', 'pathname', 'port',
22 'protocol', 'search', 'username'
23]
24
25_promise_to_future = Conversion('promiseToFuture', 'dynamic', 'Future')
26
27
28def array_type(data_type):
29 matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
30 if not matched:
31 return None
32 return matched.group(1)
33
34
35_sequence_matcher = re.compile('sequence<(.+)>')
36
37
38def TypeIdToBlinkName(interface_id, database):
39 # Maybe should use the type_registry here?
40 if database.HasEnum(interface_id):
41 return "DOMString" # All enums are strings.
42
43 seq_match = _sequence_matcher.match(interface_id)
44 if seq_match is not None:
45 t = TypeIdToBlinkName(seq_match.group(1), database)
46 return "sequence<%s>" % t
47
48 arr_match = array_type(interface_id)
49 if arr_match is not None:
50 t = TypeIdToBlinkName(arr_match, database)
51 return "%s[]" % t
52
53 return interface_id
54
55
56def DeriveQualifiedName(library_name, name):
57 return library_name + "." + name
58
59
61 return "Blink" + name
62
63
64_type_encoding_map = {
65 'long long': "ll",
66 'unsigned long': "ul",
67 'unsigned long long': "ull",
68 'unsigned short': "us",
69}
70
71
73
74 seq_match = _sequence_matcher.match(t)
75 if seq_match is not None:
76 t2 = EncodeType(seq_match.group(1))
77 t = "SEQ_%s_SEQ" % t2
78 return t
79
80 arr_match = array_type(t)
81 if arr_match is not None:
82 t = EncodeType(arr_match)
83 return "A_%s_A" % t
84
85 return _type_encoding_map.get(t) or t
86
87
89 """Generates Dart implementation for one DOM IDL interface."""
90
91 def __init__(self, interface, cpp_library_emitter, options, loggerParent):
92 super(DartiumBackend, self).__init__(interface, options, True,
93 loggerParent)
94
95 self._interface_interface = interface
96 self._cpp_library_emitter = cpp_library_emitter
97 self._database_database = options.database
98 self._template_loader = options.templates
99 self._type_registry_type_registry = options.type_registry
101 self._interface_interface.id)
102 self._metadata_metadata = options.metadata
103 # These get initialized by StartInterface
104 self._cpp_header_emitter = None
105 self._cpp_impl_emitter = None
106 self._members_emitter = None
107 self._cpp_declarations_emitter = None
108 self._cpp_impl_includes = None
109 self._cpp_definitions_emitter = None
110 self._cpp_resolver_emitter = None
111 self._dart_js_interop = options.dart_js_interop
112 _logger.setLevel(loggerParent.level)
113
115 # We could not add merged functions to implementation class because
116 # underlying c++ object doesn't implement them. Merged functions are
117 # generated on merged interface implementation instead.
118 return False
119
121 return {}
122
123 def _OutputConversion(self, idl_type, member):
124 conversion = FindConversion(idl_type, 'get', self._interface_interface.id, member)
125 # TODO(jacobr) handle promise consistently in dart2js and dartium.
126 if idl_type == 'Promise':
127 return _promise_to_future
128 if conversion:
129 if conversion.function_name in ('convertNativeToDart_DateTime',
130 'convertNativeToDart_ImageData'):
131 return None
132 return conversion
133
134 def _InputConversion(self, idl_type, member):
135 return FindConversion(idl_type, 'set', self._interface_interface.id, member)
136
137 def GenerateCallback(self, info):
138 return None
139
141 template = None
142 interface_name = self._interface_interface.doc_js_name
143 if interface_name == self._interface_interface.id or not self._database_database.HasInterface(
144 interface_name):
145 template_file = 'impl_%s.darttemplate' % interface_name
146 template = self._template_loader.TryLoad(template_file)
147 if not template:
148 template = self._template_loader.Load(
149 'dart_implementation.darttemplate')
150 return template
151
152 def RootClassName(self):
153 return 'DartHtmlDomObject'
154
155 # This code matches up with the _generate_native_entry code in
156 # dart_utilities.py in the dartium repository. Any changes to this
157 # should have matching changes on that end.
158 def DeriveNativeEntry(self, name, kind, count):
159 interface_id = self._interface_interface.id
160 database = self._database_database
161 tag = ""
162 if kind == 'Getter':
163 tag = "%s_Getter" % name
164 blink_entry = tag
165 elif kind == 'Setter':
166 tag = "%s_Setter" % name
167 blink_entry = tag
168 elif kind == 'Constructor':
169 tag = "constructorCallback"
170 blink_entry = tag
171 elif kind == 'Method':
172 tag = "%s_Callback" % name
173 blink_entry = tag
174
175 interface_id = TypeIdToBlinkName(interface_id, database)
176
177 def mkPublic(s):
178 if s.startswith("_") or s.startswith("$"):
179 return "$" + s
180 return s
181
182 if count is not None:
183 arity = str(count)
184 dart_name = mkPublic("_".join([tag, arity]))
185 else:
186 dart_name = mkPublic(tag)
187 resolver_string = "_".join([interface_id, tag])
188
189 return (dart_name, resolver_string)
190
191 def DeriveNativeName(self, name, suffix=""):
192 fields = ['$' + name]
193 if suffix != "":
194 fields.append(suffix)
195 return "_".join(fields)
196
197 def DeriveQualifiedBlinkName(self, interface_name, name):
198 blinkClass = DeriveQualifiedName("_blink",
199 DeriveBlinkClassName(interface_name))
200 blinkInstance = DeriveQualifiedName(blinkClass, "instance")
201 return DeriveQualifiedName(blinkInstance, name + "_")
202
203 def NativeSpec(self):
204 return ''
205
206 def StartInterface(self, members_emitter):
207 # Create emitters for c++ implementation.
208 if not IsPureInterface(self._interface_interface.id, self._database_database) and \
209 not IsCustomType(self._interface_interface.id):
210 self._cpp_header_emitter = self._cpp_library_emitter.CreateHeaderEmitter(
211 self._interface_interface.id,
212 self._renamer.GetLibraryName(self._interface_interface))
213 self._cpp_impl_emitter = \
214 self._cpp_library_emitter.CreateSourceEmitter(self._interface_interface.id)
215 else:
218
220 self._members_emitter = members_emitter
221
223
224 # This is a hack to work around a strange C++ compile error that we weren't
225 # able to track down the true cause of.
226 if self._interface_interface.id == 'Timing':
227 self._cpp_impl_includes.add('"core/animation/TimedItem.h"')
228
231
232 # We need to revisit our treatment of typed arrays, right now
233 # it is full of hacks.
234 if self._interface_interface.ext_attrs.get('ConstructorTemplate') == 'TypedArray':
235 self._cpp_resolver_emitter.Emit(
236 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
237 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
238 INTERFACE_NAME=self._interface_interface.id)
239
240 self._cpp_impl_includes.add('"DartArrayBufferViewCustom.h"')
241 self._cpp_definitions_emitter.Emit(
242 '\n'
243 'static void constructorCallback(Dart_NativeArguments args)\n'
244 '{\n'
245 ' WebCore::DartArrayBufferViewInternal::constructWebGLArray<Dart$(INTERFACE_NAME)>(args);\n'
246 '}\n',
247 INTERFACE_NAME=self._interface_interface.id)
248
249 def _EmitConstructorInfrastructure(self,
250 constructor_info,
251 cpp_prefix,
252 cpp_suffix,
253 factory_method_name,
254 arguments=None,
255 emit_to_native=False,
256 is_custom=False):
257
258 constructor_callback_cpp_name = cpp_prefix + cpp_suffix
259
260 if arguments is None:
261 arguments = constructor_info.idl_args[0]
262 argument_count = len(arguments)
263 else:
264 argument_count = len(arguments)
265
266 typed_formals = constructor_info.ParametersAsArgumentList(
267 argument_count)
268 parameters = constructor_info.ParametersAsStringOfVariables(
269 argument_count)
270 interface_name = self._interface_type_info_interface_type_info.interface_name()
271
272 dart_native_name, constructor_callback_id = \
273 self.DeriveNativeEntry(cpp_suffix, 'Constructor', argument_count)
274
275 # Then we emit the impedance matching wrapper to call out to the
276 # toplevel wrapper
277 if not emit_to_native:
278 toplevel_name = \
280 dart_native_name)
281 self._members_emitter.Emit(
282 ' static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => '
283 '$TOPLEVEL_NAME($OUTPARAMETERS);\n',
284 INTERFACE_NAME=self._interface_type_info_interface_type_info.interface_name(),
285 FACTORY_METHOD_NAME=factory_method_name,
286 PARAMETERS=typed_formals,
287 TOPLEVEL_NAME=toplevel_name,
288 OUTPARAMETERS=parameters)
289
290 self._cpp_resolver_emitter.Emit(
291 ' if (name == "$ID")\n'
292 ' return Dart$(WEBKIT_INTERFACE_NAME)Internal::$CPP_CALLBACK;\n',
293 ID=constructor_callback_id,
294 WEBKIT_INTERFACE_NAME=self._interface_interface.id,
295 CPP_CALLBACK=constructor_callback_cpp_name)
296
297 def GenerateCustomFactory(self, constructor_info):
298 if 'CustomConstructor' not in self._interface_interface.ext_attrs:
299 return False
300
301 annotations = self._metadata_metadata.GetFormattedMetadata(
303
304 self._members_emitter.Emit(
305 '\n $(ANNOTATIONS)factory $CTOR($PARAMS) => _create($FACTORY_PARAMS);\n',
306 ANNOTATIONS=annotations,
307 CTOR=constructor_info._ConstructorFullName(self._DartType),
308 PARAMS=constructor_info.ParametersAsDeclaration(self._DartType),
309 FACTORY_PARAMS= \
310 constructor_info.ParametersAsArgumentList())
311
312 # MutationObserver has custom _create. TODO(terry): Consider table but this is only one.
313 if self._interface_interface.id != 'MutationObserver':
314 constructor_callback_cpp_name = 'constructorCallback'
316 constructor_info,
317 "",
318 constructor_callback_cpp_name,
319 '_create',
320 is_custom=True)
321
323 '\n'
324 'void $CPP_CALLBACK(Dart_NativeArguments);\n',
325 CPP_CALLBACK=constructor_callback_cpp_name)
326
327 return True
328
329 def IsConstructorArgumentOptional(self, argument):
330 return IsOptional(argument)
331
332 def MakeFactoryCall(self, factory, method, arguments, constructor_info):
333 return emitter.Format(
334 '$FACTORY.$METHOD($ARGUMENTS)',
335 FACTORY=factory,
336 METHOD=method,
337 ARGUMENTS=arguments)
338
339 def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
340 constructor_callback_cpp_name = name + 'constructorCallback'
342 constructor_info,
343 name,
344 'constructorCallback',
345 name,
346 arguments,
347 emit_to_native=True,
348 is_custom=False)
349
350 ext_attrs = self._interface_interface.ext_attrs
351
352 create_function = 'create'
353 if 'NamedConstructor' in ext_attrs:
354 create_function = 'createForJSConstructor'
355 function_expression = '%s::%s' % (
356 self._interface_type_info_interface_type_info.native_type(), create_function)
357
359 # Need to omit a support check if it is conditional in JS.
360 return self._interface_interface.doc_js_name in js_support_checks
361
363 # Assume that everything is supported on Dartium.
364 value = js_support_checks.get(self._interface_interface.doc_js_name)
365 if type(value) == tuple:
366 return (value[0], 'true')
367 else:
368 return 'true'
369
371 interface = self._interface_interface
372 if interface.parents:
373 supertype = '%sClassId' % interface.parents[0].type.id
374 else:
375 supertype = '-1'
376
377 self._GenerateCPPHeader()
378
379 self._cpp_impl_emitter.Emit(
380 self._template_loader.Load('cpp_implementation.template'),
381 INTERFACE=self._interface_interface.id,
382 SUPER_INTERFACE=supertype,
383 INCLUDES=self._GenerateCPPIncludes(self._cpp_impl_includes),
384 CALLBACKS=self._cpp_definitions_emitter.Fragments(),
385 RESOLVER=self._cpp_resolver_emitter.Fragments(),
386 WEBCORE_CLASS_NAME=self._interface_type_info_interface_type_info.native_type(),
387 WEBCORE_CLASS_NAME_ESCAPED=self._interface_type_info_interface_type_info.native_type().
388 replace('<', '_').replace('>', '_'),
389 DART_IMPLEMENTATION_CLASS=self._interface_type_info_interface_type_info.
390 implementation_name(),
391 DART_IMPLEMENTATION_LIBRARY_ID='Dart%sLibraryId' %
392 self._renamer.GetLibraryId(self._interface_interface))
393
394 def _GenerateCPPHeader(self):
395 to_native_emitter = emitter.Emitter()
396 if self._interface_type_info_interface_type_info.custom_to_native():
397 return_type = 'PassRefPtr<NativeType>'
398 to_native_body = ';'
399 to_native_arg_body = ';'
400 else:
401 return_type = 'NativeType*'
402 to_native_body = emitter.Format(
403 '\n'
404 ' {\n'
405 ' DartDOMData* domData = DartDOMData::current();\n'
406 ' return DartDOMWrapper::unwrapDartWrapper<Dart$INTERFACE>(domData, handle, exception);\n'
407 ' }',
408 INTERFACE=self._interface_interface.id)
409 to_native_arg_body = emitter.Format(
410 '\n'
411 ' {\n'
412 ' return DartDOMWrapper::unwrapDartWrapper<Dart$INTERFACE>(args, index, exception);\n'
413 ' }',
414 INTERFACE=self._interface_interface.id)
415
416 to_native_emitter.Emit(
417 ' static $RETURN_TYPE toNative(Dart_Handle handle, Dart_Handle& exception)$TO_NATIVE_BODY\n'
418 '\n'
419 ' static $RETURN_TYPE toNativeWithNullCheck(Dart_Handle handle, Dart_Handle& exception)\n'
420 ' {\n'
421 ' return Dart_IsNull(handle) ? 0 : toNative(handle, exception);\n'
422 ' }\n'
423 '\n'
424 ' static $RETURN_TYPE toNative(Dart_NativeArguments args, int index, Dart_Handle& exception)$TO_NATIVE_ARG_BODY\n'
425 '\n'
426 ' static $RETURN_TYPE toNativeWithNullCheck(Dart_NativeArguments args, int index, Dart_Handle& exception)\n'
427 ' {\n'
428 ' // toNative accounts for Null objects also.\n'
429 ' return toNative(args, index, exception);\n'
430 ' }\n',
431 RETURN_TYPE=return_type,
432 TO_NATIVE_BODY=to_native_body,
433 TO_NATIVE_ARG_BODY=to_native_arg_body,
434 INTERFACE=self._interface_interface.id)
435
436 to_dart_emitter = emitter.Emitter()
437
438 ext_attrs = self._interface_interface.ext_attrs
439
440 to_dart_emitter.Emit(
441 ' static Dart_Handle toDart(NativeType* value)\n'
442 ' {\n'
443 ' if (!value)\n'
444 ' return Dart_Null();\n'
445 ' DartDOMData* domData = DartDOMData::current();\n'
446 ' Dart_WeakPersistentHandle result =\n'
447 ' DartDOMWrapper::lookupWrapper<Dart$(INTERFACE)>(domData, value);\n'
448 ' if (result)\n'
449 ' return Dart_HandleFromWeakPersistent(result);\n'
450 ' return createWrapper(domData, value);\n'
451 ' }\n'
452 ' static void returnToDart(Dart_NativeArguments args,\n'
453 ' NativeType* value,\n'
454 ' bool autoDartScope = true)\n'
455 ' {\n'
456 ' if (value) {\n'
457 ' DartDOMData* domData = static_cast<DartDOMData*>(\n'
458 ' Dart_GetNativeIsolateData(args));\n'
459 ' Dart_WeakPersistentHandle result =\n'
460 ' DartDOMWrapper::lookupWrapper<Dart$(INTERFACE)>(domData, value);\n'
461 ' if (result)\n'
462 ' Dart_SetWeakHandleReturnValue(args, result);\n'
463 ' else {\n'
464 ' if (autoDartScope) {\n'
465 ' Dart_SetReturnValue(args, createWrapper(domData, value));\n'
466 ' } else {\n'
467 ' DartApiScope apiScope;\n'
468 ' Dart_SetReturnValue(args, createWrapper(domData, value));\n'
469 ' }\n'
470 ' }\n'
471 ' }\n'
472 ' }\n',
473 INTERFACE=self._interface_interface.id)
474
475 if ('CustomToV8' in ext_attrs or 'PureInterface' in ext_attrs or
476 'CPPPureInterface' in ext_attrs or
477 'SpecialWrapFor' in ext_attrs or
478 ('Custom' in ext_attrs and ext_attrs['Custom'] == 'Wrap') or
479 ('Custom' in ext_attrs and ext_attrs['Custom'] == 'ToV8') or
480 self._interface_type_info_interface_type_info.custom_to_dart()):
481 to_dart_emitter.Emit(
482 ' static Dart_Handle createWrapper(DartDOMData* domData, NativeType* value);\n'
483 )
484 else:
485 to_dart_emitter.Emit(
486 ' static Dart_Handle createWrapper(DartDOMData* domData, NativeType* value)\n'
487 ' {\n'
488 ' return DartDOMWrapper::createWrapper<Dart$(INTERFACE)>(domData, value, Dart$(INTERFACE)::dartClassId);\n'
489 ' }\n',
490 INTERFACE=self._interface_interface.id)
491
492 webcore_includes = self._GenerateCPPIncludes(
493 self._interface_type_info_interface_type_info.webcore_includes())
494
495 is_node_test = lambda interface: interface.id == 'Node'
496 is_active_test = lambda interface: 'ActiveDOMObject' in interface.ext_attrs
497 is_event_target_test = lambda interface: 'EventTarget' in interface.ext_attrs
498
499 def TypeCheckHelper(test):
500 return 'true' if any(
501 map(test, self._database_database.Hierarchy(
502 self._interface_interface))) else 'false'
503
504 to_active_emitter = emitter.Emitter()
505 to_node_emitter = emitter.Emitter()
506 to_event_target_emitter = emitter.Emitter()
507
508 if (any(map(is_active_test,
509 self._database_database.Hierarchy(self._interface_interface)))):
510 to_active_emitter.Emit('return toNative(value);')
511 else:
512 to_active_emitter.Emit('return 0;')
513
514 if (any(map(is_node_test, self._database_database.Hierarchy(self._interface_interface)))):
515 to_node_emitter.Emit('return toNative(value);')
516 else:
517 to_node_emitter.Emit('return 0;')
518
519 if (any(
520 map(is_event_target_test,
521 self._database_database.Hierarchy(self._interface_interface)))):
522 to_event_target_emitter.Emit('return toNative(value);')
523 else:
524 to_event_target_emitter.Emit('return 0;')
525
526 v8_interface_include = ''
527 # V8AbstractWorker.h does not exist so we have to hard code this case.
528 if self._interface_interface.id != 'AbstractWorker':
529 # FIXME: We need this to access the WrapperTypeInfo.
530 v8_interface_include = '#include "V8%s.h"' % (self._interface_interface.id)
531
532 self._cpp_header_emitter.Emit(
533 self._template_loader.Load('cpp_header.template'),
534 INTERFACE=self._interface_interface.id,
535 WEBCORE_INCLUDES=webcore_includes,
536 V8_INTERFACE_INCLUDE=v8_interface_include,
537 WEBCORE_CLASS_NAME=self._interface_type_info_interface_type_info.native_type(),
538 WEBCORE_CLASS_NAME_ESCAPED=self._interface_type_info_interface_type_info.native_type().
539 replace('<', '_').replace('>', '_'),
540 DECLARATIONS=self._cpp_declarations_emitter.Fragments(),
541 IS_NODE=TypeCheckHelper(is_node_test),
542 IS_ACTIVE=TypeCheckHelper(is_active_test),
543 IS_EVENT_TARGET=TypeCheckHelper(is_event_target_test),
544 TO_NODE=to_node_emitter.Fragments(),
545 TO_ACTIVE=to_active_emitter.Fragments(),
546 TO_EVENT_TARGET=to_event_target_emitter.Fragments(),
547 TO_NATIVE=to_native_emitter.Fragments(),
548 TO_DART=to_dart_emitter.Fragments())
549
550 def EmitAttribute(self, attribute, html_name, read_only):
551 self._AddGetter(attribute, html_name, read_only)
552 if not read_only:
553 self._AddSetter(attribute, html_name)
554
555 def _GenerateAutoSetupScope(self, idl_name, native_suffix):
556 return None
557
558 def _AddGetter(self, attr, html_name, read_only):
559 # Temporary hack to force dart:scalarlist clamped array for ImageData.data.
560 # TODO(antonm): solve in principled way.
561 if self._interface_interface.id == 'ImageData' and html_name == 'data':
562 html_name = '_data'
563 type_info = self._TypeInfo(attr.type.id)
564
565 return_type = self.SecureOutputType(
566 attr.type.id, False, False if self._dart_use_blink else True)
567 dictionary_returned = False
568 # Return type for dictionary is any (untyped).
569 if attr.type.id == 'Dictionary':
570 return_type = ''
571 dictionary_returned = True
572
573 parameters = []
574 dart_declaration = '%s get %s' % (return_type, html_name)
575 is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
576 _IsCustomValue(attr, 'Getter'))
577
578 # Operation uses blink?
579 wrap_unwrap_list = []
580 return_wrap_jso = False
581 if self._dart_use_blink:
582 # Unwrap the type to get the JsObject if Type is:
583 #
584 # - known IDL type
585 # - type_id is None then it's probably a union type or overloaded
586 # it's a dynamic/any type
587 # - type is Object
588 #
589 # JsObject maybe stored in the Dart class.
590 return_wrap_jso = wrap_return_type_blink(return_type, attr.type.id,
592 wrap_unwrap_list.append(return_wrap_jso) # wrap_jso the returned object
593 wrap_unwrap_list.append(self._dart_use_blink)
594
595 # This seems to have been replaced with Custom=Getter (see above), but
596 # check to be sure we don't see the old syntax
597 assert (not ('CustomGetter' in attr.ext_attrs))
598 native_suffix = 'Getter'
599 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
600 native_entry = \
601 self.DeriveNativeEntry(attr.id, 'Getter', None)
602 output_conversion = self._OutputConversion(attr.type.id, attr.id)
603
604 cpp_callback_name = self._GenerateNativeBinding(
605 attr.id,
606 1,
607 dart_declaration,
608 attr.is_static,
609 return_type,
610 parameters,
611 native_suffix,
612 is_custom,
613 auto_scope_setup,
614 native_entry=native_entry,
615 wrap_unwrap_list=wrap_unwrap_list,
616 dictionary_return=dictionary_returned,
617 output_conversion=output_conversion)
618 if is_custom:
619 return
620
621 if 'Reflect' in attr.ext_attrs:
622 webcore_function_name = self._TypeInfo(
623 attr.type.id).webcore_getter_name()
624 if 'URL' in attr.ext_attrs:
625 if 'NonEmpty' in attr.ext_attrs:
626 webcore_function_name = 'getNonEmptyURLAttribute'
627 else:
628 webcore_function_name = 'getURLAttribute'
629 elif 'ImplementedAs' in attr.ext_attrs:
630 webcore_function_name = attr.ext_attrs['ImplementedAs']
631 else:
632 if attr.id == 'operator':
633 webcore_function_name = '_operator'
634 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
635 webcore_function_name = 'svgTarget'
636 elif attr.id == 'CSS':
637 webcore_function_name = 'css'
638 else:
639 webcore_function_name = self._ToWebKitName(attr.id)
640
641 function_expression = self._GenerateWebCoreFunctionExpression(
642 webcore_function_name, attr)
643 raises = ('RaisesException' in attr.ext_attrs and
644 attr.ext_attrs['RaisesException'] != 'Setter')
645
646 def _AddSetter(self, attr, html_name):
647 return_type = 'void'
648 ptype = self._DartType(attr.type.id)
649
650 type_info = self._TypeInfo(attr.type.id)
651
652 # Is the setter value a DartClass (that has a JsObject) or the type is
653 # None (it's a dynamic/any type) then unwrap_jso before passing to blink.
654 parameters = ['value']
655
656 dart_declaration = 'set %s(%s value)' % (html_name, ptype)
657 is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
658 _IsCustomValue(attr, 'Setter'))
659 # This seems to have been replaced with Custom=Setter (see above), but
660 # check to be sure we don't see the old syntax
661 assert (not ('CustomSetter' in attr.ext_attrs))
662 assert (not ('V8CustomSetter' in attr.ext_attrs))
663 native_suffix = 'Setter'
664 auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
665 native_entry = \
666 self.DeriveNativeEntry(attr.id, 'Setter', None)
667
668 # setters return no object and if blink this must be unwrapped.?
669 wrap_unwrap_list = [False, self._dart_use_blink]
670
671 cpp_callback_name = self._GenerateNativeBinding(
672 attr.id,
673 2,
674 dart_declaration,
675 attr.is_static,
676 return_type,
677 parameters,
678 native_suffix,
679 is_custom,
680 auto_scope_setup,
681 native_entry=native_entry,
682 wrap_unwrap_list=wrap_unwrap_list)
683 if is_custom:
684 return
685
686 if 'Reflect' in attr.ext_attrs:
687 webcore_function_name = self._TypeInfo(
688 attr.type.id).webcore_setter_name()
689 else:
690 if 'ImplementedAs' in attr.ext_attrs:
691 attr_name = attr.ext_attrs['ImplementedAs']
692 else:
693 attr_name = attr.id
694 webcore_function_name = re.sub(r'^(xml|css|(?=[A-Z])|\w)',
695 lambda s: s.group(1).upper(),
696 attr_name)
697 webcore_function_name = 'set%s' % webcore_function_name
698
699 function_expression = self._GenerateWebCoreFunctionExpression(
700 webcore_function_name, attr)
701 raises = ('RaisesException' in attr.ext_attrs and
702 attr.ext_attrs['RaisesException'] != 'Getter')
703
704 def AddIndexer(self, element_type, nullable):
705 """Adds all the methods required to complete implementation of List."""
706 # We would like to simply inherit the implementation of everything except
707 # length, [], and maybe []=. It is possible to extend from a base
708 # array implementation class only when there is no other implementation
709 # inheritance. There might be no implementation inheritance other than
710 # DOMBaseWrapper for many classes, but there might be some where the
711 # array-ness is introduced by a non-root interface:
712 #
713 # interface Y extends X, List<T> ...
714 #
715 # In the non-root case we have to choose between:
716 #
717 # class YImpl extends XImpl { add List<T> methods; }
718 #
719 # and
720 #
721 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
722 #
723 dart_element_type = self._DartType(element_type)
724 if self._HasNativeIndexGetter():
725 self._EmitNativeIndexGetter(dart_element_type)
726 elif self._HasExplicitIndexedGetter():
727 self._EmitExplicitIndexedGetter(dart_element_type)
728 else:
729 is_custom = any((op.id == 'item' and _IsCustom(op))
730 for op in self._interface_interface.operations)
731
732 output_conversion = self._OutputConversion(element_type, 'item')
733 conversion_name = ''
734 if output_conversion:
735 conversion_name = output_conversion.function_name
736
737 # First emit a toplevel function to do the native call
738 # Calls to this are emitted elsewhere,
739 dart_native_name, resolver_string = \
740 self.DeriveNativeEntry("item", 'Method', 1)
741
742 # Emit the method which calls the toplevel function, along with
743 # the [] operator.
744 dart_qualified_name = \
746 dart_native_name)
747
748 type_info = self._TypeInfo(element_type)
749 blinkNativeIndexed = """
750 $TYPE operator[](int index) {
751 if (index < 0 || index >= length)
752 throw new IndexError.withLength(index, length, indexable: this);
753 return _nativeIndexedGetter(index);
754 }
755
756 $TYPE _nativeIndexedGetter(int index) => $(CONVERSION_NAME)($(DART_NATIVE_NAME)(this, index));
757"""
758 blinkNativeIndexedGetter = \
759 ' $(DART_NATIVE_NAME)(this, index);\n'
760 self._members_emitter.Emit(
761 blinkNativeIndexed,
762 DART_NATIVE_NAME=dart_qualified_name,
763 TYPE=self.SecureOutputType(element_type),
764 INTERFACE=self._interface_interface.id,
765 CONVERSION_NAME=conversion_name)
766
767 if self._HasNativeIndexSetter():
768 self._EmitNativeIndexSetter(dart_element_type)
769 else:
770 self._members_emitter.Emit(
771 '\n'
772 ' void operator[]=(int index, $TYPE value) {\n'
773 ' throw new UnsupportedError("Cannot assign element of immutable List.");\n'
774 ' }\n',
775 TYPE=dart_element_type)
776
777 self.EmitListMixin(dart_element_type, nullable)
778
779 def AmendIndexer(self, element_type):
780 # If interface is marked as having native indexed
781 # getter or setter, we must emit overrides as it's not
782 # guaranteed that the corresponding methods in C++ would be
783 # virtual. For example, as of time of writing, even though
784 # Uint8ClampedArray inherits from Uint8Array, ::set method
785 # is not virtual and accessing it through Uint8Array pointer
786 # would lead to wrong semantics (modulo vs. clamping.)
787 dart_element_type = self._DartType(element_type)
788
789 if self._HasNativeIndexGetter():
790 self._EmitNativeIndexGetter(dart_element_type)
791 if self._HasNativeIndexSetter():
792 self._EmitNativeIndexSetter(dart_element_type)
793
794 def _HasNativeIndexGetter(self):
795 return 'CustomIndexedGetter' in self._interface_interface.ext_attrs
796
797 def _EmitNativeIndexGetter(self, element_type):
798 return_type = self.SecureOutputType(element_type, True)
799 parameters = ['index']
800 dart_declaration = '%s operator[](int index)' % return_type
801 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
802 False, return_type, parameters, 'Callback',
803 True, False)
804
805 def _HasExplicitIndexedGetter(self):
806 return any(op.id == 'getItem' for op in self._interface_interface.operations)
807
808 def _EmitExplicitIndexedGetter(self, dart_element_type):
809 if any(op.id == 'getItem' for op in self._interface_interface.operations):
810 indexed_getter = 'getItem'
811
812 self._members_emitter.Emit(
813 '\n'
814 ' $TYPE operator[](int index) {\n'
815 ' if (index < 0 || index >= length)\n'
816 ' throw new IndexError.withLength(index, length, indexable: this);\n'
817 ' return $INDEXED_GETTER(index);\n'
818 ' }\n',
819 TYPE=dart_element_type,
820 INDEXED_GETTER=indexed_getter)
821
822 def _HasNativeIndexSetter(self):
823 return 'CustomIndexedSetter' in self._interface_interface.ext_attrs
824
825 def _EmitNativeIndexSetter(self, element_type):
826 return_type = 'void'
827 formals = ', '.join(['int index', '%s value' % element_type])
828 parameters = ['index', 'value']
829 dart_declaration = 'void operator[]=(%s)' % formals
830 self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
831 False, return_type, parameters, 'Callback',
832 True, False)
833
834 def _ChangePrivateOpMapArgToAny(self, operations):
835 # TODO(terry): Hack to map any operations marked as private to not
836 # handle converting Map to native (JsObject) the public
837 # members that call the private method will have done
838 # conversions.
839 for operation in operations:
840 for arg in operation.arguments:
841 type = arg.type
842 if type.id == 'Dictionary':
843 type.id = 'any'
844
845 def EmitOperation(self, info, html_name, dart_js_interop=False):
846 """
847 Arguments:
848 info: An OperationInfo object.
849 """
850 if self._renamer.isPrivate(self._interface_interface, info.operations[0].id):
851 # Any private operations with Maps parameters changed to any type.
852 # The public method that delegates to this private operation has already
853 # converted from Map to native (JsObject) e.g., Element.animate.
854 self._ChangePrivateOpMapArgToAny(info.operations)
855
856 return_type = self.SecureOutputType(info.type_name, False,
857 False if dart_js_interop else True)
858
859 formals = info.ParametersAsDeclaration(self._DartType)
860
861 parameters = info.ParametersAsListOfVariables(
862 None, self._type_registry_type_registry if self._dart_use_blink else None,
863 dart_js_interop, self)
864
865 operation = info.operations[0]
866
867 output_conversion = self._OutputConversion(operation.type.id,
868 operation.id)
869
870 dictionary_returned = False
871 # Return type for dictionary is any (untyped).
872 if operation.type.id == 'Dictionary':
873 return_type = ''
874 dictionary_returned = True
875
876 dart_declaration = '%s%s %s(%s)' % ('static ' if info.IsStatic() else
877 '', return_type, html_name, formals)
878
879 is_custom = _IsCustom(operation)
880 has_optional_arguments = any(
881 IsOptional(argument) for argument in operation.arguments)
882 needs_dispatcher = not is_custom and (len(info.operations) > 1 or
883 has_optional_arguments)
884
885 # Operation uses blink?
886 wrap_unwrap_list = []
887 return_wrap_jso = False
888 # return type wrapped?
889 if self._dart_use_blink:
890 # Wrap the type to store the JsObject if Type is:
891 #
892 # it's a dynamic/any type
893 # - type is Object
894 #
895 # JsObject maybe stored in the Dart class.
896 return_wrap_jso = wrap_return_type_blink(
897 return_type, info.type_name, self._type_registry_type_registry)
898 return_type_info = self._type_registry_type_registry.TypeInfo(info.type_name)
899 # wrap_jso the returned object
900 wrap_unwrap_list.append(return_wrap_jso)
901 wrap_unwrap_list.append(self._dart_use_blink)
902
903 if info.callback_args:
904 self._AddFutureifiedOperation(info, html_name)
905 elif not needs_dispatcher:
906 # Bind directly to native implementation
907 argument_count = (0 if info.IsStatic() else 1) + len(
908 info.param_infos)
909 native_suffix = 'Callback'
910 auto_scope_setup = self._GenerateAutoSetupScope(
911 info.name, native_suffix)
912 native_entry = \
913 self.DeriveNativeEntry(operation.id, 'Method', len(info.param_infos))
914 cpp_callback_name = self._GenerateNativeBinding(
915 info.name,
916 argument_count,
917 dart_declaration,
918 info.IsStatic(),
919 return_type,
920 parameters,
921 native_suffix,
922 is_custom,
923 auto_scope_setup,
924 native_entry=native_entry,
925 wrap_unwrap_list=wrap_unwrap_list,
926 dictionary_return=dictionary_returned,
927 output_conversion=output_conversion)
928 if not is_custom:
930 operation, operation.arguments, cpp_callback_name,
931 auto_scope_setup)
932 else:
933 self._GenerateDispatcher(info, info.operations, dart_declaration,
934 html_name)
935
936 def _GenerateDispatcher(self, info, operations, dart_declaration,
937 html_name):
938
939 def GenerateCall(stmts_emitter, call_emitter, version, operation,
940 argument_count):
941 native_suffix = 'Callback'
942 actuals = info.ParametersAsListOfVariables(
943 argument_count,
944 self._type_registry_type_registry if self._dart_use_blink else None,
945 self._dart_js_interop, self)
946 actuals_s = ", ".join(actuals)
947 formals = actuals
948 return_type = self.SecureOutputType(operation.type.id)
949
950 return_wrap_jso = False
951 if self._dart_use_blink:
952 return_wrap_jso = wrap_return_type_blink(
953 return_type, info.type_name, self._type_registry_type_registry)
954
955 native_suffix = 'Callback'
956 is_custom = _IsCustom(operation)
957 base_name = '_%s_%s' % (operation.id, version)
958 static = True
959 if not operation.is_static:
960 actuals = ['this'] + actuals
961 formals = ['mthis'] + formals
962 actuals_s = ", ".join(actuals)
963 formals_s = ", ".join(formals)
964 dart_declaration = '%s(%s)' % (base_name, formals_s)
965 native_entry = \
966 self.DeriveNativeEntry(operation.id, 'Method', argument_count)
967 overload_base_name = native_entry[0]
968 overload_name = \
970 overload_base_name)
971 call_emitter.Emit(
972 '$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s)
973 auto_scope_setup = \
974 self._GenerateAutoSetupScope(base_name, native_suffix)
975 cpp_callback_name = self._GenerateNativeBinding(
976 base_name, (0 if static else 1) + argument_count,
977 dart_declaration,
978 static,
979 return_type,
980 formals,
981 native_suffix,
982 is_custom,
983 auto_scope_setup,
984 emit_metadata=False,
985 emit_to_native=True,
986 native_entry=native_entry)
987 if not is_custom:
989 operation, operation.arguments[:argument_count],
990 cpp_callback_name, auto_scope_setup)
991
992 self._GenerateDispatcherBody(info, operations, dart_declaration,
993 GenerateCall, IsOptional)
994
995 def SecondaryContext(self, interface):
996 pass
997
998 def _GenerateOperationNativeCallback(self,
999 operation,
1000 arguments,
1001 cpp_callback_name,
1002 auto_scope_setup=True):
1003 webcore_function_name = operation.ext_attrs.get('ImplementedAs',
1004 operation.id)
1005
1006 function_expression = self._GenerateWebCoreFunctionExpression(
1007 webcore_function_name, operation, cpp_callback_name)
1008
1009 def _GenerateNativeBinding(self,
1010 idl_name,
1011 argument_count,
1012 dart_declaration,
1013 static,
1014 return_type,
1015 parameters,
1016 native_suffix,
1017 is_custom,
1018 auto_scope_setup=True,
1019 emit_metadata=True,
1020 emit_to_native=False,
1021 native_entry=None,
1022 wrap_unwrap_list=[],
1023 dictionary_return=False,
1024 output_conversion=None):
1025 metadata = []
1026 if emit_metadata:
1027 metadata = self._metadata.GetFormattedMetadata(
1028 self._renamer.GetLibraryName(self._interface), self._interface,
1029 idl_name, ' ')
1030
1031 if (native_entry):
1032 dart_native_name, native_binding = native_entry
1033 else:
1034 dart_native_name = \
1035 self.DeriveNativeName(idl_name, native_suffix)
1036 native_binding_id = self._interface.id
1037 native_binding_id = TypeIdToBlinkName(native_binding_id,
1038 self._database)
1039 native_binding = \
1040 '%s_%s_%s' % (native_binding_id, idl_name, native_suffix)
1041
1042 if not static:
1043 formals = ", ".join(['mthis'] + parameters)
1044 actuals = ", ".join(['this'] + parameters)
1045 else:
1046 formals = ", ".join(parameters)
1047 actuals = ", ".join(parameters)
1048
1049 if not emit_to_native:
1050 caller_emitter = self._members_emitter
1051 full_dart_name = \
1052 self.DeriveQualifiedBlinkName(self._interface.id,
1053 dart_native_name)
1054 if IsPureInterface(self._interface.id, self._database):
1055 caller_emitter.Emit('\n'
1056 ' $METADATA$DART_DECLARATION;\n',
1057 METADATA=metadata,
1058 DART_DECLARATION=dart_declaration)
1059 else:
1060 emit_template = '''
1061 $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);
1062 '''
1063 if output_conversion and not dictionary_return:
1064 conversion_template = '''
1065 $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
1066 '''
1067 emit_template = conversion_template % output_conversion.function_name
1068
1069 elif wrap_unwrap_list and wrap_unwrap_list[0]:
1070 if return_type == 'Rectangle':
1071 jso_util_method = 'make_dart_rectangle'
1072 elif wrap_unwrap_list[0]:
1073 jso_util_method = ''
1074
1075 if dictionary_return:
1076 emit_jso_template = '''
1077 $METADATA$DART_DECLARATION => convertNativeDictionaryToDartDictionary(%s($DART_NAME($ACTUALS)));
1078 '''
1079 else:
1080 emit_jso_template = '''
1081 $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
1082 '''
1083 emit_template = emit_jso_template % jso_util_method
1084
1085 if caller_emitter:
1086 caller_emitter.Emit(
1087 emit_template,
1088 METADATA=metadata,
1089 DART_DECLARATION=dart_declaration,
1090 DART_NAME=full_dart_name,
1091 ACTUALS=actuals)
1092 cpp_callback_name = '%s%s' % (idl_name, native_suffix)
1093
1094 self._cpp_resolver_emitter.Emit(
1095 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING") {\n'
1096 ' *autoSetupScope = $AUTO_SCOPE_SETUP;\n'
1097 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n'
1098 ' }\n',
1099 ARGC=argument_count,
1100 NATIVE_BINDING=native_binding,
1101 INTERFACE_NAME=self._interface.id,
1102 AUTO_SCOPE_SETUP='true' if auto_scope_setup else 'false',
1103 CPP_CALLBACK_NAME=cpp_callback_name)
1104
1105 if is_custom:
1106 self._cpp_declarations_emitter.Emit(
1107 '\n'
1108 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n',
1109 CPP_CALLBACK_NAME=cpp_callback_name)
1110
1111 return cpp_callback_name
1112
1113 def _GenerateWebCoreReflectionAttributeName(self, attr):
1114 namespace = 'HTMLNames'
1115 svg_exceptions = [
1116 'class', 'id', 'onabort', 'onclick', 'onerror', 'onload',
1117 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
1118 'onmouseup', 'onresize', 'onscroll', 'onunload'
1119 ]
1120 if self._interface.id.startswith(
1121 'SVG') and not attr.id in svg_exceptions:
1122 namespace = 'SVGNames'
1123 self._cpp_impl_includes.add('"%s.h"' % namespace)
1124
1125 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower()
1126 return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
1127
1128 def _IsStatic(self, attribute_name):
1129 return False
1130
1131 def _GenerateWebCoreFunctionExpression(self,
1132 function_name,
1133 idl_node,
1134 cpp_callback_name=None):
1135 return None
1136
1137 def _IsArgumentOptionalInWebCore(self, operation, argument):
1138 if not IsOptional(argument):
1139 return False
1140 if 'Callback' in argument.ext_attrs:
1141 return False
1142 if operation.id in ['addEventListener', 'removeEventListener'
1143 ] and argument.id == 'useCapture':
1144 return False
1145 if 'DartForceOptional' in argument.ext_attrs:
1146 return False
1147 if argument.type.id == 'Dictionary':
1148 return False
1149 return True
1150
1151 def _GenerateCPPIncludes(self, includes):
1152 return None
1153
1154 def _ToWebKitName(self, name):
1155 name = name[0].lower() + name[1:]
1156 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(),
1157 name)
1158 return re.sub(r'^(create|exclusive)',
1159 lambda s: 'is' + s.group(1).capitalize(), name)
1160
1161
1163
1164 def __init__(self, emitters, cpp_sources_dir):
1165 self._emitters = emitters
1166 self._cpp_sources_dir = cpp_sources_dir
1167 self._library_headers = dict((lib, []) for lib in HTML_LIBRARY_NAMES)
1168 self._sources_list = []
1169
1171 interface_name,
1172 library_name,
1173 is_callback=False):
1174 path = os.path.join(self._cpp_sources_dir, 'Dart%s.h' % interface_name)
1175 if not is_callback:
1176 self._library_headers[library_name].append(path)
1177 return self._emitters.FileEmitter(path)
1178
1179 def CreateSourceEmitter(self, interface_name):
1180 path = os.path.join(self._cpp_sources_dir,
1181 'Dart%s.cpp' % interface_name)
1182 self._sources_list.append(path)
1183 return self._emitters.FileEmitter(path)
1184
1185 def EmitDerivedSources(self, template, output_dir):
1186 partitions = 20 # FIXME: this should be configurable.
1187 sources_count = len(self._sources_list)
1188 for i in range(0, partitions):
1189 file_path = os.path.join(output_dir,
1190 'DartDerivedSources%02i.cpp' % (i + 1))
1191 includes_emitter = self._emitters.FileEmitter(file_path).Emit(
1192 template)
1193 for source_file in self._sources_list[i::partitions]:
1194 path = os.path.relpath(source_file, output_dir)
1195 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
1196
1197 def EmitResolver(self, template, output_dir):
1198 for library_name in self._library_headers.keys():
1199 file_path = os.path.join(output_dir,
1200 '%s_DartResolver.cpp' % library_name)
1201 includes_emitter, body_emitter = self._emitters.FileEmitter(
1202 file_path).Emit(
1203 template, LIBRARY_NAME=library_name)
1204
1205 headers = self._library_headers[library_name]
1206 for header_file in headers:
1207 path = os.path.relpath(header_file, output_dir)
1208 includes_emitter.Emit('#include "$PATH"\n', PATH=path)
1209 body_emitter.Emit(
1210 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount, autoSetupScope))\n'
1211 ' return func;\n',
1212 CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
1213
1214 def EmitClassIdTable(self, database, output_dir, type_registry, renamer):
1215
1216 def HasConverters(interface):
1217 is_node_test = lambda interface: interface.id == 'Node'
1218 is_active_test = lambda interface: 'ActiveDOMObject' in interface.ext_attrs
1219 is_event_target_test = lambda interface: 'EventTarget' in interface.ext_attrs
1220
1221 return (
1222 any(map(is_node_test, database.Hierarchy(interface))) or
1223 any(map(is_active_test, database.Hierarchy(interface))) or
1224 any(map(is_event_target_test, database.Hierarchy(interface))))
1225
1226 path = os.path.join(output_dir, 'DartWebkitClassIds.h')
1227 e = self._emitters.FileEmitter(path)
1228 e.Emit(
1229 '// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file\n'
1230 )
1231 e.Emit(
1232 '// for details. All rights reserved. Use of this source code is governed by a\n'
1233 )
1234 e.Emit('// BSD-style license that can be found in the LICENSE file.\n')
1235 e.Emit('// WARNING: Do not edit - generated code.\n')
1236 e.Emit('// See dart/tools/dom/scripts/systemnative.py\n')
1237 e.Emit('\n')
1238 e.Emit('#ifndef DartWebkitClassIds_h\n')
1239 e.Emit('#define DartWebkitClassIds_h\n')
1240 e.Emit('\n')
1241 e.Emit('namespace WebCore {\n')
1242 e.Emit('\n')
1243 e.Emit('enum {\n')
1244 e.Emit(' _InvalidClassId = 0,\n')
1245 e.Emit(' _HistoryCrossFrameClassId,\n')
1246 e.Emit(' _LocationCrossFrameClassId,\n')
1247 e.Emit(' _DOMWindowCrossFrameClassId,\n')
1248 e.Emit(' _DateTimeClassId,\n')
1249 e.Emit(' _JsObjectClassId,\n')
1250 e.Emit(' _JsFunctionClassId,\n')
1251 e.Emit(' _JsArrayClassId,\n')
1252 e.Emit(
1253 ' // New types that are not auto-generated should be added here.\n'
1254 )
1255 e.Emit('\n')
1256 for interface in database.GetInterfaces():
1257 e.Emit(' %sClassId,\n' % interface.id)
1258 e.Emit(' NumWebkitClassIds\n')
1259 e.Emit('};\n')
1260 e.Emit(
1261 'class ActiveDOMObject;\n'
1262 'class EventTarget;\n'
1263 'class Node;\n'
1264 'typedef ActiveDOMObject* (*ToActiveDOMObject)(void* value);\n'
1265 'typedef EventTarget* (*ToEventTarget)(void* value);\n'
1266 'typedef Node* (*ToNode)(void* value);\n'
1267 'typedef struct {\n'
1268 ' const char* class_name;\n'
1269 ' int library_id;\n'
1270 ' int base_class_id;\n'
1271 ' ToActiveDOMObject toActiveDOMObject;\n'
1272 ' ToEventTarget toEventTarget;\n'
1273 ' ToNode toNode;\n'
1274 '} DartWrapperTypeInfo;\n'
1275 'typedef DartWrapperTypeInfo _DartWebkitClassInfo[NumWebkitClassIds];\n'
1276 '\n'
1277 'extern _DartWebkitClassInfo DartWebkitClassInfo;\n'
1278 '\n'
1279 '} // namespace WebCore\n'
1280 '#endif // DartWebkitClassIds_h\n')
1281
1282 path = os.path.join(output_dir, 'DartWebkitClassIds.cpp')
1283 e = self._emitters.FileEmitter(path)
1284 e.Emit(
1285 '// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file\n'
1286 )
1287 e.Emit(
1288 '// for details. All rights reserved. Use of this source code is governed by a\n'
1289 )
1290 e.Emit('// BSD-style license that can be found in the LICENSE file.\n')
1291 e.Emit('// WARNING: Do not edit - generated code.\n')
1292 e.Emit('// See dart/tools/dom/scripts/systemnative.py\n')
1293 e.Emit('\n')
1294 e.Emit('#include "config.h"\n')
1295 e.Emit('#include "DartWebkitClassIds.h"\n')
1296 e.Emit('\n')
1297 e.Emit('#include "bindings/dart/DartLibraryIds.h"\n')
1298 for interface in database.GetInterfaces():
1299 if HasConverters(interface):
1300 e.Emit('#include "Dart%s.h"\n' % interface.id)
1301 e.Emit('\n')
1302
1303 e.Emit('namespace WebCore {\n')
1304
1305 e.Emit('\n')
1306
1307 e.Emit(
1308 'ActiveDOMObject* toNullActiveDOMObject(void* value) { return 0; }\n'
1309 )
1310 e.Emit('EventTarget* toNullEventTarget(void* value) { return 0; }\n')
1311 e.Emit('Node* toNullNode(void* value) { return 0; }\n')
1312
1313 e.Emit("_DartWebkitClassInfo DartWebkitClassInfo = {\n")
1314
1315 e.Emit(' {\n'
1316 ' "_InvalidClassId", -1, -1,\n'
1317 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1318 ' },\n')
1319 e.Emit(' {\n'
1320 ' "_HistoryCrossFrame", DartHtmlLibraryId, -1,\n'
1321 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1322 ' },\n')
1323 e.Emit(' {\n'
1324 ' "_LocationCrossFrame", DartHtmlLibraryId, -1,\n'
1325 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1326 ' },\n')
1327 e.Emit(' {\n'
1328 ' "_DOMWindowCrossFrame", DartHtmlLibraryId, -1,\n'
1329 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1330 ' },\n')
1331 e.Emit(' {\n'
1332 ' "DateTime", DartCoreLibraryId, -1,\n'
1333 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1334 ' },\n')
1335 e.Emit(' {\n'
1336 ' "JsObject", DartJsLibraryId, -1,\n'
1337 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1338 ' },\n')
1339 e.Emit(' {\n'
1340 ' "JsFunction", DartJsLibraryId, _JsObjectClassId,\n'
1341 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1342 ' },\n')
1343 e.Emit(' {\n'
1344 ' "JsArray", DartJsLibraryId, _JsObjectClassId,\n'
1345 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1346 ' },\n')
1347 e.Emit(
1348 ' // New types that are not auto-generated should be added here.\n'
1349 )
1350 for interface in database.GetInterfaces():
1351 name = interface.id
1352 type_info = type_registry.TypeInfo(name)
1353 type_info.native_type().replace('<', '_').replace('>', '_')
1354 e.Emit(' {\n')
1355 e.Emit(' "%s", ' % type_info.implementation_name())
1356 e.Emit('Dart%sLibraryId, ' % renamer.GetLibraryId(interface))
1357 if interface.parents:
1358 supertype = interface.parents[0].type.id
1359 e.Emit('%sClassId,\n' % supertype)
1360 else:
1361 e.Emit(' -1,\n')
1362 if HasConverters(interface):
1363 e.Emit(
1364 ' Dart%s::toActiveDOMObject, Dart%s::toEventTarget,'
1365 ' Dart%s::toNode\n' % (name, name, name))
1366 else:
1367 e.Emit(
1368 ' toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
1369 )
1370 e.Emit(' },\n')
1371
1372 e.Emit("};\n")
1373 e.Emit('\n')
1374 e.Emit('} // namespace WebCore\n')
1375
1376
1377def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument):
1378 return (interface.id.endswith('Event') and
1379 operation.id.startswith('init') and
1380 argument.default_value == 'Undefined' and
1381 argument.type.id == 'DOMString')
1382
1383
1384def _IsCustom(op_or_attr):
1385 assert (isinstance(op_or_attr, IDLMember))
1386 return 'Custom' in op_or_attr.ext_attrs or 'DartCustom' in op_or_attr.ext_attrs
1387
1388
1389def _IsCustomValue(op_or_attr, value):
1390 if _IsCustom(op_or_attr):
1391 return op_or_attr.ext_attrs.get('Custom') == value \
1392 or op_or_attr.ext_attrs.get('DartCustom') == value
1393 return False
GLenum type
def SecureOutputType(self, type_name, is_dart_type=False, can_narrow_type=False, nullable=False)
def _GenerateDispatcherBody(self, info, operations, declaration, generate_call, is_optional, can_omit_type_check=lambda type, False pos)
def EmitListMixin(self, element_name, nullable)
def _AddFutureifiedOperation(self, info, html_name)
def EmitDerivedSources(self, template, output_dir)
def CreateSourceEmitter(self, interface_name)
def CreateHeaderEmitter(self, interface_name, library_name, is_callback=False)
def EmitResolver(self, template, output_dir)
def __init__(self, emitters, cpp_sources_dir)
def EmitClassIdTable(self, database, output_dir, type_registry, renamer)
def GenerateCustomFactory(self, constructor_info)
def __init__(self, interface, cpp_library_emitter, options, loggerParent)
Definition: systemnative.py:91
def _EmitExplicitIndexedGetter(self, dart_element_type)
def _EmitConstructorInfrastructure(self, constructor_info, cpp_prefix, cpp_suffix, factory_method_name, arguments=None, emit_to_native=False, is_custom=False)
def _OutputConversion(self, idl_type, member)
def _GenerateAutoSetupScope(self, idl_name, native_suffix)
def EmitStaticFactoryOverload(self, constructor_info, name, arguments)
def _GenerateWebCoreFunctionExpression(self, function_name, idl_node, cpp_callback_name=None)
def _GenerateCPPIncludes(self, includes)
def _EmitNativeIndexSetter(self, element_type)
def DeriveNativeEntry(self, name, kind, count)
def _AddSetter(self, attr, html_name)
def _GenerateDispatcher(self, info, operations, dart_declaration, html_name)
def EmitOperation(self, info, html_name, dart_js_interop=False)
def _EmitNativeIndexGetter(self, element_type)
def MakeFactoryCall(self, factory, method, arguments, constructor_info)
def AddIndexer(self, element_type, nullable)
def _AddGetter(self, attr, html_name, read_only)
def _ChangePrivateOpMapArgToAny(self, operations)
def DeriveNativeName(self, name, suffix="")
def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, static, return_type, parameters, native_suffix, is_custom, auto_scope_setup=True, emit_metadata=True, emit_to_native=False, native_entry=None, wrap_unwrap_list=[], dictionary_return=False, output_conversion=None)
def _GenerateOperationNativeCallback(self, operation, arguments, cpp_callback_name, auto_scope_setup=True)
def EmitAttribute(self, attribute, html_name, read_only)
def DeriveQualifiedBlinkName(self, interface_name, name)
def SecondaryContext(self, interface)
def StartInterface(self, members_emitter)
def AmendIndexer(self, element_type)
def IsConstructorArgumentOptional(self, argument)
static void append(char **dst, size_t *count, const char *src, size_t n)
Definition: editor.cpp:211
struct MyStruct s
def DeriveQualifiedName(library_name, name)
Definition: systemnative.py:56
def array_type(data_type)
Definition: systemnative.py:28
def TypeIdToBlinkName(interface_id, database)
Definition: systemnative.py:38
def DeriveBlinkClassName(name)
Definition: systemnative.py:60
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741