def _generate_typedefs_for_domain(self, domain): type_declarations = self.type_declarations_for_domain(domain) primitive_declarations = filter( lambda decl: isinstance(decl.type, AliasedType), type_declarations) array_declarations = filter( lambda decl: isinstance(decl.type, ArrayType), type_declarations) if len(primitive_declarations) == 0 and len(array_declarations) == 0: return '' sections = [] for declaration in primitive_declarations: primitive_name = CppGenerator.cpp_name_for_primitive_type( declaration.type.aliased_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('typedef %s %s;' % (primitive_name, declaration.type_name)) sections.append('\n'.join(typedef_lines)) for declaration in array_declarations: element_type = CppGenerator.cpp_protocol_type_for_type( declaration.type.element_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('typedef JSON::ArrayOf<%s> %s;' % (element_type, declaration.type_name)) sections.append('\n'.join(typedef_lines)) lines = [] lines.append('namespace %s {' % domain.domain_name) lines.append('\n'.join(sections)) lines.append('} // %s' % domain.domain_name) return self.wrap_with_guard_for_domain(domain, '\n'.join(lines))
def _generate_builder_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member), 'helpersNamespace': self.helpers_namespace(), } lines = [] lines.append('') lines.append( ' Builder<STATE | %(camelName)sSet>& set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') lines.append( ' COMPILE_ASSERT(!(STATE & %(camelName)sSet), property_%(name)s_already_set);' % setter_args) if isinstance(type_member.type, EnumType): lines.append( ' m_result->%(keyedSet)s("%(name)s"_s, Inspector::Protocol::%(helpersNamespace)s::getEnumConstantValue(value));' % setter_args) else: lines.append( ' m_result->%(keyedSet)s("%(name)s"_s, value);' % setter_args) lines.append(' return castState<%(camelName)sSet>();' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_enum_conversion_methods_for_domain(self, domain): def type_member_is_anonymous_enum_type(type_member): return isinstance(type_member.type, EnumType) and type_member.type.is_anonymous def generate_conversion_method_body(enum_type, cpp_protocol_type): body_lines = [] body_lines.extend([ 'template<>', 'Optional<%s> parseEnumValueFromString<%s>(const String& protocolString)' % (cpp_protocol_type, cpp_protocol_type), '{', ' static const size_t constantValues[] = {', ]) enum_values = enum_type.enum_values() for enum_value in enum_values: body_lines.append(' (size_t)%s::%s,' % (cpp_protocol_type, Generator.stylized_name_for_enum_value(enum_value))) body_lines.extend([ ' };', ' for (size_t i = 0; i < %d; ++i)' % len(enum_values), ' if (protocolString == enum_constant_values[constantValues[i]])', ' return (%s)constantValues[i];' % cpp_protocol_type, '', ' return WTF::nullopt;', '}', ]) return '\n'.join(body_lines) type_declarations = self.type_declarations_for_domain(domain) declaration_types = [decl.type for decl in type_declarations] object_types = [_type for _type in declaration_types if isinstance(_type, ObjectType)] enum_types = [_type for _type in declaration_types if isinstance(_type, EnumType)] if len(object_types) + len(enum_types) == 0: return '' sorted(object_types, key=methodcaller('raw_name')) sorted(enum_types, key=methodcaller('raw_name')) lines = [] lines.append("// Enums in the '%s' Domain" % domain.domain_name) for enum_type in enum_types: cpp_protocol_type = CppGenerator.cpp_type_for_enum(enum_type, enum_type.raw_name()) lines.append('') lines.append(self.wrap_with_guard_for_condition(enum_type.declaration().condition, generate_conversion_method_body(enum_type, cpp_protocol_type))) for object_type in object_types: object_lines = [] for enum_member in filter(type_member_is_anonymous_enum_type, object_type.members): cpp_protocol_type = CppGenerator.cpp_type_for_enum(enum_member.type, '%s::%s' % (object_type.raw_name(), ucfirst(enum_member.member_name))) object_lines.append(generate_conversion_method_body(enum_member.type, cpp_protocol_type)) if len(object_lines): if len(lines): lines.append('') lines.append(self.wrap_with_guard_for_condition(object_type.declaration().condition, '\n'.join(object_lines))) if len(lines) == 1: return '' # No real declarations to emit, just the domain comment. return self.wrap_with_guard_for_condition(domain.condition, '\n'.join(lines))
def _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member), 'helpersNamespace': self.helpers_namespace(), } lines = [] lines.append('') lines.append(' void set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') if isinstance(type_member.type, EnumType): lines.append( ' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, Inspector::Protocol::%(helpersNamespace)s::getEnumConstantValue(value));' % setter_args) elif CppGenerator.should_use_references_for_type(type_member.type): lines.append( ' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, WTFMove(value));' % setter_args) else: lines.append( ' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, value);' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_typedefs_for_domain(self, domain): primitive_declarations = filter(lambda decl: isinstance(decl.type, AliasedType), domain.type_declarations) array_declarations = filter(lambda decl: isinstance(decl.type, ArrayType), domain.type_declarations) if len(primitive_declarations) == 0 and len(array_declarations) == 0: return '' sections = [] for declaration in primitive_declarations: primitive_name = CppGenerator.cpp_name_for_primitive_type(declaration.type.aliased_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('typedef %s %s;' % (primitive_name, declaration.type_name)) sections.append('\n'.join(typedef_lines)) for declaration in array_declarations: element_type = CppGenerator.cpp_protocol_type_for_type(declaration.type.element_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('typedef Inspector::Protocol::Array<%s> %s;' % (element_type, declaration.type_name)) sections.append('\n'.join(typedef_lines)) lines = [] lines.append('namespace %s {' % domain.domain_name) lines.append('\n'.join(sections)) lines.append('} // %s' % domain.domain_name) return self.wrap_with_guard_for_domain(domain, '\n'.join(lines))
def _generate_handler_declaration_for_command(self, command, used_enum_names): if command.is_async: return self._generate_async_handler_declaration_for_command(command) lines = [] parameters = ['ErrorString&'] for _parameter in command.call_parameters: parameter_name = 'in_' + _parameter.parameter_name if _parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), parameter_name)) if isinstance(_parameter.type, EnumType) and _parameter.parameter_name not in used_enum_names: lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command)) used_enum_names.add(_parameter.parameter_name) for _parameter in command.return_parameters: parameter_name = 'out_' + _parameter.parameter_name if _parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_formal_out_parameter(_parameter), parameter_name)) if isinstance(_parameter.type, EnumType) and _parameter.parameter_name not in used_enum_names: lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command)) used_enum_names.add(_parameter.parameter_name) command_args = { 'commandName': command.command_name, 'parameters': ", ".join(parameters) } lines.append(' virtual void %(commandName)s(%(parameters)s) = 0;' % command_args) return '\n'.join(lines)
def _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member) } lines = [] lines.append('') lines.append(' void set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') if isinstance(type_member.type, EnumType): lines.append( ' InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));' % setter_args) elif CppGenerator.should_use_references_for_type(type_member.type): lines.append( ' InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), WTF::move(value));' % setter_args) else: lines.append( ' InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), value);' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_handler_declaration_for_command(self, command): if command.is_async: return self._generate_async_handler_declaration_for_command(command) lines = [] parameters = [] for parameter in command.call_parameters: parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_command_parameter(parameter.type, parameter.is_optional), parameter_name)) returns = [] for parameter in command.return_parameters: parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name returns.append('%s /* %s */' % (CppGenerator.cpp_type_for_command_return_declaration(parameter.type, parameter.is_optional), parameter_name)) command_args = { 'commandName': command.command_name, 'parameters': ", ".join(parameters), 'returns': ", ".join(returns), } if len(returns) == 1: lines.append(' virtual Protocol::ErrorStringOr<%(returns)s> %(commandName)s(%(parameters)s) = 0;' % command_args) elif len(returns) > 1: lines.append(' virtual Protocol::ErrorStringOr<std::tuple<%(returns)s>> %(commandName)s(%(parameters)s) = 0;' % command_args) else: lines.append(' virtual Protocol::ErrorStringOr<void> %(commandName)s(%(parameters)s) = 0;' % command_args) return self.wrap_with_guard_for_condition(command.condition, '\n'.join(lines))
def _generate_async_handler_declaration_for_command(self, command): callbackName = "%sCallback" % ucfirst(command.command_name) in_parameters = ['ErrorString&'] for _parameter in command.call_parameters: parameter_name = 'in_' + _parameter.parameter_name if _parameter.is_optional: parameter_name = 'opt_' + parameter_name in_parameters.append("%s %s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), parameter_name)) in_parameters.append("Ref<%s>&& callback" % callbackName) out_parameters = [] for _parameter in command.return_parameters: out_parameters.append("%s %s" % (CppGenerator.cpp_type_for_formal_async_parameter(_parameter), _parameter.parameter_name)) class_components = ['class'] export_macro = self.model().framework.setting('export_macro', None) if export_macro: class_components.append(export_macro) command_args = { 'classAndExportMacro': ' '.join(class_components), 'callbackName': callbackName, 'commandName': command.command_name, 'inParameters': ", ".join(in_parameters), 'outParameters': ", ".join(out_parameters), } return Template(CppTemplates.BackendDispatcherHeaderAsyncCommandDeclaration).substitute(None, **command_args)
def _generate_async_handler_declaration_for_command(self, command): callbackName = "%sCallback" % ucfirst(command.command_name) parameters = [] for parameter in command.call_parameters: parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_command_parameter(parameter.type, parameter.is_optional), parameter_name)) parameters.append("Ref<%s>&&" % callbackName) returns = [] for parameter in command.return_parameters: parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name returns.append("%s %s" % (CppGenerator.cpp_type_for_command_return_argument(parameter.type, parameter.is_optional), parameter_name)) class_components = ['class'] export_macro = self.model().framework.setting('export_macro', None) if export_macro: class_components.append(export_macro) command_args = { 'classAndExportMacro': ' '.join(class_components), 'callbackName': callbackName, 'commandName': command.command_name, 'parameters': ", ".join(parameters), 'returns': ", ".join(returns), } return self.wrap_with_guard_for_condition(command.condition, Template(CppTemplates.BackendDispatcherHeaderAsyncCommandDeclaration).substitute(None, **command_args))
def _generate_forward_declarations_for_binding_traits(self): # A list of (builder_type, needs_runtime_cast) type_arguments = [] for domain in self.domains_to_generate(): declarations_to_generate = [decl for decl in domain.type_declarations if self.type_needs_shape_assertions(decl.type)] for type_declaration in declarations_to_generate: for type_member in type_declaration.type_members: if isinstance(type_member.type, EnumType): type_arguments.append((CppGenerator.cpp_protocol_type_for_type_member(type_member, type_declaration), False)) if isinstance(type_declaration.type, ObjectType): type_arguments.append((CppGenerator.cpp_protocol_type_for_type(type_declaration.type), Generator.type_needs_runtime_casts(type_declaration.type))) struct_keywords = ['struct'] function_keywords = ['static void'] export_macro = self.model().framework.setting('export_macro', None) if export_macro is not None: struct_keywords.append(export_macro) #function_keywords[1:1] = [export_macro] lines = [] for argument in type_arguments: lines.append('template<> %s BindingTraits<%s> {' % (' '.join(struct_keywords), argument[0])) if argument[1]: lines.append('static RefPtr<%s> runtimeCast(RefPtr<Inspector::InspectorValue>&& value);' % argument[0]) lines.append('#if !ASSERT_DISABLED') lines.append('%s assertValueHasExpectedType(Inspector::InspectorValue*);' % ' '.join(function_keywords)) lines.append('#endif // !ASSERT_DISABLED') lines.append('};') return '\n'.join(lines)
def _generate_async_dispatcher_class_for_domain(self, command, domain): out_parameter_assignments = [] formal_parameters = [] for parameter in command.return_parameters: param_args = { 'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type), 'parameterKey': parameter.parameter_name, 'parameterName': parameter.parameter_name, 'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter), 'helpersNamespace': self.helpers_namespace(), } formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_formal_async_parameter(parameter), parameter.parameter_name)) if parameter.is_optional: if CppGenerator.should_use_wrapper_for_return_type(parameter.type): out_parameter_assignments.append(' if (%(parameterName)s.has_value())' % param_args) out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, *%(parameterName)s);' % param_args) else: out_parameter_assignments.append(' if (%(parameterName)s)' % param_args) out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterName)s);' % param_args) elif parameter.type.is_enum(): out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, Inspector::Protocol::%(helpersNamespace)s::getEnumConstantValue(%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterName)s);' % param_args) async_args = { 'domainName': domain.domain_name, 'callbackName': ucfirst(command.command_name) + 'Callback', 'formalParameters': ", ".join(formal_parameters), 'outParameterAssignments': "\n".join(out_parameter_assignments) } return Template(CppTemplates.BackendDispatcherImplementationAsyncCommand).substitute(None, **async_args)
def _generate_async_dispatcher_class_for_domain(self, command, domain): out_parameter_assignments = [] formal_parameters = [] for parameter in command.return_parameters: param_args = { 'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type), 'parameterKey': parameter.parameter_name, 'parameterName': parameter.parameter_name, 'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter), } formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_formal_async_parameter(parameter), parameter.parameter_name)) if parameter.is_optional: if CppGenerator.should_use_wrapper_for_return_type(parameter.type): out_parameter_assignments.append(' if (%(parameterName)s.isAssigned())' % param_args) out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s.getValue());' % param_args) else: out_parameter_assignments.append(' if (%(parameterName)s)' % param_args) out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s);' % param_args) elif parameter.type.is_enum(): out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::getEnumConstantValue(%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), %(parameterName)s);' % param_args) async_args = { 'domainName': domain.domain_name, 'callbackName': ucfirst(command.command_name) + 'Callback', 'formalParameters': ", ".join(formal_parameters), 'outParameterAssignments': "\n".join(out_parameter_assignments) } return Template(CppTemplates.BackendDispatcherImplementationAsyncCommand).substitute(None, **async_args)
def _generate_handler_declaration_for_command(self, command, used_enum_names): if command.is_async: return self._generate_async_handler_declaration_for_command(command) lines = [] parameters = ['ErrorString&'] for _parameter in command.call_parameters: parameter_name = 'in_' + _parameter.parameter_name if _parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), parameter_name)) if isinstance(_parameter.type, EnumType) and _parameter.type.is_anonymous and _parameter.parameter_name not in used_enum_names: lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command)) used_enum_names.add(_parameter.parameter_name) for _parameter in command.return_parameters: parameter_name = 'out_' + _parameter.parameter_name if _parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append("%s %s" % (CppGenerator.cpp_type_for_formal_out_parameter(_parameter), parameter_name)) if isinstance(_parameter.type, EnumType) and _parameter.type.is_anonymous and _parameter.parameter_name not in used_enum_names: lines.append(self._generate_anonymous_enum_for_parameter(_parameter, command)) used_enum_names.add(_parameter.parameter_name) command_args = { 'commandName': command.command_name, 'parameters': ", ".join(parameters) } lines.append(' virtual void %(commandName)s(%(parameters)s) = 0;' % command_args) return '\n'.join(lines)
def _generate_forward_declarations_for_binding_traits(self): # A list of (builder_type, needs_runtime_cast) type_arguments = [] for domain in self.domains_to_generate(): declarations_to_generate = filter(lambda decl: self.type_needs_shape_assertions(decl.type), domain.type_declarations) for type_declaration in declarations_to_generate: for type_member in type_declaration.type_members: if isinstance(type_member.type, EnumType): type_arguments.append((CppGenerator.cpp_protocol_type_for_type_member(type_member, type_declaration), False)) if isinstance(type_declaration.type, ObjectType): type_arguments.append((CppGenerator.cpp_protocol_type_for_type(type_declaration.type), Generator.type_needs_runtime_casts(type_declaration.type))) struct_keywords = ['struct'] function_keywords = ['static void'] export_macro = self.model().framework.setting('export_macro', None) if export_macro is not None: struct_keywords.append(export_macro) #function_keywords[1:1] = [export_macro] lines = [] for argument in type_arguments: lines.append('template<> %s BindingTraits<%s> {' % (' '.join(struct_keywords), argument[0])) if argument[1]: lines.append('static RefPtr<%s> runtimeCast(RefPtr<Inspector::InspectorValue>&& value);' % argument[0]) lines.append('#if !ASSERT_DISABLED') lines.append('%s assertValueHasExpectedType(Inspector::InspectorValue*);' % ' '.join(function_keywords)) lines.append('#endif // !ASSERT_DISABLED') lines.append('};') return '\n'.join(lines)
def _generate_async_handler_declaration_for_command(self, command): callbackName = "%sCallback" % ucfirst(command.command_name) in_parameters = ['ErrorString&'] for _parameter in command.call_parameters: in_parameters.append( "%s in_%s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter( _parameter), _parameter.parameter_name)) in_parameters.append("Ref<%s>&& callback" % callbackName) out_parameters = [] for _parameter in command.return_parameters: out_parameters.append( "%s %s" % (CppGenerator.cpp_type_for_formal_async_parameter(_parameter), _parameter.parameter_name)) class_components = ['class'] export_macro = self.model().framework.setting('export_macro', None) if export_macro: class_components.append(export_macro) command_args = { 'classAndExportMacro': ' '.join(class_components), 'callbackName': callbackName, 'commandName': command.command_name, 'inParameters': ", ".join(in_parameters), 'outParameters': ", ".join(out_parameters), } return Template( CppTemplates.BackendDispatcherHeaderAsyncCommandDeclaration ).substitute(None, **command_args)
def _generate_enum_conversion_methods_for_domain(self, domain): def type_member_is_anonymous_enum_type(type_member): return isinstance(type_member.type, EnumType) and type_member.type.is_anonymous def generate_conversion_method_body(enum_type, cpp_protocol_type): body_lines = [] body_lines.extend([ 'template<>', 'Optional<%s> parseEnumValueFromString<%s>(const String& protocolString)' % (cpp_protocol_type, cpp_protocol_type), '{', ' static const size_t constantValues[] = {', ]) enum_values = enum_type.enum_values() for enum_value in enum_values: body_lines.append(' (size_t)%s::%s,' % (cpp_protocol_type, Generator.stylized_name_for_enum_value(enum_value))) body_lines.extend([ ' };', ' for (size_t i = 0; i < %d; ++i)' % len(enum_values), ' if (protocolString == enum_constant_values[constantValues[i]])', ' return (%s)constantValues[i];' % cpp_protocol_type, '', ' return WTF::nullopt;', '}', '', ]) return body_lines type_declarations = self.type_declarations_for_domain(domain) declaration_types = [decl.type for decl in type_declarations] object_types = [_type for _type in declaration_types if isinstance(_type, ObjectType)] enum_types = [_type for _type in declaration_types if isinstance(_type, EnumType)] if len(object_types) + len(enum_types) == 0: return '' sorted(object_types, key=methodcaller('raw_name')) sorted(enum_types, key=methodcaller('raw_name')) lines = [] lines.append("// Enums in the '%s' Domain" % domain.domain_name) for enum_type in enum_types: cpp_protocol_type = CppGenerator.cpp_protocol_type_for_type(enum_type) lines.extend(generate_conversion_method_body(enum_type, cpp_protocol_type)) for object_type in object_types: for enum_member in filter(type_member_is_anonymous_enum_type, object_type.members): cpp_protocol_type = CppGenerator.cpp_protocol_type_for_type_member(enum_member, object_type.declaration()) lines.extend(generate_conversion_method_body(enum_member.type, cpp_protocol_type)) if len(lines) == 1: return '' # No real declarations to emit, just the domain comment. return self.wrap_with_guard_for_domain(domain, '\n'.join(lines))
def _generate_declarations_for_enum_conversion_methods(self, domains): sections = [] sections.append('\n'.join([ 'namespace %s {' % self.helpers_namespace(), '', 'template<typename ProtocolEnumType>', 'Optional<ProtocolEnumType> parseEnumValueFromString(const String&);', ])) def return_type_with_export_macro(cpp_protocol_type): enum_return_type = 'Optional<%s>' % cpp_protocol_type result_terms = [enum_return_type] export_macro = self.model().framework.setting('export_macro', None) if export_macro is not None: result_terms[:0] = [export_macro] return ' '.join(result_terms) def type_member_is_anonymous_enum_type(type_member): return isinstance(type_member.type, EnumType) and type_member.type.is_anonymous for domain in domains: type_declarations = self.type_declarations_for_domain(domain) declaration_types = [decl.type for decl in type_declarations] object_types = [_type for _type in declaration_types if isinstance(_type, ObjectType)] enum_types = [_type for _type in declaration_types if isinstance(_type, EnumType)] if len(object_types) + len(enum_types) == 0: continue sorted(object_types, key=methodcaller('raw_name')) sorted(enum_types, key=methodcaller('raw_name')) domain_lines = [] domain_lines.append("// Enums in the '%s' Domain" % domain.domain_name) for enum_type in enum_types: cpp_protocol_type = CppGenerator.cpp_protocol_type_for_type(enum_type) domain_lines.append('template<>') domain_lines.append('%s parseEnumValueFromString<%s>(const String&);' % (return_type_with_export_macro(cpp_protocol_type), cpp_protocol_type)) for object_type in object_types: for enum_member in filter(type_member_is_anonymous_enum_type, object_type.members): cpp_protocol_type = CppGenerator.cpp_protocol_type_for_type_member(enum_member, object_type.declaration()) domain_lines.append('template<>') domain_lines.append('%s parseEnumValueFromString<%s>(const String&);' % (return_type_with_export_macro(cpp_protocol_type), cpp_protocol_type)) if len(domain_lines) == 1: continue # No real declarations to emit, just the domain comment. Skip. sections.append(self.wrap_with_guard_for_domain(domain, '\n'.join(domain_lines))) if len(sections) == 1: return [] # No real sections to emit, just the namespace and template declaration. Skip. sections.append('} // namespace %s' % self.helpers_namespace()) return ['\n\n'.join(sections)]
def _generate_assertion_for_object_declaration(self, object_declaration): required_members = [member for member in object_declaration.type_members if not member.is_optional] optional_members = [member for member in object_declaration.type_members if member.is_optional] should_count_properties = not Generator.type_has_open_fields(object_declaration.type) lines = [] lines.append('void BindingTraits<%s>::assertValueHasExpectedType(JSON::Value* value)' % (CppGenerator.cpp_protocol_type_for_type(object_declaration.type))) lines.append("""{ #if ASSERT_DISABLED UNUSED_PARAM(value); #else ASSERT_ARG(value, value); RefPtr<JSON::Object> object; bool castSucceeded = value->asObject(object); ASSERT_UNUSED(castSucceeded, castSucceeded);""") for type_member in required_members: args = { 'memberName': type_member.member_name, 'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration) } lines.append(""" { auto %(memberName)sPos = object->find("%(memberName)s"_s); ASSERT(%(memberName)sPos != object->end()); %(assertMethod)s(%(memberName)sPos->value.get()); }""" % args) if should_count_properties: lines.append('') lines.append(' int foundPropertiesCount = %s;' % len(required_members)) for type_member in optional_members: args = { 'memberName': type_member.member_name, 'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration) } lines.append(""" { auto %(memberName)sPos = object->find("%(memberName)s"_s); if (%(memberName)sPos != object->end()) { %(assertMethod)s(%(memberName)sPos->value.get());""" % args) if should_count_properties: lines.append(' ++foundPropertiesCount;') lines.append(' }') lines.append(' }') if should_count_properties: lines.append(' if (foundPropertiesCount != object->size())') lines.append(' FATAL("Unexpected properties in object: %s\\n", object->toJSONString().ascii().data());') lines.append('#endif // !ASSERT_DISABLED') lines.append('}') return '\n'.join(lines)
def _generate_assertion_for_object_declaration(self, object_declaration): required_members = filter(lambda member: not member.is_optional, object_declaration.type_members) optional_members = filter(lambda member: member.is_optional, object_declaration.type_members) should_count_properties = not Generator.type_has_open_fields(object_declaration.type) lines = [] lines.append('#if !ASSERT_DISABLED') lines.append('void BindingTraits<%s>::assertValueHasExpectedType(Inspector::InspectorValue* value)' % (CppGenerator.cpp_protocol_type_for_type(object_declaration.type))) lines.append("""{ ASSERT_ARG(value, value); RefPtr<InspectorObject> object; bool castSucceeded = value->asObject(object); ASSERT_UNUSED(castSucceeded, castSucceeded);""") for type_member in required_members: args = { 'memberName': type_member.member_name, 'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration) } lines.append(""" { InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s")); ASSERT(%(memberName)sPos != object->end()); %(assertMethod)s(%(memberName)sPos->value.get()); }""" % args) if should_count_properties: lines.append('') lines.append(' int foundPropertiesCount = %s;' % len(required_members)) for type_member in optional_members: args = { 'memberName': type_member.member_name, 'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration) } lines.append(""" { InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s")); if (%(memberName)sPos != object->end()) { %(assertMethod)s(%(memberName)sPos->value.get());""" % args) if should_count_properties: lines.append(' ++foundPropertiesCount;') lines.append(' }') lines.append(' }') if should_count_properties: lines.append(' if (foundPropertiesCount != object->size())') lines.append(' FATAL("Unexpected properties in object: %s\\n", object->toJSONString().ascii().data());') lines.append('}') lines.append('#endif // !ASSERT_DISABLED') return '\n'.join(lines)
def _generate_forward_declarations_for_binding_traits(self, domains): # A list of (builder_type, needs_runtime_cast) type_arguments = [] for domain in domains: type_declarations = self.type_declarations_for_domain(domain) declarations_to_generate = [ decl for decl in type_declarations if self.type_needs_shape_assertions(decl.type) ] for type_declaration in declarations_to_generate: if isinstance(type_declaration.type, ObjectType): type_arguments.append((self.wrap_with_guard_for_condition( type_declaration.condition, CppGenerator.cpp_protocol_type_for_type( type_declaration.type)), Generator.type_needs_runtime_casts( type_declaration.type))) for type_member in type_declaration.type_members: if isinstance(type_member.type, EnumType): type_arguments.append( (self.wrap_with_guard_for_condition( type_declaration.condition, CppGenerator.cpp_type_for_enum( type_member.type, '%s::%s' % (type_declaration.type_name, ucfirst(type_member.member_name)))), False)) struct_keywords = ['struct'] function_keywords = ['static void'] export_macro = self.model().framework.setting('export_macro', None) if export_macro is not None: struct_keywords.append(export_macro) #function_keywords[1:1] = [export_macro] lines = [] for argument in type_arguments: lines.append('template<> %s BindingTraits<%s> {' % (' '.join(struct_keywords), argument[0])) if argument[1]: lines.append( 'static Ref<%s> runtimeCast(Ref<JSON::Value>&& value);' % argument[0]) lines.append('%s assertValueHasExpectedType(JSON::Value*);' % ' '.join(function_keywords)) lines.append('};') return '\n'.join(lines)
def _generate_dispatcher_implementation_for_event(self, event, domain): lines = [] parameter_assignments = [] formal_parameters = [] for parameter in event.event_parameters: parameter_value = parameter.parameter_name if parameter.is_optional and not CppGenerator.should_pass_by_copy_for_return_type(parameter.type): parameter_value = '*' + parameter_value if parameter.type.is_enum(): parameter_value = 'Inspector::Protocol::%s::getEnumConstantValue(%s)' % (self.helpers_namespace(), parameter_value) parameter_args = { 'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter), 'parameterName': parameter.parameter_name, 'parameterValue': parameter_value, 'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type), } if parameter.is_optional: parameter_assignments.append(' if (%(parameterName)s)' % parameter_args) parameter_assignments.append(' paramsObject->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), %(parameterValue)s);' % parameter_args) else: parameter_assignments.append(' paramsObject->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), %(parameterValue)s);' % parameter_args) formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_checked_formal_event_parameter(parameter), parameter.parameter_name)) event_args = { 'domainName': domain.domain_name, 'eventName': event.event_name, 'formalParameters': ", ".join(formal_parameters) } lines.append('void %(domainName)sFrontendDispatcher::%(eventName)s(%(formalParameters)s)' % event_args) lines.append('{') lines.append(' Ref<InspectorObject> jsonMessage = InspectorObject::create();') lines.append(' jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("%(domainName)s.%(eventName)s"));' % event_args) if len(parameter_assignments) > 0: lines.append(' Ref<InspectorObject> paramsObject = InspectorObject::create();') lines.extend(parameter_assignments) lines.append(' jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));') lines.append('') lines.append(' m_frontendRouter.sendEvent(jsonMessage->toJSONString());') lines.append('}') return "\n".join(lines)
def _generate_handler_implementation_for_command(self, domain, command): lines = [] parameters = ['long protocol_requestId'] for parameter in command.call_parameters: parameter_type = parameter.type if isinstance(parameter_type, AliasedType): parameter_type = parameter_type.aliased_type if isinstance(parameter_type, EnumType): parameter_type = parameter_type.primitive_type parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name parameter_name = 'in_' + parameter_name parameters.append('%s %s' % (CppGenerator.cpp_type_for_command_parameter(parameter_type, parameter.is_optional), parameter_name)) command_args = { 'domainName': domain.domain_name, 'commandName': command.command_name, 'parameters': ', '.join(parameters), 'respondsToSelector': self._generate_responds_to_selector_for_command(domain, command), 'successCallback': self._generate_success_block_for_command(domain, command), 'conversions': self._generate_conversions_for_command(domain, command), 'invocation': self._generate_invocation_for_command(domain, command), } return self.wrap_with_guard_for_condition(command.condition, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerImplementation).substitute(None, **command_args))
def _generate_handler_implementation_for_command(self, domain, command): lines = [] parameters = ['long callId'] for parameter in command.call_parameters: parameters.append( '%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter( parameter), parameter.parameter_name)) command_args = { 'domainName': domain.domain_name, 'commandName': command.command_name, 'parameters': ', '.join(parameters), 'successCallback': self._generate_success_block_for_command(domain, command), 'conversions': self._generate_conversions_for_command(domain, command), 'invocation': self._generate_invocation_for_command(domain, command), } return self.wrap_with_guard_for_domain( domain, Template( ObjCTemplates. BackendDispatcherHeaderDomainHandlerImplementation).substitute( None, **command_args))
def _generate_event_out_parameters(self, domain, event): lines = [] lines.append( ' Ref<JSON::Object> paramsObject = JSON::Object::create();') for parameter in event.event_parameters: keyed_set_method = CppGenerator.cpp_setter_method_for_type( parameter.type) var_name = parameter.parameter_name safe_var_name = '(*%s)' % var_name if parameter.is_optional else var_name export_expression = self.objc_protocol_export_expression_for_variable( parameter.type, safe_var_name) if not parameter.is_optional: lines.append(' paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) else: lines.append(' if (%s)' % (parameter.parameter_name)) lines.append( ' paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) lines.append( ' jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));' ) return lines
def _generate_handler_declaration_for_command(self, command): lines = [] parameters = ['long protocol_requestId'] for parameter in command.call_parameters: parameter_type = parameter.type if isinstance(parameter_type, AliasedType): parameter_type = parameter_type.aliased_type if isinstance(parameter_type, EnumType): parameter_type = parameter_type.primitive_type parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name parameters.append( '%s %s' % (CppGenerator.cpp_type_for_command_parameter( parameter_type, parameter.is_optional), parameter_name)) command_args = { 'commandName': command.command_name, 'parameters': ', '.join(parameters), } lines.append(' virtual void %(commandName)s(%(parameters)s) = 0;' % command_args) return self.wrap_with_guard_for_condition(command.condition, '\n'.join(lines))
def _generate_dispatcher_declaration_for_event(self, event, domain, used_enum_names): formal_parameters = [] lines = [] for parameter in event.event_parameters: parameter_name = parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name formal_parameters.append( '%s %s' % (CppGenerator.cpp_type_for_event_parameter( parameter.type, parameter.is_optional), parameter_name)) if isinstance( parameter.type, EnumType ) and parameter.type.is_anonymous and parameter.parameter_name not in used_enum_names: lines.append( self._generate_anonymous_enum_for_parameter( parameter, event)) used_enum_names.add(parameter.parameter_name) lines.append(" void %s(%s);" % (event.event_name, ", ".join(formal_parameters))) return self.wrap_with_guard_for_condition(event.condition, "\n".join(lines))
def _generate_runtime_cast_for_object_declaration(self, object_declaration): args = { 'objectType': CppGenerator.cpp_protocol_type_for_type(object_declaration.type) } return Template(CppTemplates.ProtocolObjectRuntimeCast).substitute( None, **args)
def _generate_success_block_for_command(self, domain, command): lines = [] if command.return_parameters: success_block_parameters = [] for parameter in command.return_parameters: out_param_name = parameter.parameter_name if parameter.is_optional: out_param_name = 'opt_' + out_param_name out_param_name = 'out_' + out_param_name objc_type = self.objc_type_for_param(domain, command.command_name, parameter) success_block_parameters.append(join_type_and_name(objc_type, out_param_name)) lines.append(' id successCallback = ^(%s) {' % ', '.join(success_block_parameters)) else: lines.append(' id successCallback = ^{') lines.append(' auto protocol_jsonMessage = JSON::Object::create();') if command.return_parameters: required_pointer_parameters = [parameter for parameter in command.return_parameters if not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type)] for parameter in required_pointer_parameters: out_param_name = parameter.parameter_name if parameter.is_optional: out_param_name = 'opt_' + out_param_name out_param_name = 'out_' + out_param_name lines.append(' THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(%s, @"%s");' % (out_param_name, parameter.parameter_name)) objc_array_class = self.objc_class_for_array_type(parameter.type) if objc_array_class and objc_array_class.startswith(self.objc_prefix()): lines.append(' THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (out_param_name, objc_array_class)) optional_pointer_parameters = [parameter for parameter in command.return_parameters if parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type)] for parameter in optional_pointer_parameters: out_param_name = parameter.parameter_name if parameter.is_optional: out_param_name = 'opt_' + out_param_name out_param_name = 'out_' + out_param_name lines.append(' THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(%s, @"%s");' % (out_param_name, parameter.parameter_name)) objc_array_class = self.objc_class_for_array_type(parameter.type) if objc_array_class and objc_array_class.startswith(self.objc_prefix()): lines.append(' THROW_EXCEPTION_FOR_BAD_TYPE_IN_OPTIONAL_ARRAY(%s, [%s class]);' % (out_param_name, objc_array_class)) for parameter in command.return_parameters: out_param_name = parameter.parameter_name if parameter.is_optional: out_param_name = 'opt_' + out_param_name out_param_name = 'out_' + out_param_name keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type) var_expression = '*%s' % out_param_name if parameter.is_optional else out_param_name export_expression = self.objc_protocol_export_expression_for_variable(parameter.type, var_expression) if not parameter.is_optional: lines.append(' protocol_jsonMessage->%s("%s"_s, %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) else: lines.append(' if (!!%s)' % out_param_name) lines.append(' protocol_jsonMessage->%s("%s"_s, %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) lines.append(' backendDispatcher()->sendResponse(protocol_requestId, WTFMove(protocol_jsonMessage), false);') lines.append(' };') return '\n'.join(lines)
def _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member) } lines = [] lines.append('') lines.append(' void set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') if isinstance(type_member.type, EnumType): lines.append(' InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));' % setter_args) else: lines.append(' InspectorObjectBase::%(keyedSet)s(ASCIILiteral("%(name)s"), value);' % setter_args) lines.append(' }') return '\n'.join(lines)
def in_param_expression(param_name, parameter): _type = parameter.type if isinstance(_type, AliasedType): _type = _type.aliased_type if isinstance(_type, EnumType): _type = _type.primitive_type if _type.is_enum(): if parameter.is_optional: param_name = '*' + param_name return 'Protocol::Helpers::getEnumConstantValue(%s)' % param_name if CppGenerator.should_release_argument(_type, parameter.is_optional): return param_name + '.releaseNonNull()' if CppGenerator.should_dereference_argument(_type, parameter.is_optional): return '*' + param_name if CppGenerator.should_move_argument(_type, parameter.is_optional): return 'WTFMove(%s)' % param_name return param_name
def _generate_typedefs_for_domain(self, domain): type_declarations = self.type_declarations_for_domain(domain) primitive_declarations = [ decl for decl in type_declarations if isinstance(decl.type, AliasedType) ] array_declarations = [ decl for decl in type_declarations if isinstance(decl.type, ArrayType) ] if len(primitive_declarations) == 0 and len(array_declarations) == 0: return '' sections = [] for declaration in primitive_declarations: primitive_name = CppGenerator.cpp_name_for_primitive_type( declaration.type.aliased_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('using %s = %s;' % (declaration.type_name, primitive_name)) sections.append( self.wrap_with_guard_for_condition(declaration.condition, '\n'.join(typedef_lines))) for declaration in array_declarations: element_type = CppGenerator.cpp_protocol_type_for_type( declaration.type.element_type) typedef_lines = [] if len(declaration.description) > 0: typedef_lines.append('/* %s */' % declaration.description) typedef_lines.append('using %s = JSON::ArrayOf<%s>;' % (declaration.type_name, element_type)) sections.append( self.wrap_with_guard_for_condition(declaration.condition, '\n'.join(typedef_lines))) lines = [] lines.append('namespace %s {' % domain.domain_name) lines.append('\n'.join(sections)) lines.append('} // %s' % domain.domain_name) return self.wrap_with_guard_for_condition(domain.condition, '\n'.join(lines))
class TestCppGenerator(TestCase): def setUp(self): self.generator = CppGenerator() def check_if_generated_code_for_fake_is(self, fake, expected): generated = self.generator.generate(fake) self.assertEquals(expected, generated) def test_cpp_generator_should_generate_namespace_for_unknown_type(self): fakes = [{'type': 'namespace', 'name': 'ShortStr'}] expected = 'namespace ShortStr;' self.check_if_generated_code_for_fake_is(fakes, expected) def test_cpp_generator_should_generate_class_for_unknown_type(self): fakes = [{'type': 'class', 'name': 'ShortStr'}] expected = 'class ShortStr;' self.check_if_generated_code_for_fake_is(fakes, expected) def test_cpp_generator_should_generate_variable_declaration(self): fakes = [{'type': 'field', 'declaration': 'int', 'name': 'ma'}] expected = 'int ma;' self.check_if_generated_code_for_fake_is(fakes, expected) def test_cpp_generator_should_generate_function_declaration(self): fakes = [ {'type': 'method', 'declaration': 'void (int)', 'name': 'foo'} ] expected = 'void foo(int);' self.check_if_generated_code_for_fake_is(fakes, expected) def test_cpp_generator_should_generate_members_if_provided(self): fakes = [{ 'type': 'class', 'name': 'ShortStr', 'members': [ { 'type': 'method', 'declaration': 'void ()', 'name': 'Foo', 'access': 'public' }, { 'type': 'method', 'declaration': 'void ()', 'name': 'Bar', 'access': 'public' } ] }] expected = 'class ShortStr{\n'\ '\tpublic:\n'\ '\tvoid Foo();\n'\ '\tvoid Bar();\n'\ '};\n' self.check_if_generated_code_for_fake_is(fakes, expected)
def _generate_builder_setter_for_member(self, type_member, domain): member_name = 'in_' + type_member.member_name member_value = member_name if type_member.type.is_enum(): member_value = 'Protocol::%s::getEnumConstantValue(%s)' % ( self.helpers_namespace(), member_value) elif CppGenerator.should_move_argument(type_member.type, False): member_value = 'WTFMove(%s)' % member_value setter_args = { 'camelName': ucfirst(type_member.member_name), 'setter': CppGenerator.cpp_setter_method_for_type(type_member.type), 'memberType': CppGenerator.cpp_type_for_type_member_argument( type_member.type, type_member.member_name), 'memberKey': type_member.member_name, 'memberName': member_name, 'memberValue': member_value, } lines = [] lines.append('') lines.append( ' Builder<STATE | %(camelName)sSet>& set%(camelName)s(%(memberType)s %(memberName)s)' % setter_args) lines.append(' {') lines.append( ' COMPILE_ASSERT(!(STATE & %(camelName)sSet), property_%(memberKey)s_already_set);' % setter_args) lines.append( ' m_result->%(setter)s("%(memberKey)s"_s, %(memberValue)s);' % setter_args) lines.append(' return castState<%(camelName)sSet>();' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_dispatcher_declaration_for_event(self, event, domain, used_enum_names): formal_parameters = [] lines = [] for parameter in event.event_parameters: formal_parameters.append('%s %s' % (CppGenerator.cpp_type_for_checked_formal_event_parameter(parameter), parameter.parameter_name)) if isinstance(parameter.type, EnumType) and parameter.parameter_name not in used_enum_names: lines.append(self._generate_anonymous_enum_for_parameter(parameter, event)) used_enum_names.add(parameter.parameter_name) lines.append(" void %s(%s);" % (event.event_name, ", ".join(formal_parameters))) return "\n".join(lines)
def _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member), 'helpersNamespace': self.helpers_namespace(), } lines = [] lines.append('') lines.append(' void set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') if isinstance(type_member.type, EnumType): lines.append(' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, Inspector::Protocol::%(helpersNamespace)s::getEnumConstantValue(value));' % setter_args) elif CppGenerator.should_use_references_for_type(type_member.type): lines.append(' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, WTFMove(value));' % setter_args) else: lines.append(' JSON::ObjectBase::%(keyedSet)s("%(name)s"_s, value);' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_builder_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'keyedSet': CppGenerator.cpp_setter_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': CppGenerator.cpp_type_for_type_member(type_member) } lines = [] lines.append('') lines.append(' Builder<STATE | %(camelName)sSet>& set%(camelName)s(%(parameterType)s value)' % setter_args) lines.append(' {') lines.append(' COMPILE_ASSERT(!(STATE & %(camelName)sSet), property_%(name)s_already_set);' % setter_args) if isinstance(type_member.type, EnumType): lines.append(' m_result->%(keyedSet)s(ASCIILiteral("%(name)s"), Inspector::Protocol::getEnumConstantValue(static_cast<int>(value)));' % setter_args) else: lines.append(' m_result->%(keyedSet)s(ASCIILiteral("%(name)s"), value);' % setter_args) lines.append(' return castState<%(camelName)sSet>();' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_handler_declaration_for_command(self, command): lines = [] parameters = ['long callId'] for _parameter in command.call_parameters: parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name)) command_args = { 'commandName': command.command_name, 'parameters': ', '.join(parameters), } lines.append(' virtual void %(commandName)s(%(parameters)s) = 0;' % command_args) return '\n'.join(lines)
def _generate_handler_declaration_for_command(self, command): lines = [] parameters = ["long callId"] for _parameter in command.call_parameters: parameters.append( "%s in_%s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name) ) command_args = {"commandName": command.command_name, "parameters": ", ".join(parameters)} lines.append(" virtual void %(commandName)s(%(parameters)s) = 0;" % command_args) return "\n".join(lines)
def _generate_unchecked_setter_for_member(self, type_member, domain): member_name = 'in_opt_' + type_member.member_name member_value = member_name if type_member.type.is_enum(): member_value = 'Protocol::%s::getEnumConstantValue(%s)' % ( self.helpers_namespace(), member_value) elif CppGenerator.should_move_argument(type_member.type, False): member_value = 'WTFMove(%s)' % member_value setter_args = { 'camelName': ucfirst(type_member.member_name), 'setter': CppGenerator.cpp_setter_method_for_type(type_member.type), 'memberKey': type_member.member_name, 'memberName': member_name, 'memberValue': member_value, 'memberType': CppGenerator.cpp_type_for_type_member_argument( type_member.type, type_member.member_name), } lines = [] lines.append('') lines.append( ' void set%(camelName)s(%(memberType)s %(memberName)s)' % setter_args) lines.append(' {') lines.append( ' JSON::ObjectBase::%(setter)s("%(memberKey)s"_s, %(memberValue)s);' % setter_args) lines.append(' }') return '\n'.join(lines)
def _generate_event_out_parameters(self, domain, event): lines = [] lines.append(' RefPtr<InspectorObject> paramsObject = InspectorObject::create();') for parameter in event.event_parameters: keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type) var_name = parameter.parameter_name safe_var_name = '(*%s)' % var_name if parameter.is_optional else var_name export_expression = ObjCGenerator.objc_protocol_export_expression_for_variable(parameter.type, safe_var_name) if not parameter.is_optional: lines.append(' paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) else: lines.append(' if (%s)' % (parameter.parameter_name)) lines.append(' paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) lines.append(' jsonMessage->setObject(ASCIILiteral("params"), paramsObject);') return lines
def _generate_assertion_for_enum(self, enum_member, object_declaration): lines = [] lines.append('#if !ASSERT_DISABLED') lines.append('void %s(Inspector::InspectorValue* value)' % CppGenerator.cpp_assertion_method_for_type_member(enum_member, object_declaration)) lines.append('{') lines.append(' String result;') lines.append(' bool castSucceeded = value->asString(result);') lines.append(' ASSERT(castSucceeded);') assert_condition = ' || '.join(['result == "%s"' % enum_value for enum_value in enum_member.type.enum_values()]) lines.append(' ASSERT(%s);' % assert_condition) lines.append('}') lines.append('#endif // !ASSERT_DISABLED') return '\n'.join(lines)
def _generate_success_block_for_command(self, domain, command): lines = [] if command.return_parameters: success_block_parameters = [] for parameter in command.return_parameters: objc_type = ObjCGenerator.objc_type_for_param(domain, command.command_name, parameter) var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name) success_block_parameters.append(join_type_and_name(objc_type, var_name)) lines.append(' id successCallback = ^(%s) {' % ', '.join(success_block_parameters)) else: lines.append(' id successCallback = ^{') if command.return_parameters: lines.append(' Ref<InspectorObject> resultObject = InspectorObject::create();') required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), command.return_parameters) for parameter in required_pointer_parameters: var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name) lines.append(' THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(%s, @"%s");' % (var_name, var_name)) objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type) if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX): lines.append(' THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class)) optional_pointer_parameters = filter(lambda parameter: parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), command.return_parameters) for parameter in optional_pointer_parameters: var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name) lines.append(' THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(%s, @"%s");' % (var_name, var_name)) objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type) if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX): lines.append(' THROW_EXCEPTION_FOR_BAD_TYPE_IN_OPTIONAL_ARRAY(%s, [%s class]);' % (var_name, objc_array_class)) for parameter in command.return_parameters: keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type) var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name) var_expression = '*%s' % var_name if parameter.is_optional else var_name export_expression = ObjCGenerator.objc_protocol_export_expression_for_variable(parameter.type, var_expression) if not parameter.is_optional: lines.append(' resultObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) else: lines.append(' if (%s)' % var_name) lines.append(' resultObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression)) lines.append(' backendDispatcher()->sendResponse(requestId, WTF::move(resultObject));') else: lines.append(' backendDispatcher()->sendResponse(requestId, InspectorObject::create());') lines.append(' };') return '\n'.join(lines)
def _generate_assertion_for_enum(self, enum_member, object_declaration): lines = [] lines.append('#if !ASSERT_DISABLED') lines.append('void %s(Inspector::InspectorValue* value)' % CppGenerator.cpp_assertion_method_for_type_member(enum_member, object_declaration)) lines.append('{') lines.append(' ASSERT_ARG(value, value);') lines.append(' String result;') lines.append(' bool castSucceeded = value->asString(result);') lines.append(' ASSERT(castSucceeded);') assert_condition = ' || '.join(['result == "%s"' % enum_value for enum_value in enum_member.type.enum_values()]) lines.append(' ASSERT(%s);' % assert_condition) lines.append('}') lines.append('#endif // !ASSERT_DISABLED') return '\n'.join(lines)
def prepare(self): # check class name if not self.class_name: self.class_name = RandomGenerater.generate_string(8, 32) self.class_name = self.class_name[0].upper() + self.class_name[1:] cpp_class = CppGenerator.generate_class( self.tpl_folder_path, self.config["field_count"], self.config["method_count"], self.config["parameter_count"], self.config["return_probability"], self.class_name) if "call_others" in self.config and self.config["call_others"]: for i in range(len(cpp_class.methods) - 1): cpp_class.methods[i].call(cpp_class.methods[i + 1]) self.c_class = cpp_class
def _generate_handler_implementation_for_command(self, domain, command): lines = [] parameters = ['long callId'] for parameter in command.call_parameters: parameters.append('%s in_%s' % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(parameter), parameter.parameter_name)) command_args = { 'domainName': domain.domain_name, 'commandName': command.command_name, 'parameters': ', '.join(parameters), 'successCallback': self._generate_success_block_for_command(domain, command), 'conversions': self._generate_conversions_for_command(domain, command), 'invocation': self._generate_invocation_for_command(domain, command), } return self.wrap_with_guard_for_domain(domain, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerImplementation).substitute(None, **command_args))
def _generate_handler_implementation_for_command(self, domain, command): lines = [] parameters = ["long requestId"] for parameter in command.call_parameters: parameters.append( "%s in_%s" % (CppGenerator.cpp_type_for_unchecked_formal_in_parameter(parameter), parameter.parameter_name) ) command_args = { "domainName": domain.domain_name, "commandName": command.command_name, "parameters": ", ".join(parameters), "successCallback": self._generate_success_block_for_command(domain, command), "conversions": self._generate_conversions_for_command(domain, command), "invocation": self._generate_invocation_for_command(domain, command), } return self.wrap_with_guard_for_domain( domain, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerImplementation).substitute(None, **command_args), )
def setUp(self): self.faker = CppFaker([]) self.generator = CppGenerator()
class TestCppFaker(TestCase): def setUp(self): self.faker = CppFaker([]) self.generator = CppGenerator() def check_if_generated_code_is_as_expected(self, lines, expected): for line in lines: self.faker.process_line(line) fakes = self.faker.get_fakes() generated = self.generator.generate(fakes) self.assertMultiLineEqual(expected, generated) def test_cpp_faker_should_generate_empty_string_for_unknown_msgtype(self): self.check_if_generated_code_is_as_expected( [('', '', '', 'warning', ['', 'ShortStr'])], '' ) def test_cpp_faker_should_generate_empty_string_for_unknown_err(self): self.check_if_generated_code_is_as_expected( [('', '', '', 'error', ['unknown', 'ShortStr'])], '' ) def test_cpp_faker_should_generate_class_for_undeclared_identifier(self): self.check_if_generated_code_is_as_expected( [('', '', '', 'error', ['use of undeclared identifier', 'Short'])], 'class Short{\n};\n' ) def test_cpp_faker_should_generate_class_for_unknown_type_name(self): self.check_if_generated_code_is_as_expected( [('', '', '', 'error', ['unknown type name', 'ShortStr'])], 'class ShortStr;' ) def test_cpp_faker_should_generate_members_for_classes(self): lines = [ ('', '', '', 'error', ['unknown type name', 'Foo']), ('', '', '', 'error', ['no member named', 'Bar', 'in', 'Foo']) ] expected = 'class Foo{\n'\ '\tpublic:\n'\ '\tvoid Bar();\n'\ '};\n' self.check_if_generated_code_is_as_expected(lines, expected) def test_cpp_faker_initialization(self): initial = ('', '', '', 'error', ['unknown type name', 'Foo']) self.faker.process_line(initial) fakes = self.faker.get_fakes() self.faker = CppFaker(fakes) lines = [ ('', '', '', 'error', ['no member named', 'Bar', 'in', 'Foo']) ] expected = 'class Foo{\n'\ '\tpublic:\n'\ '\tvoid Bar();\n'\ '};\n' self.check_if_generated_code_is_as_expected(lines, expected) def test_cpp_faker_should_not_register_duplicate_findings(self): self.check_if_generated_code_is_as_expected( [ ('', '', '', 'error', ['unknown type name', 'ShortStr']), ('', '', '', 'error', ['unknown type name', 'ShortStr']) ], 'class ShortStr;' ) def test_cpp_faker_should_not_register_duplicate_members(self): self.check_if_generated_code_is_as_expected( [ ('', '', '', 'error', ['unknown type name', 'Foo']), ('', '', '', 'error', ['no member named', 'Bar', 'in', 'Foo']), ('', '', '', 'error', ['no member named', 'Bar', 'in', 'Foo']) ], 'class Foo{\n' '\tpublic:\n' '\tvoid Bar();\n' '};\n', ) def test_cpp_faker_should_change_type_of_a_variable(self): lines = [ ( 'r.cpp', '6', '4', 'error', ['use of undeclared identifier', 'ma', '']), ( 'r.cpp', '6', '4', 'error', ['', 'ma', 'does not refer to a value']) ] expected = 'int ma;' self.check_if_generated_code_is_as_expected(lines, expected)
def create_wrapper_cpp(filename, fakes): with open("faked.cpp", "wb") as faked: generator = CppGenerator() faked.write(generator.generate(fakes)) faked.write('\n#include "{}"'.format(filename))
def _generate_runtime_cast_for_object_declaration(self, object_declaration): args = { 'objectType': CppGenerator.cpp_protocol_type_for_type(object_declaration.type) } return Template(CppTemplates.ProtocolObjectRuntimeCast).substitute(None, **args)
def setUp(self): self.generator = CppGenerator()
def __init__(self, model, input_filepath): CppGenerator.__init__(self, model, input_filepath)
def _generate_dispatcher_implementation_for_command(self, command, domain): in_parameter_declarations = [] out_parameter_declarations = [] out_parameter_assignments = [] alternate_dispatcher_method_parameters = ['requestId'] method_parameters = ['error'] for parameter in command.call_parameters: parameter_name = 'in_' + parameter.parameter_name if parameter.is_optional: parameter_name = 'opt_' + parameter_name out_success_argument = 'nullptr' if parameter.is_optional: out_success_argument = '&%s_valueFound' % parameter_name in_parameter_declarations.append(' bool %s_valueFound = false;' % parameter_name) # Now add appropriate operators. parameter_expression = parameter_name if CppGenerator.should_use_references_for_type(parameter.type): if parameter.is_optional: parameter_expression = '%s.get()' % parameter_expression else: # This assumes that we have already proved the object is non-null. # If a required property is missing, InspectorBackend::getObject will # append a protocol error, and the method dispatcher will return without # invoking the backend method (and dereferencing the object). parameter_expression = '*%s' % parameter_expression elif parameter.is_optional: parameter_expression = '&%s' % parameter_expression param_args = { 'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter), 'parameterKey': parameter.parameter_name, 'parameterName': parameter_name, 'parameterExpression': parameter_expression, 'keyedGetMethod': CppGenerator.cpp_getter_method_for_type(parameter.type), 'successOutParam': out_success_argument } in_parameter_declarations.append(' %(parameterType)s %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(parameters.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s);' % param_args) if parameter.is_optional: optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args alternate_dispatcher_method_parameters.append(optional_in_parameter_string) method_parameters.append(optional_in_parameter_string) else: alternate_dispatcher_method_parameters.append(parameter_expression) method_parameters.append(parameter_expression) if command.is_async: async_args = { 'domainName': domain.domain_name, 'callbackName': ucfirst(command.command_name) + 'Callback' } out_parameter_assignments.append(' callback->disable();') out_parameter_assignments.append(' m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);') out_parameter_assignments.append(' return;') method_parameters.append('callback.copyRef()') else: for parameter in command.return_parameters: param_args = { 'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter), 'parameterKey': parameter.parameter_name, 'parameterName': parameter.parameter_name, 'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type), } out_parameter_declarations.append(' %(parameterType)s out_%(parameterName)s;' % param_args) if parameter.is_optional: if CppGenerator.should_use_wrapper_for_return_type(parameter.type): out_parameter_assignments.append(' if (out_%(parameterName)s.isAssigned())' % param_args) out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s.getValue());' % param_args) else: out_parameter_assignments.append(' if (out_%(parameterName)s)' % param_args) out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args) elif parameter.type.is_enum(): out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args) if CppGenerator.should_pass_by_copy_for_return_type(parameter.type): method_parameters.append('out_' + parameter.parameter_name) else: method_parameters.append('&out_' + parameter.parameter_name) command_args = { 'domainName': domain.domain_name, 'callbackName': '%sCallback' % ucfirst(command.command_name), 'commandName': command.command_name, 'inParameterDeclarations': '\n'.join(in_parameter_declarations), 'invocationParameters': ', '.join(method_parameters), 'alternateInvocationParameters': ', '.join(alternate_dispatcher_method_parameters), } lines = [] if len(command.call_parameters) == 0: lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&&)' % command_args) else: lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&& parameters)' % command_args) lines.append('{') if len(command.call_parameters) > 0: lines.append(Template(CppTemplates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args)) lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)') lines.append(' if (m_alternateDispatcher) {') lines.append(' m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);' % command_args) lines.append(' return;') lines.append(' }') lines.append('#endif') lines.append('') lines.append(' ErrorString error;') lines.append(' Ref<InspectorObject> result = InspectorObject::create();') if command.is_async: lines.append(' Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), requestId));' % command_args) if len(command.return_parameters) > 0: lines.extend(out_parameter_declarations) lines.append(' m_agent->%(commandName)s(%(invocationParameters)s);' % command_args) lines.append('') if command.is_async: lines.append(' if (error.length()) {') lines.extend(out_parameter_assignments) lines.append(' }') elif len(command.return_parameters) > 1: lines.append(' if (!error.length()) {') lines.extend(out_parameter_assignments) lines.append(' }') elif len(command.return_parameters) == 1: lines.append(' if (!error.length())') lines.extend(out_parameter_assignments) lines.append('') if not command.is_async: lines.append(' if (!error.length())') lines.append(' m_backendDispatcher->sendResponse(requestId, WTF::move(result));') lines.append(' else') lines.append(' m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));') lines.append('}') return "\n".join(lines)
def __init__(self, *args, **kwargs): CppGenerator.__init__(self, *args, **kwargs)
def _generate_dispatcher_implementation_for_command(self, command, domain): in_parameter_declarations = [] out_parameter_declarations = [] out_parameter_assignments = [] alternate_dispatcher_method_parameters = ['callId'] method_parameters = ['error'] for parameter in command.call_parameters: out_success_argument = 'nullptr' if parameter.is_optional: out_success_argument = '&%s_valueFound' % parameter.parameter_name in_parameter_declarations.append(' bool %s_valueFound = false;' % parameter.parameter_name) param_args = { 'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter), 'parameterName': parameter.parameter_name, 'keyedGetMethod': CppGenerator.cpp_getter_method_for_type(parameter.type), 'successOutParam': out_success_argument } in_parameter_declarations.append(' %(parameterType)s in_%(parameterName)s = InspectorBackendDispatcher::%(keyedGetMethod)s(paramsContainerPtr, ASCIILiteral("%(parameterName)s"), %(successOutParam)s, protocolErrorsPtr);' % param_args) if parameter.is_optional: optional_in_parameter_string = '%(parameterName)s_valueFound ? &in_%(parameterName)s : nullptr' % param_args alternate_dispatcher_method_parameters.append(optional_in_parameter_string) method_parameters.append(optional_in_parameter_string) else: alternate_dispatcher_method_parameters.append('in_' + parameter.parameter_name) method_parameters.append('in_' + parameter.parameter_name) if command.is_async: async_args = { 'domainName': domain.domain_name, 'callbackName': ucfirst(command.command_name) + 'Callback' } out_parameter_assignments.append(' callback->disable();') out_parameter_assignments.append(' m_backendDispatcher->reportProtocolError(&callId, Inspector::InspectorBackendDispatcher::ServerError, error);') out_parameter_assignments.append(' return;') method_parameters.append('callback') else: for parameter in command.return_parameters: param_args = { 'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter), 'parameterName': parameter.parameter_name, 'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type), } out_parameter_declarations.append(' %(parameterType)s out_%(parameterName)s;' % param_args) if parameter.is_optional: if CppGenerator.should_use_wrapper_for_return_type(parameter.type): out_parameter_assignments.append(' if (out_%(parameterName)s.isAssigned())' % param_args) out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s.getValue());' % param_args) else: out_parameter_assignments.append(' if (out_%(parameterName)s)' % param_args) out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);' % param_args) elif parameter.type.is_enum(): out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);' % param_args) if CppGenerator.should_pass_by_copy_for_return_type(parameter.type): method_parameters.append('out_' + parameter.parameter_name) else: method_parameters.append('&out_' + parameter.parameter_name) command_args = { 'domainName': domain.domain_name, 'callbackName': '%sCallback' % ucfirst(command.command_name), 'commandName': command.command_name, 'inParameterDeclarations': '\n'.join(in_parameter_declarations), 'invocationParameters': ', '.join(method_parameters), 'alternateInvocationParameters': ', '.join(alternate_dispatcher_method_parameters), } lines = [] if len(command.call_parameters) == 0: lines.append('void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject&)' % command_args) else: lines.append('void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject& message)' % command_args) lines.append('{') if len(command.call_parameters) > 0: lines.append(Template(CppTemplates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args)) lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)') lines.append(' if (m_alternateDispatcher) {') lines.append(' m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);' % command_args) lines.append(' return;') lines.append(' }') lines.append('#endif') lines.append('') lines.append(' ErrorString error;') lines.append(' RefPtr<InspectorObject> result = InspectorObject::create();') if command.is_async: lines.append(' RefPtr<Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(new Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher,callId));' % command_args) if len(command.return_parameters) > 0: lines.extend(out_parameter_declarations) lines.append(' m_agent->%(commandName)s(%(invocationParameters)s);' % command_args) lines.append('') if command.is_async: lines.append(' if (error.length()) {') lines.extend(out_parameter_assignments) lines.append(' }') elif len(command.return_parameters) > 1: lines.append(' if (!error.length()) {') lines.extend(out_parameter_assignments) lines.append(' }') elif len(command.return_parameters) == 1: lines.append(' if (!error.length())') lines.extend(out_parameter_assignments) lines.append('') if not command.is_async: lines.append(' m_backendDispatcher->sendResponse(callId, result.release(), error);') lines.append('}') return "\n".join(lines)