Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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) |
| OLD | NEW |