Meta+LibWeb: Port PropertyID.h/cpp generators to invoke_generator()

This commit is contained in:
Sam Atkins 2022-04-01 17:41:43 +01:00 committed by Tim Flynn
parent fc81d6c9f3
commit b07659d00c
Notes: sideshowbarker 2024-07-17 16:19:45 +09:00
4 changed files with 140 additions and 157 deletions

View file

@ -1,8 +1,7 @@
set(SOURCES "") # avoid pulling SOURCES from parent scope
lagom_tool(GenerateCSSMediaFeatureID SOURCES GenerateCSSMediaFeatureID.cpp LIBS LagomMain)
lagom_tool(Generate_CSS_PropertyID_h SOURCES Generate_CSS_PropertyID_h.cpp LIBS LagomMain)
lagom_tool(Generate_CSS_PropertyID_cpp SOURCES Generate_CSS_PropertyID_cpp.cpp LIBS LagomMain)
lagom_tool(GenerateCSSPropertyID SOURCES GenerateCSSPropertyID.cpp LIBS LagomMain)
lagom_tool(GenerateCSSValueID SOURCES GenerateCSSValueID.cpp LIBS LagomMain)
add_subdirectory(WrapperGenerator)

View file

@ -6,23 +6,145 @@
*/
#include "GeneratorUtil.h"
#include <AK/Array.h>
#include <AK/SourceGenerator.h>
#include <AK/StringBuilder.h>
#include <LibCore/ArgsParser.h>
#include <LibMain/Main.h>
ErrorOr<void> generate_header_file(JsonObject& properties, Core::Stream::File& file);
ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::Stream::File& file);
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
if (arguments.argc != 2) {
warnln("usage: {} <path/to/CSS/Properties.json>", arguments.strings[0]);
return 1;
StringView generated_header_path;
StringView generated_implementation_path;
StringView properties_json_path;
Core::ArgsParser args_parser;
args_parser.add_option(generated_header_path, "Path to the PropertyID header file to generate", "generated-header-path", 'h', "generated-header-path");
args_parser.add_option(generated_implementation_path, "Path to the PropertyID implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path");
args_parser.add_option(properties_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path");
args_parser.parse(arguments);
auto json = TRY(read_entire_file_as_json(properties_json_path));
VERIFY(json.is_object());
auto properties = json.as_object();
auto generated_header_file = TRY(Core::Stream::File::open(generated_header_path, Core::Stream::OpenMode::Write));
auto generated_implementation_file = TRY(Core::Stream::File::open(generated_implementation_path, Core::Stream::OpenMode::Write));
TRY(generate_header_file(properties, *generated_header_file));
TRY(generate_implementation_file(properties, *generated_implementation_file));
return 0;
}
ErrorOr<void> generate_header_file(JsonObject& properties, Core::Stream::File& file)
{
StringBuilder builder;
SourceGenerator generator { builder };
generator.append(R"~~~(
#pragma once
#include <AK/NonnullRefPtr.h>
#include <AK/StringView.h>
#include <AK/Traits.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
enum class PropertyID {
Invalid,
Custom,
)~~~");
Vector<String> shorthand_property_ids;
Vector<String> longhand_property_ids;
properties.for_each_member([&](auto& name, auto& value) {
VERIFY(value.is_object());
if (value.as_object().has("longhands"))
shorthand_property_ids.append(name);
else
longhand_property_ids.append(name);
});
auto first_property_id = shorthand_property_ids.first();
auto last_property_id = longhand_property_ids.last();
for (auto& name : shorthand_property_ids) {
auto member_generator = generator.fork();
member_generator.set("name:titlecase", title_casify(name));
member_generator.append(R"~~~(
@name:titlecase@,
)~~~");
}
auto json = TRY(read_entire_file_as_json(arguments.strings[1]));
VERIFY(json.is_object());
for (auto& name : longhand_property_ids) {
auto member_generator = generator.fork();
member_generator.set("name:titlecase", title_casify(name));
auto& properties = json.as_object();
member_generator.append(R"~~~(
@name:titlecase@,
)~~~");
}
generator.set("first_property_id", title_casify(first_property_id));
generator.set("last_property_id", title_casify(last_property_id));
generator.set("first_shorthand_property_id", title_casify(shorthand_property_ids.first()));
generator.set("last_shorthand_property_id", title_casify(shorthand_property_ids.last()));
generator.set("first_longhand_property_id", title_casify(longhand_property_ids.first()));
generator.set("last_longhand_property_id", title_casify(longhand_property_ids.last()));
generator.append(R"~~~(
};
PropertyID property_id_from_camel_case_string(StringView);
PropertyID property_id_from_string(StringView);
const char* string_from_property_id(PropertyID);
bool is_inherited_property(PropertyID);
NonnullRefPtr<StyleValue> property_initial_value(PropertyID);
bool property_accepts_value(PropertyID, StyleValue&);
size_t property_maximum_value_count(PropertyID);
bool property_affects_layout(PropertyID);
bool property_affects_stacking_context(PropertyID);
constexpr PropertyID first_property_id = PropertyID::@first_property_id@;
constexpr PropertyID last_property_id = PropertyID::@last_property_id@;
constexpr PropertyID first_shorthand_property_id = PropertyID::@first_shorthand_property_id@;
constexpr PropertyID last_shorthand_property_id = PropertyID::@last_shorthand_property_id@;
constexpr PropertyID first_longhand_property_id = PropertyID::@first_longhand_property_id@;
constexpr PropertyID last_longhand_property_id = PropertyID::@last_longhand_property_id@;
enum class Quirk {
// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
HashlessHexColor,
// https://quirks.spec.whatwg.org/#the-unitless-length-quirk
UnitlessLength,
};
bool property_has_quirk(PropertyID, Quirk);
} // namespace Web::CSS
namespace AK {
template<>
struct Traits<Web::CSS::PropertyID> : public GenericTraits<Web::CSS::PropertyID> {
static unsigned hash(Web::CSS::PropertyID property_id) { return int_hash((unsigned)property_id); }
};
} // namespace AK
)~~~");
TRY(file.write(generator.as_string_view().bytes()));
return {};
}
ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::Stream::File& file)
{
StringBuilder builder;
SourceGenerator generator { builder };
@ -465,6 +587,6 @@ size_t property_maximum_value_count(PropertyID property_id)
)~~~");
outln("{}", generator.as_string_view());
return 0;
TRY(file.write(generator.as_string_view().bytes()));
return {};
}

View file

@ -1,122 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "GeneratorUtil.h"
#include <AK/SourceGenerator.h>
#include <AK/StringBuilder.h>
#include <LibMain/Main.h>
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
if (arguments.argc != 2) {
warnln("usage: {} <path/to/CSS/Properties.json>", arguments.strings[0]);
return 1;
}
auto json = TRY(read_entire_file_as_json(arguments.strings[1]));
VERIFY(json.is_object());
StringBuilder builder;
SourceGenerator generator { builder };
generator.append(R"~~~(
#pragma once
#include <AK/NonnullRefPtr.h>
#include <AK/StringView.h>
#include <AK/Traits.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
enum class PropertyID {
Invalid,
Custom,
)~~~");
Vector<String> shorthand_property_ids;
Vector<String> longhand_property_ids;
json.as_object().for_each_member([&](auto& name, auto& value) {
VERIFY(value.is_object());
if (value.as_object().has("longhands"))
shorthand_property_ids.append(name);
else
longhand_property_ids.append(name);
});
auto first_property_id = shorthand_property_ids.first();
auto last_property_id = longhand_property_ids.last();
for (auto& name : shorthand_property_ids) {
auto member_generator = generator.fork();
member_generator.set("name:titlecase", title_casify(name));
member_generator.append(R"~~~(
@name:titlecase@,
)~~~");
}
for (auto& name : longhand_property_ids) {
auto member_generator = generator.fork();
member_generator.set("name:titlecase", title_casify(name));
member_generator.append(R"~~~(
@name:titlecase@,
)~~~");
}
generator.set("first_property_id", title_casify(first_property_id));
generator.set("last_property_id", title_casify(last_property_id));
generator.set("first_shorthand_property_id", title_casify(shorthand_property_ids.first()));
generator.set("last_shorthand_property_id", title_casify(shorthand_property_ids.last()));
generator.set("first_longhand_property_id", title_casify(longhand_property_ids.first()));
generator.set("last_longhand_property_id", title_casify(longhand_property_ids.last()));
generator.append(R"~~~(
};
PropertyID property_id_from_camel_case_string(StringView);
PropertyID property_id_from_string(StringView);
const char* string_from_property_id(PropertyID);
bool is_inherited_property(PropertyID);
NonnullRefPtr<StyleValue> property_initial_value(PropertyID);
bool property_accepts_value(PropertyID, StyleValue&);
size_t property_maximum_value_count(PropertyID);
bool property_affects_layout(PropertyID);
bool property_affects_stacking_context(PropertyID);
constexpr PropertyID first_property_id = PropertyID::@first_property_id@;
constexpr PropertyID last_property_id = PropertyID::@last_property_id@;
constexpr PropertyID first_shorthand_property_id = PropertyID::@first_shorthand_property_id@;
constexpr PropertyID last_shorthand_property_id = PropertyID::@last_shorthand_property_id@;
constexpr PropertyID first_longhand_property_id = PropertyID::@first_longhand_property_id@;
constexpr PropertyID last_longhand_property_id = PropertyID::@last_longhand_property_id@;
enum class Quirk {
// https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
HashlessHexColor,
// https://quirks.spec.whatwg.org/#the-unitless-length-quirk
UnitlessLength,
};
bool property_has_quirk(PropertyID, Quirk);
} // namespace Web::CSS
namespace AK {
template<>
struct Traits<Web::CSS::PropertyID> : public GenericTraits<Web::CSS::PropertyID> {
static unsigned hash(Web::CSS::PropertyID property_id) { return int_hash((unsigned)property_id); }
};
} // namespace AK
)~~~");
outln("{}", generator.as_string_view());
return 0;
}

View file

@ -612,31 +612,15 @@ invoke_generator(
arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/MediaFeatures.json"
)
add_custom_command(
OUTPUT CSS/PropertyID.h
COMMAND ${CMAKE_COMMAND} -E make_directory CSS
COMMAND "$<TARGET_FILE:Lagom::Generate_CSS_PropertyID_h>" "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json" > CSS/PropertyID.h.tmp
COMMAND "${CMAKE_COMMAND}" -E copy_if_different CSS/PropertyID.h.tmp CSS/PropertyID.h
COMMAND "${CMAKE_COMMAND}" -E remove CSS/PropertyID.h.tmp
VERBATIM
DEPENDS Lagom::Generate_CSS_PropertyID_h
MAIN_DEPENDENCY CSS/Properties.json
invoke_generator(
"PropertyID"
Lagom::GenerateCSSPropertyID
"${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json"
""
"CSS/PropertyID.h"
"CSS/PropertyID.cpp"
arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json"
)
add_custom_target(generate_PropertyID.h DEPENDS CSS/PropertyID.h)
add_dependencies(all_generated generate_PropertyID.h)
add_custom_command(
OUTPUT CSS/PropertyID.cpp
COMMAND ${CMAKE_COMMAND} -E make_directory CSS
COMMAND "$<TARGET_FILE:Lagom::Generate_CSS_PropertyID_cpp>" "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json" > CSS/PropertyID.cpp.tmp
COMMAND "${CMAKE_COMMAND}" -E copy_if_different CSS/PropertyID.cpp.tmp CSS/PropertyID.cpp
COMMAND "${CMAKE_COMMAND}" -E remove CSS/PropertyID.cpp.tmp
VERBATIM
DEPENDS Lagom::Generate_CSS_PropertyID_cpp
MAIN_DEPENDENCY CSS/Properties.json
)
add_custom_target(generate_PropertyID.cpp DEPENDS CSS/PropertyID.cpp)
add_dependencies(all_generated generate_PropertyID.cpp)
invoke_generator(
"ValueID"