Chromium Code Reviews| 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 |
| 11 from systemdart2js import * | 11 from systembase import * |
| 12 from systeminterface import * | 12 from systeminterface import * |
| 13 | 13 |
| 14 _js_custom_members = set([ | 14 _js_custom_members = set([ |
| 15 'CSSStyleDeclaration.setProperty', | 15 'CSSStyleDeclaration.setProperty', |
| 16 'Element.insertAdjacentElement', | 16 'Element.insertAdjacentElement', |
| 17 'Element.insertAdjacentHTML', | 17 'Element.insertAdjacentHTML', |
| 18 'Element.insertAdjacentText', | 18 'Element.insertAdjacentText', |
| 19 'Element.remove', | 19 'Element.remove', |
| 20 'ElementEvents.mouseWheel', | 20 'ElementEvents.mouseWheel', |
| 21 'IDBDatabase.transaction', | 21 'IDBDatabase.transaction', |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 class HtmlGeneratorDummyBackend(object): | 765 class HtmlGeneratorDummyBackend(object): |
| 766 def AddAttribute(self, attribute, html_name, read_only): | 766 def AddAttribute(self, attribute, html_name, read_only): |
| 767 pass | 767 pass |
| 768 | 768 |
| 769 def AddOperation(self, info, html_name): | 769 def AddOperation(self, info, html_name): |
| 770 pass | 770 pass |
| 771 | 771 |
| 772 | 772 |
| 773 # ------------------------------------------------------------------------------ | 773 # ------------------------------------------------------------------------------ |
| 774 | 774 |
| 775 # TODO(jmesserly): inheritance is probably not the right way to factor this long | 775 class Dart2JSBackend(BaseGenerator): |
| 776 # term, but it makes merging better for now. | |
| 777 class Dart2JSBackend(Dart2JSInterfaceGenerator): | |
| 778 """Generates a dart2js class for the dart:html library from a DOM IDL | 776 """Generates a dart2js class for the dart:html library from a DOM IDL |
| 779 interface. | 777 interface. |
| 780 """ | 778 """ |
| 781 | 779 |
| 782 def __init__(self, interface, options): | 780 def __init__(self, interface, options): |
| 783 super(Dart2JSBackend, self).__init__(options, interface, None, None) | 781 super(Dart2JSBackend, self).__init__(None, None, interface) |
| 782 self._database = options.database | |
| 783 self._template_loader = options.templates | |
| 784 self._type_registry = options.type_registry | |
| 784 self._html_interface_name = options.renamer.RenameInterface(self._interface) | 785 self._html_interface_name = options.renamer.RenameInterface(self._interface) |
| 786 self._current_secondary_parent = None | |
| 785 | 787 |
| 786 def HasImplementation(self): | 788 def HasImplementation(self): |
| 787 return not (IsPureInterface(self._interface.id) or | 789 return not (IsPureInterface(self._interface.id) or |
| 788 self._interface.id in _merged_html_interfaces) | 790 self._interface.id in _merged_html_interfaces) |
| 789 | 791 |
| 790 def ImplementationClassName(self): | 792 def ImplementationClassName(self): |
| 791 return self._ImplClassName(self._html_interface_name) | 793 return self._ImplClassName(self._html_interface_name) |
| 792 | 794 |
| 793 def SetImplementationEmitter(self, implementation_emitter): | 795 def SetImplementationEmitter(self, implementation_emitter): |
| 794 self._dart_code = implementation_emitter | 796 self._dart_code = implementation_emitter |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 CLASSNAME=self._class_name, | 845 CLASSNAME=self._class_name, |
| 844 EXTENDS=extends, | 846 EXTENDS=extends, |
| 845 IMPLEMENTS=' implements ' + ', '.join(implements), | 847 IMPLEMENTS=' implements ' + ', '.join(implements), |
| 846 NATIVESPEC=' native "' + native_spec + '"') | 848 NATIVESPEC=' native "' + native_spec + '"') |
| 847 if self._members_emitter == None: | 849 if self._members_emitter == None: |
| 848 raise Exception("Class %s doesn't use the $!MEMBERS variable" % | 850 raise Exception("Class %s doesn't use the $!MEMBERS variable" % |
| 849 self._class_name) | 851 self._class_name) |
| 850 | 852 |
| 851 return self._members_emitter | 853 return self._members_emitter |
| 852 | 854 |
| 855 def FinishInterface(self): | |
|
podivilov1
2012/10/01 10:37:34
All green lines below are moved from systemdart2js
| |
| 856 pass | |
| 857 | |
| 858 def AddConstant(self, constant): | |
| 859 # Since we are currently generating native classes without interfaces, | |
| 860 # generate the constants as part of the class. This will need to go away | |
| 861 # if we revert back to generating interfaces. | |
| 862 self._members_emitter.Emit('\n static const $TYPE $NAME = $VALUE;\n', | |
| 863 NAME=constant.id, | |
| 864 TYPE=self._DartType(constant.type.id), | |
| 865 VALUE=constant.value) | |
| 866 | |
| 853 def EmitFactoryProvider(self, constructor_info, factory_provider, emitter): | 867 def EmitFactoryProvider(self, constructor_info, factory_provider, emitter): |
| 854 template_file = ('factoryprovider_%s.darttemplate' % | 868 template_file = ('factoryprovider_%s.darttemplate' % |
| 855 self._html_interface_name) | 869 self._html_interface_name) |
| 856 template = self._template_loader.TryLoad(template_file) | 870 template = self._template_loader.TryLoad(template_file) |
| 857 if not template: | 871 if not template: |
| 858 template = self._template_loader.Load('factoryprovider.darttemplate') | 872 template = self._template_loader.Load('factoryprovider.darttemplate') |
| 859 | 873 |
| 860 emitter.Emit( | 874 emitter.Emit( |
| 861 template, | 875 template, |
| 862 FACTORYPROVIDER=factory_provider, | 876 FACTORYPROVIDER=factory_provider, |
| 863 CONSTRUCTOR=self._html_interface_name, | 877 CONSTRUCTOR=self._html_interface_name, |
| 864 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da rtType), | 878 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da rtType), |
| 865 NAMED_CONSTRUCTOR=constructor_info.name or self._html_interface_name, | 879 NAMED_CONSTRUCTOR=constructor_info.name or self._html_interface_name, |
| 866 ARGUMENTS=constructor_info.ParametersAsArgumentList()) | 880 ARGUMENTS=constructor_info.ParametersAsArgumentList()) |
| 867 | 881 |
| 882 def SecondaryContext(self, interface): | |
| 883 if interface is not self._current_secondary_parent: | |
| 884 self._current_secondary_parent = interface | |
| 885 self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id) | |
| 886 | |
| 868 def AddIndexer(self, element_type): | 887 def AddIndexer(self, element_type): |
| 869 """Adds all the methods required to complete implementation of List.""" | 888 """Adds all the methods required to complete implementation of List.""" |
| 870 # We would like to simply inherit the implementation of everything except | 889 # We would like to simply inherit the implementation of everything except |
| 871 # length, [], and maybe []=. It is possible to extend from a base | 890 # length, [], and maybe []=. It is possible to extend from a base |
| 872 # array implementation class only when there is no other implementation | 891 # array implementation class only when there is no other implementation |
| 873 # inheritance. There might be no implementation inheritance other than | 892 # inheritance. There might be no implementation inheritance other than |
| 874 # DOMBaseWrapper for many classes, but there might be some where the | 893 # DOMBaseWrapper for many classes, but there might be some where the |
| 875 # array-ness is introduced by a non-root interface: | 894 # array-ness is introduced by a non-root interface: |
| 876 # | 895 # |
| 877 # interface Y extends X, List<T> ... | 896 # interface Y extends X, List<T> ... |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1230 member_name = '%sEvents.%s' % (self._html_interface_name, member_name) | 1249 member_name = '%sEvents.%s' % (self._html_interface_name, member_name) |
| 1231 return member_name in _js_custom_members | 1250 return member_name in _js_custom_members |
| 1232 | 1251 |
| 1233 def _HasJavaScriptIndexingBehaviour(self): | 1252 def _HasJavaScriptIndexingBehaviour(self): |
| 1234 """Returns True if the native object has an indexer and length property.""" | 1253 """Returns True if the native object has an indexer and length property.""" |
| 1235 (element_type, requires_indexer) = ListImplementationInfo( | 1254 (element_type, requires_indexer) = ListImplementationInfo( |
| 1236 self._interface, self._database) | 1255 self._interface, self._database) |
| 1237 if element_type and requires_indexer: return True | 1256 if element_type and requires_indexer: return True |
| 1238 return False | 1257 return False |
| 1239 | 1258 |
| 1259 def _ShouldNarrowToImplementationType(self, type_name): | |
| 1260 # TODO(sra): Move into the 'system' and cache the result. | |
| 1261 do_not_narrow = ['DOMStringList', 'DOMStringMap', 'EventListener', | |
| 1262 'IDBAny', 'IDBKey', 'MediaQueryListListener'] | |
| 1263 if type_name in do_not_narrow: | |
| 1264 return False | |
| 1265 if self._database.HasInterface(type_name): | |
| 1266 interface = self._database.GetInterface(type_name) | |
| 1267 # Callbacks are typedef functions so don't have a class. | |
| 1268 return 'Callback' not in interface.ext_attrs | |
| 1269 return False | |
| 1270 | |
| 1271 def _NarrowToImplementationType(self, type_name): | |
| 1272 if self._ShouldNarrowToImplementationType(type_name): | |
| 1273 return self._ImplClassName(self._DartType(type_name)) | |
| 1274 return self._DartType(type_name) | |
| 1275 | |
| 1276 def _NarrowInputType(self, type_name): | |
| 1277 return self._NarrowToImplementationType(type_name) | |
| 1278 | |
| 1279 def _NarrowOutputType(self, type_name): | |
| 1280 return self._NarrowToImplementationType(type_name) | |
| 1281 | |
| 1282 def _FindShadowedAttribute(self, attr, merged_interfaces={}): | |
| 1283 """Returns (attribute, superinterface) or (None, None).""" | |
| 1284 def FindInParent(interface): | |
| 1285 """Returns matching attribute in parent, or None.""" | |
| 1286 if interface.parents: | |
| 1287 parent = interface.parents[0] | |
| 1288 if IsDartCollectionType(parent.type.id): | |
| 1289 return (None, None) | |
| 1290 if IsPureInterface(parent.type.id): | |
| 1291 return (None, None) | |
| 1292 if self._database.HasInterface(parent.type.id): | |
| 1293 interfaces_to_search_in = [] | |
| 1294 if parent.type.id in merged_interfaces: | |
| 1295 # IDL parent was merged into another interface, which became a | |
| 1296 # parent interface in Dart. | |
| 1297 interfaces_to_search_in.append(parent.type.id) | |
| 1298 parent_interface_name = merged_interfaces[parent.type.id] | |
| 1299 else: | |
| 1300 parent_interface_name = parent.type.id | |
| 1301 | |
| 1302 for interface_name in merged_interfaces: | |
| 1303 if merged_interfaces[interface_name] == parent_interface_name: | |
| 1304 # IDL parent has another interface that was merged into it. | |
| 1305 interfaces_to_search_in.append(interface_name) | |
| 1306 | |
| 1307 interfaces_to_search_in.append(parent_interface_name) | |
| 1308 for interface_name in interfaces_to_search_in: | |
| 1309 interface = self._database.GetInterface(interface_name) | |
| 1310 attr2 = FindMatchingAttribute(interface, attr) | |
| 1311 if attr2: | |
| 1312 return (attr2, parent_interface_name) | |
| 1313 | |
| 1314 return FindInParent( | |
| 1315 self._database.GetInterface(parent_interface_name)) | |
| 1316 return (None, None) | |
| 1317 | |
| 1318 return FindInParent(self._interface) if attr else (None, None) | |
| 1240 | 1319 |
| 1241 # ------------------------------------------------------------------------------ | 1320 # ------------------------------------------------------------------------------ |
| 1242 | 1321 |
| 1243 class DartLibraryEmitter(): | 1322 class DartLibraryEmitter(): |
| 1244 def __init__(self, emitters, template, dart_sources_dir): | 1323 def __init__(self, emitters, template, dart_sources_dir): |
| 1245 self._emitters = emitters | 1324 self._emitters = emitters |
| 1246 self._template = template | 1325 self._template = template |
| 1247 self._dart_sources_dir = dart_sources_dir | 1326 self._dart_sources_dir = dart_sources_dir |
| 1248 self._dart_sources_list = [] | 1327 self._dart_sources_list = [] |
| 1249 | 1328 |
| 1250 def CreateFileEmitter(self, filename): | 1329 def CreateFileEmitter(self, filename): |
| 1251 path = os.path.join(self._dart_sources_dir, filename) | 1330 path = os.path.join(self._dart_sources_dir, filename) |
| 1252 self._dart_sources_list.append(path) | 1331 self._dart_sources_list.append(path) |
| 1253 return self._emitters.FileEmitter(path) | 1332 return self._emitters.FileEmitter(path) |
| 1254 | 1333 |
| 1255 def EmitLibrary(self, library_file_path, auxiliary_dir): | 1334 def EmitLibrary(self, library_file_path, auxiliary_dir): |
| 1256 def massage_path(path): | 1335 def massage_path(path): |
| 1257 # The most robust way to emit path separators is to use / always. | 1336 # The most robust way to emit path separators is to use / always. |
| 1258 return path.replace('\\', '/') | 1337 return path.replace('\\', '/') |
| 1259 | 1338 |
| 1260 library_emitter = self._emitters.FileEmitter(library_file_path) | 1339 library_emitter = self._emitters.FileEmitter(library_file_path) |
| 1261 library_file_dir = os.path.dirname(library_file_path) | 1340 library_file_dir = os.path.dirname(library_file_path) |
| 1262 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) | 1341 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) |
| 1263 imports_emitter = library_emitter.Emit( | 1342 imports_emitter = library_emitter.Emit( |
| 1264 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) | 1343 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) |
| 1265 for path in sorted(self._dart_sources_list): | 1344 for path in sorted(self._dart_sources_list): |
| 1266 relpath = os.path.relpath(path, library_file_dir) | 1345 relpath = os.path.relpath(path, library_file_dir) |
| 1267 imports_emitter.Emit( | 1346 imports_emitter.Emit( |
| 1268 "#source('$PATH');\n", PATH=massage_path(relpath)) | 1347 "#source('$PATH');\n", PATH=massage_path(relpath)) |
| OLD | NEW |