| 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 native binding from the IDL database.""" | 7 native binding from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 import os | 10 import os |
| 11 import systembase | 11 import systembase |
| 12 from generator import * | 12 from generator import * |
| 13 from systemhtml import DomToHtmlEvent, DomToHtmlEvents, HtmlSystemShared | 13 from systemhtml import HtmlSystemShared |
| 14 from systemhtml import HtmlElementConstructorInfos | 14 |
| 15 from systemhtml import EmitHtmlElementFactoryConstructors | |
| 16 | 15 |
| 17 class NativeImplementationSystem(systembase.System): | 16 class NativeImplementationSystem(systembase.System): |
| 18 | 17 |
| 19 def __init__(self, templates, database, emitters, output_dir, auxiliary_dir): | 18 def __init__(self, templates, database, emitters, output_dir, auxiliary_dir): |
| 20 super(NativeImplementationSystem, self).__init__( | 19 super(NativeImplementationSystem, self).__init__( |
| 21 templates, database, emitters, output_dir) | 20 templates, database, emitters, output_dir) |
| 22 self._auxiliary_dir = auxiliary_dir | 21 self._auxiliary_dir = auxiliary_dir |
| 23 self._dom_impl_files = [] | |
| 24 self._cpp_header_files = [] | 22 self._cpp_header_files = [] |
| 25 self._cpp_impl_files = [] | 23 self._cpp_impl_files = [] |
| 26 self._html_system = HtmlSystemShared(database) | 24 self._html_system = HtmlSystemShared(database) |
| 27 self._factory_provider_emitters = {} | |
| 28 | 25 |
| 29 def ImplementationGenerator(self, interface): | 26 def ImplementationGenerator(self, interface): |
| 30 return NativeImplementationGenerator(self, interface) | 27 return NativeImplementationGenerator(self, interface) |
| 31 | 28 |
| 32 def ProcessCallback(self, interface, info): | 29 def ProcessCallback(self, interface, info): |
| 33 self._interface = interface | 30 self._interface = interface |
| 34 | 31 |
| 35 if IsPureInterface(self._interface.id): | 32 if IsPureInterface(self._interface.id): |
| 36 return None | 33 return None |
| 37 | 34 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 INCLUDES=_GenerateCPPIncludes(cpp_impl_includes), | 96 INCLUDES=_GenerateCPPIncludes(cpp_impl_includes), |
| 100 INTERFACE=self._interface.id, | 97 INTERFACE=self._interface.id, |
| 101 HANDLERS=cpp_impl_handlers_emitter.Fragments()) | 98 HANDLERS=cpp_impl_handlers_emitter.Fragments()) |
| 102 | 99 |
| 103 def GenerateLibraries(self, interface_files): | 100 def GenerateLibraries(self, interface_files): |
| 104 # Generate dart:html library. | 101 # Generate dart:html library. |
| 105 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) | 102 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) |
| 106 self._GenerateLibFile( | 103 self._GenerateLibFile( |
| 107 'html_dartium.darttemplate', | 104 'html_dartium.darttemplate', |
| 108 os.path.join(self._output_dir, 'html_dartium.dart'), | 105 os.path.join(self._output_dir, 'html_dartium.dart'), |
| 109 interface_files + self._dom_impl_files, | 106 interface_files, |
| 110 AUXILIARY_DIR=systembase.MassagePath(auxiliary_dir)) | 107 AUXILIARY_DIR=systembase.MassagePath(auxiliary_dir)) |
| 111 | 108 |
| 112 # Generate DartDerivedSourcesXX.cpp. | 109 # Generate DartDerivedSourcesXX.cpp. |
| 113 partitions = 20 # FIXME: this should be configurable. | 110 partitions = 20 # FIXME: this should be configurable. |
| 114 sources_count = len(self._cpp_impl_files) | 111 sources_count = len(self._cpp_impl_files) |
| 115 for i in range(0, partitions): | 112 for i in range(0, partitions): |
| 116 derived_sources_path = os.path.join(self._output_dir, | 113 derived_sources_path = os.path.join(self._output_dir, |
| 117 'DartDerivedSources%02i.cpp' % (i + 1)) | 114 'DartDerivedSources%02i.cpp' % (i + 1)) |
| 118 | 115 |
| 119 includes_emitter = emitter.Emitter() | 116 includes_emitter = emitter.Emitter() |
| (...skipping 21 matching lines...) Expand all Loading... |
| 141 | 138 |
| 142 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) | 139 cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path) |
| 143 cpp_resolver_emitter.Emit( | 140 cpp_resolver_emitter.Emit( |
| 144 self._templates.Load('cpp_resolver.template'), | 141 self._templates.Load('cpp_resolver.template'), |
| 145 INCLUDES=includes_emitter.Fragments(), | 142 INCLUDES=includes_emitter.Fragments(), |
| 146 RESOLVER_BODY=resolver_body_emitter.Fragments()) | 143 RESOLVER_BODY=resolver_body_emitter.Fragments()) |
| 147 | 144 |
| 148 def Finish(self): | 145 def Finish(self): |
| 149 pass | 146 pass |
| 150 | 147 |
| 151 def _FilePathForDartFactoryProviderImplementation(self, interface_name): | |
| 152 return os.path.join(self._output_dir, 'dart', | |
| 153 '%sFactoryProviderImplementation.dart' % interface_name) | |
| 154 | |
| 155 def _FilePathForCppHeader(self, interface_name): | 148 def _FilePathForCppHeader(self, interface_name): |
| 156 return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name) | 149 return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name) |
| 157 | 150 |
| 158 def _FilePathForCppImplementation(self, interface_name): | 151 def _FilePathForCppImplementation(self, interface_name): |
| 159 return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name) | 152 return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name) |
| 160 | 153 |
| 161 def _EmitterForFactoryProviderBody(self, name): | |
| 162 if name not in self._factory_provider_emitters: | |
| 163 file_name = self._FilePathForDartFactoryProviderImplementation(name) | |
| 164 self._dom_impl_files.append(file_name) | |
| 165 template = self._templates.Load('factoryprovider_%s.darttemplate' % name) | |
| 166 file_emitter = self._emitters.FileEmitter(file_name) | |
| 167 self._factory_provider_emitters[name] = file_emitter.Emit(template) | |
| 168 return self._factory_provider_emitters[name] | |
| 169 | |
| 170 | 154 |
| 171 class NativeImplementationGenerator(systembase.BaseGenerator): | 155 class NativeImplementationGenerator(systembase.BaseGenerator): |
| 172 """Generates Dart implementation for one DOM IDL interface.""" | 156 """Generates Dart implementation for one DOM IDL interface.""" |
| 173 | 157 |
| 174 def __init__(self, system, interface): | 158 def __init__(self, system, interface): |
| 175 """Generates Dart and C++ code for the given interface. | 159 """Generates Dart and C++ code for the given interface. |
| 176 | 160 |
| 177 Args: | 161 Args: |
| 178 system: The NativeImplementationSystem. | 162 system: The NativeImplementationSystem. |
| 179 interface: an IDLInterface instance. It is assumed that all types have | 163 interface: an IDLInterface instance. It is assumed that all types have |
| 180 been converted to Dart types (e.g. int, String), unless they are in | 164 been converted to Dart types (e.g. int, String), unless they are in |
| 181 the same package as the interface. | 165 the same package as the interface. |
| 182 """ | 166 """ |
| 183 super(NativeImplementationGenerator, self).__init__( | 167 super(NativeImplementationGenerator, self).__init__( |
| 184 system._database, interface) | 168 system._database, interface) |
| 185 self._system = system | 169 self._system = system |
| 186 self._current_secondary_parent = None | 170 self._current_secondary_parent = None |
| 187 self._html_system = self._system._html_system | 171 self._html_system = self._system._html_system |
| 188 self._html_renames = self._html_system._html_renames | 172 self._html_interface_name = self._html_system._html_renames.get( |
| 173 self._interface.id, self._interface.id) |
| 189 | 174 |
| 190 def HasImplementation(self): | 175 def HasImplementation(self): |
| 191 return not IsPureInterface(self._interface.id) | 176 return not IsPureInterface(self._interface.id) |
| 192 | 177 |
| 193 def ImplementationClassName(self): | 178 def ImplementationClassName(self): |
| 194 return self._ImplClassName(self._interface.id) | 179 return self._ImplClassName(self._interface.id) |
| 195 | 180 |
| 196 def FilePathForDartImplementation(self): | 181 def FilePathForDartImplementation(self): |
| 197 return os.path.join(self._system._output_dir, 'dart', | 182 return os.path.join(self._system._output_dir, 'dart', |
| 198 '%sImplementation.dart' % self._interface.id) | 183 '%sImplementation.dart' % self._interface.id) |
| 199 | 184 |
| 185 def FilePathForDartFactoryProviderImplementation(self): |
| 186 file_name = '%sFactoryProviderImplementation.dart' % self._interface.id |
| 187 return os.path.join(self._system._output_dir, 'dart', file_name) |
| 188 |
| 189 def FilePathForDartElementsFactoryProviderImplementation(self): |
| 190 return os.path.join(self._system._output_dir, 'dart', |
| 191 '_ElementsFactoryProviderImplementation.dart') |
| 192 |
| 200 def SetImplementationEmitter(self, implementation_emitter): | 193 def SetImplementationEmitter(self, implementation_emitter): |
| 201 self._dart_impl_emitter = implementation_emitter | 194 self._dart_impl_emitter = implementation_emitter |
| 202 | 195 |
| 203 def AddMergedMembers(self, merged_interface): | 196 def AddMergedMembers(self, merged_interface): |
| 204 # We could not add merged functions to implementation class because | 197 # We could not add merged functions to implementation class because |
| 205 # underlying c++ object doesn't implement them. Merged functions are | 198 # underlying c++ object doesn't implement them. Merged functions are |
| 206 # generated on merged interface implementation instead. | 199 # generated on merged interface implementation instead. |
| 207 pass | 200 pass |
| 208 | 201 |
| 209 def StartInterface(self): | 202 def StartInterface(self): |
| (...skipping 13 matching lines...) Expand all Loading... |
| 223 self._members_emitter = emitter.Emitter() | 216 self._members_emitter = emitter.Emitter() |
| 224 self._cpp_declarations_emitter = emitter.Emitter() | 217 self._cpp_declarations_emitter = emitter.Emitter() |
| 225 self._cpp_impl_includes = set() | 218 self._cpp_impl_includes = set() |
| 226 self._cpp_definitions_emitter = emitter.Emitter() | 219 self._cpp_definitions_emitter = emitter.Emitter() |
| 227 self._cpp_resolver_emitter = emitter.Emitter() | 220 self._cpp_resolver_emitter = emitter.Emitter() |
| 228 | 221 |
| 229 self._GenerateConstructors() | 222 self._GenerateConstructors() |
| 230 return self._members_emitter | 223 return self._members_emitter |
| 231 | 224 |
| 232 def _GenerateConstructors(self): | 225 def _GenerateConstructors(self): |
| 233 html_interface_name = self._HTMLInterfaceName(self._interface.id) | |
| 234 | |
| 235 if not self._IsConstructable(): | 226 if not self._IsConstructable(): |
| 236 return | 227 return |
| 237 | 228 |
| 238 # TODO(antonm): currently we don't have information about number of argument
s expected by | 229 # TODO(antonm): currently we don't have information about number of argument
s expected by |
| 239 # the constructor, so name only dispatch. | 230 # the constructor, so name only dispatch. |
| 240 self._cpp_resolver_emitter.Emit( | 231 self._cpp_resolver_emitter.Emit( |
| 241 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' | 232 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' |
| 242 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n', | 233 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n', |
| 243 INTERFACE_NAME=self._interface.id) | 234 INTERFACE_NAME=self._interface.id) |
| 244 | 235 |
| 245 | 236 |
| 246 constructor_info = AnalyzeConstructor(self._interface) | 237 constructor_info = AnalyzeConstructor(self._interface) |
| 247 if constructor_info: | |
| 248 self._EmitFactoryProvider(self._interface.id, constructor_info) | |
| 249 | 238 |
| 250 ext_attrs = self._interface.ext_attrs | 239 ext_attrs = self._interface.ext_attrs |
| 251 | 240 |
| 252 if 'CustomConstructor' in ext_attrs: | 241 if 'CustomConstructor' in ext_attrs: |
| 253 # We have a custom implementation for it. | 242 # We have a custom implementation for it. |
| 254 self._cpp_declarations_emitter.Emit( | 243 self._cpp_declarations_emitter.Emit( |
| 255 '\n' | 244 '\n' |
| 256 'void constructorCallback(Dart_NativeArguments);\n') | 245 'void constructorCallback(Dart_NativeArguments);\n') |
| 257 return | 246 return |
| 258 | 247 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 # FIXME: We're currently injecting List<..> and EventTarget as | 338 # FIXME: We're currently injecting List<..> and EventTarget as |
| 350 # supertypes in dart.idl. We should annotate/preserve as | 339 # supertypes in dart.idl. We should annotate/preserve as |
| 351 # attributes instead. For now, this hack lets the self._interfaces | 340 # attributes instead. For now, this hack lets the self._interfaces |
| 352 # inherit, but not the classes. | 341 # inherit, but not the classes. |
| 353 # List methods are injected in AddIndexer. | 342 # List methods are injected in AddIndexer. |
| 354 if IsDartListType(supertype) or IsDartCollectionType(supertype): | 343 if IsDartListType(supertype) or IsDartCollectionType(supertype): |
| 355 return root_class | 344 return root_class |
| 356 | 345 |
| 357 return self._ImplClassName(supertype) | 346 return self._ImplClassName(supertype) |
| 358 | 347 |
| 359 def _HTMLInterfaceName(self, interface_name): | |
| 360 return self._html_renames.get(interface_name, interface_name) | |
| 361 | |
| 362 def _IsConstructable(self): | 348 def _IsConstructable(self): |
| 363 # FIXME: support ConstructorTemplate. | 349 # FIXME: support ConstructorTemplate. |
| 364 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'Name
dConstructor']) & set(self._interface.ext_attrs) | 350 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'Name
dConstructor']) & set(self._interface.ext_attrs) |
| 365 | 351 |
| 366 def _EmitFactoryProvider(self, interface_name, constructor_info): | 352 def EmitFactoryProvider(self, constructor_info, factory_provider, emitter): |
| 367 dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation( | 353 template_file = 'factoryprovider_%s.darttemplate' % self._html_interface_nam
e |
| 368 interface_name) | |
| 369 self._system._dom_impl_files.append(dart_impl_path) | |
| 370 | |
| 371 html_interface_name = self._HTMLInterfaceName(interface_name) | |
| 372 template_file = 'factoryprovider_%s.darttemplate' % html_interface_name | |
| 373 template = self._system._templates.TryLoad(template_file) | 354 template = self._system._templates.TryLoad(template_file) |
| 374 if not template: | 355 if not template: |
| 375 template = self._system._templates.Load('factoryprovider.darttemplate') | 356 template = self._system._templates.Load('factoryprovider.darttemplate') |
| 376 | 357 |
| 377 native_implementation_function = '%s_constructor_Callback' % interface_name | 358 native_binding = '%s_constructor_Callback' % self._interface.id |
| 378 emitter = self._system._emitters.FileEmitter(dart_impl_path) | |
| 379 emitter.Emit( | 359 emitter.Emit( |
| 380 template, | 360 template, |
| 381 FACTORYPROVIDER='_%sFactoryProvider' % html_interface_name, | 361 FACTORYPROVIDER=factory_provider, |
| 382 INTERFACE=html_interface_name, | 362 INTERFACE=self._html_interface_name, |
| 383 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), | 363 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), |
| 384 ARGUMENTS=constructor_info.ParametersAsArgumentList(), | 364 ARGUMENTS=constructor_info.ParametersAsArgumentList(), |
| 385 NATIVE_NAME=native_implementation_function) | 365 NATIVE_NAME=native_binding) |
| 386 | 366 |
| 387 def FinishInterface(self): | 367 def FinishInterface(self): |
| 388 html_interface_name = self._HTMLInterfaceName(self._interface.id) | |
| 389 template = None | 368 template = None |
| 390 if html_interface_name == self._interface.id or not self._database.HasInterf
ace(html_interface_name): | 369 if self._html_interface_name == self._interface.id or not self._database.Has
Interface(self._html_interface_name): |
| 391 template_file = 'impl_%s.darttemplate' % html_interface_name | 370 template_file = 'impl_%s.darttemplate' % self._html_interface_name |
| 392 template = self._system._templates.TryLoad(template_file) | 371 template = self._system._templates.TryLoad(template_file) |
| 393 if not template: | 372 if not template: |
| 394 template = self._system._templates.Load('dart_implementation.darttemplate'
) | 373 template = self._system._templates.Load('dart_implementation.darttemplate'
) |
| 395 | 374 |
| 396 class_name = self._ImplClassName(self._interface.id) | 375 class_name = self._ImplClassName(self._interface.id) |
| 397 members_emitter = self._dart_impl_emitter.Emit( | 376 members_emitter = self._dart_impl_emitter.Emit( |
| 398 template, | 377 template, |
| 399 CLASSNAME=class_name, | 378 CLASSNAME=class_name, |
| 400 EXTENDS=' extends ' + self._BaseClassName(), | 379 EXTENDS=' extends ' + self._BaseClassName(), |
| 401 IMPLEMENTS=' implements ' + html_interface_name, | 380 IMPLEMENTS=' implements ' + self._html_interface_name, |
| 402 NATIVESPEC='') | 381 NATIVESPEC='') |
| 403 members_emitter.Emit(''.join(self._members_emitter.Fragments())) | 382 members_emitter.Emit(''.join(self._members_emitter.Fragments())) |
| 404 | 383 |
| 405 self._GenerateCppHeader() | 384 self._GenerateCppHeader() |
| 406 | 385 |
| 407 self._cpp_impl_emitter.Emit( | 386 self._cpp_impl_emitter.Emit( |
| 408 self._system._templates.Load('cpp_implementation.template'), | 387 self._system._templates.Load('cpp_implementation.template'), |
| 409 INTERFACE=self._interface.id, | 388 INTERFACE=self._interface.id, |
| 410 INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes), | 389 INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes), |
| 411 CALLBACKS=self._cpp_definitions_emitter.Fragments(), | 390 CALLBACKS=self._cpp_definitions_emitter.Fragments(), |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 | 983 |
| 1005 def _IsArgumentOptionalInWebCore(argument): | 984 def _IsArgumentOptionalInWebCore(argument): |
| 1006 return IsOptional(argument) and not 'Callback' in argument.ext_attrs | 985 return IsOptional(argument) and not 'Callback' in argument.ext_attrs |
| 1007 | 986 |
| 1008 def _ToWebKitName(name): | 987 def _ToWebKitName(name): |
| 1009 name = name[0].lower() + name[1:] | 988 name = name[0].lower() + name[1:] |
| 1010 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), | 989 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), |
| 1011 name) | 990 name) |
| 1012 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, | 991 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, |
| 1013 name) | 992 name) |
| OLD | NEW |