mirror of
https://github.com/RGBCube/serenity
synced 2025-05-25 16:35:06 +00:00
Meta+LibWeb: Port PropertyID.h/cpp generators to invoke_generator()
This commit is contained in:
parent
fc81d6c9f3
commit
b07659d00c
4 changed files with 140 additions and 157 deletions
|
@ -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)
|
||||
|
|
|
@ -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 {};
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue