OLD | NEW |
---|---|
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 generates Dart APIs from the IDL database.""" | 6 """This module generates Dart APIs from the IDL database.""" |
7 | 7 |
8 import emitter | 8 import emitter |
9 import idlnode | 9 import idlnode |
10 import logging | 10 import logging |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 # Dart templates | 278 # Dart templates |
279 parent_type_name = type_name[0 : dart_template_match.start(1) - 1] | 279 parent_type_name = type_name[0 : dart_template_match.start(1) - 1] |
280 sub_type_name = dart_template_match.group(1) | 280 sub_type_name = dart_template_match.group(1) |
281 return '%s<%s>' % (ConvertType(interface, parent_type_name), | 281 return '%s<%s>' % (ConvertType(interface, parent_type_name), |
282 ConvertType(interface, sub_type_name)) | 282 ConvertType(interface, sub_type_name)) |
283 | 283 |
284 return self._StripModules(type_name) | 284 return self._StripModules(type_name) |
285 | 285 |
286 for interface in database.GetInterfaces(): | 286 for interface in database.GetInterfaces(): |
287 for idl_type in interface.all(idlnode.IDLType): | 287 for idl_type in interface.all(idlnode.IDLType): |
288 original_type_name = idl_type.id | |
288 idl_type.id = ConvertType(interface, idl_type.id) | 289 idl_type.id = ConvertType(interface, idl_type.id) |
290 # FIXME: remember original idl types that are needed by native | |
291 # generator. We should migrate other generators to idl registry and | |
292 # remove this hack. | |
293 if original_type_name != idl_type.id: | |
294 _original_idl_types[idl_type] = original_type_name | |
289 | 295 |
290 def FilterInterfaces(self, database, | 296 def FilterInterfaces(self, database, |
291 and_annotations=[], | 297 and_annotations=[], |
292 or_annotations=[], | 298 or_annotations=[], |
293 exclude_displaced=[], | 299 exclude_displaced=[], |
294 exclude_suppressed=[]): | 300 exclude_suppressed=[]): |
295 """Filters a database to remove interfaces and members that are missing | 301 """Filters a database to remove interfaces and members that are missing |
296 annotations. | 302 annotations. |
297 | 303 |
298 The FremontCut IDLs use annotations to specify implementation | 304 The FremontCut IDLs use annotations to specify implementation |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 self._systems.append(html_system) | 438 self._systems.append(html_system) |
433 | 439 |
434 if 'htmldartium' in systems: | 440 if 'htmldartium' in systems: |
435 html_system = HtmlDartiumSystem( | 441 html_system = HtmlDartiumSystem( |
436 TemplateLoader(self._template_dir, ['html/dartium', 'html', '']), | 442 TemplateLoader(self._template_dir, ['html/dartium', 'html', '']), |
437 self._database, self._emitters, self._output_dir) | 443 self._database, self._emitters, self._output_dir) |
438 | 444 |
439 html_system._interface_system = html_interface_system | 445 html_system._interface_system = html_interface_system |
440 self._systems.append(html_system) | 446 self._systems.append(html_system) |
441 | 447 |
442 | |
443 # Collect interfaces | 448 # Collect interfaces |
444 interfaces = [] | 449 interfaces = [] |
445 for interface in database.GetInterfaces(): | 450 for interface in database.GetInterfaces(): |
446 if not _MatchSourceFilter(source_filter, interface): | 451 if not _MatchSourceFilter(source_filter, interface): |
447 # Skip this interface since it's not present in the required source | 452 # Skip this interface since it's not present in the required source |
448 _logger.info('Omitting interface - %s' % interface.id) | 453 _logger.info('Omitting interface - %s' % interface.id) |
449 continue | 454 continue |
450 interfaces.append(interface) | 455 interfaces.append(interface) |
451 | 456 |
452 # TODO(sra): Use this list of exception names to generate information to | 457 # TODO(sra): Use this list of exception names to generate information to |
(...skipping 13 matching lines...) Expand all Loading... | |
466 super_database.HasInterface(super_name)): | 471 super_database.HasInterface(super_name)): |
467 super_interface = super_name | 472 super_interface = super_name |
468 | 473 |
469 interface_name = interface.id | 474 interface_name = interface.id |
470 auxiliary_file = self._auxiliary_files.get(interface_name) | 475 auxiliary_file = self._auxiliary_files.get(interface_name) |
471 if auxiliary_file is not None: | 476 if auxiliary_file is not None: |
472 _logger.info('Skipping %s because %s exists' % ( | 477 _logger.info('Skipping %s because %s exists' % ( |
473 interface_name, auxiliary_file)) | 478 interface_name, auxiliary_file)) |
474 continue | 479 continue |
475 | 480 |
476 | |
477 info = _RecognizeCallback(interface) | 481 info = _RecognizeCallback(interface) |
478 if info: | 482 if info: |
479 for system in self._systems: | 483 for system in self._systems: |
480 system.ProcessCallback(interface, info) | 484 system.ProcessCallback(interface, info) |
481 else: | 485 else: |
482 if 'Callback' in interface.ext_attrs: | 486 if 'Callback' in interface.ext_attrs: |
483 _logger.info('Malformed callback: %s' % interface.id) | 487 _logger.info('Malformed callback: %s' % interface.id) |
484 self._ProcessInterface(interface, super_interface, | 488 self._ProcessInterface(interface, super_interface, |
485 source_filter, common_prefix) | 489 source_filter, common_prefix) |
486 | 490 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 source_filter, | 522 source_filter, |
519 common_prefix): | 523 common_prefix): |
520 """.""" | 524 """.""" |
521 _logger.info('Generating %s' % interface.id) | 525 _logger.info('Generating %s' % interface.id) |
522 | 526 |
523 generators = [system.InterfaceGenerator(interface, | 527 generators = [system.InterfaceGenerator(interface, |
524 common_prefix, | 528 common_prefix, |
525 super_interface_name, | 529 super_interface_name, |
526 source_filter) | 530 source_filter) |
527 for system in self._systems] | 531 for system in self._systems] |
532 generators = filter(lambda x: x, generators) | |
antonm
2012/02/14 14:18:22
filter(None, generators) should do to. Up to you
podivilov
2012/02/14 17:47:58
Done.
| |
528 | 533 |
529 for generator in generators: | 534 for generator in generators: |
530 generator.StartInterface() | 535 generator.StartInterface() |
531 | 536 |
532 for const in sorted(interface.constants, ConstantOutputOrder): | 537 for const in sorted(interface.constants, ConstantOutputOrder): |
533 for generator in generators: | 538 for generator in generators: |
534 generator.AddConstant(const) | 539 generator.AddConstant(const) |
535 | 540 |
536 attributes = [attr for attr in interface.attributes | 541 attributes = [attr for attr in interface.attributes |
537 if not self._IsEventAttribute(interface, attr)] | 542 if not self._IsEventAttribute(interface, attr)] |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 """Returns a list of (getter, setter) pairs sorted by name. | 699 """Returns a list of (getter, setter) pairs sorted by name. |
695 | 700 |
696 One element of the pair may be None. | 701 One element of the pair may be None. |
697 """ | 702 """ |
698 names = sorted(set(attr.id for attr in attributes)) | 703 names = sorted(set(attr.id for attr in attributes)) |
699 getters = {} | 704 getters = {} |
700 setters = {} | 705 setters = {} |
701 for attr in attributes: | 706 for attr in attributes: |
702 if attr.is_fc_getter: | 707 if attr.is_fc_getter: |
703 getters[attr.id] = attr | 708 getters[attr.id] = attr |
704 elif attr.is_fc_setter: | 709 elif attr.is_fc_setter and 'Replaceable' not in attr.ext_attrs: |
705 setters[attr.id] = attr | 710 setters[attr.id] = attr |
706 return [(getters.get(id), setters.get(id)) for id in names] | 711 return [(getters.get(id), setters.get(id)) for id in names] |
707 | 712 |
708 | 713 |
709 def _FindMatchingAttribute(interface, attr1): | 714 def _FindMatchingAttribute(interface, attr1): |
710 matches = [attr2 for attr2 in interface.attributes | 715 matches = [attr2 for attr2 in interface.attributes |
711 if attr1.id == attr2.id | 716 if attr1.id == attr2.id |
712 and attr1.is_fc_getter == attr2.is_fc_getter | 717 and attr1.is_fc_getter == attr2.is_fc_getter |
713 and attr1.is_fc_setter == attr2.is_fc_setter] | 718 and attr1.is_fc_setter == attr2.is_fc_setter] |
714 if matches: | 719 if matches: |
(...skipping 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2268 for getter, setter in event_attrs: | 2273 for getter, setter in event_attrs: |
2269 event = getter or setter | 2274 event = getter or setter |
2270 events_members.Emit( | 2275 events_members.Emit( |
2271 "\n" | 2276 "\n" |
2272 "EventListenerList get $NAME() => _get('$NAME');\n", | 2277 "EventListenerList get $NAME() => _get('$NAME');\n", |
2273 NAME=event.id) | 2278 NAME=event.id) |
2274 | 2279 |
2275 | 2280 |
2276 # ------------------------------------------------------------------------------ | 2281 # ------------------------------------------------------------------------------ |
2277 | 2282 |
2283 class IDLTypeInfo(object): | |
2284 def __init__(self, idl_type, native_type=None, ref_counted=True, | |
2285 has_dart_wrapper=True, conversion_template=None, | |
2286 custom_to_dart=False): | |
2287 self._idl_type = idl_type | |
2288 self._native_type = native_type | |
2289 self._ref_counted = ref_counted | |
2290 self._has_dart_wrapper = has_dart_wrapper | |
2291 self._conversion_template = conversion_template | |
2292 self._custom_to_dart = custom_to_dart | |
2293 | |
2294 def idl_type(self): | |
2295 return self._idl_type | |
2296 | |
2297 def native_type(self): | |
2298 if self._native_type: | |
antonm
2012/02/14 14:18:22
nit: if self._native_type is not None might be mor
| |
2299 return self._native_type | |
2300 return self._idl_type | |
2301 | |
2302 def parameter_adapter_info(self): | |
2303 native_type = self.native_type() | |
2304 if self._ref_counted: | |
2305 native_type = 'RefPtr< %s >' % native_type | |
2306 if self._has_dart_wrapper: | |
2307 wrapper_type = 'Dart%s' % self.idl_type() | |
2308 adapter_type = 'ParameterAdapter<%s, %s>' % (native_type, wrapper_type) | |
2309 return (adapter_type, wrapper_type) | |
2310 return ('ParameterAdapter< %s >' % native_type, self._idl_type) | |
2311 | |
2312 def parameter_type(self): | |
2313 return '%s*' % self.native_type() | |
2314 | |
2315 def webcore_include(self): | |
2316 if self._idl_type == 'SVGNumber' or self._idl_type == 'SVGPoint': | |
2317 return None | |
2318 if self._idl_type.startswith('SVGPathSeg'): | |
2319 return self._idl_type.replace('Abs', '').replace('Rel', '') | |
2320 return self._idl_type | |
2321 | |
2322 def receiver(self): | |
2323 return 'receiver->' | |
2324 | |
2325 def conversion_include(self): | |
2326 return 'Dart%s' % self._idl_type | |
2327 | |
2328 def conversion_cast(self, expression): | |
2329 if self._conversion_template: | |
2330 return self._conversion_template % expression | |
2331 return expression | |
2332 | |
2333 def custom_to_dart(self): | |
2334 return self._custom_to_dart | |
2335 | |
2336 class PrimitiveIDLTypeInfo(IDLTypeInfo): | |
2337 def __init__(self, idl_type, native_type=None, ref_counted=False, | |
2338 conversion_template=None, | |
2339 webcore_getter_name='getAttribute', | |
2340 webcore_setter_name='setAttribute'): | |
2341 super(PrimitiveIDLTypeInfo, self).__init__(idl_type, | |
2342 native_type=native_type, ref_counted=ref_counted, | |
2343 conversion_template=conversion_template) | |
2344 self._webcore_getter_name = webcore_getter_name | |
2345 self._webcore_setter_name = webcore_setter_name | |
2346 | |
2347 def parameter_adapter_info(self): | |
2348 native_type = self.native_type() | |
2349 if self._ref_counted: | |
2350 native_type = 'RefPtr< %s >' % native_type | |
2351 return ('ParameterAdapter< %s >' % native_type, None) | |
2352 | |
2353 def parameter_type(self): | |
2354 if self.native_type() == 'String': | |
2355 return 'const String&' | |
2356 return self.native_type() | |
2357 | |
2358 def conversion_include(self): | |
2359 return None | |
2360 | |
2361 def webcore_getter_name(self): | |
2362 return self._webcore_getter_name | |
2363 | |
2364 def webcore_setter_name(self): | |
2365 return self._webcore_setter_name | |
2366 | |
2367 class SVGTearOffIDLTypeInfo(IDLTypeInfo): | |
2368 def __init__(self, idl_type, native_type='', ref_counted=True): | |
2369 super(SVGTearOffIDLTypeInfo, self).__init__(idl_type, | |
2370 native_type=native_type, | |
2371 ref_counted=ref_counted) | |
2372 | |
2373 def native_type(self): | |
2374 if self._native_type: | |
2375 return self._native_type | |
2376 tear_off_type = 'SVGPropertyTearOff' | |
2377 if self._idl_type.endswith('List'): | |
2378 tear_off_type = 'SVGListPropertyTearOff' | |
2379 return '%s<%s>' % (tear_off_type, self._idl_type) | |
2380 | |
2381 def receiver(self): | |
2382 if self._idl_type.endswith('List'): | |
2383 return 'receiver->' | |
2384 return 'receiver->propertyReference().' | |
2385 | |
2386 | |
2387 _idl_type_registry = { | |
2388 # There is GC3Dboolean which is not a bool, but unsigned char for OpenGL co mpatibility. | |
2389 'boolean': PrimitiveIDLTypeInfo('boolean', native_type='bool', | |
2390 conversion_template='static_cast<bool>(%s)', | |
2391 webcore_getter_name='hasAttribute', | |
2392 webcore_setter_name='setBooleanAttribute'), | |
2393 # Some IDL's unsigned shorts/shorts are mapped to WebCore C++ enums, so we | |
2394 # use a static_cast<int> here not to provide overloads for all enums. | |
2395 'short': PrimitiveIDLTypeInfo('short', native_type='int', conversion_templat e='static_cast<int>(%s)'), | |
2396 'unsigned short': PrimitiveIDLTypeInfo('unsigned short', native_type='int', conversion_template='static_cast<int>(%s)'), | |
2397 'int': PrimitiveIDLTypeInfo('int'), | |
2398 'unsigned int': PrimitiveIDLTypeInfo('unsigned int', native_type='unsigned') , | |
2399 'long': PrimitiveIDLTypeInfo('long', native_type='int', | |
2400 webcore_getter_name='getIntegralAttribute', | |
2401 webcore_setter_name='setIntegralAttribute'), | |
2402 'unsigned long': PrimitiveIDLTypeInfo('unsigned long', native_type='unsigned ', | |
2403 webcore_getter_name='getUnsignedIntegralAttribute', | |
2404 webcore_setter_name='setUnsignedIntegralAttribute'), | |
2405 'long long': PrimitiveIDLTypeInfo('long long'), | |
2406 'unsigned long long': PrimitiveIDLTypeInfo('unsigned long long'), | |
2407 'double': PrimitiveIDLTypeInfo('double'), | |
2408 | |
2409 'Date': PrimitiveIDLTypeInfo('Date', native_type='double'), | |
2410 'DOMString': PrimitiveIDLTypeInfo('DOMString', native_type='String'), | |
2411 'DOMTimeStamp': PrimitiveIDLTypeInfo('DOMTimeStamp'), | |
2412 'object': PrimitiveIDLTypeInfo('object', native_type='ScriptValue'), | |
2413 'SerializedScriptValue': PrimitiveIDLTypeInfo('SerializedScriptValue', ref_c ounted=True), | |
2414 | |
2415 'DOMException': IDLTypeInfo('DOMCoreException'), | |
2416 'DOMWindow': IDLTypeInfo('DOMWindow', custom_to_dart=True), | |
2417 'Element': IDLTypeInfo('Element', custom_to_dart=True), | |
2418 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False), | |
2419 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False), | |
2420 'HTMLElement': IDLTypeInfo('HTMLElement', custom_to_dart=True), | |
2421 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wra pper=False), | |
2422 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False), | |
2423 'SVGElement': IDLTypeInfo('SVGElement', custom_to_dart=True), | |
2424 | |
2425 'SVGAngle': SVGTearOffIDLTypeInfo('SVGAngle'), | |
2426 'SVGLength': SVGTearOffIDLTypeInfo('SVGLength'), | |
2427 'SVGLengthList': SVGTearOffIDLTypeInfo('SVGLengthList', ref_counted=False), | |
2428 'SVGMatrix': SVGTearOffIDLTypeInfo('SVGMatrix'), | |
2429 'SVGNumber': SVGTearOffIDLTypeInfo('SVGNumber', native_type='SVGPropertyTear Off<float>'), | |
2430 'SVGNumberList': SVGTearOffIDLTypeInfo('SVGNumberList', ref_counted=False), | |
2431 'SVGPathSegList': SVGTearOffIDLTypeInfo('SVGPathSegList', native_type='SVGPa thSegListPropertyTearOff', ref_counted=False), | |
2432 'SVGPoint': SVGTearOffIDLTypeInfo('SVGPoint', native_type='SVGPropertyTearOf f<FloatPoint>'), | |
2433 'SVGPointList': SVGTearOffIDLTypeInfo('SVGPointList', ref_counted=False), | |
2434 'SVGPreserveAspectRatio': SVGTearOffIDLTypeInfo('SVGPreserveAspectRatio'), | |
2435 'SVGRect': SVGTearOffIDLTypeInfo('SVGRect', native_type='SVGPropertyTearOff< FloatRect>'), | |
2436 'SVGStringList': SVGTearOffIDLTypeInfo('SVGStringList', native_type='SVGStat icListPropertyTearOff<SVGStringList>', ref_counted=False), | |
2437 'SVGTransform': SVGTearOffIDLTypeInfo('SVGTransform'), | |
2438 'SVGTransformList': SVGTearOffIDLTypeInfo('SVGTransformList', native_type='S VGTransformListPropertyTearOff', ref_counted=False) | |
2439 } | |
2440 | |
2441 _original_idl_types = { | |
2442 } | |
2443 | |
2444 def GetIDLTypeInfo(idl_type): | |
2445 idl_type_name = _original_idl_types.get(idl_type, idl_type.id) | |
2446 return GetIDLTypeInfoByName(idl_type_name) | |
2447 | |
2448 def GetIDLTypeInfoByName(idl_type_name): | |
2449 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) | |
2450 | |
2278 class NativeImplementationSystem(System): | 2451 class NativeImplementationSystem(System): |
2279 | 2452 |
2280 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir): | 2453 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir): |
2281 super(NativeImplementationSystem, self).__init__( | 2454 super(NativeImplementationSystem, self).__init__( |
2282 templates, database, emitters, output_dir) | 2455 templates, database, emitters, output_dir) |
2283 | 2456 |
2284 self._auxiliary_dir = auxiliary_dir | 2457 self._auxiliary_dir = auxiliary_dir |
2285 self._dom_public_files = [] | 2458 self._dom_public_files = [] |
2286 self._dom_impl_files = [] | 2459 self._dom_impl_files = [] |
2287 self._cpp_header_files = [] | 2460 self._cpp_header_files = [] |
2288 self._cpp_impl_files = [] | 2461 self._cpp_impl_files = [] |
2289 | 2462 |
2290 def InterfaceGenerator(self, | 2463 def InterfaceGenerator(self, |
2291 interface, | 2464 interface, |
2292 common_prefix, | 2465 common_prefix, |
2293 super_interface_name, | 2466 super_interface_name, |
2294 source_filter): | 2467 source_filter): |
2295 interface_name = interface.id | 2468 interface_name = interface.id |
2296 | 2469 |
2297 dart_interface_path = self._FilePathForDartInterface(interface_name) | 2470 dart_interface_path = self._FilePathForDartInterface(interface_name) |
2298 self._dom_public_files.append(dart_interface_path) | 2471 self._dom_public_files.append(dart_interface_path) |
2299 | 2472 |
2473 pure_interfaces = set([ | |
2474 'ElementTimeControl', | |
2475 'ElementTraversal', | |
2476 'MediaQueryListListener', | |
2477 'NodeSelector', | |
2478 'SVGExternalResourcesRequired', | |
2479 'SVGFilterPrimitiveStandardAttributes', | |
2480 'SVGFitToViewBox', | |
2481 'SVGLangSpace', | |
2482 'SVGLocatable', | |
2483 'SVGStylable', | |
2484 'SVGTests', | |
2485 'SVGTransformable', | |
2486 'SVGURIReference', | |
2487 'SVGViewSpec', | |
2488 'SVGZoomAndPan']) | |
2489 if interface_name in pure_interfaces: | |
2490 return None | |
2491 | |
2300 dart_impl_path = self._FilePathForDartImplementation(interface_name) | 2492 dart_impl_path = self._FilePathForDartImplementation(interface_name) |
2301 self._dom_impl_files.append(dart_impl_path) | 2493 self._dom_impl_files.append(dart_impl_path) |
2302 | 2494 |
2303 cpp_header_path = self._FilePathForCppHeader(interface_name) | 2495 cpp_header_path = self._FilePathForCppHeader(interface_name) |
2304 self._cpp_header_files.append(cpp_header_path) | 2496 self._cpp_header_files.append(cpp_header_path) |
2305 | 2497 |
2306 cpp_impl_path = self._FilePathForCppImplementation(interface_name) | 2498 cpp_impl_path = self._FilePathForCppImplementation(interface_name) |
2307 self._cpp_impl_files.append(cpp_impl_path) | 2499 self._cpp_impl_files.append(cpp_impl_path) |
2308 | 2500 |
2309 return NativeImplementationGenerator(interface, super_interface_name, | 2501 return NativeImplementationGenerator(interface, super_interface_name, |
2310 self._emitters.FileEmitter(dart_impl_path), | 2502 self._emitters.FileEmitter(dart_impl_path), |
2311 self._emitters.FileEmitter(cpp_header_path), | 2503 self._emitters.FileEmitter(cpp_header_path), |
2312 self._emitters.FileEmitter(cpp_impl_path), | 2504 self._emitters.FileEmitter(cpp_impl_path), |
2313 self._BaseDefines(interface), | 2505 self._BaseDefines(interface), |
2314 self._templates) | 2506 self._templates) |
2315 | 2507 |
2316 def ProcessCallback(self, interface, info): | 2508 def ProcessCallback(self, interface, info): |
2317 self._dom_public_files.append(self._FilePathForDartInterface(interface.id)) | 2509 self._interface = interface |
2510 | |
2511 dart_interface_path = self._FilePathForDartInterface(self._interface.id) | |
2512 self._dom_public_files.append(dart_interface_path) | |
2513 | |
2514 cpp_header_handlers_emitter = emitter.Emitter() | |
2515 cpp_impl_handlers_emitter = emitter.Emitter() | |
2516 class_name = 'Dart%s' % self._interface.id | |
2517 for operation in interface.operations: | |
2518 if operation.type.id == 'void': | |
2519 return_type = 'void' | |
2520 return_prefix = '' | |
2521 else: | |
2522 return_type = 'bool' | |
2523 return_prefix = 'return ' | |
2524 | |
2525 parameters = [] | |
antonm
2012/02/14 14:18:22
up to you, but another option would be:
parameter
| |
2526 arguments = [] | |
2527 for argument in operation.arguments: | |
2528 argument_type_info = GetIDLTypeInfo(argument.type) | |
2529 parameters.append('%s %s' % (argument_type_info.parameter_type(), | |
2530 argument.id)) | |
2531 arguments.append(argument.id) | |
2532 | |
2533 cpp_header_handlers_emitter.Emit( | |
2534 '\n' | |
2535 ' virtual $TYPE handleEvent($PARAMETERS);\n', | |
2536 TYPE=return_type, PARAMETERS=', '.join(parameters)) | |
2537 | |
2538 cpp_impl_handlers_emitter.Emit( | |
2539 '\n' | |
2540 '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n' | |
2541 '{\n' | |
2542 ' $(RETURN_PREFIX)m_callback.handleEvent($ARGUMENTS);\n' | |
2543 '}\n', | |
2544 TYPE=return_type, | |
2545 CLASS_NAME=class_name, | |
2546 PARAMETERS=', '.join(parameters), | |
2547 RETURN_PREFIX=return_prefix, | |
2548 ARGUMENTS=', '.join(arguments)) | |
2549 | |
2550 cpp_header_path = self._FilePathForCppHeader(self._interface.id) | |
2551 cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path) | |
2552 cpp_header_emitter.Emit( | |
2553 self._templates.Load('cpp_callback_header.template'), | |
2554 INTERFACE=self._interface.id, | |
2555 HANDLERS=cpp_header_handlers_emitter.Fragments()) | |
2556 | |
2557 cpp_impl_path = self._FilePathForCppImplementation(self._interface.id) | |
2558 self._cpp_impl_files.append(cpp_impl_path) | |
2559 cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path) | |
2560 cpp_impl_emitter.Emit( | |
2561 self._templates.Load('cpp_callback_implementation.template'), | |
2562 INTERFACE=self._interface.id, | |
2563 HANDLERS=cpp_impl_handlers_emitter.Fragments()) | |
2318 | 2564 |
2319 def GenerateLibraries(self, lib_dir): | 2565 def GenerateLibraries(self, lib_dir): |
2320 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) | 2566 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) |
2321 | 2567 |
2322 # Generate dom_public.dart. | 2568 # Generate dom_public.dart. |
2323 self._GenerateLibFile( | 2569 self._GenerateLibFile( |
2324 'dom_public.darttemplate', | 2570 'dom_public.darttemplate', |
2325 os.path.join(self._output_dir, 'dom_public.dart'), | 2571 os.path.join(self._output_dir, 'dom_public.dart'), |
2326 self._dom_public_files, | 2572 self._dom_public_files, |
2327 AUXILIARY_DIR=auxiliary_dir); | 2573 AUXILIARY_DIR=auxiliary_dir); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2359 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argume ntCount))\n' | 2605 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argume ntCount))\n' |
2360 ' return func;\n', | 2606 ' return func;\n', |
2361 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) | 2607 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) |
2362 | 2608 |
2363 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) | 2609 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) |
2364 cpp_resolver_emitter.Emit( | 2610 cpp_resolver_emitter.Emit( |
2365 self._templates.Load('cpp_resolver.template'), | 2611 self._templates.Load('cpp_resolver.template'), |
2366 INCLUDES=includes_emitter.Fragments(), | 2612 INCLUDES=includes_emitter.Fragments(), |
2367 RESOLVER_BODY=resolver_body_emitter.Fragments()) | 2613 RESOLVER_BODY=resolver_body_emitter.Fragments()) |
2368 | 2614 |
2615 # Generate DartDerivedSourcesAll.cpp | |
2616 cpp_all_in_one_path = os.path.join(self._output_dir, | |
2617 'DartDerivedSourcesAll.cpp') | |
2618 | |
2619 includes_emitter = emitter.Emitter() | |
2620 for file in self._cpp_impl_files: | |
2621 path = os.path.relpath(file, os.path.dirname(cpp_all_in_one_path)) | |
2622 includes_emitter.Emit('#include "$PATH"\n', PATH=path) | |
2623 | |
2624 cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path) | |
2625 cpp_all_in_one_emitter.Emit( | |
2626 self._templates.Load('cpp_all_in_one.template'), | |
antonm
2012/02/14 14:18:22
just curious: how are you going to customize it?
podivilov
2012/02/14 17:47:58
Will add a parameter probably.
| |
2627 INCLUDES=includes_emitter.Fragments()) | |
2628 | |
2629 # Generate DartResolver.cpp | |
2630 cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp') | |
2631 | |
2632 includes_emitter = emitter.Emitter() | |
2633 resolver_body_emitter = emitter.Emitter() | |
2634 for file in self._cpp_header_files: | |
2635 path = os.path.relpath(file, os.path.dirname(cpp_resolver_path)) | |
2636 includes_emitter.Emit('#include "$PATH"\n', PATH=path) | |
2637 resolver_body_emitter.Emit( | |
2638 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu mentCount))\n' | |
2639 ' return func;\n', | |
2640 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) | |
2641 | |
2642 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) | |
2643 cpp_resolver_emitter.Emit( | |
2644 self._templates.Load('cpp_resolver.template'), | |
2645 INCLUDES=includes_emitter.Fragments(), | |
2646 RESOLVER_BODY=resolver_body_emitter.Fragments()) | |
2647 | |
2369 def Finish(self): | 2648 def Finish(self): |
2370 pass | 2649 pass |
2371 | 2650 |
2372 def _FilePathForDartInterface(self, interface_name): | 2651 def _FilePathForDartInterface(self, interface_name): |
2373 return os.path.join(self._output_dir, 'src', 'interface', | 2652 return os.path.join(self._output_dir, 'src', 'interface', |
2374 '%s.dart' % interface_name) | 2653 '%s.dart' % interface_name) |
2375 | 2654 |
2376 def _FilePathForDartImplementation(self, interface_name): | 2655 def _FilePathForDartImplementation(self, interface_name): |
2377 return os.path.join(self._output_dir, 'dart', | 2656 return os.path.join(self._output_dir, 'dart', |
2378 '%sImplementation.dart' % interface_name) | 2657 '%sImplementation.dart' % interface_name) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2411 self._super_interface = super_interface | 2690 self._super_interface = super_interface |
2412 self._dart_impl_emitter = dart_impl_emitter | 2691 self._dart_impl_emitter = dart_impl_emitter |
2413 self._cpp_header_emitter = cpp_header_emitter | 2692 self._cpp_header_emitter = cpp_header_emitter |
2414 self._cpp_impl_emitter = cpp_impl_emitter | 2693 self._cpp_impl_emitter = cpp_impl_emitter |
2415 self._base_members = base_members | 2694 self._base_members = base_members |
2416 self._templates = templates | 2695 self._templates = templates |
2417 self._current_secondary_parent = None | 2696 self._current_secondary_parent = None |
2418 | 2697 |
2419 def StartInterface(self): | 2698 def StartInterface(self): |
2420 self._class_name = self._ImplClassName(self._interface.id) | 2699 self._class_name = self._ImplClassName(self._interface.id) |
2700 self._interface_type_info = GetIDLTypeInfoByName(self._interface.id) | |
2421 self._members_emitter = emitter.Emitter() | 2701 self._members_emitter = emitter.Emitter() |
2702 self._cpp_declarations_emitter = emitter.Emitter() | |
2703 self._cpp_impl_includes = {} | |
2704 self._cpp_definitions_emitter = emitter.Emitter() | |
2705 self._cpp_resolver_emitter = emitter.Emitter() | |
2706 | |
2707 # Generate constructor. | |
2708 # FIXME: add proper support for non-custom constructors. | |
2709 if ('CustomConstructor' in self._interface.ext_attrs or | |
2710 'V8CustomConstructor' in self._interface.ext_attrs or | |
2711 self._interface.id in ['FileReader', 'WebKitCSSMatrix']): | |
2712 self._cpp_resolver_emitter.Emit( | |
2713 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' | |
2714 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n' , | |
2715 INTERFACE_NAME=self._interface.id) | |
2716 self._cpp_declarations_emitter.Emit( | |
2717 '\n' | |
2718 'void constructorCallback(Dart_NativeArguments);\n') | |
2422 | 2719 |
2423 def _ImplClassName(self, interface_name): | 2720 def _ImplClassName(self, interface_name): |
2424 return interface_name + 'Implementation' | 2721 return interface_name + 'Implementation' |
2425 | 2722 |
2426 def FinishInterface(self): | 2723 def FinishInterface(self): |
2427 base = self._BaseClassName(self._interface) | 2724 base = self._BaseClassName(self._interface) |
2428 self._dart_impl_emitter.Emit( | 2725 self._dart_impl_emitter.Emit( |
2429 self._templates.Load('dart_implementation.darttemplate'), | 2726 self._templates.Load('dart_implementation.darttemplate'), |
2430 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id, | 2727 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id, |
2431 MEMBERS=self._members_emitter.Fragments()) | 2728 MEMBERS=self._members_emitter.Fragments()) |
2432 | 2729 |
2433 self._cpp_header_emitter.Emit( | 2730 self._GenerateCppHeader() |
2434 self._templates.Load('cpp_header.template'), | |
2435 INTERFACE=self._interface.id) | |
2436 | 2731 |
2437 self._cpp_impl_emitter.Emit( | 2732 self._cpp_impl_emitter.Emit( |
2438 self._templates.Load('cpp_implementation.template'), | 2733 self._templates.Load('cpp_implementation.template'), |
2439 INTERFACE=self._interface.id) | 2734 INTERFACE=self._interface.id, |
2735 INCLUDES=''.join(['#include "%s.h"\n' % | |
2736 k for k in self._cpp_impl_includes.keys()]), | |
2737 CALLBACKS=self._cpp_definitions_emitter.Fragments(), | |
2738 RESOLVER=self._cpp_resolver_emitter.Fragments()) | |
2739 | |
2740 def _GenerateCppHeader(self): | |
2741 webcore_include = self._interface_type_info.webcore_include() | |
2742 if webcore_include: | |
2743 webcore_include = '#include "%s.h"\n' % webcore_include | |
2744 else: | |
2745 webcore_include = '' | |
2746 | |
2747 if ('CustomToJS' in self._interface.ext_attrs or | |
antonm
2012/02/14 14:18:22
FIXME?
podivilov
2012/02/14 17:47:58
Why fixme?
antonm
2012/02/15 13:27:32
Is it possible to put attributes check into custom
| |
2748 'PureInterface' in self._interface.ext_attrs or | |
2749 self._interface_type_info.custom_to_dart()): | |
2750 to_dart_value_template = ( | |
2751 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n') | |
2752 else: | |
2753 to_dart_value_template = ( | |
2754 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n' | |
2755 '{\n' | |
2756 ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n' | |
2757 '}\n') | |
2758 to_dart_value_emitter = emitter.Emitter() | |
2759 to_dart_value_emitter.Emit( | |
2760 to_dart_value_template, | |
2761 INTERFACE=self._interface.id, | |
2762 WEBCORE_CLASS_NAME=self._interface_type_info.native_type()) | |
2763 | |
2764 self._cpp_header_emitter.Emit( | |
2765 self._templates.Load('cpp_header.template'), | |
2766 INTERFACE=self._interface.id, | |
2767 WEBCORE_INCLUDE=webcore_include, | |
2768 ADDITIONAL_INCLUDES='', | |
2769 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(), | |
2770 TO_DART_VALUE=to_dart_value_emitter.Fragments(), | |
2771 DECLARATIONS=self._cpp_declarations_emitter.Fragments()) | |
2440 | 2772 |
2441 def AddAttribute(self, getter, setter): | 2773 def AddAttribute(self, getter, setter): |
2774 # FIXME: Dartium does not support attribute event listeners. However, JS | |
2775 # implementation falls back to them when addEventListener is not available. | |
2776 # Make sure addEventListener is available in all EventTargets and remove | |
2777 # this check. | |
2778 if (getter or setter).type.id == 'EventListener': | |
2779 return | |
2780 | |
2781 # FIXME: support 'ImplementedBy'. | |
2782 if 'ImplementedBy' in (getter or setter).ext_attrs: | |
2783 return | |
2784 | |
2785 # FIXME: these should go away. | |
2786 classes_with_unsupported_custom_getters = [ | |
2787 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent', | |
2788 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame', | |
2789 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement', | |
2790 'ScriptProfileNode', 'WebKitAnimation'] | |
2791 if (self._interface.id in classes_with_unsupported_custom_getters and | |
2792 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)): | |
antonm
2012/02/14 14:18:22
& ?
podivilov
2012/02/14 17:47:58
set intersection.
| |
2793 return | |
2794 | |
2442 if getter: | 2795 if getter: |
2443 self._AddGetter(getter) | 2796 self._AddGetter(getter) |
2444 if setter: | 2797 if setter: |
2445 self._AddSetter(setter) | 2798 self._AddSetter(setter) |
2446 | 2799 |
2447 def _AddGetter(self, attr): | 2800 def _AddGetter(self, attr): |
2448 self._members_emitter.Emit( | 2801 dart_declaration = '%s get %s()' % (attr.type.id, attr.id) |
2449 '\n' | 2802 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs |
2450 ' $TYPE get $NAME() native "$(INTERFACE)_$(NAME)_Getter";\n', | 2803 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, |
2451 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) | 2804 dart_declaration, 'Getter', is_custom) |
2805 if is_custom: | |
2806 return | |
2807 | |
2808 arguments = [] | |
2809 if 'Reflect' in attr.ext_attrs: | |
2810 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_getter_name() | |
2811 if 'URL' in attr.ext_attrs: | |
2812 if 'NonEmpty' in attr.ext_attrs: | |
2813 webcore_function_name = 'getNonEmptyURLAttribute' | |
2814 else: | |
2815 webcore_function_name = 'getURLAttribute' | |
2816 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | |
2817 else: | |
2818 if attr.id == 'operator': | |
2819 webcore_function_name = '_operator' | |
2820 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': | |
2821 webcore_function_name = 'svgTarget' | |
2822 else: | |
2823 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)', | |
2824 lambda s: s.group(1).lower(), | |
2825 attr.id) | |
2826 webcore_function_name = re.sub(r'^(create|exclusive)', | |
2827 lambda s: 'is' + s.group(1).capitalize(), | |
2828 webcore_function_name) | |
2829 if attr.type.id.startswith('SVGAnimated'): | |
2830 webcore_function_name += 'Animated' | |
2831 | |
2832 self._GenerateNativeCallback(cpp_callback_name, attr, '', | |
2833 webcore_function_name, arguments, idl_return_type=attr.type, | |
2834 raises_dart_exceptions=attr.get_raises, | |
2835 raises_dom_exceptions=attr.get_raises) | |
2452 | 2836 |
2453 def _AddSetter(self, attr): | 2837 def _AddSetter(self, attr): |
2454 self._members_emitter.Emit( | 2838 dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id) |
2455 '\n' | 2839 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs) |
2456 ' void set $NAME($TYPE) native "$(INTERFACE)_$(NAME)_Setter";\n', | 2840 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, |
2457 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) | 2841 dart_declaration, 'Setter', is_custom) |
2842 if is_custom: | |
2843 return | |
2844 | |
2845 arguments = [] | |
2846 if 'Reflect' in attr.ext_attrs: | |
2847 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_setter_name() | |
2848 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | |
2849 else: | |
2850 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', | |
2851 lambda s: s.group(1).upper(), | |
2852 attr.id) | |
2853 webcore_function_name = 'set%s' % webcore_function_name | |
2854 if attr.type.id.startswith('SVGAnimated'): | |
2855 webcore_function_name += 'Animated' | |
2856 | |
2857 arguments.append(attr.id) | |
2858 parameter_definitions_emitter = emitter.Emitter() | |
2859 self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0) | |
2860 parameter_definitions = parameter_definitions_emitter.Fragments() | |
2861 self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions, | |
2862 webcore_function_name, arguments, idl_return_type=None, | |
2863 raises_dart_exceptions=True, | |
2864 raises_dom_exceptions=attr.set_raises) | |
2458 | 2865 |
2459 def _HasNativeIndexGetter(self, interface): | 2866 def _HasNativeIndexGetter(self, interface): |
2460 return ('HasCustomIndexGetter' in interface.ext_attrs or | 2867 return ('HasCustomIndexGetter' in interface.ext_attrs or |
2461 'HasNumericIndexGetter' in interface.ext_attrs) | 2868 'HasNumericIndexGetter' in interface.ext_attrs) |
2462 | 2869 |
2463 def _EmitNativeIndexGetter(self, interface, element_type): | 2870 def _EmitNativeIndexGetter(self, interface, element_type): |
2464 native_binding = '%s_numericIndexGetter_Callback' % interface.id | 2871 dart_declaration = '%s operator[](int index)' % element_type |
2465 self._members_emitter.Emit( | 2872 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration, |
2466 '\n' | 2873 'Callback', True) |
2467 ' $TYPE operator[](int index) native "$NATIVE_BINDING";\n', | |
2468 TYPE=element_type, NATIVE_BINDING=native_binding) | |
2469 | 2874 |
2470 def _EmitNativeIndexSetter(self, interface, element_type): | 2875 def _EmitNativeIndexSetter(self, interface, element_type): |
2471 native_binding = '%s_numericIndexSetter_Callback' % self._interface.id | 2876 dart_declaration = 'void operator[]=(int index, %s value)' % element_type |
2472 self._members_emitter.Emit( | 2877 self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration, |
2473 '\n' | 2878 'Callback', True) |
2474 ' void operator[]=(int index, $TYPE value) native "$NATIVE_BINDING";\n' , | |
2475 TYPE=element_type, NATIVE_BINDING=native_binding) | |
2476 | 2879 |
2477 def AddOperation(self, info): | 2880 def AddOperation(self, info): |
2478 """ | 2881 """ |
2479 Arguments: | 2882 Arguments: |
2480 info: An OperationInfo object. | 2883 info: An OperationInfo object. |
2481 """ | 2884 """ |
2482 | 2885 |
2483 if 'Custom' in info.overloads[0].ext_attrs: | 2886 if 'Custom' in info.overloads[0].ext_attrs: |
2484 self._members_emitter.Emit( | 2887 parameters = info.ParametersImplementationDeclaration() |
2485 '\n' | 2888 dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters) |
2486 ' $TYPE $NAME($PARAMETERS) native "$(INTERFACE)_$(NAME)_Callback";\ n', | 2889 argument_count = 1 + len(info.arg_infos) |
2487 TYPE=info.type_name, | 2890 self._GenerateNativeBinding(info.name, argument_count, dart_declaration, |
2488 NAME=info.name, | 2891 'Callback', True) |
2489 PARAMETERS=info.ParametersImplementationDeclaration(), | 2892 return |
2490 INTERFACE=self._interface.id) | |
2491 return | |
2492 | 2893 |
2493 body = self._members_emitter.Emit( | 2894 body = self._members_emitter.Emit( |
2494 '\n' | 2895 '\n' |
2495 ' $TYPE $NAME($PARAMETERS) {\n' | 2896 ' $TYPE $NAME($PARAMETERS) {\n' |
2496 '$!BODY' | 2897 '$!BODY' |
2497 ' }\n', | 2898 ' }\n', |
2498 TYPE=info.type_name, | 2899 TYPE=info.type_name, |
2499 NAME=info.name, | 2900 NAME=info.name, |
2500 PARAMETERS=info.ParametersImplementationDeclaration()) | 2901 PARAMETERS=info.ParametersImplementationDeclaration()) |
2501 | 2902 |
2502 # Process in order of ascending number of arguments to ensure missing | 2903 # Process in order of ascending number of arguments to ensure missing |
2503 # optional arguments are processed early. | 2904 # optional arguments are processed early. |
2504 overloads = sorted(info.overloads, | 2905 overloads = sorted(info.overloads, |
2505 key=lambda overload: len(overload.arguments)) | 2906 key=lambda overload: len(overload.arguments)) |
2506 self._native_version = 0 | 2907 self._native_version = 0 |
2507 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) | 2908 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) |
2508 if fallthrough: | 2909 if fallthrough: |
2509 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 2910 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
2510 | 2911 |
2511 def GenerateSingleOperation(self, emitter, info, indent, operation): | 2912 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation): |
2512 """Generates a call to a single operation. | 2913 """Generates a call to a single operation. |
2513 | 2914 |
2514 Arguments: | 2915 Arguments: |
2515 emitter: an Emitter for the body of a block of code. | 2916 dispatch_emitter: an dispatch_emitter for the body of a block of code. |
2516 info: the compound information about the operation and its overloads. | 2917 info: the compound information about the operation and its overloads. |
2517 indent: an indentation string for generated code. | 2918 indent: an indentation string for generated code. |
2518 operation: the IDLOperation to call. | 2919 operation: the IDLOperation to call. |
2519 """ | 2920 """ |
2520 | 2921 |
2521 arg_names = [info.arg_infos[i][0] | 2922 # FIXME: support ImplementedBy callbacks. |
2522 for (i, arg) in enumerate(operation.arguments)] | 2923 if 'ImplementedBy' in operation.ext_attrs: |
2924 return | |
2925 | |
2926 for op in self._interface.operations: | |
2927 if op.id != operation.id or len(op.arguments) <= len(operation.arguments): | |
2928 continue | |
2929 next_argument = op.arguments[len(operation.arguments)] | |
2930 if next_argument.is_optional and 'Callback' in next_argument.ext_attrs: | |
2931 # FIXME: '[Optional, Callback]' arguments could be non-optional in | |
2932 # webcore. We need to fix overloads handling to generate native | |
2933 # callbacks properly. | |
2934 return | |
2523 | 2935 |
2524 self._native_version += 1 | 2936 self._native_version += 1 |
2525 native_name = '_%s' % info.name | 2937 native_name = info.name |
2526 if self._native_version > 1: | 2938 if self._native_version > 1: |
2527 native_name = '%s_%s' % (native_name, self._native_version) | 2939 native_name = '%s_%s' % (native_name, self._native_version) |
2528 | 2940 argument_list = ', '.join([info.arg_infos[i][0] |
2529 argument_expressions = ', '.join(arg_names) | 2941 for (i, arg) in enumerate(operation.arguments)]) |
2942 | |
2943 # Generate dispatcher. | |
2530 if info.type_name != 'void': | 2944 if info.type_name != 'void': |
2531 emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n', | 2945 dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n', |
2532 INDENT=indent, | 2946 INDENT=indent, |
2533 NATIVENAME=native_name, | 2947 NATIVENAME=native_name, |
2534 ARGS=argument_expressions) | 2948 ARGS=argument_list) |
2535 else: | 2949 else: |
2536 emitter.Emit('$(INDENT)$NATIVENAME($ARGS);\n' | 2950 dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n' |
2537 '$(INDENT)return;\n', | 2951 '$(INDENT)return;\n', |
2538 INDENT=indent, | 2952 INDENT=indent, |
2539 NATIVENAME=native_name, | 2953 NATIVENAME=native_name, |
2540 ARGS=argument_expressions) | 2954 ARGS=argument_list) |
2541 | 2955 # Generate binding. |
2542 self._members_emitter.Emit(' $TYPE $NATIVE_NAME($PARAMS) native ' | 2956 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name, |
2543 '"$(INTERFACE)$(NATIVE_NAME)_Callback";\n', | 2957 argument_list) |
2544 NATIVE_NAME=native_name, | 2958 is_custom = 'Custom' in operation.ext_attrs |
2545 TYPE=info.type_name, | 2959 cpp_callback_name = self._GenerateNativeBinding( |
2546 PARAMS=', '.join(arg_names), | 2960 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback', |
2547 INTERFACE=self._interface.id) | 2961 is_custom) |
2962 if is_custom: | |
2963 return | |
2964 | |
2965 # Generate callback. | |
2966 webcore_function_name = operation.id | |
2967 if 'ImplementationFunction' in operation.ext_attrs: | |
2968 webcore_function_name = operation.ext_attrs['ImplementationFunction'] | |
2969 | |
2970 parameter_definitions_emitter = emitter.Emitter() | |
2971 raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises | |
2972 arguments = [] | |
2973 | |
2974 # Process 'CallWith' argument. | |
2975 if ('CallWith' in operation.ext_attrs and | |
2976 operation.ext_attrs['CallWith'] == 'ScriptExecutionContext'): | |
2977 parameter_definitions_emitter.Emit( | |
2978 ' ScriptExecutionContext* context = DartUtilities::scriptExecut ionContext();\n' | |
2979 ' if (!context)\n' | |
2980 ' return;\n') | |
2981 arguments.append('context') | |
2982 | |
2983 # Process Dart arguments. | |
2984 for (i, argument) in enumerate(operation.arguments): | |
2985 if i == len(operation.arguments) - 1 and 'CustomArgumentHandling' in opera tion.ext_attrs: | |
2986 # FIXME: we are skipping last argument here because it was added in | |
2987 # supplemental dart.idl. Cleanup dart.idl and remove this check. | |
2988 break | |
2989 self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i) | |
2990 arguments.append(argument.id) | |
2991 | |
2992 if operation.id in ['addEventListener', 'removeEventListener']: | |
2993 # addEventListener's and removeEventListener's last argument is marked | |
2994 # as optional in idl, but is not optional in webcore implementation. | |
2995 if len(operation.arguments) == 2: | |
2996 arguments.append('false') | |
2997 | |
2998 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty': | |
2999 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart | |
3000 # idl, but is not optional in webcore implementation. | |
3001 if len(operation.arguments) == 2: | |
3002 arguments.append('String()') | |
3003 | |
3004 # Process auxiliary arguments. | |
3005 if 'CustomArgumentHandling' in operation.ext_attrs: | |
3006 raises_dart_exceptions = True | |
3007 self._cpp_impl_includes['ScriptArguments'] = 1 | |
3008 self._cpp_impl_includes['ScriptCallStack'] = 1 | |
3009 self._cpp_impl_includes['V8Proxy'] = 1 | |
3010 self._cpp_impl_includes['v8'] = 1 | |
3011 parameter_definitions_emitter.Emit( | |
3012 ' v8::HandleScope handleScope;\n' | |
3013 ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilit ies::domWindowForCurrentIsolate()->frame()));\n' | |
3014 ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $IN DEX);\n' | |
3015 ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::create ScriptArguments(customArgument, exception));\n' | |
3016 ' if (!scriptArguments)\n' | |
3017 ' goto fail;\n' | |
3018 ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::create ScriptCallStack());\n' | |
3019 ' if (!scriptCallStack->size())\n' | |
3020 ' return;\n', | |
3021 INDEX=len(operation.arguments)) | |
3022 arguments.extend(['scriptArguments', 'scriptCallStack']) | |
3023 | |
3024 if 'NeedsUserGestureCheck' in operation.ext_attrs: | |
3025 arguments.extend('DartUtilities::processingUserGesture') | |
3026 | |
3027 parameter_definitions = parameter_definitions_emitter.Fragments() | |
3028 self._GenerateNativeCallback(cpp_callback_name, operation, | |
3029 parameter_definitions, webcore_function_name, arguments, | |
3030 idl_return_type=operation.type, | |
3031 raises_dart_exceptions=raises_dart_exceptions, | |
3032 raises_dom_exceptions=operation.raises) | |
3033 | |
3034 def _GenerateNativeCallback(self, callback_name, idl_node, | |
3035 parameter_definitions, function_name, arguments, idl_return_type, | |
3036 raises_dart_exceptions, raises_dom_exceptions): | |
3037 receiver = self._interface_type_info.receiver() | |
3038 if raises_dom_exceptions: | |
3039 arguments.append('ec') | |
3040 callback = '%s%s(%s)' % (receiver, function_name, ', '.join(arguments)) | |
3041 | |
3042 nested_templates = [] | |
3043 if idl_return_type and idl_return_type.id != 'void': | |
3044 return_type_info = GetIDLTypeInfo(idl_return_type) | |
3045 conversion_cast = return_type_info.conversion_cast('$BODY') | |
3046 if isinstance(return_type_info, SVGTearOffIDLTypeInfo): | |
3047 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', | |
3048 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] | |
3049 conversion_cast = '%s::create($BODY)' | |
3050 if self._interface.id.startswith('SVGAnimated'): | |
3051 conversion_cast = 'static_cast<%s*>($BODY)' | |
3052 elif return_type_info.idl_type() == 'SVGStringList': | |
3053 conversion_cast = '%s::create(receiver, $BODY)' | |
3054 elif self._interface.id.endswith('List'): | |
3055 conversion_cast = 'static_cast<%s*>($BODY.get())' | |
3056 elif return_type_info.idl_type() in svg_primitive_types: | |
3057 conversion_cast = '%s::create($BODY)' | |
3058 else: | |
3059 conversion_cast = 'static_cast<%s*>($BODY)' | |
3060 conversion_cast = conversion_cast % return_type_info.native_type() | |
3061 nested_templates.append(conversion_cast) | |
3062 | |
3063 if return_type_info.conversion_include(): | |
3064 self._cpp_impl_includes[return_type_info.conversion_include()] = 1 | |
3065 if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and | |
3066 'ConvertNullStringTo' in idl_node.ext_attrs): | |
3067 nested_templates.append('$BODY, ConvertDefaultToNull') | |
3068 nested_templates.append( | |
3069 ' Dart_Handle returnValue = toDartValue($BODY);\n' | |
3070 ' if (returnValue)\n' | |
3071 ' Dart_SetReturnValue(args, returnValue);\n') | |
3072 else: | |
3073 nested_templates.append(' $BODY;\n') | |
3074 | |
3075 if raises_dom_exceptions: | |
3076 nested_templates.append( | |
3077 ' ExceptionCode ec = 0;\n' | |
3078 '$BODY' | |
3079 ' if (UNLIKELY(ec)) {\n' | |
3080 ' exception = DartDOMWrapper::exceptionCodeToDartException( ec);\n' | |
3081 ' goto fail;\n' | |
3082 ' }\n') | |
3083 | |
3084 nested_templates.append( | |
3085 ' {\n' | |
3086 ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBC ORE_CLASS_NAME >(args);\n' | |
3087 '$PARAMETER_DEFINITIONS' | |
3088 '\n' | |
3089 '$BODY' | |
3090 ' return;\n' | |
3091 ' }\n') | |
3092 | |
3093 if raises_dart_exceptions: | |
3094 nested_templates.append( | |
3095 ' Dart_Handle exception;\n' | |
3096 '$BODY' | |
3097 '\n' | |
3098 'fail:\n' | |
3099 ' Dart_ThrowException(exception);\n' | |
3100 ' ASSERT_NOT_REACHED();\n') | |
3101 | |
3102 nested_templates.append( | |
3103 '\n' | |
3104 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n' | |
3105 '{\n' | |
3106 ' DartApiScope dartApiScope;\n' | |
3107 '$BODY' | |
3108 '}\n') | |
3109 | |
3110 template_parameters = { | |
3111 'CALLBACK_NAME': callback_name, | |
3112 'WEBCORE_CLASS_NAME': self._interface_type_info.native_type(), | |
3113 'PARAMETER_DEFINITIONS': parameter_definitions, | |
3114 } | |
3115 for template in nested_templates: | |
3116 template_parameters['BODY'] = callback | |
3117 callback_emitter = emitter.Emitter() | |
3118 callback_emitter.Emit(template, **template_parameters) | |
3119 callback = ''.join(callback_emitter.Fragments()) | |
3120 | |
3121 self._cpp_definitions_emitter.Emit(callback) | |
3122 | |
3123 def _GenerateParameterAdapter(self, emitter, idl_argument, index): | |
3124 type_info = GetIDLTypeInfo(idl_argument.type) | |
3125 (adapter_type, include_name) = type_info.parameter_adapter_info() | |
3126 if include_name: | |
3127 self._cpp_impl_includes[include_name] = 1 | |
3128 emitter.Emit( | |
3129 '\n' | |
3130 ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)) ;\n' | |
3131 ' if (!$NAME.conversionSuccessful()) {\n' | |
3132 ' exception = $NAME.exception();\n' | |
3133 ' goto fail;\n' | |
3134 ' }\n', | |
3135 ADAPTER_TYPE=adapter_type, | |
3136 NAME=idl_argument.id, | |
3137 INDEX=index + 1) | |
3138 | |
3139 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, | |
3140 native_suffix, is_custom): | |
3141 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) | |
3142 self._members_emitter.Emit( | |
3143 '\n' | |
3144 ' $DART_DECLARATION native "$NATIVE_BINDING";\n', | |
3145 DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding) | |
3146 | |
3147 cpp_callback_name = '%s%s' % (idl_name, native_suffix) | |
3148 self._cpp_resolver_emitter.Emit( | |
3149 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n' | |
3150 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n', | |
3151 ARGC=argument_count, | |
3152 NATIVE_BINDING=native_binding, | |
3153 INTERFACE_NAME=self._interface.id, | |
3154 CPP_CALLBACK_NAME=cpp_callback_name) | |
3155 | |
3156 if is_custom: | |
3157 self._cpp_declarations_emitter.Emit( | |
3158 '\n' | |
3159 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n', | |
3160 CPP_CALLBACK_NAME=cpp_callback_name) | |
3161 | |
3162 return cpp_callback_name | |
3163 | |
3164 def _GenerateWebCoreReflectionAttributeName(self, attr): | |
3165 namespace = 'HTMLNames' | |
3166 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload', | |
3167 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', | |
3168 'onmouseup', 'onresize', 'onscroll', 'onunload'] | |
3169 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions: | |
3170 namespace = 'SVGNames' | |
3171 self._cpp_impl_includes[namespace] = 1 | |
3172 | |
3173 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() | |
3174 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) | |
OLD | NEW |