| 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 provides shared functionality for the system to generate | 6 """This module provides shared functionality for the system to generate |
| 7 Dart:html APIs from the IDL database.""" | 7 Dart:html APIs from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 | 10 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 "Node.set:nodeValue", | 265 "Node.set:nodeValue", |
| 266 "Node.get:CDATA_SECTION_NODE", | 266 "Node.get:CDATA_SECTION_NODE", |
| 267 "Node.get:nodeName", | 267 "Node.get:nodeName", |
| 268 "Node.lookupPrefix", | 268 "Node.lookupPrefix", |
| 269 "Node.get:PROCESSING_INSTRUCTION_NODE", | 269 "Node.get:PROCESSING_INSTRUCTION_NODE", |
| 270 "IFrameElement.get:contentDocument", | 270 "IFrameElement.get:contentDocument", |
| 271 "Window.get:frameElement", | 271 "Window.get:frameElement", |
| 272 ]) | 272 ]) |
| 273 | 273 |
| 274 _html_library_custom = set([ | 274 _html_library_custom = set([ |
| 275 'IFrameElement.get:contentWindow', | 275 'IFrameElement.contentWindow', |
| 276 'Window.get:document', | 276 'Window.document', |
| 277 'Window.get:top', | 277 'Window.top', |
| 278 'Window.get:location', | 278 'Window.location', |
| 279 'Window.set:location', | |
| 280 'Window.open', | 279 'Window.open', |
| 281 'IDBDatabase.transaction', | 280 'IDBDatabase.transaction', |
| 282 ]) | 281 ]) |
| 283 | 282 |
| 284 # This map controls merging of interfaces in dart:html library. | 283 # This map controls merging of interfaces in dart:html library. |
| 285 # All constants, attributes, and operations of merged interface (key) are | 284 # All constants, attributes, and operations of merged interface (key) are |
| 286 # added to target interface (value). All references to the merged interface | 285 # added to target interface (value). All references to the merged interface |
| 287 # (e.g. parameter types, return types, parent interfaces) are replaced with | 286 # (e.g. parameter types, return types, parent interfaces) are replaced with |
| 288 # target interface. There are two important restrictions: | 287 # target interface. There are two important restrictions: |
| 289 # 1) Merged and target interfaces shouldn't have common members, otherwise there | 288 # 1) Merged and target interfaces shouldn't have common members, otherwise there |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 merged_interface = self._database.GetInterface(merged_interface) | 939 merged_interface = self._database.GetInterface(merged_interface) |
| 941 self.AddMembers(merged_interface) | 940 self.AddMembers(merged_interface) |
| 942 self._backend = old_backend | 941 self._backend = old_backend |
| 943 | 942 |
| 944 def AddIndexer(self, element_type): | 943 def AddIndexer(self, element_type): |
| 945 self._backend.AddIndexer(element_type) | 944 self._backend.AddIndexer(element_type) |
| 946 | 945 |
| 947 def AmendIndexer(self, element_type): | 946 def AmendIndexer(self, element_type): |
| 948 self._backend.AmendIndexer(element_type) | 947 self._backend.AmendIndexer(element_type) |
| 949 | 948 |
| 950 def AddAttribute(self, attribute): | 949 def AddAttribute(self, attribute, is_secondary=False): |
| 951 self._backend.AddAttribute(attribute) | 950 dom_name = DartDomNameOfAttribute(attribute) |
| 952 | 951 html_name = self._shared.RenameInHtmlLibrary( |
| 953 getter = attribute | |
| 954 setter = attribute if not IsReadOnly(attribute) else None | |
| 955 dom_name = DartDomNameOfAttribute(getter) | |
| 956 html_getter_name = self._shared.RenameInHtmlLibrary( | |
| 957 self._interface.id, dom_name, 'get:') | 952 self._interface.id, dom_name, 'get:') |
| 958 html_setter_name = self._shared.RenameInHtmlLibrary( | 953 if not html_name or self._shared.IsPrivate(html_name): |
| 959 self._interface.id, dom_name, 'set:') | |
| 960 | |
| 961 if not html_getter_name or self._shared.IsPrivate(html_getter_name): | |
| 962 getter = None | |
| 963 if not html_setter_name or self._shared.IsPrivate(html_setter_name): | |
| 964 setter = None | |
| 965 if not getter and not setter: | |
| 966 return | 954 return |
| 967 | 955 |
| 956 |
| 957 html_setter_name = self._shared.RenameInHtmlLibrary( |
| 958 self._interface.id, dom_name, 'set:') |
| 959 read_only = IsReadOnly(attribute) or not html_setter_name |
| 960 |
| 968 # We don't yet handle inconsistent renames of the getter and setter yet. | 961 # We don't yet handle inconsistent renames of the getter and setter yet. |
| 969 if html_getter_name and html_setter_name: | 962 assert(not html_setter_name or html_name == html_setter_name) |
| 970 assert html_getter_name == html_setter_name | |
| 971 | 963 |
| 972 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 964 if not is_secondary: |
| 973 DOMINTERFACE=getter.doc_js_interface_name, | 965 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 974 DOMNAME=dom_name) | 966 DOMINTERFACE=attribute.doc_js_interface_name, |
| 975 if (getter and setter and | 967 DOMNAME=dom_name) |
| 976 getter.type.id == setter.type.id): | 968 modifier = 'final ' if read_only else '' |
| 977 self._members_emitter.Emit('\n $TYPE $NAME;\n', | 969 self._members_emitter.Emit('\n $MODIFIER$TYPE $NAME;\n', |
| 978 NAME=html_getter_name, | 970 MODIFIER=modifier, |
| 979 TYPE=self._shared.DartType(getter.type.id)) | 971 NAME=html_name, |
| 980 return | 972 TYPE=self._shared.DartType(attribute.type.id)) |
| 981 if getter and not setter: | 973 self._backend.AddAttribute(attribute, html_name, read_only) |
| 982 self._members_emitter.Emit('\n final $TYPE $NAME;\n', | |
| 983 NAME=html_getter_name, | |
| 984 TYPE=self._shared.DartType(getter.type.id)) | |
| 985 return | |
| 986 raise Exception('Unexpected getter/setter combination %s %s' % | |
| 987 (getter, setter)) | |
| 988 | 974 |
| 989 def AddOperation(self, info): | 975 def AddSecondaryAttribute(self, interface, attribute): |
| 976 self._backend.SecondaryContext(interface) |
| 977 self.AddAttribute(attribute, True) |
| 978 |
| 979 def AddOperation(self, info, is_secondary=False): |
| 990 """ | 980 """ |
| 991 Arguments: | 981 Arguments: |
| 992 operations - contains the overloads, one or more operations with the same | 982 operations - contains the overloads, one or more operations with the same |
| 993 name. | 983 name. |
| 994 """ | 984 """ |
| 995 html_name = self._shared.RenameInHtmlLibrary( | 985 html_name = self._shared.RenameInHtmlLibrary( |
| 996 self._interface.id, info.name) | 986 self._interface.id, info.name) |
| 997 if html_name and not self._shared.IsPrivate(html_name): | 987 if html_name and not self._shared.IsPrivate(html_name) and not is_secondary: |
| 998 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 988 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 999 DOMINTERFACE=info.overloads[0].doc_js_interface_name, | 989 DOMINTERFACE=info.overloads[0].doc_js_interface_name, |
| 1000 DOMNAME=info.name) | 990 DOMNAME=info.name) |
| 1001 | 991 |
| 1002 self._members_emitter.Emit('\n' | 992 self._members_emitter.Emit('\n' |
| 1003 ' $TYPE $NAME($PARAMS);\n', | 993 ' $TYPE $NAME($PARAMS);\n', |
| 1004 TYPE=self._shared.DartType(info.type_name), | 994 TYPE=self._shared.DartType(info.type_name), |
| 1005 NAME=html_name, | 995 NAME=html_name, |
| 1006 PARAMS=info.ParametersInterfaceDeclaration( | 996 PARAMS=info.ParametersInterfaceDeclaration( |
| 1007 self._shared.DartType)) | 997 self._shared.DartType)) |
| 1008 self._backend.AddOperation(info) | 998 self._backend.AddOperation(info) |
| 1009 | 999 |
| 1010 def AddStaticOperation(self, info): | 1000 def AddStaticOperation(self, info): |
| 1011 self._backend.AddStaticOperation(info) | 1001 self._backend.AddStaticOperation(info) |
| 1012 | 1002 |
| 1003 def AddSecondaryOperation(self, interface, info): |
| 1004 self._backend.SecondaryContext(interface) |
| 1005 self.AddOperation(info, True) |
| 1006 |
| 1013 def FinishInterface(self): | 1007 def FinishInterface(self): |
| 1014 self._backend.AddSecondaryMembers(self._interface) | |
| 1015 self._backend.FinishInterface() | 1008 self._backend.FinishInterface() |
| 1016 | 1009 |
| 1017 def AddConstant(self, constant): | 1010 def AddConstant(self, constant): |
| 1018 type = TypeOrNothing(DartType(constant.type.id), constant.type.id) | 1011 type = TypeOrNothing(DartType(constant.type.id), constant.type.id) |
| 1019 self._members_emitter.Emit('\n static final $TYPE$NAME = $VALUE;\n', | 1012 self._members_emitter.Emit('\n static final $TYPE$NAME = $VALUE;\n', |
| 1020 NAME=constant.id, | 1013 NAME=constant.id, |
| 1021 TYPE=type, | 1014 TYPE=type, |
| 1022 VALUE=constant.value) | 1015 VALUE=constant.value) |
| 1023 self._backend.AddConstant(constant) | 1016 self._backend.AddConstant(constant) |
| 1024 | 1017 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 '\n */' | 1069 '\n */' |
| 1077 '\n $TYPE get on();\n', | 1070 '\n $TYPE get on();\n', |
| 1078 TYPE=events_interface) | 1071 TYPE=events_interface) |
| 1079 | 1072 |
| 1080 self._implementation_members_emitter.Emit( | 1073 self._implementation_members_emitter.Emit( |
| 1081 '\n $TYPE get on() =>\n new $TYPE(this);\n', | 1074 '\n $TYPE get on() =>\n new $TYPE(this);\n', |
| 1082 TYPE=events_class) | 1075 TYPE=events_class) |
| 1083 | 1076 |
| 1084 | 1077 |
| 1085 class HtmlGeneratorDummyBackend(object): | 1078 class HtmlGeneratorDummyBackend(object): |
| 1086 def AddAttribute(self, attribute): | 1079 def AddAttribute(self, attribute, html_name, read_only): |
| 1087 pass | 1080 pass |
| 1088 | 1081 |
| 1089 def AddOperation(self, info): | 1082 def AddOperation(self, info): |
| 1090 pass | 1083 pass |
| 1091 | 1084 |
| 1092 | 1085 |
| 1093 # ------------------------------------------------------------------------------ | 1086 # ------------------------------------------------------------------------------ |
| 1094 | 1087 |
| 1095 # TODO(jmesserly): inheritance is probably not the right way to factor this long | 1088 # TODO(jmesserly): inheritance is probably not the right way to factor this long |
| 1096 # term, but it makes merging better for now. | 1089 # term, but it makes merging better for now. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 ' }\n', | 1234 ' }\n', |
| 1242 TYPE=self._NarrowInputType(element_type)) | 1235 TYPE=self._NarrowInputType(element_type)) |
| 1243 | 1236 |
| 1244 # TODO(sra): Use separate mixins for mutable implementations of List<T>. | 1237 # TODO(sra): Use separate mixins for mutable implementations of List<T>. |
| 1245 # TODO(sra): Use separate mixins for typed array implementations of List<T>. | 1238 # TODO(sra): Use separate mixins for typed array implementations of List<T>. |
| 1246 if self._interface.id != 'NodeList': | 1239 if self._interface.id != 'NodeList': |
| 1247 template_file = 'immutable_list_mixin.darttemplate' | 1240 template_file = 'immutable_list_mixin.darttemplate' |
| 1248 template = self._system._templates.Load(template_file) | 1241 template = self._system._templates.Load(template_file) |
| 1249 self._members_emitter.Emit(template, E=self._shared.DartType(element_type)
) | 1242 self._members_emitter.Emit(template, E=self._shared.DartType(element_type)
) |
| 1250 | 1243 |
| 1251 def AddAttribute(self, attribute): | 1244 def AddAttribute(self, attribute, html_name, read_only): |
| 1252 getter = attribute | 1245 if self._shared.IsCustomInHtmlLibrary(self._interface, attribute.id): |
| 1253 setter = attribute if not IsReadOnly(attribute) else None | |
| 1254 dom_name = DartDomNameOfAttribute(getter or setter) | |
| 1255 html_getter_name = None | |
| 1256 if not self._shared.IsCustomInHtmlLibrary( | |
| 1257 self._interface, dom_name, 'get:'): | |
| 1258 html_getter_name = self._shared.RenameInHtmlLibrary( | |
| 1259 self._interface.id, dom_name, 'get:', | |
| 1260 implementation_class=True) | |
| 1261 html_setter_name = None | |
| 1262 if not self._shared.IsCustomInHtmlLibrary( | |
| 1263 self._interface, dom_name, 'set:'): | |
| 1264 html_setter_name = self._shared.RenameInHtmlLibrary( | |
| 1265 self._interface.id, dom_name, 'set:', | |
| 1266 implementation_class=True) | |
| 1267 | |
| 1268 if not html_getter_name: | |
| 1269 getter = None | |
| 1270 if not html_setter_name: | |
| 1271 setter = None | |
| 1272 | |
| 1273 if not getter and not setter: | |
| 1274 return | 1246 return |
| 1275 | 1247 |
| 1276 if ((getter and html_getter_name != getter.id) or | 1248 if attribute.id != html_name: |
| 1277 (setter and html_setter_name != setter.id)): | 1249 self._AddRenamingGetter(attribute, html_name) |
| 1278 if getter: | 1250 if not read_only: |
| 1279 self._AddRenamingGetter(getter, html_getter_name) | 1251 self._AddRenamingSetter(attribute, html_name) |
| 1280 if setter: | |
| 1281 self._AddRenamingSetter(setter, html_setter_name) | |
| 1282 return | 1252 return |
| 1283 | 1253 |
| 1284 # If the (getter, setter) pair is shadowing, we can't generate a shadowing | 1254 # If the attribute is shadowing, we can't generate a shadowing |
| 1285 # field (Issue 1633). | 1255 # field (Issue 1633). |
| 1286 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter,
_merged_html_interfaces) | 1256 (super_attribute, super_attribute_interface) = self._FindShadowedAttribute(a
ttribute, _merged_html_interfaces) |
| 1287 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter,
_merged_html_interfaces) | 1257 if super_attribute: |
| 1288 if super_getter or super_setter: | 1258 if read_only: |
| 1289 if getter and not setter and super_getter and not super_setter: | 1259 if attribute.type.id == super_attribute.type.id: |
| 1290 if getter.type.id == super_getter.type.id: | 1260 # Compatible attribute, use the superclass property. This works |
| 1291 # Compatible getter, use the superclass property. This works because | 1261 # because JavaScript will do its own dynamic dispatch. |
| 1292 # JavaScript will do its own dynamic dispatch. | |
| 1293 output_type = getter and self._NarrowOutputType(getter.type.id) | |
| 1294 self._members_emitter.Emit( | 1262 self._members_emitter.Emit( |
| 1295 '\n' | 1263 '\n' |
| 1296 ' // Use implementation from $SUPER.\n' | 1264 ' // Use implementation from $SUPER.\n' |
| 1297 ' // final $TYPE $NAME;\n', | 1265 ' // final $TYPE $NAME;\n', |
| 1298 SUPER=super_getter_interface, | 1266 SUPER=super_attribute_interface, |
| 1299 NAME=DartDomNameOfAttribute(getter), | 1267 NAME=DartDomNameOfAttribute(attribute), |
| 1300 TYPE=output_type) | 1268 TYPE=self._NarrowOutputType(attribute.type.id)) |
| 1301 return | 1269 return |
| 1302 | 1270 |
| 1303 self._members_emitter.Emit('\n // Shadowing definition.') | 1271 self._members_emitter.Emit('\n // Shadowing definition.') |
| 1304 self._AddAttributeUsingProperties(getter, setter) | 1272 self._AddAttributeUsingProperties(attribute, read_only) |
| 1305 return | 1273 return |
| 1306 | 1274 |
| 1307 output_type = getter and self._NarrowOutputType(getter.type.id) | 1275 output_type = self._NarrowOutputType(attribute.type.id) |
| 1308 input_type = setter and self._NarrowInputType(setter.type.id) | 1276 input_type = self._NarrowInputType(attribute.type.id) |
| 1309 if getter and setter and input_type == output_type: | 1277 if not read_only: |
| 1310 self._members_emitter.Emit( | 1278 self._members_emitter.Emit( |
| 1311 '\n $TYPE $NAME;\n', | 1279 '\n $TYPE $NAME;\n', |
| 1312 NAME=DartDomNameOfAttribute(getter), | 1280 NAME=DartDomNameOfAttribute(attribute), |
| 1313 TYPE=output_type) | 1281 TYPE=output_type) |
| 1314 return | 1282 else: |
| 1315 if getter and not setter: | |
| 1316 self._members_emitter.Emit( | 1283 self._members_emitter.Emit( |
| 1317 '\n final $TYPE $NAME;\n', | 1284 '\n final $TYPE $NAME;\n', |
| 1318 NAME=DartDomNameOfAttribute(getter), | 1285 NAME=DartDomNameOfAttribute(attribute), |
| 1319 TYPE=output_type) | 1286 TYPE=output_type) |
| 1320 return | |
| 1321 self._AddAttributeUsingProperties(getter, setter) | |
| 1322 | 1287 |
| 1323 def _AddAttributeUsingProperties(self, getter, setter): | 1288 def _AddAttributeUsingProperties(self, attribute, read_only): |
| 1324 if getter: | 1289 self._AddGetter(attribute) |
| 1325 self._AddGetter(getter) | 1290 if not read_only: |
| 1326 if setter: | 1291 self._AddSetter(attribute) |
| 1327 self._AddSetter(setter) | |
| 1328 | 1292 |
| 1329 def _AddGetter(self, attr): | 1293 def _AddGetter(self, attr): |
| 1330 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr)) | 1294 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr)) |
| 1331 | 1295 |
| 1332 def _AddSetter(self, attr): | 1296 def _AddSetter(self, attr): |
| 1333 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr)) | 1297 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr)) |
| 1334 | 1298 |
| 1335 def _AddRenamingGetter(self, attr, html_name): | 1299 def _AddRenamingGetter(self, attr, html_name): |
| 1336 return_type = self._NarrowOutputType(attr.type.id) | 1300 return_type = self._NarrowOutputType(attr.type.id) |
| 1337 self._members_emitter.Emit( | 1301 self._members_emitter.Emit( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 Collect(database.GetInterface(parent.type.id), | 1386 Collect(database.GetInterface(parent.type.id), |
| 1423 seen, collected) | 1387 seen, collected) |
| 1424 | 1388 |
| 1425 inheritance_closure = {} | 1389 inheritance_closure = {} |
| 1426 for interface in database.GetInterfaces(): | 1390 for interface in database.GetInterfaces(): |
| 1427 seen = set() | 1391 seen = set() |
| 1428 collected = [] | 1392 collected = [] |
| 1429 Collect(interface, seen, collected) | 1393 Collect(interface, seen, collected) |
| 1430 inheritance_closure[interface.id] = collected | 1394 inheritance_closure[interface.id] = collected |
| 1431 return inheritance_closure | 1395 return inheritance_closure |
| OLD | NEW |