def _generate_open_field_names(self): lines = [] for domain in self.domains_to_generate(): domain_lines = [] type_declarations = self.type_declarations_for_domain(domain) for type_declaration in [ decl for decl in type_declarations if Generator.type_has_open_fields(decl.type) ]: open_members = Generator.open_fields(type_declaration) for type_member in sorted( open_members, key=lambda member: member.member_name): field_name = '::'.join([ 'Inspector', 'Protocol', domain.domain_name, ucfirst(type_declaration.type_name), ucfirst(type_member.member_name) ]) domain_lines.append('const char* %s = "%s";' % (field_name, type_member.member_name)) if len(domain_lines): lines.append( self.wrap_with_guard_for_condition( domain.condition, '\n'.join(domain_lines))) return '\n'.join(lines)
def objc_enum_name_for_anonymous_enum_parameter(domain, event_or_command_name, parameter): domain_name = domain.domain_name name = '%s%s%s' % (domain_name, ucfirst(event_or_command_name), ucfirst(parameter.parameter_name)) name = remove_duplicate_from_str(name, domain_name) return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
def objc_enum_name_for_anonymous_enum_parameter(self, domain, event_or_command_name, parameter): domain_name = domain.domain_name name = '%s%s%s' % (domain_name, ucfirst(event_or_command_name), ucfirst(parameter.parameter_name)) name = remove_duplicate_from_str(name, domain_name) return '%s%s' % (self.objc_prefix(), name)
def _generate_anonymous_enum_for_parameter(self, parameter, event): enum_args = { 'parameterName': parameter.parameter_name, 'eventName': event.event_name } lines = [] lines.append(' // Named after parameter \'%(parameterName)s\' while generating command/event %(eventName)s.' % enum_args) lines.append(' enum class %s {' % ucfirst(parameter.parameter_name)) for enum_value in parameter.type.enum_values(): lines.append(' %s = %d,' % (Generator.stylized_name_for_enum_value(enum_value), self.encoding_for_enum_value(enum_value))) lines.append(' }; // enum class %s' % ucfirst(parameter.parameter_name)) return "\n".join(lines)
def _generate_class_for_object_declaration(self, type_declaration, domain): if len(type_declaration.type_members) == 0: return '' enum_members = [member for member in type_declaration.type_members if isinstance(member.type, EnumType) and member.type.is_anonymous] required_members = [member for member in type_declaration.type_members if not member.is_optional] optional_members = [member for member in type_declaration.type_members if member.is_optional] object_name = type_declaration.type_name lines = [] if len(type_declaration.description) > 0: lines.append('/* %s */' % type_declaration.description) base_class = 'JSON::Object' if not Generator.type_has_open_fields(type_declaration.type): base_class = base_class + 'Base' lines.append('class %s : public %s {' % (object_name, base_class)) lines.append('public:') for enum_member in enum_members: lines.append(' // Named after property name \'%s\' while generating %s.' % (enum_member.member_name, object_name)) lines.append(self._generate_struct_for_anonymous_enum_member(enum_member)) lines.append(self._generate_builder_state_enum(type_declaration)) constructor_example = [] constructor_example.append(' * Ref<%s> result = %s::create()' % (object_name, object_name)) for member in required_members: constructor_example.append(' * .set%s(...)' % ucfirst(member.member_name)) constructor_example.append(' * .release()') builder_args = { 'objectType': object_name, 'constructorExample': '\n'.join(constructor_example) + ';', } lines.append(Template(CppTemplates.ProtocolObjectBuilderDeclarationPrelude).substitute(None, **builder_args)) for type_member in required_members: lines.append(self._generate_builder_setter_for_member(type_member, domain)) lines.append(Template(CppTemplates.ProtocolObjectBuilderDeclarationPostlude).substitute(None, **builder_args)) for member in optional_members: lines.append(self._generate_unchecked_setter_for_member(member, domain)) if Generator.type_has_open_fields(type_declaration.type): lines.append('') lines.append(' // Property names for type generated as open.') open_members = Generator.open_fields(type_declaration) for type_member in open_members: export_macro = self.model().framework.setting('export_macro', None) lines.append(' %s static const char* %s;' % (export_macro, ucfirst(type_member.member_name))) lines.append('};') lines.append('') return '\n'.join(lines)
def _generate_class_for_object_declaration(self, type_declaration, domain): if len(type_declaration.type_members) == 0: return '' enum_members = filter(lambda member: isinstance(member.type, EnumType) and member.type.is_anonymous, type_declaration.type_members) required_members = filter(lambda member: not member.is_optional, type_declaration.type_members) optional_members = filter(lambda member: member.is_optional, type_declaration.type_members) object_name = type_declaration.type_name lines = [] if len(type_declaration.description) > 0: lines.append('/* %s */' % type_declaration.description) base_class = 'Inspector::InspectorObject' if not Generator.type_has_open_fields(type_declaration.type): base_class = base_class + 'Base' lines.append('class %s : public %s {' % (object_name, base_class)) lines.append('public:') for enum_member in enum_members: lines.append(' // Named after property name \'%s\' while generating %s.' % (enum_member.member_name, object_name)) lines.append(self._generate_struct_for_anonymous_enum_member(enum_member)) lines.append(self._generate_builder_state_enum(type_declaration)) constructor_example = [] constructor_example.append(' * RefPtr<%s> result = %s::create()' % (object_name, object_name)) for member in required_members: constructor_example.append(' * .set%s(...)' % ucfirst(member.member_name)) builder_args = { 'objectType': object_name, 'constructorExample': '\n'.join(constructor_example) + ';', } lines.append(Template(Templates.TypeBuilderDeclarationPrelude).substitute(None, **builder_args)) for type_member in required_members: lines.append(self._generate_builder_setter_for_member(type_member, domain)) lines.append(Template(Templates.TypeBuilderDeclarationPostlude).substitute(None, **builder_args)) for member in optional_members: lines.append(self._generate_unchecked_setter_for_member(member, domain)) if Generator.type_has_open_fields(type_declaration.type): lines.append('') lines.append(' // Property names for type generated as open.') for type_member in type_declaration.type_members: lines.append(' static const char* %s;' % ucfirst(type_member.member_name)) lines.append('};') lines.append('') return '\n'.join(lines)
def cpp_type_for_formal_async_parameter(parameter): _type = parameter.type if isinstance(_type, AliasedType): _type = _type.aliased_type # Fall through. if isinstance(_type, (ObjectType, ArrayType)): return 'RefPtr<%s>&&' % CppGenerator.cpp_protocol_type_for_type( _type) if isinstance(_type, PrimitiveType): cpp_name = CppGenerator.cpp_name_for_primitive_type(_type) if parameter.is_optional: return "Optional<%s>&" % cpp_name elif _type.qualified_name() in ['integer', 'number']: return CppGenerator.cpp_name_for_primitive_type(_type) elif _type.qualified_name() in ['string']: return 'const %s&' % cpp_name else: return cpp_name if isinstance(_type, EnumType): if _type.is_anonymous: cpp_name = '%sBackendDispatcherHandler::%s' % ( _type.type_domain().domain_name, ucfirst(parameter.parameter_name)) else: cpp_name = 'Inspector::Protocol::%s::%s' % ( _type.type_domain().domain_name, _type.raw_name()) if parameter.is_optional: return "Optional<%s>" % cpp_name else: return cpp_name raise ValueError("Unknown formal async parameter type.")
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" % (Generator.type_string_for_unchecked_formal_in_parameter( _parameter), _parameter.parameter_name)) in_parameters.append("PassRefPtr<%s> callback" % callbackName) out_parameters = [] for _parameter in command.return_parameters: out_parameters.append( "%s %s" % (Generator.type_string_for_formal_async_parameter(_parameter), _parameter.parameter_name)) command_args = { 'callbackName': callbackName, 'commandName': command.command_name, 'inParameters': ", ".join(in_parameters), 'outParameters': ", ".join(out_parameters), } return Template( Templates.BackendDispatcherHeaderAsyncCommandDeclaration ).substitute(None, **command_args)
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_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_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 cpp_type_for_type_with_name(_type, type_name, is_optional): if isinstance(_type, (ArrayType, ObjectType)): return 'RefPtr<%s>' % CppGenerator.cpp_protocol_type_for_type(_type) if isinstance(_type, AliasedType): builder_type = CppGenerator.cpp_protocol_type_for_type(_type) if is_optional: return 'const %s* const' % builder_type elif _type.aliased_type.qualified_name() in ['integer', 'number']: return CppGenerator.cpp_name_for_primitive_type(_type.aliased_type) elif _type.aliased_type.qualified_name() in ['string']: return 'const %s&' % builder_type else: return builder_type if isinstance(_type, PrimitiveType): cpp_name = CppGenerator.cpp_name_for_primitive_type(_type) if _type.qualified_name() in ['object']: return 'RefPtr<Inspector::InspectorObject>' elif _type.qualified_name() in ['any']: return 'RefPtr<Inspector::InspectorValue>' elif is_optional: return 'const %s* const' % cpp_name elif _type.qualified_name() in ['string']: return 'const %s&' % cpp_name else: return cpp_name if isinstance(_type, EnumType): if _type.is_anonymous: enum_type_name = ucfirst(type_name) else: enum_type_name = 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name()) if is_optional: return '%s*' % enum_type_name else: return '%s' % enum_type_name
def cpp_type_for_formal_out_parameter(parameter): _type = parameter.type if isinstance(_type, AliasedType): _type = _type.aliased_type # Fall through. if isinstance(_type, (ObjectType, ArrayType)): return 'RefPtr<%s>&' % CppGenerator.cpp_protocol_type_for_type( _type) if isinstance(_type, PrimitiveType): cpp_name = CppGenerator.cpp_name_for_primitive_type(_type) if parameter.is_optional: return "Inspector::Protocol::OptOutput<%s>*" % cpp_name else: return '%s*' % cpp_name if isinstance(_type, EnumType): if _type.is_anonymous: return 'Inspector%sBackendDispatcherHandler::%s*' % ( _type.type_domain().domain_name, ucfirst(parameter.parameter_name)) else: return 'Inspector::Protocol::%s::%s*' % ( _type.type_domain().domain_name, _type.raw_name()) raise ValueError("unknown formal out parameter type.")
def _generate_init_method_for_required_members(self, domain, declaration, required_members): pairs = [] for member in required_members: objc_type = self.objc_type_for_member(declaration, member) var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) pairs.append('%s:(%s)%s' % (var_name, objc_type, var_name)) pairs[0] = ucfirst(pairs[0]) lines = [] lines.append('- (instancetype)initWith%s' % ' '.join(pairs)) lines.append('{') lines.append(' if (!(self = [super init]))') lines.append(' return nil;') lines.append('') required_pointer_members = filter(lambda member: ObjCGenerator.is_type_objc_pointer_type(member.type), required_members) if required_pointer_members: for member in required_pointer_members: var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) lines.append(' THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(%s, @"%s");' % (var_name, var_name)) objc_array_class = self.objc_class_for_array_type(member.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]);' % (var_name, objc_array_class)) lines.append('') for member in required_members: var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) lines.append(' self.%s = %s;' % (var_name, var_name)) lines.append('') lines.append(' return self;') lines.append('}') return '\n'.join(lines)
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_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_dispatcher_class_for_domain(self, command, domain): out_parameter_assignments = [] formal_parameters = [] for parameter in command.return_parameters: param_args = { 'frameworkPrefix': self.model().framework.setting('prefix'), 'keyedSetMethod': Generator.keyed_set_method_for_type(parameter.type), 'parameterName': parameter.parameter_name, 'parameterType': Generator.type_string_for_stack_in_parameter(parameter), } formal_parameters.append('%s %s' % (Generator.type_string_for_formal_async_parameter(parameter), parameter.parameter_name)) if parameter.is_optional: if Generator.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("%(parameterName)s"), %(parameterName)s.getValue());' % param_args) else: out_parameter_assignments.append(' if (%(parameterName)s)' % param_args) out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), %(parameterName)s);' % param_args) elif parameter.type.is_enum(): out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), Inspector::Protocol::get%(frameworkPrefix)sEnumConstantValue(%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' jsonMessage->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)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(Templates.BackendDispatcherImplementationAsyncCommand).substitute(None, **async_args)
def cpp_type_for_type_member_argument(_type, name): if isinstance(_type, AliasedType): _type = _type.aliased_type # Fallthrough. if isinstance(_type, (ArrayType, ObjectType)): return 'Ref<%s>&&' % CppGenerator.cpp_protocol_type_for_type(_type) if _type.qualified_name() == 'object': return 'Ref<JSON::Object>&&' if _type.qualified_name() == 'array': return 'Ref<JSON::Array>&&' if _type.qualified_name() == 'any': return 'Ref<JSON::Value>&&' if _type.qualified_name() == 'string': return 'const %s&' % CppGenerator.cpp_name_for_primitive_type( _type) if isinstance(_type, EnumType): if _type.is_anonymous: return ucfirst(name) return 'Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name()) if isinstance(_type, PrimitiveType): return CppGenerator.cpp_name_for_primitive_type(_type) raise ValueError("unknown type")
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_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_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_builder_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'frameworkPrefix': self.model().framework.setting('prefix'), 'keyedSet': Generator.keyed_set_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': Generator.type_string_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::TypeBuilder::get%(frameworkPrefix)sEnumConstantValue(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_domain(self, domain): lines = [] args = { 'domain': domain.domain_name } lines.append('// %(domain)s.' % args) has_async_commands = any(map(lambda command: command.is_async, domain.commands)) if len(domain.events) > 0 or has_async_commands: lines.append('InspectorBackend.register%(domain)sDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "%(domain)s");' % args) for declaration in domain.type_declarations: if declaration.type.is_enum(): enum_args = { 'domain': domain.domain_name, 'enumName': declaration.type_name, 'enumMap': ", ".join(['%s: "%s"' % (Generator.stylized_name_for_enum_value(enum_value), enum_value) for enum_value in declaration.type.enum_values()]) } lines.append('InspectorBackend.registerEnum("%(domain)s.%(enumName)s", {%(enumMap)s});' % enum_args) def is_anonymous_enum_member(type_member): return isinstance(type_member.type, EnumType) and type_member.type.is_anonymous for _member in filter(is_anonymous_enum_member, declaration.type_members): enum_args = { 'domain': domain.domain_name, 'enumName': '%s%s' % (declaration.type_name, ucfirst(_member.member_name)), 'enumMap': ", ".join(['%s: "%s"' % (Generator.stylized_name_for_enum_value(enum_value), enum_value) for enum_value in _member.type.enum_values()]) } lines.append('InspectorBackend.registerEnum("%(domain)s.%(enumName)s", {%(enumMap)s});' % enum_args) for event in domain.events: event_args = { 'domain': domain.domain_name, 'eventName': event.event_name, 'params': ", ".join(['"%s"' % parameter.parameter_name for parameter in event.event_parameters]) } lines.append('InspectorBackend.registerEvent("%(domain)s.%(eventName)s", [%(params)s]);' % event_args) for command in domain.commands: def generate_parameter_object(parameter): optional_string = "true" if parameter.is_optional else "false" pairs = [] pairs.append('"name": "%s"' % parameter.parameter_name) pairs.append('"type": "%s"' % Generator.js_name_for_parameter_type(parameter.type)) pairs.append('"optional": %s' % optional_string) return "{%s}" % ", ".join(pairs) command_args = { 'domain': domain.domain_name, 'commandName': command.command_name, 'callParams': ", ".join([generate_parameter_object(parameter) for parameter in command.call_parameters]), 'returnParams': ", ".join(['"%s"' % parameter.parameter_name for parameter in command.return_parameters]), } lines.append('InspectorBackend.registerCommand("%(domain)s.%(commandName)s", [%(callParams)s], [%(returnParams)s]);' % command_args) return "\n".join(lines)
def _generate_init_method_for_required_members(self, domain, declaration, required_members): pairs = [] for member in required_members: objc_type = ObjCGenerator.objc_type_for_member(declaration, member) var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) pairs.append('%s:(%s)%s' % (var_name, objc_type, var_name)) pairs[0] = ucfirst(pairs[0]) return '- (instancetype)initWith%s;' % ' '.join(pairs)
def _generate_struct_for_enum_type(self, enum_name, enum_type): lines = [] enum_name = ucfirst(enum_name) lines.append('enum class %s {' % enum_name) for enum_value in enum_type.enum_values(): lines.append(' %s = %s,' % (Generator.stylized_name_for_enum_value(enum_value), self.encoding_for_enum_value(enum_value))) lines.append('}; // enum class %s' % enum_name) return lines # The caller may want to adjust indentation, so don't join these lines.
def _generate_init_method_for_required_members(self, domain, declaration, required_members): pairs = [] for member in required_members: objc_type = self.objc_type_for_member(declaration, member) var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) pairs.append('%s:(%s)%s' % (var_name, objc_type, var_name)) pairs[0] = ucfirst(pairs[0]) return '- (instancetype)initWith%s;' % ' '.join(pairs)
def _generate_open_field_names(self): lines = [] for domain in self.domains_to_generate(): for type_declaration in filter( lambda decl: Generator.type_has_open_fields(decl.type), domain.type_declarations): for type_member in sorted( type_declaration.type_members, key=lambda member: member.member_name): field_name = '::'.join([ 'Inspector', 'Protocol', domain.domain_name, ucfirst(type_declaration.type_name), ucfirst(type_member.member_name) ]) lines.append('const char* %s = "%s";' % (field_name, type_member.member_name)) return '\n'.join(lines)
def _generate_event_signature(self, domain, event): if not event.event_parameters: return '- (void)%s' % event.event_name pairs = [] for parameter in event.event_parameters: param_name = parameter.parameter_name pairs.append('%s:(%s)%s' % (param_name, ObjCGenerator.objc_type_for_param(domain, event.event_name, parameter), param_name)) pairs[0] = ucfirst(pairs[0]) return '- (void)%sWith%s' % (event.event_name, ' '.join(pairs))
def cpp_protocol_type_for_type_member(type_member, object_declaration): if isinstance(type_member.type, EnumType) and type_member.type.is_anonymous: return '::'.join([ CppGenerator.cpp_protocol_type_for_type( object_declaration.type), ucfirst(type_member.member_name) ]) else: return CppGenerator.cpp_protocol_type_for_type(type_member.type)
def _generate_single_event_interface(self, domain, event): if not event.event_parameters: return self.wrap_with_guard_for_condition(event.condition, '- (void)%s;' % event.event_name) pairs = [] for parameter in event.event_parameters: param_name = parameter.parameter_name pairs.append('%s:(%s)%s' % (param_name, self.objc_type_for_param(domain, event.event_name, parameter), param_name)) pairs[0] = ucfirst(pairs[0]) return self.wrap_with_guard_for_condition(event.condition, '- (void)%sWith%s;' % (event.event_name, ' '.join(pairs)))
def _generate_setter_for_member(self, domain, declaration, member): objc_type = ObjCGenerator.objc_type_for_member(declaration, member) var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) setter_method = ObjCGenerator.objc_setter_method_for_member(declaration, member) conversion_expression = ObjCGenerator.objc_to_protocol_expression_for_member(declaration, member, var_name) lines = [] lines.append('- (void)set%s:(%s)%s' % (ucfirst(var_name), objc_type, var_name)) lines.append('{') lines.append(' [super %s:%s forKey:@"%s"];' % (setter_method, conversion_expression, member.member_name)) lines.append('}') return '\n'.join(lines)
def _generate_setter_for_member(self, domain, declaration, member): objc_type = self.objc_type_for_member(declaration, member) var_name = ObjCGenerator.identifier_to_objc_identifier(member.member_name) setter_method = ObjCGenerator.objc_setter_method_for_member(declaration, member) conversion_expression = self.objc_to_protocol_expression_for_member(declaration, member, var_name) lines = [] lines.append('- (void)set%s:(%s)%s' % (ucfirst(var_name), objc_type, var_name)) lines.append('{') objc_array_class = self.objc_class_for_array_type(member.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]);' % (var_name, objc_array_class)) lines.append(' [super %s:%s forKey:@"%s"];' % (setter_method, conversion_expression, member.member_name)) lines.append('}') 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_builder_state_enum(self, type_declaration): lines = [] required_members = [member for member in type_declaration.type_members if not member.is_optional] enum_values = [] lines.append(' enum {') lines.append(' NoFieldsSet = 0,') for i in range(len(required_members)): enum_value = "%sSet" % ucfirst(required_members[i].member_name) enum_values.append(enum_value) lines.append(' %s = 1 << %d,' % (enum_value, i)) if len(enum_values) > 0: lines.append(' AllFieldsSet = (%s)' % ' | '.join(enum_values)) else: lines.append(' AllFieldsSet = 0') lines.append(' };') lines.append('') return '\n'.join(lines)
def cpp_setter_method_for_type(_type): if isinstance(_type, ObjectType): return 'setObject' if isinstance(_type, ArrayType): return 'setArray' if isinstance(_type, PrimitiveType): if _type.raw_name() is 'integer': return 'setInteger' elif _type.raw_name() is 'number': return 'setDouble' elif _type.raw_name() is 'any': return 'setValue' else: return 'set' + ucfirst(_type.raw_name()) if isinstance(_type, AliasedType): return CppGenerator.cpp_setter_method_for_type(_type.aliased_type) if isinstance(_type, EnumType): return CppGenerator.cpp_setter_method_for_type(_type.primitive_type)
def _generate_builder_state_enum(self, type_declaration): lines = [] required_members = filter(lambda member: not member.is_optional, type_declaration.type_members) enum_values = [] lines.append(' enum {') lines.append(' NoFieldsSet = 0,') for i in range(len(required_members)): enum_value = "%sSet" % ucfirst(required_members[i].member_name) enum_values.append(enum_value) lines.append(' %s = 1 << %d,' % (enum_value, i)) if len(enum_values) > 0: lines.append(' AllFieldsSet = (%s)' % ' | '.join(enum_values)) else: lines.append(' AllFieldsSet = 0') lines.append(' };') 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 _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'frameworkPrefix': self.model().framework.setting('prefix'), 'keyedSet': Generator.keyed_set_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': Generator.type_string_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::TypeBuilder::get%(frameworkPrefix)sEnumConstantValue(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 _generate_unchecked_setter_for_member(self, type_member, domain): setter_args = { 'camelName': ucfirst(type_member.member_name), 'frameworkPrefix': self.model().framework.setting('prefix'), 'keyedSet': Generator.keyed_set_method_for_type(type_member.type), 'name': type_member.member_name, 'parameterType': Generator.type_string_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::get%(frameworkPrefix)sEnumConstantValue(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 _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" % (Generator.type_string_for_unchecked_formal_in_parameter(_parameter), _parameter.parameter_name)) in_parameters.append("PassRefPtr<%s> callback" % callbackName) out_parameters = [] for _parameter in command.return_parameters: out_parameters.append("%s %s" % (Generator.type_string_for_formal_async_parameter(_parameter), _parameter.parameter_name)) command_args = { 'callbackName': callbackName, 'commandName': command.command_name, 'inParameters': ", ".join(in_parameters), 'outParameters': ", ".join(out_parameters), } return Template(Templates.BackendDispatcherHeaderAsyncCommandDeclaration).substitute(None, **command_args)
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 objc_enum_name_for_anonymous_enum_member(declaration, member): domain_name = member.type.type_domain().domain_name name = '%s%s%s' % (domain_name, declaration.type.raw_name(), ucfirst(member.member_name)) name = remove_duplicate_from_str(name, domain_name) return '%s%s' % (ObjCGenerator.OBJC_PREFIX, name)
def cpp_protocol_type_for_type_member(type_member, object_declaration): if isinstance(type_member.type, EnumType) and type_member.type.is_anonymous: return '::'.join([CppGenerator.cpp_protocol_type_for_type(object_declaration.type), ucfirst(type_member.member_name)]) else: return CppGenerator.cpp_protocol_type_for_type(type_member.type)
def objc_enum_name_for_anonymous_enum_member(self, declaration, member): domain_name = member.type.type_domain().domain_name name = '%s%s%s' % (domain_name, declaration.type.raw_name(), ucfirst(member.member_name)) name = remove_duplicate_from_str(name, domain_name) return '%s%s' % (self.objc_prefix(), name)
def _generate_open_field_names(self): lines = [] for domain in self.domains_to_generate(): for type_declaration in filter(lambda decl: Generator.type_has_open_fields(decl.type), domain.type_declarations): for type_member in sorted(type_declaration.type_members, key=lambda member: member.member_name): field_name = '::'.join(['Inspector', 'Protocol', domain.domain_name, ucfirst(type_declaration.type_name), ucfirst(type_member.member_name)]) lines.append('const char* %s = "%s";' % (field_name, type_member.member_name)) return '\n'.join(lines)
def cpp_type_for_formal_out_parameter(parameter): _type = parameter.type if isinstance(_type, AliasedType): _type = _type.aliased_type # Fall through. if isinstance(_type, (ObjectType, ArrayType)): return 'RefPtr<%s>&' % CppGenerator.cpp_protocol_type_for_type(_type) if isinstance(_type, PrimitiveType): cpp_name = CppGenerator.cpp_name_for_primitive_type(_type) if parameter.is_optional: return "Inspector::Protocol::OptOutput<%s>*" % cpp_name else: return '%s*' % cpp_name if isinstance(_type, EnumType): if _type.is_anonymous: return '%sBackendDispatcherHandler::%s*' % (_type.type_domain().domain_name, ucfirst(parameter.parameter_name)) else: return 'Inspector::Protocol::%s::%s*' % (_type.type_domain().domain_name, _type.raw_name()) raise ValueError("unknown formal out parameter type.")
def _generate_dispatcher_implementation_for_command(self, command, domain): in_parameter_declarations = [] out_parameter_declarations = [] out_parameter_assignments = [] 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': Generator.type_string_for_stack_in_parameter(parameter), 'parameterName': parameter.parameter_name, 'keyedGetMethod': Generator.keyed_get_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: method_parameters.append('%(parameterName)s_valueFound ? &in_%(parameterName)s : nullptr' % param_args) else: 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': Generator.type_string_for_stack_out_parameter(parameter), 'parameterName': parameter.parameter_name, 'keyedSetMethod': Generator.keyed_set_method_for_type(parameter.type), 'frameworkPrefix': self.model().framework.setting('prefix') } out_parameter_declarations.append(' %(parameterType)s out_%(parameterName)s;' % param_args) if parameter.is_optional: if Generator.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::TypeBuilder::get%(frameworkPrefix)sEnumConstantValue(out_%(parameterName)s));' % param_args) else: out_parameter_assignments.append(' result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);' % param_args) if Generator.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) } 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(Templates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args)) 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)
def cpp_type_for_stack_out_parameter(parameter): _type = parameter.type if isinstance(_type, (ArrayType, ObjectType)): return 'RefPtr<%s>' % CppGenerator.cpp_protocol_type_for_type(_type) if isinstance(_type, AliasedType): builder_type = CppGenerator.cpp_protocol_type_for_type(_type) if parameter.is_optional: return "Inspector::Protocol::OptOutput<%s>" % builder_type return '%s' % builder_type if isinstance(_type, PrimitiveType): cpp_name = CppGenerator.cpp_name_for_primitive_type(_type) if parameter.is_optional: return "Inspector::Protocol::OptOutput<%s>" % cpp_name else: return cpp_name if isinstance(_type, EnumType): if _type.is_anonymous: return '%sBackendDispatcherHandler::%s' % (_type.type_domain().domain_name, ucfirst(parameter.parameter_name)) else: return 'Inspector::Protocol::%s::%s' % (_type.type_domain().domain_name, _type.raw_name())
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)