Skip to content

Commit

Permalink
Allow generated serialization of nested classes
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=246057
rdar://100788834

Reviewed by Tim Horton.

* Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h:
(WebCore::ApplicationManifest::encode const): Deleted.
(WebCore::ApplicationManifest::decode): Deleted.
(WebCore::ApplicationManifest::Icon::encode const): Deleted.
(WebCore::ApplicationManifest::Icon::decode): Deleted.
* Source/WebKit/Scripts/generate-serializers.py:
(SerializedType.__init__):
(SerializedEnum.is_option_set):
(SerializedEnum):
(SerializedEnum.is_nested):
(argument_coder_declarations):
(generate_header):
(generate_impl):
(parse_serialized_types):
* Source/WebKit/Scripts/webkit/tests/GeneratedSerializers.cpp:
* Source/WebKit/Scripts/webkit/tests/GeneratedSerializers.h:
* Source/WebKit/Scripts/webkit/tests/SerializedTypeInfo.cpp:
* Source/WebKit/Scripts/webkit/tests/TestSerializedType.serialization.in:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:

Canonical link: https://commits.webkit.org/255154@main
  • Loading branch information
Alex Christensen authored and achristensen07 committed Oct 5, 2022
1 parent 9fb95a3 commit 58c2188
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 121 deletions.
86 changes: 2 additions & 84 deletions Source/WebCore/Modules/applicationmanifest/ApplicationManifest.h
Expand Up @@ -35,15 +35,15 @@
namespace WebCore {

struct ApplicationManifest {
enum class Display {
enum class Display : uint8_t {
Browser,
MinimalUI,
Standalone,
Fullscreen,
};

struct Icon {
enum class Purpose : uint8_t {
enum class Purpose : uint8_t {
Any = 1 << 0,
Monochrome = 1 << 1,
Maskable = 1 << 2,
Expand All @@ -53,9 +53,6 @@ struct ApplicationManifest {
Vector<String> sizes;
String type;
OptionSet<Purpose> purposes;

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ApplicationManifest::Icon> decode(Decoder&);
};

String name;
Expand All @@ -66,88 +63,9 @@ struct ApplicationManifest {
URL startURL;
Color themeColor;
Vector<Icon> icons;

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ApplicationManifest> decode(Decoder&);
};

template<class Encoder>
void ApplicationManifest::encode(Encoder& encoder) const
{
encoder << name << shortName << description << scope << display << startURL << themeColor << icons;
}

template<class Decoder>
std::optional<ApplicationManifest> ApplicationManifest::decode(Decoder& decoder)
{
ApplicationManifest result;

if (!decoder.decode(result.name))
return std::nullopt;
if (!decoder.decode(result.shortName))
return std::nullopt;
if (!decoder.decode(result.description))
return std::nullopt;
if (!decoder.decode(result.scope))
return std::nullopt;
if (!decoder.decode(result.display))
return std::nullopt;
if (!decoder.decode(result.startURL))
return std::nullopt;
if (!decoder.decode(result.themeColor))
return std::nullopt;
if (!decoder.decode(result.icons))
return std::nullopt;

return result;
}

template<class Encoder>
void ApplicationManifest::Icon::encode(Encoder& encoder) const
{
encoder << src << sizes << type << purposes;
}

template<class Decoder>
std::optional<ApplicationManifest::Icon> ApplicationManifest::Icon::decode(Decoder& decoder)
{
ApplicationManifest::Icon result;
if (!decoder.decode(result.src))
return std::nullopt;
if (!decoder.decode(result.sizes))
return std::nullopt;
if (!decoder.decode(result.type))
return std::nullopt;
if (!decoder.decode(result.purposes))
return std::nullopt;

return result;
}

} // namespace WebCore

namespace WTF {

template<> struct EnumTraits<WebCore::ApplicationManifest::Display> {
using values = EnumValues<
WebCore::ApplicationManifest::Display,
WebCore::ApplicationManifest::Display::Browser,
WebCore::ApplicationManifest::Display::MinimalUI,
WebCore::ApplicationManifest::Display::Standalone,
WebCore::ApplicationManifest::Display::Fullscreen
>;
};

template<> struct EnumTraits<WebCore::ApplicationManifest::Icon::Purpose> {
using values = EnumValues<
WebCore::ApplicationManifest::Icon::Purpose,
WebCore::ApplicationManifest::Icon::Purpose::Any,
WebCore::ApplicationManifest::Icon::Purpose::Monochrome,
WebCore::ApplicationManifest::Icon::Purpose::Maskable
>;
};

} // namespace WTF;

#endif // ENABLE(APPLICATION_MANIFEST)

75 changes: 50 additions & 25 deletions Source/WebKit/Scripts/generate-serializers.py
Expand Up @@ -39,17 +39,22 @@ def __init__(self, struct_or_class, namespace, name, parent_class, members, cond
self.return_ref = False
self.create_using = False
self.populate_from_empty_constructor = False
self.nested = False
if attributes is not None:
for attribute in attributes.split(', '):
key, value = attribute.split('=')
if key == 'AdditionalEncoder':
self.encoders.append(value)
if key == 'Return' and value == 'Ref':
self.return_ref = True
if key == 'CreateUsing':
self.create_using = value
if key == 'LegacyPopulateFrom' and value == 'EmptyConstructor':
self.populate_from_empty_constructor = True
if '=' in attribute:
key, value = attribute.split('=')
if key == 'AdditionalEncoder':
self.encoders.append(value)
if key == 'Return' and value == 'Ref':
self.return_ref = True
if key == 'CreateUsing':
self.create_using = value
if key == 'LegacyPopulateFrom' and value == 'EmptyConstructor':
self.populate_from_empty_constructor = True
else:
if attribute == 'Nested':
self.nested = True

def namespace_and_name(self):
if self.namespace is None:
Expand Down Expand Up @@ -85,7 +90,10 @@ def parameter(self):
return self.underlying_type

def is_option_set(self):
return self.attributes == '[OptionSet] '
return 'OptionSet' in self.attributes

def is_nested(self):
return 'Nested' in self.attributes


class MemberVariable(object):
Expand Down Expand Up @@ -146,6 +154,27 @@ def sanitize_string_for_variable_name(string):
"""


def argument_coder_declarations(serialized_types, skip_nested):
result = []
for type in serialized_types:
if type.nested == skip_nested:
continue
result.append('')
if type.condition is not None:
result.append('#if ' + type.condition)
result.append('template<> struct ArgumentCoder<' + type.namespace_and_name() + '> {')
for encoder in type.encoders:
result.append(' static void encode(' + encoder + '&, const ' + type.namespace_and_name() + '&);')
if type.return_ref:
result.append(' static std::optional<Ref<' + type.namespace_and_name() + '>> decode(Decoder&);')
else:
result.append(' static std::optional<' + type.namespace_and_name() + '> decode(Decoder&);')
result.append('};')
if type.condition is not None:
result.append('#endif')
return result


def generate_header(serialized_types, serialized_enums):
result = []
result.append(_license_header)
Expand All @@ -156,12 +185,16 @@ def generate_header(serialized_types, serialized_enums):
result.append('#include <wtf/Ref.h>')
result.append('')
for enum in serialized_enums:
if enum.is_nested():
continue
if enum.condition is not None:
result.append('#if ' + enum.condition)
result.append('namespace ' + enum.namespace + ' { enum class ' + enum.name + ' : ' + enum.underlying_type + '; }')
if enum.condition is not None:
result.append('#endif')
for type in serialized_types:
if type.nested:
continue
if type.condition is not None:
result.append('#if ' + type.condition)
if type.namespace is None:
Expand All @@ -176,26 +209,15 @@ def generate_header(serialized_types, serialized_enums):
result.append('class Decoder;')
result.append('class Encoder;')
result.append('class StreamConnectionEncoder;')
for type in serialized_types:
result.append('')
if type.condition is not None:
result.append('#if ' + type.condition)
result.append('template<> struct ArgumentCoder<' + type.namespace_and_name() + '> {')
for encoder in type.encoders:
result.append(' static void encode(' + encoder + '&, const ' + type.namespace_and_name() + '&);')
if type.return_ref:
result.append(' static std::optional<Ref<' + type.namespace_and_name() + '>> decode(Decoder&);')
else:
result.append(' static std::optional<' + type.namespace_and_name() + '> decode(Decoder&);')
result.append('};')
if type.condition is not None:
result.append('#endif')
result = result + argument_coder_declarations(serialized_types, True)
result.append('')
result.append('} // namespace IPC\n')
result.append('')
result.append('namespace WTF {')
result.append('')
for enum in serialized_enums:
if enum.is_nested():
continue
if enum.underlying_type == 'bool':
continue
if enum.condition is not None:
Expand Down Expand Up @@ -237,6 +259,9 @@ def generate_impl(serialized_types, serialized_enums, headers):
result.append('#endif')
result.append('')
result.append('namespace IPC {')
result.append('')
result = result + argument_coder_declarations(serialized_types, False)
result.append('')
for type in serialized_types:
result.append('')
if type.condition is not None:
Expand Down Expand Up @@ -479,7 +504,7 @@ def parse_serialized_types(file, file_name):
serialized_enums.append(SerializedEnum(namespace, name, underlying_type, members, type_condition, attributes))
else:
serialized_types.append(SerializedType(struct_or_class, namespace, name, parent_class, members, type_condition, attributes))
if namespace is not None and (attributes is None or 'CustomHeader=True' not in attributes):
if namespace is not None and (attributes is None or 'CustomHeader' not in attributes and 'Nested' not in attributes):
if namespace == 'WebKit':
headers.append(ConditionalHeader('"' + name + '.h"', type_condition))
elif namespace == 'WebKit::WebGPU':
Expand Down
8 changes: 7 additions & 1 deletion Source/WebKit/Scripts/webkit/tests/GeneratedSerializers.cpp
Expand Up @@ -37,12 +37,18 @@
#endif
#include <Namespace/EmptyConstructorNullable.h>
#include <Namespace/EmptyConstructorStruct.h>
#include <Namespace/OtherClass.h>
#include <Namespace/ReturnRefClass.h>
#include <WebCore/InheritsFrom.h>

namespace IPC {


template<> struct ArgumentCoder<Namespace::OtherClass> {
static void encode(Encoder&, const Namespace::OtherClass&);
static std::optional<Namespace::OtherClass> decode(Decoder&);
};


#if ENABLE(TEST_FEATURE)

void ArgumentCoder<Namespace::Subnamespace::StructName>::encode(Encoder& encoder, const Namespace::Subnamespace::StructName& instance)
Expand Down
8 changes: 0 additions & 8 deletions Source/WebKit/Scripts/webkit/tests/GeneratedSerializers.h
Expand Up @@ -34,11 +34,9 @@ namespace EnumNamespace { enum class BoolEnumType : bool; }
#if ENABLE(UINT16_ENUM)
namespace EnumNamespace { enum class EnumType : uint16_t; }
#endif
namespace EnumNamespace2 { enum class OptionSetEnumType : uint8_t; }
#if ENABLE(TEST_FEATURE)
namespace Namespace::Subnamespace { struct StructName; }
#endif
namespace Namespace { class OtherClass; }
namespace Namespace { class ReturnRefClass; }
namespace Namespace { struct EmptyConstructorStruct; }
namespace Namespace { class EmptyConstructorNullable; }
Expand All @@ -60,11 +58,6 @@ template<> struct ArgumentCoder<Namespace::Subnamespace::StructName> {
};
#endif

template<> struct ArgumentCoder<Namespace::OtherClass> {
static void encode(Encoder&, const Namespace::OtherClass&);
static std::optional<Namespace::OtherClass> decode(Decoder&);
};

template<> struct ArgumentCoder<Namespace::ReturnRefClass> {
static void encode(Encoder&, const Namespace::ReturnRefClass&);
static std::optional<Ref<Namespace::ReturnRefClass>> decode(Decoder&);
Expand Down Expand Up @@ -104,6 +97,5 @@ namespace WTF {
#if ENABLE(UINT16_ENUM)
template<> bool isValidEnum<EnumNamespace::EnumType, void>(uint16_t);
#endif
template<> bool isValidOptionSet<EnumNamespace2::OptionSetEnumType>(OptionSet<EnumNamespace2::OptionSetEnumType>);

} // namespace WTF
1 change: 0 additions & 1 deletion Source/WebKit/Scripts/webkit/tests/SerializedTypeInfo.cpp
Expand Up @@ -37,7 +37,6 @@
#endif
#include <Namespace/EmptyConstructorNullable.h>
#include <Namespace/EmptyConstructorStruct.h>
#include <Namespace/OtherClass.h>
#include <Namespace/ReturnRefClass.h>
#include <WebCore/InheritsFrom.h>

Expand Down
Expand Up @@ -13,7 +13,7 @@ headers: "StructHeader.h" "FirstMemberType.h" "SecondMemberType.h"
}
#endif

class Namespace::OtherClass {
[Nested] class Namespace::OtherClass {
[ReturnEarlyIfTrue] bool isNull
int a
bool b
Expand Down Expand Up @@ -63,7 +63,7 @@ enum class EnumNamespace::EnumType : uint16_t {
}
#endif

[OptionSet] enum class EnumNamespace2::OptionSetEnumType : uint8_t {
[OptionSet, Nested] enum class EnumNamespace2::OptionSetEnumType : uint8_t {
OptionSetFirstValue,
#if ENABLE(OPTION_SET_SECOND_VALUE)
OptionSetSecondValue,
Expand Down
33 changes: 33 additions & 0 deletions Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
Expand Up @@ -682,3 +682,36 @@ struct WebCore::ApplePayCouponCodeUpdate : WebCore::ApplePayDetailsUpdateBase {
Vector<WebCore::ApplePayShippingMethod> newShippingMethods;
};
#endif

#if ENABLE(APPLICATION_MANIFEST)
[Nested] enum class WebCore::ApplicationManifest::Display : uint8_t {
Browser
MinimalUI
Standalone
Fullscreen
};

[Nested, OptionSet] enum class WebCore::ApplicationManifest::Icon::Purpose : uint8_t {
Any
Monochrome
Maskable
}

[Nested] struct WebCore::ApplicationManifest::Icon {
URL src
Vector<String> sizes
String type
OptionSet<WebCore::ApplicationManifest::Icon::Purpose> purposes
}

struct WebCore::ApplicationManifest {
String name
String shortName
String description
URL scope
WebCore::ApplicationManifest::Display display
URL startURL
WebCore::Color themeColor
Vector<WebCore::ApplicationManifest::Icon> icons
}
#endif // ENABLE(APPLICATION_MANIFEST)

0 comments on commit 58c2188

Please sign in to comment.