def _GenerateParameterAdapter(self, emitter, idl_node, index, adapter_name=None): """idl_node is IDLArgument or IDLAttribute.""" type_info = GetIDLTypeInfo(idl_node.type.id) (adapter_type, include_name) = type_info.parameter_adapter_info() if include_name: self._cpp_impl_includes.add(include_name) flags = '' if (idl_node.ext_attrs.get('Optional') == 'DefaultIsNullString' or 'RequiredCppParameter' in idl_node.ext_attrs): flags = ', DartUtilities::ConvertNullToDefaultValue' emitter.Emit( '\n' ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)$FLAGS);\n' ' if (!$NAME.conversionSuccessful()) {\n' ' exception = $NAME.exception();\n' ' goto fail;\n' ' }\n', ADAPTER_TYPE=adapter_type, NAME=adapter_name or idl_node.id, INDEX=index + 1, FLAGS=flags)
def _EmitFactoryProvider(self, interface_name, constructor_info): factory_provider = '_' + interface_name + 'FactoryProvider' implementation_class = interface_name + 'FactoryProviderImplementation' implementation_function = 'create' + interface_name native_implementation_function = '%s_constructor_Callback' % interface_name # Emit private factory provider in public library. template_file = 'factoryprovider_%s.darttemplate' % interface_name template = self._system._templates.TryLoad(template_file) if not template: template = self._system._templates.Load( 'factoryprovider.darttemplate') dart_impl_path = self._system._FilePathForDartFactoryProvider( interface_name) self._system._dom_public_files.append(dart_impl_path) emitter = self._system._emitters.FileEmitter(dart_impl_path) emitter.Emit( template, FACTORY_PROVIDER=factory_provider, CONSTRUCTOR=interface_name, PARAMETERS=constructor_info.ParametersImplementationDeclaration(), IMPL_CLASS=implementation_class, IMPL_FUNCTION=implementation_function, ARGUMENTS=constructor_info.ParametersAsArgumentList()) # Emit public implementation in implementation libary. dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation( interface_name) self._system._dom_impl_files.append(dart_impl_path) emitter = self._system._emitters.FileEmitter(dart_impl_path) emitter.Emit( 'class $IMPL_CLASS {\n' ' static $INTERFACE_NAME $IMPL_FUNCTION($PARAMETERS)\n' ' native "$NATIVE_NAME";\n' '}', INTERFACE_NAME=interface_name, PARAMETERS=constructor_info.ParametersImplementationDeclaration(), IMPL_CLASS=implementation_class, IMPL_FUNCTION=implementation_function, NATIVE_NAME=native_implementation_function)
def FileEmitter(self, basename, library_name, template=None): aux_dir = os.path.join(self._dart_sources_dir, library_name) path = os.path.join(aux_dir, '%s.dart' % basename) if not path in self._path_to_emitter: emitter = self._multiemitter.FileEmitter(path) if not template is None: emitter = emitter.Emit(template) self._path_to_emitter[path] = emitter self._dart_libraries.AddFile(basename, library_name, path) return self._path_to_emitter[path]
def EmitFactoryProvider(self, constructor_info, factory_provider, emitter): template_file = 'factoryprovider_%s.darttemplate' % self._html_interface_name template = self._template_loader.TryLoad(template_file) if not template: template = self._template_loader.Load('factoryprovider.darttemplate') native_binding = '%s_constructor_Callback' % self._interface.id emitter.Emit( template, FACTORYPROVIDER=factory_provider, INTERFACE=self._html_interface_name, PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._DartType), ARGUMENTS=constructor_info.ParametersAsArgumentList(), NATIVE_NAME=native_binding)
def _EmitFactoryProvider(self, interface_name, constructor_info): dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation( interface_name) self._system._dom_impl_files.append(dart_impl_path) html_interface_name = self._HTMLInterfaceName(interface_name) template_file = 'factoryprovider_%s.darttemplate' % html_interface_name template = self._system._templates.TryLoad(template_file) if not template: template = self._system._templates.Load('factoryprovider.darttemplate') native_implementation_function = '%s_constructor_Callback' % interface_name emitter = self._system._emitters.FileEmitter(dart_impl_path) emitter.Emit( template, FACTORYPROVIDER='_%sFactoryProvider' % html_interface_name, INTERFACE=html_interface_name, PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._DartType), ARGUMENTS=constructor_info.ParametersAsArgumentList(), NATIVE_NAME=native_implementation_function)
def _GenerateOverloadDispatcher( self, info, signatures, is_void, declaration, generate_call, is_optional, emitter, can_omit_type_check=lambda type, pos: False): parameter_names = [p.name for p in info.param_infos] number_of_required_in_dart = info.NumberOfRequiredInDart() body_emitter = emitter.Emit('\n' ' $DECLARATION {\n' '$!BODY' ' }\n', DECLARATION=declaration) version = [0] def GenerateCall(signature_index, argument_count, checks): if checks: (stmts_emitter, call_emitter) = body_emitter.Emit( ' if ($CHECKS) {\n$!STMTS$!CALL }\n', INDENT=' ', CHECKS=' && '.join(checks)) else: (stmts_emitter, call_emitter) = body_emitter.Emit('$!STMTS$!CALL', INDENT=' ') if is_void: call_emitter = call_emitter.Emit( '$(INDENT)$!CALL;\n$(INDENT)return;\n') else: call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n') version[0] += 1 generate_call(stmts_emitter, call_emitter, version[0], signature_index, argument_count) def GenerateChecksAndCall(signature_index, argument_count): checks = [] typechecked_interface = \ ('TypeChecking' in self._interface.ext_attrs) and \ ('Interface' in self._interface.ext_attrs['TypeChecking']) for i in reversed(range(0, argument_count)): argument = signatures[signature_index][i] parameter_name = parameter_names[i] test_type = self._NarrowToImplementationType(argument.type.id) if test_type in ['dynamic', 'Object']: checks.append('%s != null' % parameter_name) elif not can_omit_type_check(test_type, i): typechecked = typechecked_interface or \ ('TypeChecking' in argument.ext_attrs) and \ ('Interface' in argument.ext_attrs['TypeChecking']) converts_null = \ ('TreatNullAs' in argument.ext_attrs) or \ (argument.default_value is not None) or \ (argument.default_value_is_null) if argument.type.nullable or converts_null or not typechecked: checks.append( '(%s is %s || %s == null)' % (parameter_name, test_type, parameter_name)) else: checks.append('(%s is %s)' % (parameter_name, test_type)) elif i >= number_of_required_in_dart: checks.append('%s != null' % parameter_name) # There can be multiple presence checks. We need them all since a later # optional argument could have been passed by name, leaving 'holes'. checks.extend([ '%s == null' % name for name in parameter_names[argument_count:] ]) GenerateCall(signature_index, argument_count, checks) # TODO: Optimize the dispatch to avoid repeated checks. if len(signatures) > 1: index_swaps = {} for signature_index, signature in enumerate(signatures): for argument_position, argument in enumerate(signature): if argument.type.id != 'ArrayBuffer': continue candidates = enumerate(signatures[signature_index + 1:], signature_index + 1) for candidate_index, candidate in candidates: if len(candidate) <= argument_position: continue if candidate[ argument_position].type.id != 'ArrayBufferView': continue if len(index_swaps): raise Exception( 'Cannot deal with more than a single swap') index_swaps[candidate_index] = signature_index index_swaps[signature_index] = candidate_index for signature_index in range(len(signatures)): signature_index = index_swaps.get(signature_index, signature_index) signature = signatures[signature_index] for argument_position, argument in enumerate(signature): if is_optional(signature_index, argument): GenerateChecksAndCall(signature_index, argument_position) GenerateChecksAndCall(signature_index, len(signature)) body_emitter.Emit( ' throw new ArgumentError("Incorrect number or type of arguments");' '\n') else: signature = signatures[0] argument_count = len(signature) for argument_position, argument in list( enumerate(signature))[::-1]: if is_optional(0, argument): check = '%s != null' % parameter_names[argument_position] # argument_count instead of argument_position + 1 is used here to cover one # complicated case with the effectively optional argument in the middle. # Consider foo(x, optional y, [Default=NullString] optional z) # (as of now it's modelled after HTMLMediaElement.webkitAddKey). # y is optional in WebCore, while z is not. # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation, # not foo(x, y). GenerateCall(0, argument_count, [check]) argument_count = argument_position GenerateCall(0, argument_count, [])