Esempio n. 1
0
    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))
Esempio n. 2
0
    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))
Esempio n. 4
0
    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))
Esempio n. 11
0
    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)
Esempio n. 16
0
    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)]
Esempio n. 19
0
    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)
Esempio n. 22
0
    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)
Esempio n. 24
0
    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))
Esempio n. 26
0
    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))
Esempio n. 27
0
 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
Esempio n. 28
0
    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))
Esempio n. 29
0
    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))
Esempio n. 30
0
 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))
Esempio n. 35
0
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)
Esempio n. 36
0
    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)
Esempio n. 40
0
    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)
Esempio n. 42
0
    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)
Esempio n. 47
0
    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),
        )
Esempio n. 50
0
 def setUp(self):
     self.faker = CppFaker([])
     self.generator = CppGenerator()
Esempio n. 51
0
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)
Esempio n. 52
0
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)
Esempio n. 54
0
 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)