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 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 | 568 |
569 # With multiple inheritance, attributes and operations of non-first | 569 # With multiple inheritance, attributes and operations of non-first |
570 # interfaces need to be added. Sometimes the attribute or operation is | 570 # interfaces need to be added. Sometimes the attribute or operation is |
571 # defined in the current interface as well as a parent. In that case we | 571 # defined in the current interface as well as a parent. In that case we |
572 # avoid making a duplicate definition and pray that the signatures match. | 572 # avoid making a duplicate definition and pray that the signatures match. |
573 | 573 |
574 for parent_interface in self._TransitiveSecondaryParents(interface): | 574 for parent_interface in self._TransitiveSecondaryParents(interface): |
575 if isinstance(parent_interface, str): # _IsDartCollectionType(parent_inte
rface) | 575 if isinstance(parent_interface, str): # _IsDartCollectionType(parent_inte
rface) |
576 continue | 576 continue |
577 attributes = [attr for attr in parent_interface.attributes | 577 attributes = [attr for attr in parent_interface.attributes |
578 if not self._DefinesSameAttribute(interface, attr)] | 578 if not _FindMatchingAttribute(interface, attr)] |
579 for (getter, setter) in _PairUpAttributes(attributes): | 579 for (getter, setter) in _PairUpAttributes(attributes): |
580 for generator in generators: | 580 for generator in generators: |
581 generator.AddSecondaryAttribute(parent_interface, getter, setter) | 581 generator.AddSecondaryAttribute(parent_interface, getter, setter) |
582 | 582 |
583 # Group overloaded operations by id | 583 # Group overloaded operations by id |
584 operationsById = {} | 584 operationsById = {} |
585 for operation in parent_interface.operations: | 585 for operation in parent_interface.operations: |
586 if operation.id not in operationsById: | 586 if operation.id not in operationsById: |
587 operationsById[operation.id] = [] | 587 operationsById[operation.id] = [] |
588 operationsById[operation.id].append(operation) | 588 operationsById[operation.id].append(operation) |
(...skipping 11 matching lines...) Expand all Loading... |
600 return | 600 return |
601 | 601 |
602 def _IsEventAttribute(self, interface, attr): | 602 def _IsEventAttribute(self, interface, attr): |
603 # Remove EventListener attributes like 'onclick' when addEventListener | 603 # Remove EventListener attributes like 'onclick' when addEventListener |
604 # is available. | 604 # is available. |
605 if attr.type.id == 'EventListener': | 605 if attr.type.id == 'EventListener': |
606 if 'EventTarget' in self._AllImplementedInterfaces(interface): | 606 if 'EventTarget' in self._AllImplementedInterfaces(interface): |
607 return True | 607 return True |
608 return False | 608 return False |
609 | 609 |
610 def _DefinesSameAttribute(self, interface, attr1): | |
611 return any(attr1.id == attr2.id | |
612 and attr1.is_fc_getter == attr2.is_fc_getter | |
613 and attr1.is_fc_setter == attr2.is_fc_setter | |
614 for attr2 in interface.attributes) | |
615 | |
616 def _TransitiveSecondaryParents(self, interface): | 610 def _TransitiveSecondaryParents(self, interface): |
617 """Returns a list of all non-primary parents. | 611 """Returns a list of all non-primary parents. |
618 | 612 |
619 The list contains the interface objects for interfaces defined in the | 613 The list contains the interface objects for interfaces defined in the |
620 database, and the name for undefined interfaces. | 614 database, and the name for undefined interfaces. |
621 """ | 615 """ |
622 def walk(parents): | 616 def walk(parents): |
623 for parent in parents: | 617 for parent in parents: |
624 if _IsDartCollectionType(parent.type.id): | 618 if _IsDartCollectionType(parent.type.id): |
625 result.append(parent.type.id) | 619 result.append(parent.type.id) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 getters = {} | 699 getters = {} |
706 setters = {} | 700 setters = {} |
707 for attr in attributes: | 701 for attr in attributes: |
708 if attr.is_fc_getter: | 702 if attr.is_fc_getter: |
709 getters[attr.id] = attr | 703 getters[attr.id] = attr |
710 elif attr.is_fc_setter: | 704 elif attr.is_fc_setter: |
711 setters[attr.id] = attr | 705 setters[attr.id] = attr |
712 return [(getters.get(id), setters.get(id)) for id in names] | 706 return [(getters.get(id), setters.get(id)) for id in names] |
713 | 707 |
714 | 708 |
| 709 def _FindMatchingAttribute(interface, attr1): |
| 710 matches = [attr2 for attr2 in interface.attributes |
| 711 if attr1.id == attr2.id |
| 712 and attr1.is_fc_getter == attr2.is_fc_getter |
| 713 and attr1.is_fc_setter == attr2.is_fc_setter] |
| 714 if matches: |
| 715 assert len(matches) == 1 |
| 716 return matches[0] |
| 717 return None |
| 718 |
| 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 |
721 # Zip together arguments from each overload by position, then convert | 726 # Zip together arguments from each overload by position, then convert |
722 # to a dart argument. | 727 # to a dart argument. |
723 | 728 |
724 # Given a list of overloaded arguments, choose a suitable name. | 729 # Given a list of overloaded arguments, choose a suitable name. |
(...skipping 1340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2065 self._members_emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n', | 2070 self._members_emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n', |
2066 NAME=constant.id, | 2071 NAME=constant.id, |
2067 TYPE=constant.type.id, | 2072 TYPE=constant.type.id, |
2068 VALUE=constant.value) | 2073 VALUE=constant.value) |
2069 | 2074 |
2070 pass | 2075 pass |
2071 | 2076 |
2072 def AddAttribute(self, getter, setter): | 2077 def AddAttribute(self, getter, setter): |
2073 output_type = getter and self._NarrowOutputType(getter.type.id) | 2078 output_type = getter and self._NarrowOutputType(getter.type.id) |
2074 input_type = setter and self._NarrowInputType(setter.type.id) | 2079 input_type = setter and self._NarrowInputType(setter.type.id) |
| 2080 |
| 2081 # If the (getter, setter) pair is shadowing, we can't generate a shadowing |
| 2082 # field (Issue 1633). |
| 2083 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter) |
| 2084 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter) |
| 2085 if super_getter or super_setter: |
| 2086 if getter and not setter and super_getter and not super_setter: |
| 2087 if getter.type.id == super_getter.type.id: |
| 2088 # Compatible getter, use the superclass property. This works because |
| 2089 # JavaScript will do its own dynamic dispatch. |
| 2090 self._members_emitter.Emit( |
| 2091 '\n' |
| 2092 ' // Use implementation from $SUPER.\n' |
| 2093 ' // final $TYPE $NAME;\n', |
| 2094 SUPER=super_getter_interface.id, |
| 2095 NAME=getter.id, TYPE=output_type) |
| 2096 return |
| 2097 |
| 2098 self._members_emitter.Emit('\n // Shadowing definition.') |
| 2099 self._AddAttributeUsingProperties(getter, setter) |
| 2100 return |
| 2101 |
2075 if getter and setter and input_type == output_type: | 2102 if getter and setter and input_type == output_type: |
2076 self._members_emitter.Emit( | 2103 self._members_emitter.Emit( |
2077 '\n $TYPE $NAME;\n', | 2104 '\n $TYPE $NAME;\n', |
2078 NAME=getter.id, TYPE=output_type) | 2105 NAME=getter.id, TYPE=output_type) |
2079 return | 2106 return |
2080 if getter and not setter: | 2107 if getter and not setter: |
2081 self._members_emitter.Emit( | 2108 self._members_emitter.Emit( |
2082 '\n final $TYPE $NAME;\n', | 2109 '\n final $TYPE $NAME;\n', |
2083 NAME=getter.id, TYPE=output_type) | 2110 NAME=getter.id, TYPE=output_type) |
2084 return | 2111 return |
| 2112 self._AddAttributeUsingProperties(getter, setter) |
| 2113 |
| 2114 def _AddAttributeUsingProperties(self, getter, setter): |
2085 if getter: | 2115 if getter: |
2086 self._AddGetter(getter) | 2116 self._AddGetter(getter) |
2087 if setter: | 2117 if setter: |
2088 self._AddSetter(setter) | 2118 self._AddSetter(setter) |
2089 | 2119 |
2090 def _AddGetter(self, attr): | 2120 def _AddGetter(self, attr): |
2091 # TODO(sra): Remove native body when Issue 829 fixed. | 2121 # TODO(sra): Remove native body when Issue 829 fixed. |
2092 self._members_emitter.Emit( | 2122 self._members_emitter.Emit( |
2093 '\n $TYPE get $NAME() native "return this.$NAME;";\n', | 2123 '\n $TYPE get $NAME() native "return this.$NAME;";\n', |
2094 NAME=attr.id, TYPE=self._NarrowOutputType(attr.type.id)) | 2124 NAME=attr.id, TYPE=self._NarrowOutputType(attr.type.id)) |
2095 | 2125 |
2096 def _AddSetter(self, attr): | 2126 def _AddSetter(self, attr): |
2097 # TODO(sra): Remove native body when Issue 829 fixed. | 2127 # TODO(sra): Remove native body when Issue 829 fixed. |
2098 self._members_emitter.Emit( | 2128 self._members_emitter.Emit( |
2099 '\n void set $NAME($TYPE value) native "this.$NAME = value;";\n', | 2129 ' void set $NAME($TYPE value) native "this.$NAME = value;";\n', |
2100 NAME=attr.id, TYPE=self._NarrowInputType(attr.type.id)) | 2130 NAME=attr.id, TYPE=self._NarrowInputType(attr.type.id)) |
2101 | 2131 |
| 2132 def _FindShadowedAttribute(self, attr): |
| 2133 """Returns (attribute, superinterface) or (None, None).""" |
| 2134 def FindInParent(interface): |
| 2135 """Returns matching attribute in parent, or None.""" |
| 2136 if interface.parents: |
| 2137 parent = interface.parents[0] |
| 2138 if _IsDartCollectionType(parent.type.id): |
| 2139 return (None, None) |
| 2140 if self._system._database.HasInterface(parent.type.id): |
| 2141 parent_interface = self._system._database.GetInterface(parent.type.id) |
| 2142 attr2 = _FindMatchingAttribute(parent_interface, attr) |
| 2143 if attr2: |
| 2144 return (attr2, parent_interface) |
| 2145 return FindInParent(parent_interface) |
| 2146 return (None, None) |
| 2147 |
| 2148 return FindInParent(self._interface) if attr else (None, None) |
| 2149 |
| 2150 |
2102 def AddSecondaryAttribute(self, interface, getter, setter): | 2151 def AddSecondaryAttribute(self, interface, getter, setter): |
2103 self._SecondaryContext(interface) | 2152 self._SecondaryContext(interface) |
2104 self.AddAttribute(getter, setter) | 2153 self.AddAttribute(getter, setter) |
2105 | 2154 |
2106 def AddSecondaryOperation(self, interface, info): | 2155 def AddSecondaryOperation(self, interface, info): |
2107 self._SecondaryContext(interface) | 2156 self._SecondaryContext(interface) |
2108 self.AddOperation(info) | 2157 self.AddOperation(info) |
2109 | 2158 |
2110 def AddEventAttributes(self, event_attrs): | 2159 def AddEventAttributes(self, event_attrs): |
2111 pass | 2160 pass |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2489 INDENT=indent, | 2538 INDENT=indent, |
2490 NATIVENAME=native_name, | 2539 NATIVENAME=native_name, |
2491 ARGS=argument_expressions) | 2540 ARGS=argument_expressions) |
2492 | 2541 |
2493 self._members_emitter.Emit(' $TYPE $NATIVE_NAME($PARAMS) native ' | 2542 self._members_emitter.Emit(' $TYPE $NATIVE_NAME($PARAMS) native ' |
2494 '"$(INTERFACE)$(NATIVE_NAME)_Callback";\n', | 2543 '"$(INTERFACE)$(NATIVE_NAME)_Callback";\n', |
2495 NATIVE_NAME=native_name, | 2544 NATIVE_NAME=native_name, |
2496 TYPE=info.type_name, | 2545 TYPE=info.type_name, |
2497 PARAMS=', '.join(arg_names), | 2546 PARAMS=', '.join(arg_names), |
2498 INTERFACE=self._interface.id) | 2547 INTERFACE=self._interface.id) |
OLD | NEW |