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

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

Issue 8548010: Wrapper dom changes in preparation for SVG (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweak Created 9 years, 1 month 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
« no previous file with comments | « client/dom/generated/wrapping_dom.js ('k') | client/dom/scripts/template_wrapping_dom.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 dart_interface_generator.AddOperation(info) 479 dart_interface_generator.AddOperation(info)
480 monkey_interface_generator.AddOperation(info) 480 monkey_interface_generator.AddOperation(info)
481 wrapping_interface_generator.AddOperation(info) 481 wrapping_interface_generator.AddOperation(info)
482 frog_interface_generator.AddOperation(info) 482 frog_interface_generator.AddOperation(info)
483 483
484 # With multiple inheritance, attributes and operations of non-first 484 # With multiple inheritance, attributes and operations of non-first
485 # interfaces need to be added. Sometimes the attribute or operation is 485 # interfaces need to be added. Sometimes the attribute or operation is
486 # defined in the current interface as well as a parent. In that case we 486 # defined in the current interface as well as a parent. In that case we
487 # avoid making a duplicate definition and pray that the signatures match. 487 # avoid making a duplicate definition and pray that the signatures match.
488 488
489 for parent in interface.parents[1:]: 489 for parent_interface in self._TransitiveSecondaryParents(interface):
490 if _IsDartCollectionType(parent.type.id): 490 if isinstance(interface, str): # _IsDartCollectionType(parent_interface)
491 continue 491 continue
492 if self._database.HasInterface(parent.type.id): 492 attributes = sorted(parent_interface.attributes,
493 parent_interface = self._database.GetInterface(parent.type.id) 493 AttributeOutputOrder)
494 attributes = sorted(parent_interface.attributes, 494 for attr in attributes:
495 AttributeOutputOrder) 495 if not self._DefinesSameAttribute(interface, attr):
496 for attr in attributes: 496 if attr.is_fc_getter:
497 if not self._DefinesSameAttribute(interface, attr): 497 monkey_interface_generator.AddSecondaryGetter(
498 if attr.is_fc_getter: 498 parent_interface, attr)
499 monkey_interface_generator.AddSecondaryGetter( 499 wrapping_interface_generator.AddSecondaryGetter(
500 parent_interface, attr) 500 parent_interface, attr)
501 wrapping_interface_generator.AddSecondaryGetter( 501 frog_interface_generator.AddSecondaryGetter(
502 parent_interface, attr) 502 parent_interface, attr)
503 frog_interface_generator.AddSecondaryGetter( 503 elif attr.is_fc_setter:
504 parent_interface, attr) 504 monkey_interface_generator.AddSecondarySetter(
505 elif attr.is_fc_setter: 505 parent_interface, attr)
506 monkey_interface_generator.AddSecondarySetter( 506 wrapping_interface_generator.AddSecondarySetter(
507 parent_interface, attr) 507 parent_interface, attr)
508 wrapping_interface_generator.AddSecondarySetter( 508 frog_interface_generator.AddSecondarySetter(
509 parent_interface, attr) 509 parent_interface, attr)
510 frog_interface_generator.AddSecondarySetter(
511 parent_interface, attr)
512 510
513 # Group overloaded operations by id 511 # Group overloaded operations by id
514 operationsById = {} 512 operationsById = {}
515 for operation in parent_interface.operations: 513 for operation in parent_interface.operations:
516 if operation.id not in operationsById: 514 if operation.id not in operationsById:
517 operationsById[operation.id] = [] 515 operationsById[operation.id] = []
518 operationsById[operation.id].append(operation) 516 operationsById[operation.id].append(operation)
519 517
520 # Generate operations 518 # Generate operations
521 for id in sorted(operationsById.keys()): 519 for id in sorted(operationsById.keys()):
522 if not any(op.id == id for op in interface.operations): 520 if not any(op.id == id for op in interface.operations):
523 operations = operationsById[id] 521 operations = operationsById[id]
524 info = self._AnalyzeOperation(interface, operations) 522 info = self._AnalyzeOperation(interface, operations)
525 monkey_interface_generator.AddSecondaryOperation( 523 monkey_interface_generator.AddSecondaryOperation(
526 parent_interface, info) 524 parent_interface, info)
527 wrapping_interface_generator.AddSecondaryOperation( 525 wrapping_interface_generator.AddSecondaryOperation(
528 parent_interface, info) 526 parent_interface, info)
529 frog_interface_generator.AddSecondaryOperation( 527 frog_interface_generator.AddSecondaryOperation(
530 parent_interface, info) 528 parent_interface, info)
531 529
532 dart_interface_generator.FinishInterface(self._overloaded_types) 530 dart_interface_generator.FinishInterface(self._overloaded_types)
533 monkey_interface_generator.FinishInterface() 531 monkey_interface_generator.FinishInterface()
534 wrapping_interface_generator.FinishInterface() 532 wrapping_interface_generator.FinishInterface()
535 frog_interface_generator.FinishInterface() 533 frog_interface_generator.FinishInterface()
536 return 534 return
537 535
538 def _DefinesSameAttribute(self, interface, attr1): 536 def _DefinesSameAttribute(self, interface, attr1):
539 return any(attr1.id == attr2.id 537 return any(attr1.id == attr2.id
540 and attr1.is_fc_getter == attr2.is_fc_getter 538 and attr1.is_fc_getter == attr2.is_fc_getter
541 and attr1.is_fc_setter == attr2.is_fc_setter 539 and attr1.is_fc_setter == attr2.is_fc_setter
542 for attr2 in interface.attributes) 540 for attr2 in interface.attributes)
543 541
542 def _TransitiveSecondaryParents(self, interface):
543 """Returns a list of all non-primary parents.
544
545 The list contains the interface objects for interfaces defined in the
546 database, and the name for undefined interfaces.
547 """
548 def walk(parents):
549 for parent in parents:
550 if _IsDartCollectionType(parent.type.id):
551 result.append(parent.type.id)
552 continue
553 if self._database.HasInterface(parent.type.id):
554 parent_interface = self._database.GetInterface(parent.type.id)
555 result.append(parent_interface)
556 walk(parent_interface.parents)
557
558 result = []
559 walk(interface.parents[1:])
560 return result;
vsm 2011/11/18 05:42:28 Can you get duplicates from diamond inheritance?
561
544 def _AnalyzeOperation(self, interface, operations): 562 def _AnalyzeOperation(self, interface, operations):
545 """Makes operation calling convention decision for a set of overloads. 563 """Makes operation calling convention decision for a set of overloads.
546 564
547 Returns: An OperationInfo object. 565 Returns: An OperationInfo object.
548 """ 566 """
549 567
550 # Zip together arguments from each overload by position, then convert 568 # Zip together arguments from each overload by position, then convert
551 # to a dart argument. 569 # to a dart argument.
552 570
553 # Given a list of overloaded arguments, choose a suitable name. 571 # Given a list of overloaded arguments, choose a suitable name.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 dart_wrapping_file_path = self.FilePathForDartWrappingImpl(interface_name) 750 dart_wrapping_file_path = self.FilePathForDartWrappingImpl(interface_name)
733 751
734 self._dart_wrapping_file_paths.append(dart_wrapping_file_path) 752 self._dart_wrapping_file_paths.append(dart_wrapping_file_path)
735 753
736 dart_code = self._emitters.FileEmitter(dart_wrapping_file_path) 754 dart_code = self._emitters.FileEmitter(dart_wrapping_file_path)
737 dart_code.Emit( 755 dart_code.Emit(
738 ''.join(open('template_wrapping_impl.darttemplate').readlines())) 756 ''.join(open('template_wrapping_impl.darttemplate').readlines()))
739 return WrappingInterfaceGenerator(interface, super_interface_name, 757 return WrappingInterfaceGenerator(interface, super_interface_name,
740 dart_code, self._wrapping_js_natives, 758 dart_code, self._wrapping_js_natives,
741 self._wrapping_map, 759 self._wrapping_map,
742 self._wrapping_externs) 760 self._wrapping_externs,
761 self._BaseDefines(interface))
762
763 def _BaseDefines(self, interface):
764 """Returns a set of names (strings) for members defined in a base class.
765 """
766 def WalkParentChain(interface):
767 if interface.parents:
768 # Only consider primary parent, secondary parents are not on the
769 # implementation class inheritance chain.
770 parent = interface.parents[0]
771 if _IsDartCollectionType(parent.type.id):
772 return
773 if self._database.HasInterface(parent.type.id):
774 parent_interface = self._database.GetInterface(parent.type.id)
775 for attr in parent_interface.attributes:
776 result.add(attr.id)
777 for op in parent_interface.operations:
778 result.add(op.id)
779 WalkParentChain(parent_interface)
780
781 result = set()
782 WalkParentChain(interface)
783 return result;
743 784
744 785
745 def _StartGenerateFrogImpl(self, output_dir): 786 def _StartGenerateFrogImpl(self, output_dir):
746 """Prepared for generating frog implementation. 787 """Prepared for generating frog implementation.
747 788
748 - Creates emitter for Dart code. 789 - Creates emitter for Dart code.
749 """ 790 """
750 pass 791 pass
751 792
752 793
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 # Dynamically type this field for now. 1176 # Dynamically type this field for now.
1136 return 'var' 1177 return 'var'
1137 1178
1138 1179
1139 # ------------------------------------------------------------------------------ 1180 # ------------------------------------------------------------------------------
1140 1181
1141 class WrappingInterfaceGenerator(object): 1182 class WrappingInterfaceGenerator(object):
1142 """Generates Dart and JS implementation for one DOM IDL interface.""" 1183 """Generates Dart and JS implementation for one DOM IDL interface."""
1143 1184
1144 def __init__(self, interface, super_interface, dart_code, js_code, type_map, 1185 def __init__(self, interface, super_interface, dart_code, js_code, type_map,
1145 externs): 1186 externs, base_members):
1146 """Generates Dart and JS code for the given interface. 1187 """Generates Dart and JS code for the given interface.
1147 1188
1148 Args: 1189 Args:
1149 1190
1150 interface: an IDLInterface instance. It is assumed that all types have 1191 interface: an IDLInterface instance. It is assumed that all types have
1151 been converted to Dart types (e.g. int, String), unless they are in 1192 been converted to Dart types (e.g. int, String), unless they are in
1152 the same package as the interface. 1193 the same package as the interface.
1153 super_interface: A string or None, the name of the common interface that 1194 super_interface: A string or None, the name of the common interface that
1154 this interface implements, if any. 1195 this interface implements, if any.
1155 dart_code: an Emitter for the file containing the Dart implementation 1196 dart_code: an Emitter for the file containing the Dart implementation
1156 class. 1197 class.
1157 js_code: an Emitter for the file containing JS code. 1198 js_code: an Emitter for the file containing JS code.
1158 type_map: an Emitter for the map from tokens to wrapper factory. 1199 type_map: an Emitter for the map from tokens to wrapper factory.
1159 externs: a set of (class, property, kind) externs. kind is 'attribute' or 1200 externs: a set of (class, property, kind) externs. kind is 'attribute' or
1160 'operation'. 1201 'operation'.
1202 base_members: a set of names of members defined in a base class. This is
1203 used to avoid static member 'overriding' in the generated Dart code.
1161 """ 1204 """
1162 self._interface = interface 1205 self._interface = interface
1163 self._super_interface = super_interface 1206 self._super_interface = super_interface
1164 self._dart_code = dart_code 1207 self._dart_code = dart_code
1165 self._js_code = js_code 1208 self._js_code = js_code
1166 self._type_map = type_map 1209 self._type_map = type_map
1167 self._externs = externs 1210 self._externs = externs
1211 self._base_members = base_members
1168 self._current_secondary_parent = None 1212 self._current_secondary_parent = None
1169 1213
1170 1214
1171 def StartInterface(self): 1215 def StartInterface(self):
1172 interface = self._interface 1216 interface = self._interface
1173 interface_name = interface.id 1217 interface_name = interface.id
1174 1218
1175 self._class_name = self._ImplClassName(interface_name) 1219 self._class_name = self._ImplClassName(interface_name)
1176 self._type_map.Emit(' "$INTERFACE": native_$(CLASS)_create_$(CLASS),\n', 1220 self._type_map.Emit(' "$INTERFACE": native_$(CLASS)_create_$(CLASS),\n',
1177 INTERFACE=interface_name, CLASS=self._class_name) 1221 INTERFACE=interface_name, CLASS=self._class_name)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 def _ImplClassName(self, type_name): 1263 def _ImplClassName(self, type_name):
1220 return '_' + type_name + 'WrappingImplementation' 1264 return '_' + type_name + 'WrappingImplementation'
1221 1265
1222 def FinishInterface(self): 1266 def FinishInterface(self):
1223 """.""" 1267 """."""
1224 pass 1268 pass
1225 1269
1226 def AddConstant(self, constant): 1270 def AddConstant(self, constant):
1227 pass 1271 pass
1228 1272
1273 def _MethodName(self, prefix, name):
1274 method_name = prefix + name
1275 if name in self._base_members: # Avoid illegal Dart 'static override'.
1276 method_name = method_name + '_' + self._interface.id
1277 return method_name
1278
1229 def AddGetter(self, attr): 1279 def AddGetter(self, attr):
1230 # We inject the interface into the static method name to make it 1280 # FIXME: Instead of injecting the interface name into the method when it is
1231 # unique as required by the language. A conflict only occurs when 1281 # also implemented in the base class, suppress the method altogether if it
1232 # the corresponding instance method is overloaded. 1282 # has the same signature. I.e., let the JS do the virtual dispatch instead.
1233 1283 method_name = self._MethodName('_get_', attr.id)
1234 # FIXME: Instead of injecting the interface name into the method,
1235 # suppress the method altogether when it's implemented in a base
1236 # class. I.e., let the JS do the virtual dispatch instead.
1237 self._members_emitter.Emit( 1284 self._members_emitter.Emit(
1238 '\n' 1285 '\n'
1239 ' $TYPE get $NAME() { return _get__$(INTERFACE)_$(NAME)(this); }\n' 1286 ' $TYPE get $NAME() { return $METHOD(this); }\n'
1240 ' static $TYPE _get__$(INTERFACE)_$(NAME)(var _this) native;\n', 1287 ' static $TYPE $METHOD(var _this) native;\n',
1241 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) 1288 NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
1242 if (self._interface.id, attr.id) not in _custom_getters: 1289 if (self._interface.id, attr.id) not in _custom_getters:
1243 self._js_code.Emit( 1290 self._js_code.Emit(
1244 '\n' 1291 '\n'
1245 'function native_$(CLASS)__get__$(INTERFACE)_$(NAME)(_this) {\n' 1292 'function native_$(CLASS)_$(METHOD)(_this) {\n'
1246 ' try {\n' 1293 ' try {\n'
1247 ' return __dom_wrap(_this.$dom.$NAME);\n' 1294 ' return __dom_wrap(_this.$dom.$NAME);\n'
1248 ' } catch (e) {\n' 1295 ' } catch (e) {\n'
1249 ' throw __dom_wrap_exception(e);\n' 1296 ' throw __dom_wrap_exception(e);\n'
1250 ' }\n' 1297 ' }\n'
1251 '}\n', 1298 '}\n',
1252 CLASS=self._class_name, NAME=attr.id, INTERFACE=self._interface.id) 1299 CLASS=self._class_name, NAME=attr.id, METHOD=method_name)
1253 self._externs.add((self._interface.id, attr.id, 'attribute')) 1300 self._externs.add((self._interface.id, attr.id, 'attribute'))
1254 1301
1255 def AddSetter(self, attr): 1302 def AddSetter(self, attr):
1256 # FIXME: See comment on getter. 1303 # FIXME: See comment on getter.
1304 method_name = self._MethodName('_set_', attr.id)
1257 self._members_emitter.Emit( 1305 self._members_emitter.Emit(
1258 '\n' 1306 '\n'
1259 ' void set $NAME($TYPE value) { _set__$(INTERFACE)_$(NAME)(this, value) ; }\n' 1307 ' void set $NAME($TYPE value) { $METHOD(this, value); }\n'
1260 ' static void _set__$(INTERFACE)_$(NAME)(var _this, $TYPE value) native ;\n', 1308 ' static void $METHOD(var _this, $TYPE value) native;\n',
1261 NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id) 1309 NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
1262 self._js_code.Emit( 1310 self._js_code.Emit(
1263 '\n' 1311 '\n'
1264 'function native_$(CLASS)__set__$(INTERFACE)_$(NAME)(_this, value) {\n' 1312 'function native_$(CLASS)_$(METHOD)(_this, value) {\n'
1265 ' try {\n' 1313 ' try {\n'
1266 ' _this.$dom.$NAME = __dom_unwrap(value);\n' 1314 ' _this.$dom.$NAME = __dom_unwrap(value);\n'
1267 ' } catch (e) {\n' 1315 ' } catch (e) {\n'
1268 ' throw __dom_wrap_exception(e);\n' 1316 ' throw __dom_wrap_exception(e);\n'
1269 ' }\n' 1317 ' }\n'
1270 '}\n', 1318 '}\n',
1271 CLASS=self._class_name, NAME=attr.id, INTERFACE=self._interface.id) 1319 CLASS=self._class_name, NAME=attr.id, METHOD=method_name)
1272 self._externs.add((self._interface.id, attr.id, 'attribute')) 1320 self._externs.add((self._interface.id, attr.id, 'attribute'))
1273 1321
1274 def AddSecondaryGetter(self, interface, attr): 1322 def AddSecondaryGetter(self, interface, attr):
1275 self._SecondaryContext(interface) 1323 self._SecondaryContext(interface)
1276 self.AddGetter(attr) 1324 self.AddGetter(attr)
1277 1325
1278 def AddSecondarySetter(self, interface, attr): 1326 def AddSecondarySetter(self, interface, attr):
1279 self._SecondaryContext(interface) 1327 self._SecondaryContext(interface)
1280 self.AddSetter(attr) 1328 self.AddSetter(attr)
1281 1329
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 def ArgNameAndUnwrapper(arg_info, overload_arg): 1491 def ArgNameAndUnwrapper(arg_info, overload_arg):
1444 (name, type, value) = arg_info 1492 (name, type, value) = arg_info
1445 return (name, UnwrapArgExpression(name, type)) 1493 return (name, UnwrapArgExpression(name, type))
1446 1494
1447 names_and_unwrappers = [ArgNameAndUnwrapper(info.arg_infos[i], arg) 1495 names_and_unwrappers = [ArgNameAndUnwrapper(info.arg_infos[i], arg)
1448 for (i, arg) in enumerate(operation.arguments)] 1496 for (i, arg) in enumerate(operation.arguments)]
1449 unwrap_args = [unwrap_arg for (_, unwrap_arg) in names_and_unwrappers] 1497 unwrap_args = [unwrap_arg for (_, unwrap_arg) in names_and_unwrappers]
1450 arg_names = [name for (name, _) in names_and_unwrappers] 1498 arg_names = [name for (name, _) in names_and_unwrappers]
1451 1499
1452 self._native_version += 1 1500 self._native_version += 1
1453 native_name = '_' + info.name 1501 native_name = self._MethodName('_', info.name)
1454 if self._native_version > 1: 1502 if self._native_version > 1:
1455 native_name = '%s_%s' % (native_name, self._native_version) 1503 native_name = '%s_%s' % (native_name, self._native_version)
1456 1504
1457 argument_expressions = ', '.join(['this'] + arg_names) 1505 argument_expressions = ', '.join(['this'] + arg_names)
1458 if info.type_name != 'void': 1506 if info.type_name != 'void':
1459 emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n', 1507 emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n',
1460 INDENT=indent, 1508 INDENT=indent,
1461 NATIVENAME=native_name, 1509 NATIVENAME=native_name,
1462 ARGS=argument_expressions) 1510 ARGS=argument_expressions)
1463 else: 1511 else:
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1950 Arguments: 1998 Arguments:
1951 info: An OperationInfo object. 1999 info: An OperationInfo object.
1952 """ 2000 """
1953 # TODO(vsm): Handle overloads. 2001 # TODO(vsm): Handle overloads.
1954 self._members_emitter.Emit( 2002 self._members_emitter.Emit(
1955 '\n' 2003 '\n'
1956 ' $TYPE $NAME($ARGS) native;\n', 2004 ' $TYPE $NAME($ARGS) native;\n',
1957 TYPE=info.type_name, 2005 TYPE=info.type_name,
1958 NAME=info.name, 2006 NAME=info.name,
1959 ARGS=info.arg_implementation_declaration) 2007 ARGS=info.arg_implementation_declaration)
OLDNEW
« no previous file with comments | « client/dom/generated/wrapping_dom.js ('k') | client/dom/scripts/template_wrapping_dom.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698