| 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 systems to generate | 6 """This module provides shared functionality for the systems to generate |
| 7 dart2js binding from the IDL database.""" | 7 dart2js binding from the IDL database.""" |
| 8 | 8 |
| 9 import os | 9 import os |
| 10 from generator import * | 10 from generator import * |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 """Returns the file emitter of the Dart2JS implementation file.""" | 54 """Returns the file emitter of the Dart2JS implementation file.""" |
| 55 path = os.path.join(self._output_dir, 'src', 'dart2js', '%s.dart' % name) | 55 path = os.path.join(self._output_dir, 'src', 'dart2js', '%s.dart' % name) |
| 56 self._impl_file_paths.append(path) | 56 self._impl_file_paths.append(path) |
| 57 return self._emitters.FileEmitter(path) | 57 return self._emitters.FileEmitter(path) |
| 58 | 58 |
| 59 # ------------------------------------------------------------------------------ | 59 # ------------------------------------------------------------------------------ |
| 60 | 60 |
| 61 class Dart2JSInterfaceGenerator(BaseGenerator): | 61 class Dart2JSInterfaceGenerator(BaseGenerator): |
| 62 """Generates a Dart2JS class for a DOM IDL interface.""" | 62 """Generates a Dart2JS class for a DOM IDL interface.""" |
| 63 | 63 |
| 64 def __init__(self, system, interface, template, dart_code): | 64 def __init__(self, options, interface, template, dart_code): |
| 65 """Generates Dart code for the given interface. | 65 """Generates Dart code for the given interface. |
| 66 | 66 |
| 67 Args: | 67 Args: |
| 68 | 68 |
| 69 interface: an IDLInterface instance. It is assumed that all types have | 69 interface: an IDLInterface instance. It is assumed that all types have |
| 70 been converted to Dart types (e.g. int, String), unless they are in | 70 been converted to Dart types (e.g. int, String), unless they are in |
| 71 the same package as the interface. | 71 the same package as the interface. |
| 72 template: A string template. | 72 template: A string template. |
| 73 dart_code: an Emitter for the file containing the Dart implementation | 73 dart_code: an Emitter for the file containing the Dart implementation |
| 74 class. | 74 class. |
| 75 """ | 75 """ |
| 76 super(Dart2JSInterfaceGenerator, self).__init__(system._database, interface) | 76 super(Dart2JSInterfaceGenerator, self).__init__( |
| 77 self._system = system | 77 options.database, options.type_registry, interface) |
| 78 self._template_loader = options.templates |
| 78 self._interface = interface | 79 self._interface = interface |
| 79 self._template = template | 80 self._template = template |
| 80 self._dart_code = dart_code | 81 self._dart_code = dart_code |
| 81 self._current_secondary_parent = None | 82 self._current_secondary_parent = None |
| 82 | 83 |
| 83 | |
| 84 def StartInterface(self): | 84 def StartInterface(self): |
| 85 interface = self._interface | 85 interface = self._interface |
| 86 interface_name = interface.id | 86 interface_name = interface.id |
| 87 self._class_name = self._ImplClassName(interface_name) | 87 self._class_name = self._ImplClassName(interface_name) |
| 88 | 88 |
| 89 base = None | 89 base = None |
| 90 if interface.parents: | 90 if interface.parents: |
| 91 supertype = interface.parents[0].type.id | 91 supertype = interface.parents[0].type.id |
| 92 if IsDartCollectionType(supertype): | 92 if IsDartCollectionType(supertype): |
| 93 # List methods are injected in AddIndexer. | 93 # List methods are injected in AddIndexer. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 def FinishInterface(self): | 132 def FinishInterface(self): |
| 133 """.""" | 133 """.""" |
| 134 pass | 134 pass |
| 135 | 135 |
| 136 def _ImplClassName(self, type_name): | 136 def _ImplClassName(self, type_name): |
| 137 return '_' + type_name + 'Js' | 137 return '_' + type_name + 'Js' |
| 138 | 138 |
| 139 def _EmitFactoryProvider(self, interface_name, constructor_info): | 139 def _EmitFactoryProvider(self, interface_name, constructor_info): |
| 140 template_file = 'factoryprovider_%s.darttemplate' % interface_name | 140 template_file = 'factoryprovider_%s.darttemplate' % interface_name |
| 141 template = self._system._templates.TryLoad(template_file) | 141 template = self._template_loader.TryLoad(template_file) |
| 142 if not template: | 142 if not template: |
| 143 template = self._system._templates.Load('factoryprovider.darttemplate') | 143 template = self._template_loader.Load('factoryprovider.darttemplate') |
| 144 | 144 |
| 145 factory_provider = '_' + interface_name + 'FactoryProvider' | 145 factory_provider = '_' + interface_name + 'FactoryProvider' |
| 146 emitter = self._system._ImplFileEmitter(factory_provider) | 146 emitter = self._system._ImplFileEmitter(factory_provider) |
| 147 emitter.Emit( | 147 emitter.Emit( |
| 148 template, | 148 template, |
| 149 FACTORYPROVIDER=factory_provider, | 149 FACTORYPROVIDER=factory_provider, |
| 150 CONSTRUCTOR=interface_name, | 150 CONSTRUCTOR=interface_name, |
| 151 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), | 151 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), |
| 152 NAMEDCONSTRUCTOR=constructor_info.name or interface_name, | 152 NAMEDCONSTRUCTOR=constructor_info.name or interface_name, |
| 153 ARGUMENTS=constructor_info.ParametersAsArgumentList()) | 153 ARGUMENTS=constructor_info.ParametersAsArgumentList()) |
| 154 | 154 |
| 155 def _ShouldNarrowToImplementationType(self, type_name): | 155 def _ShouldNarrowToImplementationType(self, type_name): |
| 156 # TODO(sra): Move into the 'system' and cache the result. | 156 # TODO(sra): Move into the 'system' and cache the result. |
| 157 do_not_narrow = ['DOMStringList', 'DOMStringMap', 'EventListener', | 157 do_not_narrow = ['DOMStringList', 'DOMStringMap', 'EventListener', |
| 158 'IDBAny', 'IDBKey', 'MediaQueryListListener'] | 158 'IDBAny', 'IDBKey', 'MediaQueryListListener'] |
| 159 if type_name in do_not_narrow: | 159 if type_name in do_not_narrow: |
| 160 return False | 160 return False |
| 161 if self._system._database.HasInterface(type_name): | 161 if self._database.HasInterface(type_name): |
| 162 interface = self._system._database.GetInterface(type_name) | 162 interface = self._database.GetInterface(type_name) |
| 163 # Callbacks are typedef functions so don't have a class. | 163 # Callbacks are typedef functions so don't have a class. |
| 164 return 'Callback' not in interface.ext_attrs | 164 return 'Callback' not in interface.ext_attrs |
| 165 return False | 165 return False |
| 166 | 166 |
| 167 def _NarrowToImplementationType(self, type_name): | 167 def _NarrowToImplementationType(self, type_name): |
| 168 if self._ShouldNarrowToImplementationType(type_name): | 168 if self._ShouldNarrowToImplementationType(type_name): |
| 169 return self._ImplClassName(self._DartType(type_name)) | 169 return self._ImplClassName(self._DartType(type_name)) |
| 170 return self._DartType(type_name) | 170 return self._DartType(type_name) |
| 171 | 171 |
| 172 def _NarrowInputType(self, type_name): | 172 def _NarrowInputType(self, type_name): |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 def _FindShadowedAttribute(self, attr, merged_interfaces={}): | 272 def _FindShadowedAttribute(self, attr, merged_interfaces={}): |
| 273 """Returns (attribute, superinterface) or (None, None).""" | 273 """Returns (attribute, superinterface) or (None, None).""" |
| 274 def FindInParent(interface): | 274 def FindInParent(interface): |
| 275 """Returns matching attribute in parent, or None.""" | 275 """Returns matching attribute in parent, or None.""" |
| 276 if interface.parents: | 276 if interface.parents: |
| 277 parent = interface.parents[0] | 277 parent = interface.parents[0] |
| 278 if IsDartCollectionType(parent.type.id): | 278 if IsDartCollectionType(parent.type.id): |
| 279 return (None, None) | 279 return (None, None) |
| 280 if IsPureInterface(parent.type.id): | 280 if IsPureInterface(parent.type.id): |
| 281 return (None, None) | 281 return (None, None) |
| 282 if self._system._database.HasInterface(parent.type.id): | 282 if self._database.HasInterface(parent.type.id): |
| 283 interfaces_to_search_in = [] | 283 interfaces_to_search_in = [] |
| 284 if parent.type.id in merged_interfaces: | 284 if parent.type.id in merged_interfaces: |
| 285 # IDL parent was merged into another interface, which became a | 285 # IDL parent was merged into another interface, which became a |
| 286 # parent interface in Dart. | 286 # parent interface in Dart. |
| 287 interfaces_to_search_in.append(parent.type.id) | 287 interfaces_to_search_in.append(parent.type.id) |
| 288 parent_interface_name = merged_interfaces[parent.type.id] | 288 parent_interface_name = merged_interfaces[parent.type.id] |
| 289 else: | 289 else: |
| 290 parent_interface_name = parent.type.id | 290 parent_interface_name = parent.type.id |
| 291 | 291 |
| 292 for interface_name in merged_interfaces: | 292 for interface_name in merged_interfaces: |
| 293 if merged_interfaces[interface_name] == parent_interface_name: | 293 if merged_interfaces[interface_name] == parent_interface_name: |
| 294 # IDL parent has another interface that was merged into it. | 294 # IDL parent has another interface that was merged into it. |
| 295 interfaces_to_search_in.append(interface_name) | 295 interfaces_to_search_in.append(interface_name) |
| 296 | 296 |
| 297 interfaces_to_search_in.append(parent_interface_name) | 297 interfaces_to_search_in.append(parent_interface_name) |
| 298 for interface_name in interfaces_to_search_in: | 298 for interface_name in interfaces_to_search_in: |
| 299 interface = self._system._database.GetInterface(interface_name) | 299 interface = self._database.GetInterface(interface_name) |
| 300 attr2 = FindMatchingAttribute(interface, attr) | 300 attr2 = FindMatchingAttribute(interface, attr) |
| 301 if attr2: | 301 if attr2: |
| 302 return (attr2, parent_interface_name) | 302 return (attr2, parent_interface_name) |
| 303 | 303 |
| 304 return FindInParent( | 304 return FindInParent( |
| 305 self._system._database.GetInterface(parent_interface_name)) | 305 self._database.GetInterface(parent_interface_name)) |
| 306 return (None, None) | 306 return (None, None) |
| 307 | 307 |
| 308 return FindInParent(self._interface) if attr else (None, None) | 308 return FindInParent(self._interface) if attr else (None, None) |
| 309 | 309 |
| 310 | 310 |
| 311 def AddSecondaryAttribute(self, interface, attribute): | 311 def AddSecondaryAttribute(self, interface, attribute): |
| 312 self.SecondaryContext(interface) | 312 self.SecondaryContext(interface) |
| 313 self.AddAttribute(attribute) | 313 self.AddAttribute(attribute) |
| 314 | 314 |
| 315 def AddSecondaryOperation(self, interface, info): | 315 def AddSecondaryOperation(self, interface, info): |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 self._members_emitter.Emit( | 354 self._members_emitter.Emit( |
| 355 '\n' | 355 '\n' |
| 356 ' void operator[]=(int index, $TYPE value) {\n' | 356 ' void operator[]=(int index, $TYPE value) {\n' |
| 357 ' throw new UnsupportedOperationException("Cannot assign element of
immutable List.");\n' | 357 ' throw new UnsupportedOperationException("Cannot assign element of
immutable List.");\n' |
| 358 ' }\n', | 358 ' }\n', |
| 359 TYPE=self._NarrowInputType(element_type)) | 359 TYPE=self._NarrowInputType(element_type)) |
| 360 | 360 |
| 361 # TODO(sra): Use separate mixins for mutable implementations of List<T>. | 361 # TODO(sra): Use separate mixins for mutable implementations of List<T>. |
| 362 # TODO(sra): Use separate mixins for typed array implementations of List<T>. | 362 # TODO(sra): Use separate mixins for typed array implementations of List<T>. |
| 363 template_file = 'immutable_list_mixin.darttemplate' | 363 template_file = 'immutable_list_mixin.darttemplate' |
| 364 template = self._system._templates.Load(template_file) | 364 template = self._template_loader.Load(template_file) |
| 365 self._members_emitter.Emit(template, E=self._DartType(element_type)) | 365 self._members_emitter.Emit(template, E=self._DartType(element_type)) |
| 366 | 366 |
| 367 def AddOperation(self, info): | 367 def AddOperation(self, info): |
| 368 """ | 368 """ |
| 369 Arguments: | 369 Arguments: |
| 370 info: An OperationInfo object. | 370 info: An OperationInfo object. |
| 371 """ | 371 """ |
| 372 # TODO(vsm): Handle overloads. | 372 # TODO(vsm): Handle overloads. |
| 373 params = info.ParametersImplementationDeclaration( | 373 params = info.ParametersImplementationDeclaration( |
| 374 lambda type_name: self._NarrowInputType(type_name)) | 374 lambda type_name: self._NarrowInputType(type_name)) |
| 375 | 375 |
| 376 native_string = '' | 376 native_string = '' |
| 377 if info.declared_name != info.name: | 377 if info.declared_name != info.name: |
| 378 native_string = " '%s'" % info.declared_name | 378 native_string = " '%s'" % info.declared_name |
| 379 | 379 |
| 380 self._members_emitter.Emit( | 380 self._members_emitter.Emit( |
| 381 '\n' | 381 '\n' |
| 382 ' $TYPE $NAME($PARAMS) native$NATIVESTRING;\n', | 382 ' $TYPE $NAME($PARAMS) native$NATIVESTRING;\n', |
| 383 TYPE=self._NarrowOutputType(info.type_name), | 383 TYPE=self._NarrowOutputType(info.type_name), |
| 384 NAME=info.name, | 384 NAME=info.name, |
| 385 PARAMS=params, | 385 PARAMS=params, |
| 386 NATIVESTRING=native_string) | 386 NATIVESTRING=native_string) |
| OLD | NEW |