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 = [g for g in generators if g] | |
antonm
2012/02/13 18:52:46
filter(generators) might be more readable in this
podivilov
2012/02/14 12:46:01
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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
700 """Returns a list of (getter, setter) pairs sorted by name. | 705 """Returns a list of (getter, setter) pairs sorted by name. |
701 | 706 |
702 One element of the pair may be None. | 707 One element of the pair may be None. |
703 """ | 708 """ |
704 names = sorted(set(attr.id for attr in attributes)) | 709 names = sorted(set(attr.id for attr in attributes)) |
705 getters = {} | 710 getters = {} |
706 setters = {} | 711 setters = {} |
707 for attr in attributes: | 712 for attr in attributes: |
708 if attr.is_fc_getter: | 713 if attr.is_fc_getter: |
709 getters[attr.id] = attr | 714 getters[attr.id] = attr |
710 elif attr.is_fc_setter: | 715 elif attr.is_fc_setter and 'Replaceable' not in attr.ext_attrs: |
711 setters[attr.id] = attr | 716 setters[attr.id] = attr |
712 return [(getters.get(id), setters.get(id)) for id in names] | 717 return [(getters.get(id), setters.get(id)) for id in names] |
713 | 718 |
714 | 719 |
715 def _AnalyzeOperation(interface, operations): | 720 def _AnalyzeOperation(interface, operations): |
716 """Makes operation calling convention decision for a set of overloads. | 721 """Makes operation calling convention decision for a set of overloads. |
717 | 722 |
718 Returns: An OperationInfo object. | 723 Returns: An OperationInfo object. |
719 """ | 724 """ |
720 | 725 |
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2219 for getter, setter in event_attrs: | 2224 for getter, setter in event_attrs: |
2220 event = getter or setter | 2225 event = getter or setter |
2221 events_members.Emit( | 2226 events_members.Emit( |
2222 "\n" | 2227 "\n" |
2223 "EventListenerList get $NAME() => _get('$NAME');\n", | 2228 "EventListenerList get $NAME() => _get('$NAME');\n", |
2224 NAME=event.id) | 2229 NAME=event.id) |
2225 | 2230 |
2226 | 2231 |
2227 # ------------------------------------------------------------------------------ | 2232 # ------------------------------------------------------------------------------ |
2228 | 2233 |
2234 class IDLTypeInfo(object): | |
2235 def __init__(self, idl_type, native_type='', ref_counted=True, | |
2236 has_dart_wrapper=True,conversion_template=''): | |
antonm
2012/02/13 18:52:46
nit: space after ,
podivilov
2012/02/14 12:46:01
Done.
| |
2237 self._idl_type = idl_type | |
2238 self._native_type = native_type | |
2239 self._ref_counted = ref_counted | |
2240 self._has_dart_wrapper = has_dart_wrapper | |
2241 self._conversion_template = conversion_template | |
2242 | |
2243 def idl_type(self): | |
2244 return self._idl_type | |
2245 | |
2246 def native_type(self): | |
2247 if self._native_type != '': | |
antonm
2012/02/13 18:52:46
nit: None might be more pythonic variant of missin
podivilov
2012/02/14 12:46:01
Done.
| |
2248 return self._native_type | |
2249 return self._idl_type | |
2250 | |
2251 def parameter_adapter_info(self): | |
2252 native_type = self.native_type() | |
2253 if self._ref_counted: | |
2254 native_type = 'RefPtr< %s >' % native_type | |
2255 if self._has_dart_wrapper: | |
2256 wrapper_type = 'Dart%s' % self.idl_type() | |
2257 adapter_type = 'ParameterAdapter<%s, %s>' % (native_type, wrapper_type) | |
2258 return (adapter_type, wrapper_type) | |
2259 return ('ParameterAdapter< %s >' % native_type, self._idl_type) | |
2260 | |
2261 def parameter_type(self): | |
2262 return '%s*' % self.native_type() | |
2263 | |
2264 def webcore_include(self): | |
2265 if self._idl_type == 'SVGNumber' or self._idl_type == 'SVGPoint': | |
2266 return '' | |
antonm
2012/02/13 18:52:46
return None?
podivilov
2012/02/14 12:46:01
Done.
| |
2267 if self._idl_type.startswith('SVGPathSeg'): | |
2268 return self._idl_type.replace('Abs', '').replace('Rel', '') | |
2269 return self._idl_type | |
2270 | |
2271 def receiver(self): | |
2272 return 'receiver->' | |
2273 | |
2274 def conversion_include(self): | |
2275 return 'Dart%s' % self._idl_type | |
2276 | |
2277 def conversion_cast(self, expression): | |
2278 if self._conversion_template != '': | |
antonm
2012/02/13 18:52:46
nit: same for None
podivilov
2012/02/14 12:46:01
Done.
| |
2279 return self._conversion_template % expression | |
2280 return expression | |
2281 | |
2282 class PrimitiveIDLTypeInfo(IDLTypeInfo): | |
2283 def __init__(self, idl_type, native_type='', ref_counted=False, | |
2284 conversion_template=''): | |
2285 super(PrimitiveIDLTypeInfo, self).__init__(idl_type, | |
2286 native_type=native_type, ref_counted=ref_counted, | |
2287 conversion_template=conversion_template) | |
2288 | |
2289 def parameter_adapter_info(self): | |
2290 native_type = self.native_type() | |
2291 if self._ref_counted: | |
2292 native_type = 'RefPtr< %s >' % native_type | |
2293 return ('ParameterAdapter< %s >' % native_type, None) | |
2294 | |
2295 def parameter_type(self): | |
2296 if self._native_type == 'String': | |
antonm
2012/02/13 18:52:46
_native_type or native_type() ?
podivilov
2012/02/14 12:46:01
agreed, native_type() is better
| |
2297 return 'const String&' | |
2298 return self.native_type() | |
2299 | |
2300 def conversion_include(self): | |
2301 return '' | |
antonm
2012/02/13 18:52:46
return None?
podivilov
2012/02/14 12:46:01
Done.
| |
2302 | |
2303 | |
2304 class SVGTearOffIDLTypeInfo(IDLTypeInfo): | |
2305 def __init__(self, idl_type, native_type='', ref_counted=True): | |
2306 super(SVGTearOffIDLTypeInfo, self).__init__(idl_type, | |
2307 ref_counted=ref_counted) | |
2308 self._native_type = native_type | |
antonm
2012/02/13 18:52:46
why this assignment? maybe pass native_type inste
podivilov
2012/02/14 12:46:01
Done.
| |
2309 | |
2310 def native_type(self): | |
2311 if self._native_type: | |
2312 return self._native_type | |
2313 tear_off_type = 'SVGPropertyTearOff' | |
2314 if self._idl_type.endswith('List'): | |
2315 tear_off_type = 'SVGListPropertyTearOff' | |
2316 return '%s<%s>' % (tear_off_type, self._idl_type) | |
2317 | |
2318 def receiver(self): | |
2319 if self._idl_type.endswith('List'): | |
2320 return 'receiver->' | |
2321 return 'receiver->propertyReference().' | |
2322 | |
2323 | |
2324 _idl_type_registry = { | |
2325 'boolean': PrimitiveIDLTypeInfo('boolean', native_type='bool', conversion_te mplate='static_cast<bool>(%s)'), | |
antonm
2012/02/13 18:52:46
why cast?
podivilov
2012/02/14 12:46:01
There is GC3Dboolean which is not a bool, but unsi
| |
2326 'double': PrimitiveIDLTypeInfo('double'), | |
2327 'int': PrimitiveIDLTypeInfo('int'), | |
2328 'long': PrimitiveIDLTypeInfo('long', native_type='int'), | |
2329 'long long': PrimitiveIDLTypeInfo('long long'), | |
2330 'short': PrimitiveIDLTypeInfo('short', native_type='int', conversion_templat e='static_cast<int>(%s)'), | |
2331 'unsigned int': PrimitiveIDLTypeInfo('unsigned int', native_type='unsigned') , | |
2332 'unsigned long': PrimitiveIDLTypeInfo('unsigned long', native_type='unsigned '), | |
2333 'unsigned long long': PrimitiveIDLTypeInfo('unsigned long long'), | |
2334 'unsigned short': PrimitiveIDLTypeInfo('unsigned short', native_type='int', conversion_template='static_cast<int>(%s)'), | |
antonm
2012/02/13 18:52:46
please, provide comments here and for short why ca
podivilov
2012/02/14 12:46:01
Done.
| |
2335 | |
2336 'Date': PrimitiveIDLTypeInfo('Date', native_type='double'), | |
2337 'DOMString': PrimitiveIDLTypeInfo('DOMString', native_type='String'), | |
2338 'DOMTimeStamp': PrimitiveIDLTypeInfo('DOMTimeStamp'), | |
2339 'object': PrimitiveIDLTypeInfo('object', native_type='ScriptValue'), | |
2340 'SerializedScriptValue': PrimitiveIDLTypeInfo('SerializedScriptValue', ref_c ounted=True), | |
2341 | |
2342 'DOMException': IDLTypeInfo('DOMCoreException'), | |
2343 'EventListener': IDLTypeInfo('EventListener', has_dart_wrapper=False), | |
2344 'EventTarget': IDLTypeInfo('EventTarget', has_dart_wrapper=False), | |
2345 'MediaQueryListListener': IDLTypeInfo('MediaQueryListListener', has_dart_wra pper=False), | |
2346 'OptionsObject': IDLTypeInfo('OptionsObject', has_dart_wrapper=False), | |
2347 | |
2348 'SVGAngle': SVGTearOffIDLTypeInfo('SVGAngle'), | |
2349 'SVGLength': SVGTearOffIDLTypeInfo('SVGLength'), | |
2350 'SVGLengthList': SVGTearOffIDLTypeInfo('SVGLengthList', ref_counted=False), | |
2351 'SVGMatrix': SVGTearOffIDLTypeInfo('SVGMatrix'), | |
2352 'SVGNumber': SVGTearOffIDLTypeInfo('SVGNumber', native_type='SVGPropertyTear Off<float>'), | |
2353 'SVGNumberList': SVGTearOffIDLTypeInfo('SVGNumberList', ref_counted=False), | |
2354 'SVGPathSegList': SVGTearOffIDLTypeInfo('SVGPathSegList', native_type='SVGPa thSegListPropertyTearOff', ref_counted=False), | |
2355 'SVGPoint': SVGTearOffIDLTypeInfo('SVGPoint', native_type='SVGPropertyTearOf f<FloatPoint>'), | |
2356 'SVGPointList': SVGTearOffIDLTypeInfo('SVGPointList', ref_counted=False), | |
2357 'SVGPreserveAspectRatio': SVGTearOffIDLTypeInfo('SVGPreserveAspectRatio'), | |
2358 'SVGRect': SVGTearOffIDLTypeInfo('SVGRect', native_type='SVGPropertyTearOff< FloatRect>'), | |
2359 'SVGStringList': SVGTearOffIDLTypeInfo('SVGStringList', native_type='SVGStat icListPropertyTearOff<SVGStringList>', ref_counted=False), | |
2360 'SVGTransform': SVGTearOffIDLTypeInfo('SVGTransform'), | |
2361 'SVGTransformList': SVGTearOffIDLTypeInfo('SVGTransformList', native_type='S VGTransformListPropertyTearOff', ref_counted=False) | |
2362 } | |
2363 | |
2364 _original_idl_types = { | |
2365 } | |
2366 | |
2367 def GetIDLTypeInfo(idl_type): | |
2368 if idl_type in _original_idl_types: | |
antonm
2012/02/13 18:52:46
those 4 lines can be compressed to _original_idl_t
podivilov
2012/02/14 12:46:01
That's nice!
| |
2369 idl_type_name = _original_idl_types[idl_type] | |
2370 else: | |
2371 idl_type_name = idl_type.id | |
2372 return GetIDLTypeInfoByName(idl_type_name) | |
2373 | |
2374 def GetIDLTypeInfoByName(idl_type_name): | |
2375 if idl_type_name in _idl_type_registry: | |
antonm
2012/02/13 18:52:46
ditto
podivilov
2012/02/14 12:46:01
Done.
| |
2376 return _idl_type_registry[idl_type_name] | |
2377 return IDLTypeInfo(idl_type_name) | |
2378 | |
2229 class NativeImplementationSystem(System): | 2379 class NativeImplementationSystem(System): |
2230 | 2380 |
2231 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir): | 2381 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir): |
2232 super(NativeImplementationSystem, self).__init__( | 2382 super(NativeImplementationSystem, self).__init__( |
2233 templates, database, emitters, output_dir) | 2383 templates, database, emitters, output_dir) |
2234 | 2384 |
2235 self._auxiliary_dir = auxiliary_dir | 2385 self._auxiliary_dir = auxiliary_dir |
2236 self._dom_public_files = [] | 2386 self._dom_public_files = [] |
2237 self._dom_impl_files = [] | 2387 self._dom_impl_files = [] |
2238 self._cpp_header_files = [] | 2388 self._cpp_header_files = [] |
2239 self._cpp_impl_files = [] | 2389 self._cpp_impl_files = [] |
2240 | 2390 |
2241 def InterfaceGenerator(self, | 2391 def InterfaceGenerator(self, |
2242 interface, | 2392 interface, |
2243 common_prefix, | 2393 common_prefix, |
2244 super_interface_name, | 2394 super_interface_name, |
2245 source_filter): | 2395 source_filter): |
2246 interface_name = interface.id | 2396 interface_name = interface.id |
2247 | 2397 |
2248 dart_interface_path = self._FilePathForDartInterface(interface_name) | 2398 dart_interface_path = self._FilePathForDartInterface(interface_name) |
2249 self._dom_public_files.append(dart_interface_path) | 2399 self._dom_public_files.append(dart_interface_path) |
2250 | 2400 |
2401 pure_interfaces = set([ | |
2402 'ElementTimeControl', | |
2403 'ElementTraversal', | |
2404 'MediaQueryListListener', | |
2405 'NodeSelector', | |
2406 'SVGExternalResourcesRequired', | |
2407 'SVGFilterPrimitiveStandardAttributes', | |
2408 'SVGFitToViewBox', | |
2409 'SVGLangSpace', | |
2410 'SVGLocatable', | |
2411 'SVGStylable', | |
2412 'SVGTests', | |
2413 'SVGTransformable', | |
2414 'SVGURIReference', | |
2415 'SVGViewSpec', | |
2416 'SVGZoomAndPan']) | |
2417 if interface_name in pure_interfaces: | |
2418 return None | |
2419 | |
2251 dart_impl_path = self._FilePathForDartImplementation(interface_name) | 2420 dart_impl_path = self._FilePathForDartImplementation(interface_name) |
2252 self._dom_impl_files.append(dart_impl_path) | 2421 self._dom_impl_files.append(dart_impl_path) |
2253 | 2422 |
2254 cpp_header_path = self._FilePathForCppHeader(interface_name) | 2423 cpp_header_path = self._FilePathForCppHeader(interface_name) |
2255 self._cpp_header_files.append(cpp_header_path) | 2424 self._cpp_header_files.append(cpp_header_path) |
2256 | 2425 |
2257 cpp_impl_path = self._FilePathForCppImplementation(interface_name) | 2426 cpp_impl_path = self._FilePathForCppImplementation(interface_name) |
2258 self._cpp_impl_files.append(cpp_impl_path) | 2427 self._cpp_impl_files.append(cpp_impl_path) |
2259 | 2428 |
2260 return NativeImplementationGenerator(interface, super_interface_name, | 2429 return NativeImplementationGenerator(interface, super_interface_name, |
2261 self._emitters.FileEmitter(dart_impl_path), | 2430 self._emitters.FileEmitter(dart_impl_path), |
2262 self._emitters.FileEmitter(cpp_header_path), | 2431 self._emitters.FileEmitter(cpp_header_path), |
2263 self._emitters.FileEmitter(cpp_impl_path), | 2432 self._emitters.FileEmitter(cpp_impl_path), |
2264 self._BaseDefines(interface), | 2433 self._BaseDefines(interface), |
2265 self._templates) | 2434 self._templates) |
2266 | 2435 |
2267 def ProcessCallback(self, interface, info): | 2436 def ProcessCallback(self, interface, info): |
2268 self._dom_public_files.append(self._FilePathForDartInterface(interface.id)) | 2437 self._interface = interface |
2438 | |
2439 dart_interface_path = self._FilePathForDartInterface(self._interface.id) | |
2440 self._dom_public_files.append(dart_interface_path) | |
2441 | |
2442 cpp_header_handlers_emitter = emitter.Emitter() | |
2443 cpp_impl_handlers_emitter = emitter.Emitter() | |
2444 class_name = 'Dart%s' % self._interface.id | |
2445 for operation in interface.operations: | |
2446 return_type = 'void' | |
2447 return_statement = 'm_callback.handleEvent(%s);' % ', '.join([a.id for a i n operation.arguments]) | |
2448 if operation.type.id != 'void': | |
2449 return_type = 'bool' | |
2450 return_statement = 'return %s' % return_statement | |
2451 | |
2452 parameters = [] | |
2453 for argument in operation.arguments: | |
2454 argument_type_info = GetIDLTypeInfo(argument.type) | |
2455 parameters.append('%s %s' % (argument_type_info.parameter_type(), | |
2456 argument.id)) | |
2457 | |
2458 cpp_header_handlers_emitter.Emit( | |
2459 '\n' | |
2460 ' virtual $TYPE handleEvent($PARAMETERS);\n', | |
2461 TYPE=return_type, PARAMETERS=', '.join(parameters)) | |
2462 | |
2463 cpp_impl_handlers_emitter.Emit( | |
2464 '\n' | |
2465 '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n' | |
2466 '{\n' | |
2467 ' $RETURN_STATEMENT\n' | |
antonm
2012/02/13 18:52:46
maybe provide ; here and not at ln. 2447
podivilov
2012/02/14 12:46:01
Done.
| |
2468 '}\n', | |
2469 TYPE=return_type, | |
2470 CLASS_NAME=class_name, | |
2471 PARAMETERS=', '.join(parameters), | |
2472 RETURN_STATEMENT=return_statement) | |
2473 | |
2474 cpp_header_path = self._FilePathForCppHeader(self._interface.id) | |
2475 cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path) | |
2476 cpp_header_emitter.Emit( | |
2477 self._templates.Load('cpp_callback_header.template'), | |
2478 INTERFACE=self._interface.id, | |
2479 HANDLERS=cpp_header_handlers_emitter.Fragments()) | |
2480 | |
2481 cpp_impl_path = self._FilePathForCppImplementation(self._interface.id) | |
2482 self._cpp_impl_files.append(cpp_impl_path) | |
2483 cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path) | |
2484 cpp_impl_emitter.Emit( | |
2485 self._templates.Load('cpp_callback_implementation.template'), | |
2486 INTERFACE=self._interface.id, | |
2487 HANDLERS=cpp_impl_handlers_emitter.Fragments()) | |
2269 | 2488 |
2270 def GenerateLibraries(self, lib_dir): | 2489 def GenerateLibraries(self, lib_dir): |
2271 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) | 2490 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) |
2272 | 2491 |
2273 # Generate dom_public.dart. | 2492 # Generate dom_public.dart. |
2274 self._GenerateLibFile( | 2493 self._GenerateLibFile( |
2275 'dom_public.darttemplate', | 2494 'dom_public.darttemplate', |
2276 os.path.join(self._output_dir, 'dom_public.dart'), | 2495 os.path.join(self._output_dir, 'dom_public.dart'), |
2277 self._dom_public_files, | 2496 self._dom_public_files, |
2278 AUXILIARY_DIR=auxiliary_dir); | 2497 AUXILIARY_DIR=auxiliary_dir); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2310 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argume ntCount))\n' | 2529 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argume ntCount))\n' |
2311 ' return func;\n', | 2530 ' return func;\n', |
2312 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) | 2531 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) |
2313 | 2532 |
2314 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) | 2533 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) |
2315 cpp_resolver_emitter.Emit( | 2534 cpp_resolver_emitter.Emit( |
2316 self._templates.Load('cpp_resolver.template'), | 2535 self._templates.Load('cpp_resolver.template'), |
2317 INCLUDES=includes_emitter.Fragments(), | 2536 INCLUDES=includes_emitter.Fragments(), |
2318 RESOLVER_BODY=resolver_body_emitter.Fragments()) | 2537 RESOLVER_BODY=resolver_body_emitter.Fragments()) |
2319 | 2538 |
2539 # Generate DartDerivedSourcesAll.cpp | |
2540 cpp_all_in_one_path = os.path.join(self._output_dir, | |
2541 'DartDerivedSourcesAll.cpp') | |
2542 | |
2543 includes_emitter = emitter.Emitter() | |
2544 for file in self._cpp_impl_files: | |
2545 path = os.path.relpath(file, os.path.dirname(cpp_all_in_one_path)) | |
2546 includes_emitter.Emit('#include "$PATH"\n', PATH=path) | |
2547 | |
2548 cpp_all_in_one_emitter = self._emitters.FileEmitter(cpp_all_in_one_path) | |
2549 cpp_all_in_one_emitter.Emit( | |
2550 self._templates.Load('cpp_all_in_one.template'), | |
2551 INCLUDES=includes_emitter.Fragments()) | |
2552 | |
2553 # Generate DartResolver.cpp | |
2554 cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp') | |
2555 | |
2556 includes_emitter = emitter.Emitter() | |
2557 resolver_body_emitter = emitter.Emitter() | |
2558 for file in self._cpp_header_files: | |
2559 path = os.path.relpath(file, os.path.dirname(cpp_resolver_path)) | |
2560 includes_emitter.Emit('#include "$PATH"\n', PATH=path) | |
2561 resolver_body_emitter.Emit( | |
2562 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu mentCount))\n' | |
2563 ' return func;\n', | |
2564 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) | |
2565 | |
2566 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) | |
2567 cpp_resolver_emitter.Emit( | |
2568 self._templates.Load('cpp_resolver.template'), | |
2569 INCLUDES=includes_emitter.Fragments(), | |
2570 RESOLVER_BODY=resolver_body_emitter.Fragments()) | |
2571 | |
2320 def Finish(self): | 2572 def Finish(self): |
2321 pass | 2573 pass |
2322 | 2574 |
2323 def _FilePathForDartInterface(self, interface_name): | 2575 def _FilePathForDartInterface(self, interface_name): |
2324 return os.path.join(self._output_dir, 'src', 'interface', | 2576 return os.path.join(self._output_dir, 'src', 'interface', |
2325 '%s.dart' % interface_name) | 2577 '%s.dart' % interface_name) |
2326 | 2578 |
2327 def _FilePathForDartImplementation(self, interface_name): | 2579 def _FilePathForDartImplementation(self, interface_name): |
2328 return os.path.join(self._output_dir, 'dart', | 2580 return os.path.join(self._output_dir, 'dart', |
2329 '%sImplementation.dart' % interface_name) | 2581 '%sImplementation.dart' % interface_name) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2362 self._super_interface = super_interface | 2614 self._super_interface = super_interface |
2363 self._dart_impl_emitter = dart_impl_emitter | 2615 self._dart_impl_emitter = dart_impl_emitter |
2364 self._cpp_header_emitter = cpp_header_emitter | 2616 self._cpp_header_emitter = cpp_header_emitter |
2365 self._cpp_impl_emitter = cpp_impl_emitter | 2617 self._cpp_impl_emitter = cpp_impl_emitter |
2366 self._base_members = base_members | 2618 self._base_members = base_members |
2367 self._templates = templates | 2619 self._templates = templates |
2368 self._current_secondary_parent = None | 2620 self._current_secondary_parent = None |
2369 | 2621 |
2370 def StartInterface(self): | 2622 def StartInterface(self): |
2371 self._class_name = self._ImplClassName(self._interface.id) | 2623 self._class_name = self._ImplClassName(self._interface.id) |
2624 self._interface_type_info = GetIDLTypeInfoByName(self._interface.id) | |
2372 self._members_emitter = emitter.Emitter() | 2625 self._members_emitter = emitter.Emitter() |
2626 self._cpp_declarations_emitter = emitter.Emitter() | |
2627 self._cpp_impl_includes = {} | |
2628 self._cpp_definitions_emitter = emitter.Emitter() | |
2629 self._cpp_resolver_emitter = emitter.Emitter() | |
2630 | |
2631 # Generate constructor. | |
2632 if ('CustomConstructor' in self._interface.ext_attrs or | |
2633 'V8CustomConstructor' in self._interface.ext_attrs or | |
2634 self._interface.id in ['FileReader', 'WebKitCSSMatrix']): | |
antonm
2012/02/13 18:52:46
maybe put this information into type registry?
podivilov
2012/02/14 12:46:01
This check is a temporary hack from old generator.
| |
2635 self._cpp_resolver_emitter.Emit( | |
2636 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' | |
2637 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n' , | |
2638 INTERFACE_NAME=self._interface.id) | |
2639 self._cpp_declarations_emitter.Emit( | |
2640 '\n' | |
2641 'void constructorCallback(Dart_NativeArguments);\n') | |
2373 | 2642 |
2374 def _ImplClassName(self, interface_name): | 2643 def _ImplClassName(self, interface_name): |
2375 return interface_name + 'Implementation' | 2644 return interface_name + 'Implementation' |
2376 | 2645 |
2377 def FinishInterface(self): | 2646 def FinishInterface(self): |
2378 base = self._BaseClassName(self._interface) | 2647 base = self._BaseClassName(self._interface) |
2379 self._dart_impl_emitter.Emit( | 2648 self._dart_impl_emitter.Emit( |
2380 self._templates.Load('dart_implementation.darttemplate'), | 2649 self._templates.Load('dart_implementation.darttemplate'), |
2381 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id, | 2650 CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id, |
2382 MEMBERS=self._members_emitter.Fragments()) | 2651 MEMBERS=self._members_emitter.Fragments()) |
2383 | 2652 |
2384 self._cpp_header_emitter.Emit( | 2653 self._GenerateCppHeader() |
2385 self._templates.Load('cpp_header.template'), | |
2386 INTERFACE=self._interface.id) | |
2387 | 2654 |
2388 self._cpp_impl_emitter.Emit( | 2655 self._cpp_impl_emitter.Emit( |
2389 self._templates.Load('cpp_implementation.template'), | 2656 self._templates.Load('cpp_implementation.template'), |
2390 INTERFACE=self._interface.id) | 2657 INTERFACE=self._interface.id, |
2658 INCLUDES=''.join(['#include "%s.h"\n' % | |
2659 k for k in self._cpp_impl_includes.keys()]), | |
2660 CALLBACKS=self._cpp_definitions_emitter.Fragments(), | |
2661 RESOLVER=self._cpp_resolver_emitter.Fragments()) | |
2662 | |
2663 def _GenerateCppHeader(self): | |
2664 webcore_include = self._interface_type_info.webcore_include() | |
2665 if webcore_include: | |
2666 webcore_include = '#include "%s.h"\n' % webcore_include | |
2667 | |
2668 if ('CustomToJS' in self._interface.ext_attrs or | |
2669 'PureInterface' in self._interface.ext_attrs or | |
2670 self._interface.id in ['DOMWindow', 'Element', 'HTMLElement', 'SVGElemen t']): | |
antonm
2012/02/13 18:52:46
ditto for type registry
podivilov
2012/02/14 12:46:01
Done.
| |
2671 to_dart_value_template = ( | |
2672 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n') | |
2673 else: | |
2674 to_dart_value_template = ( | |
2675 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n' | |
2676 '{\n' | |
2677 ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n' | |
2678 '}\n') | |
2679 to_dart_value_emitter = emitter.Emitter() | |
2680 to_dart_value_emitter.Emit( | |
2681 to_dart_value_template, | |
2682 INTERFACE=self._interface.id, | |
2683 WEBCORE_CLASS_NAME=self._interface_type_info.native_type()) | |
2684 | |
2685 self._cpp_header_emitter.Emit( | |
2686 self._templates.Load('cpp_header.template'), | |
2687 INTERFACE=self._interface.id, | |
2688 WEBCORE_INCLUDE=webcore_include, | |
2689 ADDITIONAL_INCLUDES='', | |
2690 WEBCORE_CLASS_NAME=self._interface_type_info.native_type(), | |
2691 TO_DART_VALUE=to_dart_value_emitter.Fragments(), | |
2692 DECLARATIONS=self._cpp_declarations_emitter.Fragments()) | |
2391 | 2693 |
2392 def AddAttribute(self, getter, setter): | 2694 def AddAttribute(self, getter, setter): |
2695 # FIXME: Dartium does not support attribute event listeners. However, JS | |
2696 # implementation falls back to them when addEventListener is not available. | |
2697 # Make sure addEventListener is available in all EventTargets and remove | |
2698 # this check. | |
2699 if (getter or setter).type.id == 'EventListener': | |
2700 return | |
2701 | |
2702 # FIXME: support 'ImplementedBy'. | |
2703 if 'ImplementedBy' in (getter or setter).ext_attrs: | |
2704 return | |
2705 | |
2706 # FIXME: these should go away. | |
2707 classes_with_unsupported_custom_getters = [ | |
2708 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent', | |
2709 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame', | |
2710 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement', | |
2711 'ScriptProfileNode', 'WebKitAnimation'] | |
2712 if (self._interface.id in classes_with_unsupported_custom_getters and | |
2713 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)): | |
2714 return | |
2715 | |
2393 if getter: | 2716 if getter: |
2394 self._AddGetter(getter) | 2717 self._AddGetter(getter) |
2395 if setter: | 2718 if setter: |
2396 self._AddSetter(setter) | 2719 self._AddSetter(setter) |
2397 | 2720 |
2398 def _AddGetter(self, attr): | 2721 def _AddGetter(self, attr): |
2399 self._members_emitter.Emit( | 2722 dart_declaration = '%s get %s()' % (attr.type.id, attr.id) |
2400 '\n' | 2723 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs |
2401 ' $TYPE get $NAME() native "$(INTERFACE)_$(NAME)_Getter";\n', | 2724 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, |
2402 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) | 2725 dart_declaration, 'Getter', is_custom) |
2726 if is_custom: | |
2727 return | |
2728 | |
2729 arguments = [] | |
2730 if 'Reflect' in attr.ext_attrs: | |
2731 idl_type = GetIDLTypeInfo(attr.type).idl_type() | |
antonm
2012/02/13 18:52:46
again, type registry?
podivilov
2012/02/14 12:46:01
Done.
| |
2732 webcore_function_name = 'getAttribute' | |
2733 if 'URL' in attr.ext_attrs: | |
2734 if 'NonEmpty' in attr.ext_attrs: | |
2735 webcore_function_name = 'getNonEmptyURLAttribute' | |
2736 else: | |
2737 webcore_function_name = 'getURLAttribute' | |
2738 elif idl_type == 'boolean': | |
2739 webcore_function_name = 'hasAttribute' | |
2740 elif idl_type == 'long': | |
2741 webcore_function_name = 'getIntegralAttribute' | |
2742 elif idl_type == 'unsigned long': | |
2743 webcore_function_name = 'getUnsignedIntegralAttribute' | |
2744 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | |
2745 else: | |
2746 if attr.id == 'operator': | |
2747 webcore_function_name = '_operator' | |
2748 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': | |
2749 webcore_function_name = 'svgTarget' | |
2750 else: | |
2751 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)', | |
2752 lambda s: s.group(1).lower(), | |
2753 attr.id) | |
2754 webcore_function_name = re.sub(r'^(create|exclusive)', | |
2755 lambda s: 'is' + s.group(1).capitalize(), | |
2756 webcore_function_name) | |
2757 if attr.type.id.startswith('SVGAnimated'): | |
2758 webcore_function_name += 'Animated' | |
2759 | |
2760 self._GenerateNativeCallback(cpp_callback_name, attr, '', | |
2761 webcore_function_name, arguments, idl_return_type=attr.type, | |
2762 raises_dart_exceptions=attr.get_raises, | |
2763 raises_dom_exceptions=attr.get_raises) | |
2403 | 2764 |
2404 def _AddSetter(self, attr): | 2765 def _AddSetter(self, attr): |
2405 self._members_emitter.Emit( | 2766 dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id) |
2406 '\n' | 2767 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs) |
2407 ' void set $NAME($TYPE) native "$(INTERFACE)_$(NAME)_Setter";\n', | 2768 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, |
2408 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) | 2769 dart_declaration, 'Setter', is_custom) |
2770 if is_custom: | |
2771 return | |
2772 | |
2773 arguments = [] | |
2774 if 'Reflect' in attr.ext_attrs: | |
2775 idl_type = GetIDLTypeInfo(attr.type).idl_type() | |
2776 webcore_function_name = 'setAttribute' | |
2777 if idl_type == 'boolean': | |
2778 webcore_function_name = 'setBooleanAttribute' | |
2779 elif idl_type == 'long': | |
2780 webcore_function_name = 'setIntegralAttribute' | |
2781 elif idl_type == 'unsigned long': | |
2782 webcore_function_name = 'setUnsignedIntegralAttribute' | |
2783 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | |
2784 else: | |
2785 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', | |
2786 lambda s: s.group(1).upper(), | |
2787 attr.id) | |
2788 webcore_function_name = 'set%s' % webcore_function_name | |
2789 if attr.type.id.startswith('SVGAnimated'): | |
2790 webcore_function_name += 'Animated' | |
2791 | |
2792 arguments.append(attr.id) | |
2793 parameter_definitions_emitter = emitter.Emitter() | |
2794 self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0) | |
2795 parameter_definitions = parameter_definitions_emitter.Fragments() | |
2796 self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions, | |
2797 webcore_function_name, arguments, idl_return_type=None, | |
2798 raises_dart_exceptions=True, | |
2799 raises_dom_exceptions=attr.set_raises) | |
2409 | 2800 |
2410 def _HasNativeIndexGetter(self, interface): | 2801 def _HasNativeIndexGetter(self, interface): |
2411 return ('HasCustomIndexGetter' in interface.ext_attrs or | 2802 return ('HasCustomIndexGetter' in interface.ext_attrs or |
2412 'HasNumericIndexGetter' in interface.ext_attrs) | 2803 'HasNumericIndexGetter' in interface.ext_attrs) |
2413 | 2804 |
2414 def _EmitNativeIndexGetter(self, interface, element_type): | 2805 def _EmitNativeIndexGetter(self, interface, element_type): |
2415 native_binding = '%s_numericIndexGetter_Callback' % interface.id | 2806 dart_declaration = '%s operator[](int index)' % element_type |
2416 self._members_emitter.Emit( | 2807 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration, |
2417 '\n' | 2808 'Callback', True) |
2418 ' $TYPE operator[](int index) native "$NATIVE_BINDING";\n', | |
2419 TYPE=element_type, NATIVE_BINDING=native_binding) | |
2420 | 2809 |
2421 def _EmitNativeIndexSetter(self, interface, element_type): | 2810 def _EmitNativeIndexSetter(self, interface, element_type): |
2422 native_binding = '%s_numericIndexSetter_Callback' % self._interface.id | 2811 dart_declaration = 'void operator[]=(int index, %s value)' % element_type |
2423 self._members_emitter.Emit( | 2812 self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration, |
2424 '\n' | 2813 'Callback', True) |
2425 ' void operator[]=(int index, $TYPE value) native "$NATIVE_BINDING";\n' , | |
2426 TYPE=element_type, NATIVE_BINDING=native_binding) | |
2427 | 2814 |
2428 def AddOperation(self, info): | 2815 def AddOperation(self, info): |
2429 """ | 2816 """ |
2430 Arguments: | 2817 Arguments: |
2431 info: An OperationInfo object. | 2818 info: An OperationInfo object. |
2432 """ | 2819 """ |
2433 | 2820 |
2434 if 'Custom' in info.overloads[0].ext_attrs: | 2821 if 'Custom' in info.overloads[0].ext_attrs: |
2435 self._members_emitter.Emit( | 2822 parameters = info.ParametersImplementationDeclaration() |
2436 '\n' | 2823 dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters) |
2437 ' $TYPE $NAME($PARAMETERS) native "$(INTERFACE)_$(NAME)_Callback";\ n', | 2824 argument_count = 1 + len(info.arg_infos) |
2438 TYPE=info.type_name, | 2825 self._GenerateNativeBinding(info.name, argument_count, dart_declaration, |
2439 NAME=info.name, | 2826 'Callback', True) |
2440 PARAMETERS=info.ParametersImplementationDeclaration(), | 2827 return |
2441 INTERFACE=self._interface.id) | |
2442 return | |
2443 | 2828 |
2444 body = self._members_emitter.Emit( | 2829 body = self._members_emitter.Emit( |
2445 '\n' | 2830 '\n' |
2446 ' $TYPE $NAME($PARAMETERS) {\n' | 2831 ' $TYPE $NAME($PARAMETERS) {\n' |
2447 '$!BODY' | 2832 '$!BODY' |
2448 ' }\n', | 2833 ' }\n', |
2449 TYPE=info.type_name, | 2834 TYPE=info.type_name, |
2450 NAME=info.name, | 2835 NAME=info.name, |
2451 PARAMETERS=info.ParametersImplementationDeclaration()) | 2836 PARAMETERS=info.ParametersImplementationDeclaration()) |
2452 | 2837 |
2453 # Process in order of ascending number of arguments to ensure missing | 2838 # Process in order of ascending number of arguments to ensure missing |
2454 # optional arguments are processed early. | 2839 # optional arguments are processed early. |
2455 overloads = sorted(info.overloads, | 2840 overloads = sorted(info.overloads, |
2456 key=lambda overload: len(overload.arguments)) | 2841 key=lambda overload: len(overload.arguments)) |
2457 self._native_version = 0 | 2842 self._native_version = 0 |
2458 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) | 2843 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads) |
2459 if fallthrough: | 2844 if fallthrough: |
2460 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 2845 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
2461 | 2846 |
2462 def GenerateSingleOperation(self, emitter, info, indent, operation): | 2847 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation): |
2463 """Generates a call to a single operation. | 2848 """Generates a call to a single operation. |
2464 | 2849 |
2465 Arguments: | 2850 Arguments: |
2466 emitter: an Emitter for the body of a block of code. | 2851 dispatch_emitter: an dispatch_emitter for the body of a block of code. |
2467 info: the compound information about the operation and its overloads. | 2852 info: the compound information about the operation and its overloads. |
2468 indent: an indentation string for generated code. | 2853 indent: an indentation string for generated code. |
2469 operation: the IDLOperation to call. | 2854 operation: the IDLOperation to call. |
2470 """ | 2855 """ |
2471 | 2856 |
2472 arg_names = [info.arg_infos[i][0] | 2857 # FIXME: support ImplementedBy callbacks. |
2473 for (i, arg) in enumerate(operation.arguments)] | 2858 if 'ImplementedBy' in operation.ext_attrs: |
2859 return | |
2860 | |
2861 for op in self._interface.operations: | |
2862 if op.id != operation.id or len(op.arguments) <= len(operation.arguments): | |
2863 continue | |
2864 next_argument = op.arguments[len(operation.arguments)] | |
2865 if next_argument.is_optional and 'Callback' in next_argument.ext_attrs: | |
2866 # FIXME: '[Optional, Callback]' arguments could be non-optional in | |
2867 # webcore. We need to fix overloads handling to generate native | |
2868 # callbacks properly. | |
2869 return | |
2474 | 2870 |
2475 self._native_version += 1 | 2871 self._native_version += 1 |
2476 native_name = '_%s' % info.name | 2872 native_name = info.name |
2477 if self._native_version > 1: | 2873 if self._native_version > 1: |
2478 native_name = '%s_%s' % (native_name, self._native_version) | 2874 native_name = '%s_%s' % (native_name, self._native_version) |
2479 | 2875 argument_list = ', '.join([info.arg_infos[i][0] |
2480 argument_expressions = ', '.join(arg_names) | 2876 for (i, arg) in enumerate(operation.arguments)]) |
2877 | |
2878 # Generate dispatcher. | |
2481 if info.type_name != 'void': | 2879 if info.type_name != 'void': |
2482 emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n', | 2880 dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n', |
2483 INDENT=indent, | 2881 INDENT=indent, |
2484 NATIVENAME=native_name, | 2882 NATIVENAME=native_name, |
2485 ARGS=argument_expressions) | 2883 ARGS=argument_list) |
2486 else: | 2884 else: |
2487 emitter.Emit('$(INDENT)$NATIVENAME($ARGS);\n' | 2885 dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n' |
2488 '$(INDENT)return;\n', | 2886 '$(INDENT)return;\n', |
2489 INDENT=indent, | 2887 INDENT=indent, |
2490 NATIVENAME=native_name, | 2888 NATIVENAME=native_name, |
2491 ARGS=argument_expressions) | 2889 ARGS=argument_list) |
2492 | 2890 # Generate binding. |
2493 self._members_emitter.Emit(' $TYPE $NATIVE_NAME($PARAMS) native ' | 2891 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name, |
2494 '"$(INTERFACE)$(NATIVE_NAME)_Callback";\n', | 2892 argument_list) |
2495 NATIVE_NAME=native_name, | 2893 is_custom = 'Custom' in operation.ext_attrs |
2496 TYPE=info.type_name, | 2894 cpp_callback_name = self._GenerateNativeBinding( |
2497 PARAMS=', '.join(arg_names), | 2895 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback', |
2498 INTERFACE=self._interface.id) | 2896 is_custom) |
2897 if is_custom: | |
2898 return | |
2899 | |
2900 # Generate callback. | |
2901 webcore_function_name = operation.id | |
2902 if 'ImplementationFunction' in operation.ext_attrs: | |
2903 webcore_function_name = operation.ext_attrs['ImplementationFunction'] | |
2904 | |
2905 parameter_definitions_emitter = emitter.Emitter() | |
2906 raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises | |
2907 arguments = [] | |
2908 | |
2909 # Process 'CallWith' argument. | |
2910 if ('CallWith' in operation.ext_attrs and | |
2911 operation.ext_attrs['CallWith'] == 'ScriptExecutionContext'): | |
2912 parameter_definitions_emitter.Emit( | |
2913 ' ScriptExecutionContext* context = DartUtilities::scriptExecut ionContext();\n' | |
2914 ' if (!context)\n' | |
2915 ' return;\n') | |
2916 arguments.append('context') | |
2917 | |
2918 # Process Dart arguments. | |
2919 for (i, argument) in enumerate(operation.arguments): | |
2920 if i == len(operation.arguments) - 1 and 'CustomArgumentHandling' in opera tion.ext_attrs: | |
2921 # FIXME: we are skipping last argument here because it was added in | |
2922 # supplemental dart.idl. Cleanup dart.idl and remove this check. | |
2923 break | |
2924 self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i) | |
2925 arguments.append(argument.id) | |
2926 | |
2927 if operation.id in ['addEventListener', 'removeEventListener']: | |
2928 # addEventListener's and removeEventListener's last argument is marked | |
2929 # as optional in idl, but is not optional in webcore implementation. | |
2930 if len(operation.arguments) == 2: | |
2931 arguments.append('false') | |
2932 | |
2933 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty': | |
2934 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart | |
2935 # idl, but is not optional in webcore implementation. | |
2936 if len(operation.arguments) == 2: | |
2937 arguments.append('String()') | |
2938 | |
2939 # Process auxiliary arguments. | |
2940 if 'CustomArgumentHandling' in operation.ext_attrs: | |
2941 raises_dart_exceptions = True | |
2942 self._cpp_impl_includes['ScriptArguments'] = 1 | |
2943 self._cpp_impl_includes['ScriptCallStack'] = 1 | |
2944 self._cpp_impl_includes['V8Proxy'] = 1 | |
2945 self._cpp_impl_includes['v8'] = 1 | |
2946 parameter_definitions_emitter.Emit( | |
2947 ' v8::HandleScope handleScope;\n' | |
antonm
2012/02/13 18:52:46
separate template file?
podivilov
2012/02/14 12:46:01
It's convenient to have small snippets inline, I t
| |
2948 ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilit ies::domWindowForCurrentIsolate()->frame()));\n' | |
2949 ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $IN DEX);\n' | |
2950 ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::create ScriptArguments(customArgument, exception));\n' | |
2951 ' if (!scriptArguments)\n' | |
2952 ' goto fail;\n' | |
2953 ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::create ScriptCallStack());\n' | |
2954 ' if (!scriptCallStack->size())\n' | |
2955 ' return;\n', | |
2956 INDEX=len(operation.arguments)) | |
2957 arguments.extend(['scriptArguments', 'scriptCallStack']) | |
2958 | |
2959 if 'NeedsUserGestureCheck' in operation.ext_attrs: | |
2960 arguments.extend('DartUtilities::processingUserGesture') | |
2961 | |
2962 parameter_definitions = parameter_definitions_emitter.Fragments() | |
2963 self._GenerateNativeCallback(cpp_callback_name, operation, | |
2964 parameter_definitions, webcore_function_name, arguments, | |
2965 idl_return_type=operation.type, | |
2966 raises_dart_exceptions=raises_dart_exceptions, | |
2967 raises_dom_exceptions=operation.raises) | |
2968 | |
2969 def _GenerateNativeCallback(self, callback_name, idl_node, | |
2970 parameter_definitions, function_name, arguments, idl_return_type, | |
2971 raises_dart_exceptions, raises_dom_exceptions): | |
2972 receiver = self._interface_type_info.receiver() | |
2973 if raises_dom_exceptions: | |
2974 arguments.append('ec') | |
2975 callback = '%s%s(%s)' % (receiver, function_name, ', '.join(arguments)) | |
2976 | |
2977 nested_templates = [] | |
2978 if idl_return_type and idl_return_type.id != 'void': | |
2979 return_type_info = GetIDLTypeInfo(idl_return_type) | |
2980 conversion_cast = return_type_info.conversion_cast('$BODY') | |
2981 if isinstance(return_type_info, SVGTearOffIDLTypeInfo): | |
2982 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', | |
2983 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] | |
2984 conversion_cast = '%s::create($BODY)' | |
2985 if self._interface.id.startswith('SVGAnimated'): | |
2986 conversion_cast = 'static_cast<%s*>($BODY)' | |
2987 elif return_type_info.idl_type() == 'SVGStringList': | |
2988 conversion_cast = '%s::create(receiver, $BODY)' | |
2989 elif self._interface.id.endswith('List'): | |
2990 conversion_cast = 'static_cast<%s*>($BODY.get())' | |
2991 elif return_type_info.idl_type() in svg_primitive_types: | |
2992 conversion_cast = '%s::create($BODY)' | |
2993 else: | |
2994 conversion_cast = 'static_cast<%s*>($BODY)' | |
2995 conversion_cast = conversion_cast % return_type_info.native_type() | |
2996 nested_templates.append(conversion_cast) | |
2997 | |
2998 if return_type_info.conversion_include(): | |
2999 self._cpp_impl_includes[return_type_info.conversion_include()] = 1 | |
3000 if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and | |
3001 'ConvertNullStringTo' in idl_node.ext_attrs): | |
3002 nested_templates.append('$BODY, ConvertDefaultToNull') | |
3003 nested_templates.append( | |
3004 ' Dart_Handle returnValue = toDartValue($BODY);\n' | |
3005 ' if (returnValue)\n' | |
3006 ' Dart_SetReturnValue(args, returnValue);\n') | |
3007 else: | |
3008 nested_templates.append(' $BODY;\n') | |
3009 | |
3010 if raises_dom_exceptions: | |
3011 nested_templates.append( | |
3012 ' ExceptionCode ec = 0;\n' | |
3013 '$BODY' | |
3014 ' if (UNLIKELY(ec)) {\n' | |
3015 ' exception = DartDOMWrapper::exceptionCodeToDartException( ec);\n' | |
3016 ' goto fail;\n' | |
3017 ' }\n') | |
3018 | |
3019 nested_templates.append( | |
3020 ' {\n' | |
3021 ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBC ORE_CLASS_NAME >(args);\n' | |
3022 '$PARAMETER_DEFINITIONS' | |
3023 '\n' | |
3024 '$BODY' | |
3025 ' return;\n' | |
3026 ' }\n') | |
3027 | |
3028 if raises_dart_exceptions: | |
3029 nested_templates.append( | |
3030 ' Dart_Handle exception;\n' | |
3031 '$BODY' | |
3032 '\n' | |
3033 'fail:\n' | |
3034 ' Dart_ThrowException(exception);\n' | |
3035 ' ASSERT_NOT_REACHED();\n') | |
3036 | |
3037 nested_templates.append( | |
3038 '\n' | |
3039 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n' | |
3040 '{\n' | |
3041 ' DartApiScope dartApiScope;\n' | |
3042 '$BODY' | |
3043 '}\n') | |
3044 | |
3045 template_parameters = { | |
3046 'CALLBACK_NAME': callback_name, | |
3047 'WEBCORE_CLASS_NAME': self._interface_type_info.native_type(), | |
3048 'PARAMETER_DEFINITIONS': parameter_definitions, | |
3049 } | |
3050 for template in nested_templates: | |
3051 template_parameters['BODY'] = callback | |
3052 callback_emitter = emitter.Emitter() | |
3053 callback_emitter.Emit(template, **template_parameters) | |
3054 callback = ''.join(callback_emitter.Fragments()) | |
3055 | |
3056 self._cpp_definitions_emitter.Emit(callback) | |
3057 | |
3058 def _GenerateParameterAdapter(self, emitter, idl_argument, index): | |
3059 type_info = GetIDLTypeInfo(idl_argument.type) | |
3060 (adapter_type, include_name) = type_info.parameter_adapter_info() | |
3061 if include_name: | |
3062 self._cpp_impl_includes[include_name] = 1 | |
3063 emitter.Emit( | |
3064 '\n' | |
3065 ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)) ;\n' | |
3066 ' if (!$NAME.conversionSuccessful()) {\n' | |
3067 ' exception = $NAME.exception();\n' | |
3068 ' goto fail;\n' | |
3069 ' }\n', | |
3070 ADAPTER_TYPE=adapter_type, | |
3071 NAME=idl_argument.id, | |
3072 INDEX=index + 1) | |
3073 | |
3074 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, | |
3075 native_suffix, is_custom): | |
3076 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) | |
3077 self._members_emitter.Emit( | |
3078 '\n' | |
3079 ' $DART_DECLARATION native "$NATIVE_BINDING";\n', | |
3080 DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding) | |
3081 | |
3082 cpp_callback_name = '%s%s' % (idl_name, native_suffix) | |
3083 self._cpp_resolver_emitter.Emit( | |
3084 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n' | |
3085 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n', | |
3086 ARGC=argument_count, | |
3087 NATIVE_BINDING=native_binding, | |
3088 INTERFACE_NAME=self._interface.id, | |
3089 CPP_CALLBACK_NAME=cpp_callback_name) | |
3090 | |
3091 if is_custom: | |
3092 self._cpp_declarations_emitter.Emit( | |
3093 '\n' | |
3094 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n', | |
3095 CPP_CALLBACK_NAME=cpp_callback_name) | |
3096 | |
3097 return cpp_callback_name | |
3098 | |
3099 def _GenerateWebCoreReflectionAttributeName(self, attr): | |
3100 namespace = 'HTMLNames' | |
3101 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload', | |
3102 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', | |
3103 'onmouseup', 'onresize', 'onscroll', 'onunload'] | |
3104 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions: | |
3105 namespace = 'SVGNames' | |
3106 self._cpp_impl_includes[namespace] = 1 | |
3107 | |
3108 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() | |
3109 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) | |
OLD | NEW |