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 = [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 |