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))
    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. 3
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_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))
Esempio n. 5
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_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. 8
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_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<>',
                'std::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 std::nullopt;',
                '}',
                '',
            ])
            return body_lines

        declaration_types = [decl.type for decl in domain.type_declarations]
        object_types = filter(lambda _type: isinstance(_type, ObjectType), declaration_types)
        enum_types = filter(lambda _type: isinstance(_type, EnumType), declaration_types)
        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))
Esempio n. 10
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_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. 12
0
    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('#if !ASSERT_DISABLED')
        lines.append(
            'void BindingTraits<%s>::assertValueHasExpectedType(Inspector::InspectorValue* value)'
            %
            (CppGenerator.cpp_protocol_type_for_type(object_declaration.type)))
        lines.append("""{
    ASSERT_ARG(value, value);
    RefPtr<InspectorObject> object;
    bool castSucceeded = value->asObject(object);
    ASSERT_UNUSED(castSucceeded, castSucceeded);""")
        for type_member in required_members:
            args = {
                'memberName':
                type_member.member_name,
                'assertMethod':
                CppGenerator.cpp_assertion_method_for_type_member(
                    type_member, object_declaration)
            }

            lines.append("""    {
        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
        ASSERT(%(memberName)sPos != object->end());
        %(assertMethod)s(%(memberName)sPos->value.get());
    }""" % args)

        if should_count_properties:
            lines.append('')
            lines.append('    int foundPropertiesCount = %s;' %
                         len(required_members))

        for type_member in optional_members:
            args = {
                'memberName':
                type_member.member_name,
                'assertMethod':
                CppGenerator.cpp_assertion_method_for_type_member(
                    type_member, object_declaration)
            }

            lines.append("""    {
        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
        if (%(memberName)sPos != object->end()) {
            %(assertMethod)s(%(memberName)sPos->value.get());""" % args)

            if should_count_properties:
                lines.append('            ++foundPropertiesCount;')
            lines.append('        }')
            lines.append('    }')

        if should_count_properties:
            lines.append('    if (foundPropertiesCount != object->size())')
            lines.append(
                '        FATAL("Unexpected properties in object: %s\\n", object->toJSONString().ascii().data());'
            )
        lines.append('}')
        lines.append('#endif // !ASSERT_DISABLED')
        return '\n'.join(lines)
    def _generate_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("""{
    ASSERT_UNUSED(value, value);
#if ASSERT_ENABLED
    auto object = value->asObject();
    ASSERT(object);""")
        for type_member in required_members:
            member_type = type_member.type
            if isinstance(member_type, AliasedType):
                member_type = member_type.aliased_type

            if isinstance(member_type, EnumType):
                member_type = CppGenerator.cpp_type_for_enum(member_type, '%s::%s' % (object_declaration.type_name, ucfirst(type_member.member_name)))
            else:
                member_type = CppGenerator.cpp_protocol_type_for_type(member_type)

            args = {
                'memberName': type_member.member_name,
                'memberType': member_type
            }

            lines.append("""    {
        auto %(memberName)sPos = object->find("%(memberName)s"_s);
        ASSERT(%(memberName)sPos != object->end());
        BindingTraits<%(memberType)s>::assertValueHasExpectedType(%(memberName)sPos->value.ptr());
    }""" % args)

        if should_count_properties:
            lines.append('')
            lines.append('    size_t foundPropertiesCount = %s;' % len(required_members))

        for type_member in optional_members:
            member_type = type_member.type
            if isinstance(member_type, AliasedType):
                member_type = member_type.aliased_type

            if isinstance(member_type, EnumType):
                member_type = CppGenerator.cpp_type_for_enum(member_type, '%s::%s' % (object_declaration.type_name, ucfirst(type_member.member_name)))
            else:
                member_type = CppGenerator.cpp_protocol_type_for_type(member_type)

            args = {
                'memberName': type_member.member_name,
                'memberType': member_type
            }

            lines.append("""    {
        auto %(memberName)sPos = object->find("%(memberName)s"_s);
        if (%(memberName)sPos != object->end()) {
            BindingTraits<%(memberType)s>::assertValueHasExpectedType(%(memberName)sPos->value.ptr());""" % 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')
        lines.append('}')
        return '\n'.join(lines)
    def _generate_assertion_for_object_declaration(self, object_declaration):
        required_members = filter(lambda member: not member.is_optional, object_declaration.type_members)
        optional_members = filter(lambda member: member.is_optional, object_declaration.type_members)
        should_count_properties = not Generator.type_has_open_fields(object_declaration.type)
        lines = []

        lines.append('#if !ASSERT_DISABLED')
        lines.append('void BindingTraits<%s>::assertValueHasExpectedType(Inspector::InspectorValue* value)' % (CppGenerator.cpp_protocol_type_for_type(object_declaration.type)))
        lines.append("""{
    ASSERT_ARG(value, value);
    RefPtr<InspectorObject> object;
    bool castSucceeded = value->asObject(object);
    ASSERT_UNUSED(castSucceeded, castSucceeded);""")
        for type_member in required_members:
            args = {
                'memberName': type_member.member_name,
                'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration)
            }

            lines.append("""    {
        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
        ASSERT(%(memberName)sPos != object->end());
        %(assertMethod)s(%(memberName)sPos->value.get());
    }""" % args)

        if should_count_properties:
            lines.append('')
            lines.append('    int foundPropertiesCount = %s;' % len(required_members))

        for type_member in optional_members:
            args = {
                'memberName': type_member.member_name,
                'assertMethod': CppGenerator.cpp_assertion_method_for_type_member(type_member, object_declaration)
            }

            lines.append("""    {
        InspectorObject::iterator %(memberName)sPos = object->find(ASCIILiteral("%(memberName)s"));
        if (%(memberName)sPos != object->end()) {
            %(assertMethod)s(%(memberName)sPos->value.get());""" % args)

            if should_count_properties:
                lines.append('            ++foundPropertiesCount;')
            lines.append('        }')
            lines.append('    }')

        if should_count_properties:
            lines.append('    if (foundPropertiesCount != object->size())')
            lines.append('        FATAL("Unexpected properties in object: %s\\n", object->toJSONString().ascii().data());')
        lines.append('}')
        lines.append('#endif // !ASSERT_DISABLED')
        return '\n'.join(lines)
 def _generate_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. 16
0
    def _generate_dispatcher_implementation_for_command(self, command, domain):
        parameter_declarations = []
        parameter_enum_resolutions = []
        alternate_dispatcher_method_parameters = ['protocol_requestId']
        method_parameters = []

        for parameter in command.call_parameters:
            parameter_name = parameter.parameter_name
            if parameter.is_optional:
                parameter_name = 'opt_' + parameter_name
            parameter_name = 'in_' + parameter_name

            variable_name = parameter_name

            _type = parameter.type
            if isinstance(_type, AliasedType):
                _type = _type.aliased_type
            if isinstance(_type, EnumType) and _type.is_anonymous:
                _type = _type.primitive_type

            if _type.is_enum():
                parameter_name = parameter_name + '_json'

                alternate_dispatcher_method_parameters.append(parameter_name)

                enum_args = {
                    'helpersNamespace': self.helpers_namespace(),
                    'parameterKey': parameter.parameter_name,
                    'enumType': CppGenerator.cpp_protocol_type_for_type(_type),
                    'enumVariableName': variable_name,
                    'stringVariableName': parameter_name,
                }

                if len(parameter_enum_resolutions):
                    parameter_enum_resolutions.append('')
                parameter_enum_resolutions.append(
                    '    auto %(enumVariableName)s = Protocol::%(helpersNamespace)s::parseEnumValueFromString<%(enumType)s>(%(stringVariableName)s);'
                    % enum_args)
                if parameter.is_optional:
                    parameter_expression = 'WTFMove(%s)' % variable_name
                else:
                    parameter_enum_resolutions.append(
                        '    if (!%(enumVariableName)s) {' % enum_args)
                    parameter_enum_resolutions.append(
                        '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, makeString("Unknown %(parameterKey)s: "_s, %(stringVariableName)s));'
                        % enum_args)
                    parameter_enum_resolutions.append('        return;')
                    parameter_enum_resolutions.append('    }')
                    parameter_expression = '*' + variable_name
            else:
                if _type.raw_name() == 'string':
                    parameter_expression = variable_name
                elif parameter.is_optional:
                    parameter_expression = 'WTFMove(%s)' % variable_name
                elif _type.raw_name() in ['boolean', 'integer', 'number']:
                    parameter_expression = '*' + variable_name
                else:
                    parameter_expression = variable_name + '.releaseNonNull()'
                alternate_dispatcher_method_parameters.append(
                    parameter_expression)
            method_parameters.append(parameter_expression)

            param_args = {
                'parameterKey': parameter.parameter_name,
                'parameterName': parameter_name,
                'keyedGetMethod':
                CppGenerator.cpp_getter_method_for_type(_type),
                'required': 'false' if parameter.is_optional else 'true',
            }
            parameter_declarations.append(
                '    auto %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(protocol_parameters.get(), "%(parameterKey)s"_s, %(required)s);'
                % param_args)

        if command.is_async:
            method_parameters.append(
                'adoptRef(*new %sBackendDispatcherHandler::%s(m_backendDispatcher.copyRef(), protocol_requestId))'
                % (domain.domain_name,
                   '%sCallback' % ucfirst(command.command_name)))

        command_args = {
            'domainName':
            domain.domain_name,
            'commandName':
            command.command_name,
            'parameterDeclarations':
            '\n'.join(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 protocol_requestId, RefPtr<JSON::Object>&&)'
                % command_args)
        else:
            lines.append(
                'void %(domainName)sBackendDispatcher::%(commandName)s(long protocol_requestId, RefPtr<JSON::Object>&& protocol_parameters)'
                % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(
                Template(CppTemplates.
                         BackendDispatcherImplementationPrepareCommandArguments
                         ).substitute(None, **command_args))

        if self.model().framework.setting('alternate_dispatchers', False):
            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 // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
            lines.append('')

        if len(parameter_enum_resolutions):
            lines.extend(parameter_enum_resolutions)
            lines.append('')

        if command.is_async:
            lines.append(
                '    m_agent->%(commandName)s(%(invocationParameters)s);' %
                command_args)
        else:
            result_destructured_names = []
            result_conversion_lines = []
            for parameter in command.return_parameters:
                parameter_name = parameter.parameter_name
                if parameter.is_optional:
                    parameter_name = 'opt_' + parameter_name
                parameter_name = 'out_' + parameter_name

                result_destructured_names.append(parameter_name)

                parameter_value = parameter_name

                _type = parameter.type
                if isinstance(_type, AliasedType):
                    _type = _type.aliased_type
                if isinstance(_type, EnumType) and _type.is_anonymous:
                    _type = _type.primitive_type

                if _type.is_enum():
                    if parameter.is_optional:
                        parameter_value = '*' + parameter_value
                    parameter_value = 'Protocol::%s::getEnumConstantValue(%s)' % (
                        self.helpers_namespace(), parameter_value)
                elif CppGenerator.should_release_argument(
                        _type, parameter.is_optional):
                    parameter_value = parameter_value + '.releaseNonNull()'
                elif CppGenerator.should_dereference_argument(
                        _type, parameter.is_optional):
                    parameter_value = '*' + parameter_value
                elif CppGenerator.should_move_argument(_type,
                                                       parameter.is_optional):
                    parameter_value = 'WTFMove(%s)' % parameter_value

                param_args = {
                    'keyedSetMethod':
                    CppGenerator.cpp_setter_method_for_type(_type),
                    'parameterKey':
                    parameter.parameter_name,
                    'parameterName':
                    parameter_name,
                    'parameterValue':
                    parameter_value,
                }

                if parameter.is_optional:
                    result_conversion_lines.append(
                        '    if (!!%(parameterName)s)' % param_args)
                    result_conversion_lines.append(
                        '        protocol_jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterValue)s);'
                        % param_args)
                else:
                    result_conversion_lines.append(
                        '    protocol_jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterValue)s);'
                        % param_args)

            lines.append(
                '    auto result = m_agent->%(commandName)s(%(invocationParameters)s);'
                % command_args)
            lines.append('    if (!result) {')
            lines.append('        ASSERT(!result.error().isEmpty());')
            lines.append(
                '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, result.error());'
            )
            lines.append('        return;')
            lines.append('    }')
            lines.append('')
            if len(result_destructured_names) == 1:
                lines.append('    auto %s = WTFMove(result.value());' %
                             result_destructured_names[0])
                lines.append('')
            elif len(result_destructured_names) > 1:
                lines.append('    auto [%s] = WTFMove(result.value());' %
                             ", ".join(result_destructured_names))
                lines.append('')
            lines.append(
                '    auto protocol_jsonMessage = JSON::Object::create();')
            lines.extend(result_conversion_lines)
            lines.append(
                '    m_backendDispatcher->sendResponse(protocol_requestId, WTFMove(protocol_jsonMessage), false);'
            )

        lines.append('}')
        return self.wrap_with_guard_for_condition(command.condition,
                                                  "\n".join(lines))