Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: client/dom/scripts/dartgenerator.py

Issue 9290020: Add support for native bindings generation to dartgenerator.py. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2011, 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 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 interface.parents = filter(HasAnnotations, interface.parents) 394 interface.parents = filter(HasAnnotations, interface.parents)
395 else: 395 else:
396 database.DeleteInterface(interface.id) 396 database.DeleteInterface(interface.id)
397 397
398 self.FilterMembersWithUnidentifiedTypes(database) 398 self.FilterMembersWithUnidentifiedTypes(database)
399 399
400 400
401 def Generate(self, database, output_dir, 401 def Generate(self, database, output_dir,
402 module_source_preference=[], source_filter=None, 402 module_source_preference=[], source_filter=None,
403 super_database=None, common_prefix=None, super_map={}, 403 super_database=None, common_prefix=None, super_map={},
404 lib_dir = None): 404 lib_dir=None, native=False):
405 """Generates Dart and JS files for the loaded interfaces. 405 """Generates Dart and JS files for the loaded interfaces.
406 406
407 Args: 407 Args:
408 database -- database containing interfaces to generate code for. 408 database -- database containing interfaces to generate code for.
409 output_dir -- directory to write generated files to. 409 output_dir -- directory to write generated files to.
410 module_source_preference -- priority order list of source annotations to 410 module_source_preference -- priority order list of source annotations to
411 use when choosing a module name, if none specified uses the module name 411 use when choosing a module name, if none specified uses the module name
412 from the database. 412 from the database.
413 source_filter -- if specified, only outputs interfaces that have one of 413 source_filter -- if specified, only outputs interfaces that have one of
414 these source annotation and rewrites the names of superclasses not 414 these source annotation and rewrites the names of superclasses not
415 marked with this source to use the common prefix. 415 marked with this source to use the common prefix.
416 super_database -- database containing super interfaces that the generated 416 super_database -- database containing super interfaces that the generated
417 interfaces should extend. 417 interfaces should extend.
418 common_prefix -- prefix for the common library, if any. 418 common_prefix -- prefix for the common library, if any.
419 lib_file_path -- filename for generated .lib file, None if not required. 419 lib_file_path -- filename for generated .lib file, None if not required.
420 lib_template -- template file in this directory for generated lib file. 420 lib_template -- template file in this directory for generated lib file.
421 """ 421 """
422 422
423 self._emitters = multiemitter.MultiEmitter() 423 self._emitters = multiemitter.MultiEmitter()
424 self._database = database 424 self._database = database
425 self._output_dir = output_dir 425 self._output_dir = output_dir
426 426
427 self._ComputeInheritanceClosure() 427 self._ComputeInheritanceClosure()
428 428
429 self._systems = []
430
429 interface_system = InterfacesSystem( 431 interface_system = InterfacesSystem(
430 TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']), 432 TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']),
431 self._database, self._emitters, self._output_dir) 433 self._database, self._emitters, self._output_dir)
434 self._systems.append(interface_system)
432 435
433 wrapping_system = WrappingImplementationSystem( 436 if native:
434 TemplateLoader(self._template_dir, ['dom/wrapping', 'dom', '']), 437 native_system = NativeImplementationSystem(
435 self._database, self._emitters, self._output_dir) 438 TemplateLoader(self._template_dir, ['dom/native', 'dom', '']),
439 self._database, self._emitters, self._auxiliary_dir,
440 self._output_dir)
441 self._systems.append(native_system)
442 else:
sra1 2012/01/26 05:35:30 Is it possible to generate everything at once?
podivilov 2012/01/26 08:28:51 Yes, but it would be a little bit slower, will pro
sra1 2012/01/26 18:32:16 I want to make sure that all targets *can* be gene
podivilov 2012/01/30 19:23:50 Added --systems switch. It defaults to 'frog,wrapp
443 wrapping_system = WrappingImplementationSystem(
444 TemplateLoader(self._template_dir, ['dom/wrapping', 'dom', '']),
445 self._database, self._emitters, self._output_dir)
436 446
437 # Makes interface files available for listing in the library for the 447 # Makes interface files available for listing in the library for the
438 # wrapping implementation. 448 # wrapping implementation.
439 449
440 wrapping_system._interface_system = interface_system 450 wrapping_system._interface_system = interface_system
451 self._systems.append(wrapping_system)
441 452
442 frog_system = FrogSystem( 453 frog_system = FrogSystem(
443 TemplateLoader(self._template_dir, ['dom/frog', 'dom', '']), 454 TemplateLoader(self._template_dir, ['dom/frog', 'dom', '']),
444 self._database, self._emitters, self._output_dir) 455 self._database, self._emitters, self._output_dir)
445 456
446 frog_system._interface_system = interface_system 457 frog_system._interface_system = interface_system
458 self._systems.append(frog_system)
447 459
448 self._systems = [interface_system,
449 wrapping_system,
450 frog_system]
451 460
452 # Render all interfaces into Dart and save them in files. 461 # Render all interfaces into Dart and save them in files.
453 for interface in database.GetInterfaces(): 462 for interface in database.GetInterfaces():
454 463
455 super_interface = None 464 super_interface = None
456 super_name = interface.id 465 super_name = interface.id
457 466
458 if not _MatchSourceFilter(source_filter, interface): 467 if not _MatchSourceFilter(source_filter, interface):
459 # Skip this interface since it's not present in the required source 468 # Skip this interface since it's not present in the required source
460 _logger.info('Omitting interface - %s' % interface.id) 469 _logger.info('Omitting interface - %s' % interface.id)
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 1332
1324 1333
1325 def StartInterface(self): 1334 def StartInterface(self):
1326 interface = self._interface 1335 interface = self._interface
1327 interface_name = interface.id 1336 interface_name = interface.id
1328 1337
1329 self._class_name = self._ImplClassName(interface_name) 1338 self._class_name = self._ImplClassName(interface_name)
1330 self._type_map.Emit(' "$INTERFACE": native_$(CLASS)_create_$(CLASS),\n', 1339 self._type_map.Emit(' "$INTERFACE": native_$(CLASS)_create_$(CLASS),\n',
1331 INTERFACE=interface_name, CLASS=self._class_name) 1340 INTERFACE=interface_name, CLASS=self._class_name)
1332 1341
1333 base = 'DOMWrapperBase' 1342 base = self._BaseClassName(interface)
1334 if interface.parents:
1335 supertype = interface.parents[0].type.id
1336 # FIXME: We're currently injecting List<..> and EventTarget as
1337 # supertypes in dart.idl. We should annotate/preserve as
1338 # attributes instead. For now, this hack lets the interfaces
1339 # inherit, but not the classes.
1340 if (not _IsDartListType(supertype) and
1341 not supertype == 'EventTarget'):
1342 base = self._ImplClassName(supertype)
1343 if _IsDartCollectionType(supertype):
1344 # List methods are injected in AddIndexer.
1345 pass
1346 elif supertype == 'EventTarget':
1347 # Most implementors of EventTarget specify the EventListener operations
1348 # again. If the operations are not specified, try to inherit from the
1349 # EventTarget implementation.
1350 #
1351 # Applies to MessagePort.
1352 if not [op for op in interface.operations if op.id == 'addEventListener' ]:
1353 base = self._ImplClassName(supertype)
1354 else:
1355 base = self._ImplClassName(supertype)
1356 1343
1357 (self._members_emitter, 1344 (self._members_emitter,
1358 self._top_level_emitter) = self._dart_code.Emit( 1345 self._top_level_emitter) = self._dart_code.Emit(
1359 '\n' 1346 '\n'
1360 'class $CLASS extends $BASE implements $INTERFACE {\n' 1347 'class $CLASS extends $BASE implements $INTERFACE {\n'
1361 ' $CLASS() : super() {}\n' 1348 ' $CLASS() : super() {}\n'
1362 '\n' 1349 '\n'
1363 ' static create_$CLASS() native {\n' 1350 ' static create_$CLASS() native {\n'
1364 ' return new $CLASS();\n' 1351 ' return new $CLASS();\n'
1365 ' }\n' 1352 ' }\n'
1366 '$!MEMBERS' 1353 '$!MEMBERS'
1367 '\n' 1354 '\n'
1368 ' String get typeName() { return "$INTERFACE"; }\n' 1355 ' String get typeName() { return "$INTERFACE"; }\n'
1369 '}\n' 1356 '}\n'
1370 '$!TOP_LEVEL', 1357 '$!TOP_LEVEL',
1371 CLASS=self._class_name, BASE=base, INTERFACE=interface_name) 1358 CLASS=self._class_name, BASE=base, INTERFACE=interface_name)
1372 1359
1373 def _ImplClassName(self, type_name): 1360 def _ImplClassName(self, type_name):
1374 return '_' + type_name + 'WrappingImplementation' 1361 return '_' + type_name + 'WrappingImplementation'
1375 1362
1363 def _BaseClassName(self, interface):
antonm 2012/01/26 11:06:14 it looks like you can simplify this function w/ ea
podivilov 2012/01/26 14:18:57 Done.
1364 base = 'DOMWrapperBase'
1365
1366 if not interface.parents:
1367 return base
1368
1369 supertype = interface.parents[0].type.id
1370 # FIXME: We're currently injecting List<..> and EventTarget as
1371 # supertypes in dart.idl. We should annotate/preserve as
1372 # attributes instead. For now, this hack lets the interfaces
1373 # inherit, but not the classes.
1374 if (not _IsDartListType(supertype) and
1375 not supertype == 'EventTarget'):
1376 base = self._ImplClassName(supertype)
1377 if _IsDartCollectionType(supertype):
1378 # List methods are injected in AddIndexer.
1379 pass
1380 elif supertype == 'EventTarget':
1381 # Most implementors of EventTarget specify the EventListener operations
1382 # again. If the operations are not specified, try to inherit from the
1383 # EventTarget implementation.
1384 #
1385 # Applies to MessagePort.
1386 if not [op for op in interface.operations if op.id == 'addEventListener']:
1387 base = self._ImplClassName(supertype)
1388 else:
1389 base = self._ImplClassName(supertype)
1390
1391 return base
1392
1376 def FinishInterface(self): 1393 def FinishInterface(self):
1377 """.""" 1394 """."""
1378 pass 1395 pass
1379 1396
1380 def AddConstant(self, constant): 1397 def AddConstant(self, constant):
1381 # Constants are already defined on the interface. 1398 # Constants are already defined on the interface.
1382 pass 1399 pass
1383 1400
1384 def _MethodName(self, prefix, name): 1401 def _MethodName(self, prefix, name):
1385 method_name = prefix + name 1402 method_name = prefix + name
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 # interface Y extends X, List<T> ... 1476 # interface Y extends X, List<T> ...
1460 # 1477 #
1461 # In the non-root case we have to choose between: 1478 # In the non-root case we have to choose between:
1462 # 1479 #
1463 # class YImpl extends XImpl { add List<T> methods; } 1480 # class YImpl extends XImpl { add List<T> methods; }
1464 # 1481 #
1465 # and 1482 # and
1466 # 1483 #
1467 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; } 1484 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
1468 # 1485 #
1469 if ('HasIndexGetter' in self._interface.ext_attrs or 1486 if (self._HasNativeIndexGetter(self._interface)):
antonm 2012/01/26 11:06:14 nit: no need in extra ()
podivilov 2012/01/26 14:18:57 Done.
1470 'HasNumericIndexGetter' in self._interface.ext_attrs): 1487 self._EmitNativeIndexGetter(self._interface, element_type)
1471 method_name = '_index'
1472 self._members_emitter.Emit(
1473 '\n'
1474 ' $TYPE operator[](int index) { return $METHOD(this, index); }\n'
1475 ' static $TYPE $METHOD(var _this, int index) native;\n',
1476 TYPE=element_type, METHOD=method_name)
1477 self._js_code.Emit(
1478 '\n'
1479 'function native_$(CLASS)_$(METHOD)(_this, index) {\n'
1480 ' try {\n'
1481 ' return __dom_wrap(_this.$dom[index]);\n'
1482 ' } catch (e) {\n'
1483 ' throw __dom_wrap_exception(e);\n'
1484 ' }\n'
1485 '}\n',
1486 CLASS=self._class_name, METHOD=method_name)
1487 else: 1488 else:
1488 self._members_emitter.Emit( 1489 self._members_emitter.Emit(
1489 '\n' 1490 '\n'
1490 ' $TYPE operator[](int index) {\n' 1491 ' $TYPE operator[](int index) {\n'
1491 ' return item(index);\n' 1492 ' return item(index);\n'
1492 ' }\n', 1493 ' }\n',
1493 TYPE=element_type) 1494 TYPE=element_type)
1494 1495
1495 1496
1496 if 'HasCustomIndexSetter' in self._interface.ext_attrs: 1497 if 'HasCustomIndexSetter' in self._interface.ext_attrs:
antonm 2012/01/26 11:06:14 for symmetry, shouldn't you add _HasNativeIndexSet
podivilov 2012/01/26 14:18:57 Done.
1497 method_name = '_set_index' 1498 self._EmitNativeIndexSetter(self._interface, element_type)
1498 self._members_emitter.Emit(
1499 '\n'
1500 ' void operator[]=(int index, $TYPE value) {\n'
1501 ' return $METHOD(this, index, value);\n'
1502 ' }\n'
1503 ' static $METHOD(_this, index, value) native;\n',
1504 TYPE=element_type, METHOD=method_name)
1505 self._js_code.Emit(
1506 '\n'
1507 'function native_$(CLASS)_$(METHOD)(_this, index, value) {\n'
1508 ' try {\n'
1509 ' return _this.$dom[index] = __dom_unwrap(value);\n'
1510 ' } catch (e) {\n'
1511 ' throw __dom_wrap_exception(e);\n'
1512 ' }\n'
1513 '}\n',
1514 CLASS=self._class_name, METHOD=method_name)
1515 else: 1499 else:
1516 self._members_emitter.Emit( 1500 self._members_emitter.Emit(
1517 '\n' 1501 '\n'
1518 ' void operator[]=(int index, $TYPE value) {\n' 1502 ' void operator[]=(int index, $TYPE value) {\n'
1519 ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n' 1503 ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
1520 ' }\n', 1504 ' }\n',
1521 TYPE=element_type) 1505 TYPE=element_type)
1522 1506
1523 self._members_emitter.Emit( 1507 self._members_emitter.Emit(
1524 '\n' 1508 '\n'
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 '\n' 1586 '\n'
1603 ' bool isEmpty() {\n' 1587 ' bool isEmpty() {\n'
1604 ' return length == 0;\n' 1588 ' return length == 0;\n'
1605 ' }\n' 1589 ' }\n'
1606 '\n' 1590 '\n'
1607 ' Iterator<$TYPE> iterator() {\n' 1591 ' Iterator<$TYPE> iterator() {\n'
1608 ' return new _FixedSizeListIterator<$TYPE>(this);\n' 1592 ' return new _FixedSizeListIterator<$TYPE>(this);\n'
1609 ' }\n', 1593 ' }\n',
1610 TYPE=element_type) 1594 TYPE=element_type)
1611 1595
1596 def _HasNativeIndexGetter(self, interface):
1597 return ('HasIndexGetter' in interface.ext_attrs or
1598 'HasNumericIndexGetter' in interface.ext_attrs)
1599
1600 def _EmitNativeIndexGetter(self, interface, element_type):
1601 method_name = '_index'
1602 self._members_emitter.Emit(
1603 '\n'
antonm 2012/01/26 11:06:14 looks like if you keep a blank line before $MEMBER
podivilov 2012/01/26 14:18:57 You could not rely on ordering here, native index
1604 ' $TYPE operator[](int index) { return $METHOD(this, index); }\n'
antonm 2012/01/26 11:06:14 $TYPE operator[](int index) => $METHOD(this, index
podivilov 2012/01/26 14:18:57 This change should produce zero diff in wrapping d
1605 ' static $TYPE $METHOD(var _this, int index) native;\n',
1606 TYPE=element_type, METHOD=method_name)
1607 self._js_code.Emit(
1608 '\n'
1609 'function native_$(CLASS)_$(METHOD)(_this, index) {\n'
1610 ' try {\n'
1611 ' return __dom_wrap(_this.$dom[index]);\n'
1612 ' } catch (e) {\n'
1613 ' throw __dom_wrap_exception(e);\n'
1614 ' }\n'
1615 '}\n',
1616 CLASS=self._class_name, METHOD=method_name)
1617
1618 def _EmitNativeIndexSetter(self, interface, element_type):
1619 method_name = '_set_index'
1620 self._members_emitter.Emit(
1621 '\n'
1622 ' void operator[]=(int index, $TYPE value) {\n'
1623 ' return $METHOD(this, index, value);\n'
1624 ' }\n'
1625 ' static $METHOD(_this, index, value) native;\n',
1626 TYPE=element_type, METHOD=method_name)
1627 self._js_code.Emit(
1628 '\n'
1629 'function native_$(CLASS)_$(METHOD)(_this, index, value) {\n'
1630 ' try {\n'
1631 ' return _this.$dom[index] = __dom_unwrap(value);\n'
1632 ' } catch (e) {\n'
1633 ' throw __dom_wrap_exception(e);\n'
1634 ' }\n'
1635 '}\n',
1636 CLASS=self._class_name, METHOD=method_name)
1637
1612 def AddOperation(self, info): 1638 def AddOperation(self, info):
1613 """ 1639 """
1614 Arguments: 1640 Arguments:
1615 info: An OperationInfo object. 1641 info: An OperationInfo object.
1616 """ 1642 """
1617 body = self._members_emitter.Emit( 1643 body = self._members_emitter.Emit(
1618 '\n' 1644 '\n'
1619 ' $TYPE $NAME($PARAMS) {\n' 1645 ' $TYPE $NAME($PARAMS) {\n'
1620 '$!BODY' 1646 '$!BODY'
1621 ' }\n', 1647 ' }\n',
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 info: An OperationInfo object. 2082 info: An OperationInfo object.
2057 """ 2083 """
2058 # TODO(vsm): Handle overloads. 2084 # TODO(vsm): Handle overloads.
2059 self._members_emitter.Emit( 2085 self._members_emitter.Emit(
2060 '\n' 2086 '\n'
2061 ' $TYPE $NAME($PARAMS) native;\n', 2087 ' $TYPE $NAME($PARAMS) native;\n',
2062 TYPE=self._NarrowOutputType(info.type_name), 2088 TYPE=self._NarrowOutputType(info.type_name),
2063 NAME=info.name, 2089 NAME=info.name,
2064 PARAMS=info.ParametersImplementationDeclaration( 2090 PARAMS=info.ParametersImplementationDeclaration(
2065 lambda type_name: self._NarrowInputType(type_name))) 2091 lambda type_name: self._NarrowInputType(type_name)))
2092
2093
2094 # ------------------------------------------------------------------------------
2095
2096 class NativeImplementationSystem(System):
2097
2098 def __init__(self, templates, database, emitters, auxiliary_dir, output_dir):
2099 super(NativeImplementationSystem, self).__init__(
2100 templates, database, emitters, output_dir)
2101
2102 self._auxiliary_dir = auxiliary_dir
2103
2104 self._dom_public_imports_emitter = emitter.Emitter()
2105 self._dom_impl_imports_emitter = emitter.Emitter()
2106
2107 def InterfaceGenerator(self,
2108 interface,
2109 common_prefix,
2110 super_interface_name,
2111 source_filter):
2112 interface_name = interface.id
2113
2114 self._dom_public_imports_emitter.Emit('#source("$PATH");\n',
2115 PATH=self._FilePathForDartInterface(interface_name))
2116 self._dom_impl_imports_emitter.Emit('#source("$PATH");\n',
2117 PATH=self._FilePathForDartImpl(interface_name))
2118
2119 dart_impl_path = os.path.join(self._output_dir,
2120 self._FilePathForDartImpl(interface_name))
antonm 2012/01/26 11:06:14 do you want to invoke this _FilePathForDartImpl tw
2121 dart_impl_emitter = self._emitters.FileEmitter(dart_impl_path)
2122
2123 return NativeImplementationGenerator(interface, super_interface_name,
2124 dart_impl_emitter,
2125 self._BaseDefines(interface),
2126 self._templates)
2127
2128 def ProcessCallback(self, interface, info):
2129 self._dom_public_imports_emitter.Emit('#source("$PATH");\n',
2130 PATH=self._FilePathForDartInterface(interface.id))
2131
2132 def GenerateLibraries(self, lib_dir):
2133 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
2134
2135 # Generate dom_public.dart
2136 dom_public_path = os.path.join(self._output_dir, 'dom_public.dart')
2137 dom_public_emitter = self._emitters.FileEmitter(dom_public_path)
2138 dom_public_emitter.Emit(self._templates.Load('dom_public.darttemplate'),
2139 AUXILIARY_DIR=auxiliary_dir,
2140 SOURCES=self._dom_public_imports_emitter.Fragments())
2141
2142 # Generate dom_impl.dart
2143 dom_impl_path = os.path.join(self._output_dir, 'dom_impl.dart')
2144 dom_impl_emitter = self._emitters.FileEmitter(dom_impl_path)
2145 dom_impl_emitter.Emit(self._templates.Load('dom_impl.darttemplate'),
2146 AUXILIARY_DIR=auxiliary_dir,
2147 SOURCES=self._dom_impl_imports_emitter.Fragments())
2148
2149 def Finish(self):
2150 pass
2151
2152 def _FilePathForDartInterface(self, interface_name):
2153 return os.path.join('src', 'interface', '%s.dart' % interface_name)
2154
2155 def _FilePathForDartImpl(self, interface_name):
2156 return os.path.join('dart', '%sImplementation.dart' % interface_name)
2157
2158
2159 class NativeImplementationGenerator(WrappingInterfaceGenerator):
2160 """Generates Dart and c++ implementation for one DOM IDL interface."""
antonm 2012/01/26 11:06:14 nit: C++
podivilov 2012/01/26 14:18:57 Done.
2161
2162 def __init__(self, interface, super_interface, dart_impl_emitter,
2163 base_members, templates):
2164 """Generates Dart code for the given interface.
2165
2166 Args:
2167
2168 interface: an IDLInterface instance. It is assumed that all types have
2169 been converted to Dart types (e.g. int, String), unless they are in
2170 the same package as the interface.
2171 super_interface: A string or None, the name of the common interface that
2172 this interface implements, if any.
2173 dart_impl_emitter: an Emitter for the file containing the Dart
2174 implementation class.
2175 base_members: a set of names of members defined in a base class. This is
2176 used to avoid static member 'overriding' in the generated Dart code.
2177 """
2178 self._interface = interface
2179 self._super_interface = super_interface
2180 self._dart_impl_emitter = dart_impl_emitter
2181 self._base_members = base_members
2182 self._templates = templates
2183 self._current_secondary_parent = None
2184
2185 def StartInterface(self):
2186 self._class_name = self._ImplClassName(self._interface.id)
2187 self._members_emitter = emitter.Emitter()
2188
2189 def _ImplClassName(self, type_name):
2190 return type_name + 'Implementation'
2191
2192 def FinishInterface(self):
2193 interface = self._interface
2194 interface_name = interface.id
2195
2196 base = self._BaseClassName(interface)
2197 self._dart_impl_emitter.Emit(
2198 self._templates.Load('dart_implementation.darttemplate'),
2199 CLASS=self._class_name, BASE=base, INTERFACE=interface_name,
2200 MEMBERS=self._members_emitter.Fragments())
2201
2202 def AddGetter(self, attr):
2203 self._members_emitter.Emit(
2204 '\n'
2205 ' $TYPE get $NAME() native "$(INTERFACE)_$(NAME)_Getter";\n',
2206 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id)
2207
2208 def AddSetter(self, attr):
2209 self._members_emitter.Emit(
2210 '\n'
2211 ' void set $NAME($TYPE) native "$(INTERFACE)_$(NAME)_Setter";\n',
2212 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id)
2213
2214 def _HasNativeIndexGetter(self, interface):
antonm 2012/01/26 11:06:14 do you need this override?
podivilov 2012/01/26 14:18:57 Yes, it repeats the logic in CodeGeneratorDart.pm.
2215 return ('HasCustomIndexGetter' in interface.ext_attrs or
2216 'HasNumericIndexGetter' in interface.ext_attrs)
2217
2218 def _EmitNativeIndexGetter(self, interface, element_type):
2219 native_binding = '%s_numericIndexGetter_Callback' % interface.id
2220 self._members_emitter.Emit(
2221 '\n'
2222 ' $TYPE operator[](int index) native "$NATIVE_BINDING";\n',
2223 TYPE=element_type, NATIVE_BINDING=native_binding)
2224
2225 def _EmitNativeIndexSetter(self, interface, element_type):
2226 native_binding = '%s_numericIndexSetter_Callback' % self._interface.id
2227 self._members_emitter.Emit(
2228 '\n'
2229 ' void operator[]=(int index, $TYPE value) native "$NATIVE_BINDING";\n' ,
2230 TYPE=element_type, NATIVE_BINDING=native_binding)
2231
2232 def AddOperation(self, info):
2233 """
2234 Arguments:
2235 info: An OperationInfo object.
2236 """
2237
2238 if 'Custom' in info.overloads[0].ext_attrs:
2239 self._members_emitter.Emit(
2240 '\n'
2241 ' $TYPE $NAME($PARAMETERS) native "$(INTERFACE)_$(NAME)_Callback";\ n',
2242 TYPE=info.type_name,
2243 NAME=info.name,
2244 PARAMETERS=info.ParametersImplementationDeclaration(),
2245 INTERFACE=self._interface.id)
2246 return
2247
2248 body = self._members_emitter.Emit(
2249 '\n'
2250 ' $TYPE $NAME($PARAMETERS) {\n'
2251 '$!BODY'
2252 ' }\n',
2253 TYPE=info.type_name,
2254 NAME=info.name,
2255 PARAMETERS=info.ParametersImplementationDeclaration())
2256
2257 # Process in order of ascending number of arguments to ensure missing
2258 # optional arguments are processed early.
2259 overloads = sorted(info.overloads,
2260 key=lambda overload: len(overload.arguments))
2261 self._native_version = 0
2262 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
2263 if fallthrough:
2264 body.Emit(' throw "Incorrect number or type of arguments";\n');
2265
2266 def GenerateSingleOperation(self, emitter, info, indent, operation):
2267 """Generates a call to a single operation.
2268
2269 Arguments:
2270 emitter: an Emitter for the body of a block of code.
2271 info: the compound information about the operation and its overloads.
2272 indent: an indentation string for generated code.
2273 operation: the IDLOperation to call.
2274 """
2275
2276 arg_names = [info.arg_infos[i][0]
2277 for (i, arg) in enumerate(operation.arguments)]
2278
2279 self._native_version += 1
2280 native_name = '_%s' % info.name
2281 if self._native_version > 1:
2282 native_name = '%s_%s' % (native_name, self._native_version)
2283
2284 argument_expressions = ', '.join(arg_names)
2285 if info.type_name != 'void':
antonm 2012/01/26 11:06:14 do you need this if? Maybe introduce prefix which
podivilov 2012/01/26 14:18:57 Note that else clause has additional return statem
2286 emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n',
2287 INDENT=indent,
2288 NATIVENAME=native_name,
2289 ARGS=argument_expressions)
2290 else:
2291 emitter.Emit('$(INDENT)$NATIVENAME($ARGS);\n'
2292 '$(INDENT)return;\n',
2293 INDENT=indent,
2294 NATIVENAME=native_name,
2295 ARGS=argument_expressions)
2296
2297 self._members_emitter.Emit(' $TYPE $NATIVE_NAME($PARAMS) native "$(INTERFAC E)$(NATIVE_NAME)_Callback";\n',
2298 NATIVE_NAME=native_name,
2299 TYPE=info.type_name,
2300 PARAMS=', '.join(arg_names),
2301 INTERFACE=self._interface.id)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698