mirror of
https://github.com/RGBCube/serenity
synced 2025-05-25 16:25:08 +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
|
set(SOURCES "") # avoid pulling SOURCES from parent scope
|
||||||
|
|
||||||
lagom_tool(GenerateCSSMediaFeatureID SOURCES GenerateCSSMediaFeatureID.cpp LIBS LagomMain)
|
lagom_tool(GenerateCSSMediaFeatureID SOURCES GenerateCSSMediaFeatureID.cpp LIBS LagomMain)
|
||||||
lagom_tool(Generate_CSS_PropertyID_h SOURCES Generate_CSS_PropertyID_h.cpp LIBS LagomMain)
|
lagom_tool(GenerateCSSPropertyID SOURCES GenerateCSSPropertyID.cpp LIBS LagomMain)
|
||||||
lagom_tool(Generate_CSS_PropertyID_cpp SOURCES Generate_CSS_PropertyID_cpp.cpp LIBS LagomMain)
|
|
||||||
lagom_tool(GenerateCSSValueID SOURCES GenerateCSSValueID.cpp LIBS LagomMain)
|
lagom_tool(GenerateCSSValueID SOURCES GenerateCSSValueID.cpp LIBS LagomMain)
|
||||||
|
|
||||||
add_subdirectory(WrapperGenerator)
|
add_subdirectory(WrapperGenerator)
|
||||||
|
|
|
@ -6,23 +6,145 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GeneratorUtil.h"
|
#include "GeneratorUtil.h"
|
||||||
#include <AK/Array.h>
|
|
||||||
#include <AK/SourceGenerator.h>
|
#include <AK/SourceGenerator.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <LibCore/ArgsParser.h>
|
||||||
#include <LibMain/Main.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)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
if (arguments.argc != 2) {
|
StringView generated_header_path;
|
||||||
warnln("usage: {} <path/to/CSS/Properties.json>", arguments.strings[0]);
|
StringView generated_implementation_path;
|
||||||
return 1;
|
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]));
|
for (auto& name : longhand_property_ids) {
|
||||||
VERIFY(json.is_object());
|
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;
|
StringBuilder builder;
|
||||||
SourceGenerator generator { builder };
|
SourceGenerator generator { builder };
|
||||||
|
|
||||||
|
@ -465,6 +587,6 @@ size_t property_maximum_value_count(PropertyID property_id)
|
||||||
|
|
||||||
)~~~");
|
)~~~");
|
||||||
|
|
||||||
outln("{}", generator.as_string_view());
|
TRY(file.write(generator.as_string_view().bytes()));
|
||||||
return 0;
|
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"
|
arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/MediaFeatures.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(
|
invoke_generator(
|
||||||
OUTPUT CSS/PropertyID.h
|
"PropertyID"
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory CSS
|
Lagom::GenerateCSSPropertyID
|
||||||
COMMAND "$<TARGET_FILE:Lagom::Generate_CSS_PropertyID_h>" "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json" > CSS/PropertyID.h.tmp
|
"${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json"
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different CSS/PropertyID.h.tmp CSS/PropertyID.h
|
""
|
||||||
COMMAND "${CMAKE_COMMAND}" -E remove CSS/PropertyID.h.tmp
|
"CSS/PropertyID.h"
|
||||||
VERBATIM
|
"CSS/PropertyID.cpp"
|
||||||
DEPENDS Lagom::Generate_CSS_PropertyID_h
|
arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json"
|
||||||
MAIN_DEPENDENCY 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(
|
invoke_generator(
|
||||||
"ValueID"
|
"ValueID"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue