Chromium Code Reviews| 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 |