mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
LibWeb: Generate property_accepts_[identifier/type]()
functions
These will be used to parse StyleValues more intelligently.
This commit is contained in:
parent
6f3e48db57
commit
9b61f79eae
|
@ -1,11 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GeneratorUtil.h"
|
#include "GeneratorUtil.h"
|
||||||
|
#include <AK/GenericShorthands.h>
|
||||||
#include <AK/SourceGenerator.h>
|
#include <AK/SourceGenerator.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibCore/ArgsParser.h>
|
#include <LibCore/ArgsParser.h>
|
||||||
|
@ -14,6 +15,11 @@
|
||||||
ErrorOr<void> generate_header_file(JsonObject& properties, Core::File& file);
|
ErrorOr<void> generate_header_file(JsonObject& properties, Core::File& file);
|
||||||
ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& file);
|
ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& file);
|
||||||
|
|
||||||
|
static bool type_name_is_enum(StringView type_name)
|
||||||
|
{
|
||||||
|
return !AK::first_is_one_of(type_name, "angle"sv, "color"sv, "frequency"sv, "image"sv, "integer"sv, "length"sv, "number"sv, "percentage"sv, "rect"sv, "resolution"sv, "string"sv, "time"sv, "url"sv);
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
StringView generated_header_path;
|
StringView generated_header_path;
|
||||||
|
@ -109,6 +115,26 @@ StringView string_from_property_id(PropertyID);
|
||||||
bool is_inherited_property(PropertyID);
|
bool is_inherited_property(PropertyID);
|
||||||
ErrorOr<NonnullRefPtr<StyleValue>> property_initial_value(JS::Realm&, PropertyID);
|
ErrorOr<NonnullRefPtr<StyleValue>> property_initial_value(JS::Realm&, PropertyID);
|
||||||
|
|
||||||
|
enum class ValueType {
|
||||||
|
Angle,
|
||||||
|
Color,
|
||||||
|
FilterValueList,
|
||||||
|
Frequency,
|
||||||
|
Image,
|
||||||
|
Integer,
|
||||||
|
Length,
|
||||||
|
Number,
|
||||||
|
Paint,
|
||||||
|
Percentage,
|
||||||
|
Position,
|
||||||
|
Rect,
|
||||||
|
Resolution,
|
||||||
|
String,
|
||||||
|
Time,
|
||||||
|
Url,
|
||||||
|
};
|
||||||
|
bool property_accepts_type(PropertyID, ValueType);
|
||||||
|
bool property_accepts_identifier(PropertyID, ValueID);
|
||||||
bool property_accepts_value(PropertyID, StyleValue&);
|
bool property_accepts_value(PropertyID, StyleValue&);
|
||||||
size_t property_maximum_value_count(PropertyID);
|
size_t property_maximum_value_count(PropertyID);
|
||||||
|
|
||||||
|
@ -403,6 +429,132 @@ bool property_has_quirk(PropertyID property_id, Quirk quirk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool property_accepts_type(PropertyID property_id, ValueType value_type)
|
||||||
|
{
|
||||||
|
switch (property_id) {
|
||||||
|
)~~~");
|
||||||
|
properties.for_each_member([&](auto& name, auto& value) {
|
||||||
|
VERIFY(value.is_object());
|
||||||
|
auto& object = value.as_object();
|
||||||
|
if (auto maybe_valid_types = object.get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) {
|
||||||
|
auto& valid_types = maybe_valid_types.value();
|
||||||
|
auto property_generator = generator.fork();
|
||||||
|
property_generator.set("name:titlecase", title_casify(name));
|
||||||
|
property_generator.append(R"~~~(
|
||||||
|
case PropertyID::@name:titlecase@: {
|
||||||
|
switch (value_type) {
|
||||||
|
)~~~");
|
||||||
|
|
||||||
|
bool did_output_accepted_type = false;
|
||||||
|
for (auto& type : valid_types.values()) {
|
||||||
|
VERIFY(type.is_string());
|
||||||
|
auto type_name = type.as_string().split_view(' ').first();
|
||||||
|
if (type_name_is_enum(type_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (type_name == "angle") {
|
||||||
|
property_generator.appendln(" case ValueType::Angle:");
|
||||||
|
} else if (type_name == "color") {
|
||||||
|
property_generator.appendln(" case ValueType::Color:");
|
||||||
|
} else if (type_name == "frequency") {
|
||||||
|
property_generator.appendln(" case ValueType::Frequency:");
|
||||||
|
} else if (type_name == "image") {
|
||||||
|
property_generator.appendln(" case ValueType::Image:");
|
||||||
|
} else if (type_name == "integer") {
|
||||||
|
property_generator.appendln(" case ValueType::Integer:");
|
||||||
|
} else if (type_name == "length") {
|
||||||
|
property_generator.appendln(" case ValueType::Length:");
|
||||||
|
} else if (type_name == "number") {
|
||||||
|
property_generator.appendln(" case ValueType::Number:");
|
||||||
|
} else if (type_name == "percentage") {
|
||||||
|
property_generator.appendln(" case ValueType::Percentage:");
|
||||||
|
} else if (type_name == "rect") {
|
||||||
|
property_generator.appendln(" case ValueType::Rect:");
|
||||||
|
} else if (type_name == "resolution") {
|
||||||
|
property_generator.appendln(" case ValueType::Resolution:");
|
||||||
|
} else if (type_name == "string") {
|
||||||
|
property_generator.appendln(" case ValueType::String:");
|
||||||
|
} else if (type_name == "time") {
|
||||||
|
property_generator.appendln(" case ValueType::Time:");
|
||||||
|
} else if (type_name == "url") {
|
||||||
|
property_generator.appendln(" case ValueType::Url:");
|
||||||
|
} else {
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
did_output_accepted_type = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (did_output_accepted_type)
|
||||||
|
property_generator.appendln(" return true;");
|
||||||
|
|
||||||
|
property_generator.append(R"~~~(
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
generator.append(R"~~~(
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool property_accepts_identifier(PropertyID property_id, ValueID identifier)
|
||||||
|
{
|
||||||
|
switch (property_id) {
|
||||||
|
)~~~");
|
||||||
|
properties.for_each_member([&](auto& name, auto& value) {
|
||||||
|
VERIFY(value.is_object());
|
||||||
|
auto& object = value.as_object();
|
||||||
|
|
||||||
|
auto property_generator = generator.fork();
|
||||||
|
property_generator.set("name:titlecase", title_casify(name));
|
||||||
|
property_generator.appendln(" case PropertyID::@name:titlecase@: {");
|
||||||
|
|
||||||
|
if (auto maybe_valid_identifiers = object.get_array("valid-identifiers"sv); maybe_valid_identifiers.has_value() && !maybe_valid_identifiers->is_empty()) {
|
||||||
|
property_generator.appendln(" switch (identifier) {");
|
||||||
|
auto& valid_identifiers = maybe_valid_identifiers.value();
|
||||||
|
for (auto& identifier : valid_identifiers.values()) {
|
||||||
|
auto identifier_generator = generator.fork();
|
||||||
|
identifier_generator.set("identifier:titlecase", title_casify(identifier.as_string()));
|
||||||
|
identifier_generator.appendln(" case ValueID::@identifier:titlecase@:");
|
||||||
|
}
|
||||||
|
property_generator.append(R"~~~(
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto maybe_valid_types = object.get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) {
|
||||||
|
auto& valid_types = maybe_valid_types.value();
|
||||||
|
for (auto& valid_type : valid_types.values()) {
|
||||||
|
auto type_name = valid_type.as_string().split_view(' ').first();
|
||||||
|
if (!type_name_is_enum(type_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto type_generator = generator.fork();
|
||||||
|
type_generator.set("type_name:snakecase", snake_casify(type_name));
|
||||||
|
type_generator.append(R"~~~(
|
||||||
|
if (value_id_to_@type_name:snakecase@(identifier).has_value())
|
||||||
|
return true;
|
||||||
|
)~~~");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property_generator.append(R"~~~(
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
)~~~");
|
||||||
|
});
|
||||||
|
generator.append(R"~~~(
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
|
bool property_accepts_value(PropertyID property_id, StyleValue& style_value)
|
||||||
{
|
{
|
||||||
if (style_value.is_builtin())
|
if (style_value.is_builtin())
|
||||||
|
|
Loading…
Reference in a new issue