mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:52:46 +00:00 
			
		
		
		
	LibWeb: Stop using fallible JSON API in code generators
This commit is contained in:
		
							parent
							
								
									20ea82bacc
								
							
						
					
					
						commit
						788c2c5a8d
					
				
					 9 changed files with 199 additions and 258 deletions
				
			
		|  | @ -51,7 +51,7 @@ ErrorOr<void> generate_header_file(JsonObject& roles_data, Core::File& file) | ||||||
| namespace Web::ARIA { | namespace Web::ARIA { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(roles_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     roles_data.for_each_member([&](auto& name, auto& value) -> void { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         JsonObject const& value_object = value.as_object(); |         JsonObject const& value_object = value.as_object(); | ||||||
| 
 | 
 | ||||||
|  | @ -67,14 +67,13 @@ class @name@ : | ||||||
| 
 | 
 | ||||||
|         JsonArray const& super_classes = value_object.get_array("superClassRoles"sv).value(); |         JsonArray const& super_classes = value_object.get_array("superClassRoles"sv).value(); | ||||||
|         bool first = true; |         bool first = true; | ||||||
|         TRY(super_classes.try_for_each([&](JsonValue const& value) -> ErrorOr<void> { |         super_classes.for_each([&](JsonValue const& value) { | ||||||
|             VERIFY(value.is_string()); |             VERIFY(value.is_string()); | ||||||
| 
 | 
 | ||||||
|             class_definition_generator.append(first ? " "sv : ", "sv); |             class_definition_generator.append(first ? " "sv : ", "sv); | ||||||
|             class_definition_generator.append(TRY(String::formatted("public {}", value.as_string()))); |             class_definition_generator.append(MUST(String::formatted("public {}", value.as_string()))); | ||||||
|             first = false; |             first = false; | ||||||
|             return {}; |         }); | ||||||
|         })); |  | ||||||
| 
 | 
 | ||||||
|         class_definition_generator.append(R"~~~( |         class_definition_generator.append(R"~~~( | ||||||
| { | { | ||||||
|  | @ -106,8 +105,7 @@ public: | ||||||
|     virtual NameFromSource name_from_source() const override; |     virtual NameFromSource name_from_source() const override; | ||||||
| )~~~"); | )~~~"); | ||||||
|         class_definition_generator.appendln("};"); |         class_definition_generator.appendln("};"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.appendln("}"); |     generator.appendln("}"); | ||||||
| 
 | 
 | ||||||
|  | @ -115,25 +113,24 @@ public: | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<String> generate_hash_table_population(JsonArray const& values, StringView hash_table_name, StringView enum_class) | String generate_hash_table_population(JsonArray const& values, StringView hash_table_name, StringView enum_class) | ||||||
| { | { | ||||||
|     StringBuilder builder; |     StringBuilder builder; | ||||||
|     TRY(values.try_for_each([&](auto& value) -> ErrorOr<void> { |     values.for_each([&](auto& value) { | ||||||
|         VERIFY(value.is_string()); |         VERIFY(value.is_string()); | ||||||
|         TRY(builder.try_appendff("        {}.set({}::{});\n", hash_table_name, enum_class, value.as_string())); |         builder.appendff("        {}.set({}::{});\n", hash_table_name, enum_class, value.as_string()); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     return builder.to_string(); |     return MUST(builder.to_string()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> generate_hash_table_member(SourceGenerator& generator, StringView member_name, StringView hash_table_name, StringView enum_class, JsonArray const& values) | void generate_hash_table_member(SourceGenerator& generator, StringView member_name, StringView hash_table_name, StringView enum_class, JsonArray const& values) | ||||||
| { | { | ||||||
|     auto member_generator = generator.fork(); |     auto member_generator = generator.fork(); | ||||||
|     member_generator.set("member_name"sv, member_name); |     member_generator.set("member_name"sv, member_name); | ||||||
|     member_generator.set("hash_table_name"sv, hash_table_name); |     member_generator.set("hash_table_name"sv, hash_table_name); | ||||||
|     member_generator.set("enum_class"sv, enum_class); |     member_generator.set("enum_class"sv, enum_class); | ||||||
|     member_generator.set("hash_table_size"sv, TRY(String::number(values.size()))); |     member_generator.set("hash_table_size"sv, MUST(String::number(values.size()))); | ||||||
| 
 | 
 | ||||||
|     if (values.size() == 0) { |     if (values.size() == 0) { | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|  | @ -143,7 +140,7 @@ HashTable<@enum_class@> const& @name@::@member_name@() const | ||||||
|     return @hash_table_name@; |     return @hash_table_name@; | ||||||
| } | } | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     member_generator.append(R"~~~( |     member_generator.append(R"~~~( | ||||||
|  | @ -153,14 +150,12 @@ HashTable<@enum_class@> const& @name@::@member_name@() const | ||||||
|     if (@hash_table_name@.is_empty()) { |     if (@hash_table_name@.is_empty()) { | ||||||
|         @hash_table_name@.ensure_capacity(@hash_table_size@); |         @hash_table_name@.ensure_capacity(@hash_table_size@); | ||||||
| )~~~"); | )~~~"); | ||||||
|     member_generator.append(TRY(generate_hash_table_population(values, hash_table_name, enum_class))); |     member_generator.append(generate_hash_table_population(values, hash_table_name, enum_class)); | ||||||
|     member_generator.append(R"~~~( |     member_generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|     return @hash_table_name@; |     return @hash_table_name@; | ||||||
| } | } | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 |  | ||||||
|     return {}; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| StringView aria_name_to_enum_name(StringView name) | StringView aria_name_to_enum_name(StringView name) | ||||||
|  | @ -266,15 +261,14 @@ StringView aria_name_to_enum_name(StringView name) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<JsonArray> translate_aria_names_to_enum(JsonArray const& names) | JsonArray translate_aria_names_to_enum(JsonArray const& names) | ||||||
| { | { | ||||||
|     JsonArray translated_names; |     JsonArray translated_names; | ||||||
|     TRY(names.try_for_each([&](JsonValue const& value) -> ErrorOr<void> { |     names.for_each([&](JsonValue const& value) { | ||||||
|         VERIFY(value.is_string()); |         VERIFY(value.is_string()); | ||||||
|         auto name = value.as_string(); |         auto name = value.as_string(); | ||||||
|         TRY(translated_names.append(aria_name_to_enum_name(name))); |         MUST(translated_names.append(aria_name_to_enum_name(name))); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     return translated_names; |     return translated_names; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -289,7 +283,7 @@ ErrorOr<void> generate_implementation_file(JsonObject& roles_data, Core::File& f | ||||||
| namespace Web::ARIA { | namespace Web::ARIA { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(roles_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     roles_data.for_each_member([&](auto& name, auto& value) -> void { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|  | @ -297,25 +291,25 @@ namespace Web::ARIA { | ||||||
| 
 | 
 | ||||||
|         JsonObject const& value_object = value.as_object(); |         JsonObject const& value_object = value.as_object(); | ||||||
| 
 | 
 | ||||||
|         JsonArray const& supported_states = TRY(translate_aria_names_to_enum(value_object.get_array("supportedStates"sv).value())); |         JsonArray const& supported_states = translate_aria_names_to_enum(value_object.get_array("supportedStates"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "supported_states"sv, "states"sv, "StateAndProperties"sv, supported_states)); |         generate_hash_table_member(member_generator, "supported_states"sv, "states"sv, "StateAndProperties"sv, supported_states); | ||||||
|         JsonArray const& supported_properties = TRY(translate_aria_names_to_enum(value_object.get_array("supportedProperties"sv).value())); |         JsonArray const& supported_properties = translate_aria_names_to_enum(value_object.get_array("supportedProperties"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "supported_properties"sv, "properties"sv, "StateAndProperties"sv, supported_properties)); |         generate_hash_table_member(member_generator, "supported_properties"sv, "properties"sv, "StateAndProperties"sv, supported_properties); | ||||||
| 
 | 
 | ||||||
|         JsonArray const& required_states = TRY(translate_aria_names_to_enum(value_object.get_array("requiredStates"sv).value())); |         JsonArray const& required_states = translate_aria_names_to_enum(value_object.get_array("requiredStates"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "required_states"sv, "states"sv, "StateAndProperties"sv, required_states)); |         generate_hash_table_member(member_generator, "required_states"sv, "states"sv, "StateAndProperties"sv, required_states); | ||||||
|         JsonArray const& required_properties = TRY(translate_aria_names_to_enum(value_object.get_array("requiredProperties"sv).value())); |         JsonArray const& required_properties = translate_aria_names_to_enum(value_object.get_array("requiredProperties"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "required_properties"sv, "properties"sv, "StateAndProperties"sv, required_properties)); |         generate_hash_table_member(member_generator, "required_properties"sv, "properties"sv, "StateAndProperties"sv, required_properties); | ||||||
| 
 | 
 | ||||||
|         JsonArray const& prohibited_states = TRY(translate_aria_names_to_enum(value_object.get_array("prohibitedStates"sv).value())); |         JsonArray const& prohibited_states = translate_aria_names_to_enum(value_object.get_array("prohibitedStates"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "prohibited_states"sv, "states"sv, "StateAndProperties"sv, prohibited_states)); |         generate_hash_table_member(member_generator, "prohibited_states"sv, "states"sv, "StateAndProperties"sv, prohibited_states); | ||||||
|         JsonArray const& prohibited_properties = TRY(translate_aria_names_to_enum(value_object.get_array("prohibitedProperties"sv).value())); |         JsonArray const& prohibited_properties = translate_aria_names_to_enum(value_object.get_array("prohibitedProperties"sv).value()); | ||||||
|         TRY(generate_hash_table_member(member_generator, "prohibited_properties"sv, "properties"sv, "StateAndProperties"sv, prohibited_properties)); |         generate_hash_table_member(member_generator, "prohibited_properties"sv, "properties"sv, "StateAndProperties"sv, prohibited_properties); | ||||||
| 
 | 
 | ||||||
|         JsonArray const& required_context_roles = value_object.get_array("requiredContextRoles"sv).value(); |         JsonArray const& required_context_roles = value_object.get_array("requiredContextRoles"sv).value(); | ||||||
|         TRY(generate_hash_table_member(member_generator, "required_context_roles"sv, "roles"sv, "Role"sv, required_context_roles)); |         generate_hash_table_member(member_generator, "required_context_roles"sv, "roles"sv, "Role"sv, required_context_roles); | ||||||
|         JsonArray const& required_owned_elements = value_object.get_array("requiredOwnedElements"sv).value(); |         JsonArray const& required_owned_elements = value_object.get_array("requiredOwnedElements"sv).value(); | ||||||
|         TRY(generate_hash_table_member(member_generator, "required_owned_elements"sv, "roles"sv, "Role"sv, required_owned_elements)); |         generate_hash_table_member(member_generator, "required_owned_elements"sv, "roles"sv, "Role"sv, required_owned_elements); | ||||||
| 
 | 
 | ||||||
|         bool accessible_name_required = value_object.get_bool("accessibleNameRequired"sv).value(); |         bool accessible_name_required = value_object.get_bool("accessibleNameRequired"sv).value(); | ||||||
|         member_generator.set("accessible_name_required"sv, accessible_name_required ? "true"sv : "false"sv); |         member_generator.set("accessible_name_required"sv, accessible_name_required ? "true"sv : "false"sv); | ||||||
|  | @ -358,7 +352,7 @@ DefaultValueType @name@::default_value_for_property_or_state(StateAndProperties | ||||||
| { | { | ||||||
|     switch (state_or_property) { |     switch (state_or_property) { | ||||||
| )~~~"); | )~~~"); | ||||||
|             TRY(implicit_value_for_role.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |             implicit_value_for_role.for_each_member([&](auto& name, auto& value) { | ||||||
|                 auto case_generator = member_generator.fork(); |                 auto case_generator = member_generator.fork(); | ||||||
|                 VERIFY(value.is_string()); |                 VERIFY(value.is_string()); | ||||||
|                 case_generator.set("state_or_property"sv, aria_name_to_enum_name(name)); |                 case_generator.set("state_or_property"sv, aria_name_to_enum_name(name)); | ||||||
|  | @ -367,8 +361,7 @@ DefaultValueType @name@::default_value_for_property_or_state(StateAndProperties | ||||||
|     case StateAndProperties::@state_or_property@: |     case StateAndProperties::@state_or_property@: | ||||||
|         return @implicit_value@; |         return @implicit_value@; | ||||||
| )~~~"); | )~~~"); | ||||||
|                 return {}; |             }); | ||||||
|             })); |  | ||||||
|             member_generator.append(R"~~~( |             member_generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -387,9 +380,7 @@ NameFromSource @name@::name_from_source() const | ||||||
| } | } | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
| 
 |     }); | ||||||
|         return {}; |  | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append("}"); |     generator.append("}"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,12 +56,11 @@ namespace Web::CSS { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     generator.appendln("enum class EasingFunction {"); |     generator.appendln("enum class EasingFunction {"); | ||||||
|     TRY(easing_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     easing_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.appendln("    @name:titlecase@,"); |         member_generator.appendln("    @name:titlecase@,"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.appendln("};"); |     generator.appendln("};"); | ||||||
| 
 | 
 | ||||||
|     generator.appendln("Optional<EasingFunction> easing_function_from_string(StringView);"); |     generator.appendln("Optional<EasingFunction> easing_function_from_string(StringView);"); | ||||||
|  | @ -108,16 +107,15 @@ namespace Web::CSS { | ||||||
| Optional<EasingFunction> easing_function_from_string(StringView name) | Optional<EasingFunction> easing_function_from_string(StringView name) | ||||||
| { | { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(easing_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     easing_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (name.equals_ignoring_ascii_case("@name@"sv)) |     if (name.equals_ignoring_ascii_case("@name@"sv)) | ||||||
|         return EasingFunction::@name:titlecase@; |         return EasingFunction::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
|  | @ -128,16 +126,15 @@ StringView to_string(EasingFunction easing_function) | ||||||
| { | { | ||||||
|     switch (easing_function) { |     switch (easing_function) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(easing_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     easing_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case EasingFunction::@name:titlecase@: |     case EasingFunction::@name:titlecase@: | ||||||
|         return "@name@"sv; |         return "@name@"sv; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|  | @ -150,7 +147,7 @@ EasingFunctionMetadata easing_function_metadata(EasingFunction easing_function) | ||||||
| { | { | ||||||
|     switch (easing_function) { |     switch (easing_function) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(easing_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     easing_data.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|  | @ -163,7 +160,7 @@ EasingFunctionMetadata easing_function_metadata(EasingFunction easing_function) | ||||||
|         if (auto parameters = value.as_object().get_array("parameters"sv); parameters.has_value()) { |         if (auto parameters = value.as_object().get_array("parameters"sv); parameters.has_value()) { | ||||||
|             bool first = true; |             bool first = true; | ||||||
|             // parameters: [ "<foo>", "<foo [0, 1]>" ]
 |             // parameters: [ "<foo>", "<foo [0, 1]>" ]
 | ||||||
|             TRY(parameters.value().try_for_each([&](JsonValue const& value) -> ErrorOr<void> { |             parameters.value().for_each([&](JsonValue const& value) { | ||||||
|                 GenericLexer lexer { value.as_string() }; |                 GenericLexer lexer { value.as_string() }; | ||||||
|                 VERIFY(lexer.consume_specific('<')); |                 VERIFY(lexer.consume_specific('<')); | ||||||
|                 auto parameter_type_name = lexer.consume_until([](char ch) { return ch == ' ' || ch == '>'; }); |                 auto parameter_type_name = lexer.consume_until([](char ch) { return ch == ' ' || ch == '>'; }); | ||||||
|  | @ -192,19 +189,17 @@ EasingFunctionMetadata easing_function_metadata(EasingFunction easing_function) | ||||||
|                 member_generator.append(first ? " "sv : ", "sv); |                 member_generator.append(first ? " "sv : ", "sv); | ||||||
|                 first = false; |                 first = false; | ||||||
| 
 | 
 | ||||||
|                 member_generator.append(TRY(String::formatted( |                 member_generator.append(MUST(String::formatted( | ||||||
|                     "{{ EasingFunctionParameterType::{}, {} }}", |                     "{{ EasingFunctionParameterType::{}, {} }}", | ||||||
|                     parameter_type, |                     parameter_type, | ||||||
|                     is_optional ? "true"sv : "false"sv))); |                     is_optional ? "true"sv : "false"sv))); | ||||||
|                 return {}; |             }); | ||||||
|             })); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         member_generator.append(R"~~~( } |         member_generator.append(R"~~~( } | ||||||
|     }; |     }; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ enum class ValueID; | ||||||
| 
 | 
 | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(enums_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     enums_data.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_array()); |         VERIFY(value.is_array()); | ||||||
|         auto& members = value.as_array(); |         auto& members = value.as_array(); | ||||||
| 
 | 
 | ||||||
|  | @ -91,8 +91,7 @@ enum class ValueID; | ||||||
|         enum_generator.appendln("ValueID to_value_id(@name:titlecase@);"); |         enum_generator.appendln("ValueID to_value_id(@name:titlecase@);"); | ||||||
|         enum_generator.appendln("StringView to_string(@name:titlecase@);"); |         enum_generator.appendln("StringView to_string(@name:titlecase@);"); | ||||||
|         enum_generator.append("\n"); |         enum_generator.append("\n"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.appendln("}"); |     generator.appendln("}"); | ||||||
| 
 | 
 | ||||||
|  | @ -112,7 +111,7 @@ ErrorOr<void> generate_implementation_file(JsonObject& enums_data, Core::File& f | ||||||
| namespace Web::CSS { | namespace Web::CSS { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(enums_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     enums_data.for_each_member([&](auto& name, auto& value) -> void { | ||||||
|         VERIFY(value.is_array()); |         VERIFY(value.is_array()); | ||||||
|         auto& members = value.as_array(); |         auto& members = value.as_array(); | ||||||
| 
 | 
 | ||||||
|  | @ -182,7 +181,7 @@ StringView to_string(@name:titlecase@ value) | ||||||
|             auto member_name = member.to_deprecated_string(); |             auto member_name = member.to_deprecated_string(); | ||||||
|             if (member_name.contains('=')) |             if (member_name.contains('=')) | ||||||
|                 continue; |                 continue; | ||||||
|             member_generator.set("member:css", TRY(String::from_deprecated_string(member_name))); |             member_generator.set("member:css", member_name); | ||||||
|             member_generator.set("member:titlecase", title_casify(member_name)); |             member_generator.set("member:titlecase", title_casify(member_name)); | ||||||
| 
 | 
 | ||||||
|             member_generator.append(R"~~~( |             member_generator.append(R"~~~( | ||||||
|  | @ -196,8 +195,7 @@ StringView to_string(@name:titlecase@ value) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.appendln("}"); |     generator.appendln("}"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -53,12 +53,11 @@ namespace Web::CSS { | ||||||
| enum class MathFunction { | enum class MathFunction { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(functions_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     functions_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.appendln("    @name:titlecase@,"sv); |         member_generator.appendln("    @name:titlecase@,"sv); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| }; | }; | ||||||
|  | @ -70,7 +69,7 @@ enum class MathFunction { | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<String> generate_calculation_type_check(StringView calculation_variable_name, StringView parameter_types) | String generate_calculation_type_check(StringView calculation_variable_name, StringView parameter_types) | ||||||
| { | { | ||||||
|     StringBuilder builder; |     StringBuilder builder; | ||||||
|     auto allowed_types = parameter_types.split_view('|'); |     auto allowed_types = parameter_types.split_view('|'); | ||||||
|  | @ -81,29 +80,29 @@ ErrorOr<String> generate_calculation_type_check(StringView calculation_variable_ | ||||||
|         first_type_check = false; |         first_type_check = false; | ||||||
| 
 | 
 | ||||||
|         if (allowed_type_name == "<angle>"sv) { |         if (allowed_type_name == "<angle>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_angle()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_angle()"sv); | ||||||
|         } else if (allowed_type_name == "<dimension>"sv) { |         } else if (allowed_type_name == "<dimension>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_dimension()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_dimension()"sv); | ||||||
|         } else if (allowed_type_name == "<flex>"sv) { |         } else if (allowed_type_name == "<flex>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_flex()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_flex()"sv); | ||||||
|         } else if (allowed_type_name == "<frequency>"sv) { |         } else if (allowed_type_name == "<frequency>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_frequency()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_frequency()"sv); | ||||||
|         } else if (allowed_type_name == "<length>"sv) { |         } else if (allowed_type_name == "<length>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_length()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_length()"sv); | ||||||
|         } else if (allowed_type_name == "<number>"sv) { |         } else if (allowed_type_name == "<number>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_number()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_number()"sv); | ||||||
|         } else if (allowed_type_name == "<percentage>"sv) { |         } else if (allowed_type_name == "<percentage>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_percentage()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_percentage()"sv); | ||||||
|         } else if (allowed_type_name == "<resolution>"sv) { |         } else if (allowed_type_name == "<resolution>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_resolution()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_resolution()"sv); | ||||||
|         } else if (allowed_type_name == "<time>"sv) { |         } else if (allowed_type_name == "<time>"sv) { | ||||||
|             TRY(builder.try_appendff("{}.{}", calculation_variable_name, "matches_time()"sv)); |             builder.appendff("{}.{}", calculation_variable_name, "matches_time()"sv); | ||||||
|         } else { |         } else { | ||||||
|             dbgln("I don't know what '{}' is!", allowed_type_name); |             dbgln("I don't know what '{}' is!", allowed_type_name); | ||||||
|             VERIFY_NOT_REACHED(); |             VERIFY_NOT_REACHED(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return builder.to_string(); |     return MUST(builder.to_string()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> generate_implementation_file(JsonObject& functions_data, Core::File& file) | ErrorOr<void> generate_implementation_file(JsonObject& functions_data, Core::File& file) | ||||||
|  | @ -150,12 +149,12 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|     auto arguments = parse_a_comma_separated_list_of_component_values(stream); |     auto arguments = parse_a_comma_separated_list_of_component_values(stream); | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(functions_data.try_for_each_member([&](auto& name, JsonValue const& value) -> ErrorOr<void> { |     functions_data.for_each_member([&](auto& name, JsonValue const& value) -> void { | ||||||
|         auto& function_data = value.as_object(); |         auto& function_data = value.as_object(); | ||||||
|         auto& parameters = function_data.get_array("parameters"sv).value(); |         auto& parameters = function_data.get_array("parameters"sv).value(); | ||||||
| 
 | 
 | ||||||
|         auto function_generator = generator.fork(); |         auto function_generator = generator.fork(); | ||||||
|         function_generator.set("name:lowercase", TRY(String::from_deprecated_string(name))); |         function_generator.set("name:lowercase", name); | ||||||
|         function_generator.set("name:titlecase", title_casify(name)); |         function_generator.set("name:titlecase", title_casify(name)); | ||||||
|         function_generator.appendln("    if (function.name().equals_ignoring_ascii_case(\"@name:lowercase@\"sv)) {"); |         function_generator.appendln("    if (function.name().equals_ignoring_ascii_case(\"@name:lowercase@\"sv)) {"); | ||||||
|         if (function_data.get_bool("is-variadic"sv).value_or(false)) { |         if (function_data.get_bool("is-variadic"sv).value_or(false)) { | ||||||
|  | @ -184,7 +183,7 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|             VERIFY(parameters.size() == 1); |             VERIFY(parameters.size() == 1); | ||||||
|             auto& parameter_data = parameters[0].as_object(); |             auto& parameter_data = parameters[0].as_object(); | ||||||
|             auto parameter_type_string = parameter_data.get_deprecated_string("type"sv).value(); |             auto parameter_type_string = parameter_data.get_deprecated_string("type"sv).value(); | ||||||
|             function_generator.set("type_check", TRY(generate_calculation_type_check("argument_type"sv, parameter_type_string))); |             function_generator.set("type_check", generate_calculation_type_check("argument_type"sv, parameter_type_string)); | ||||||
|             function_generator.append(R"~~~( |             function_generator.append(R"~~~( | ||||||
|             if (!(@type_check@)) { |             if (!(@type_check@)) { | ||||||
|                 dbgln_if(CSS_PARSER_DEBUG, "@name:lowercase@() argument #{} type ({}) is not an accepted type", parsed_arguments.size(), MUST(argument_type.dump())); |                 dbgln_if(CSS_PARSER_DEBUG, "@name:lowercase@() argument #{} type ({}) is not an accepted type", parsed_arguments.size(), MUST(argument_type.dump())); | ||||||
|  | @ -216,8 +215,8 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|                 if (parameter.get_bool("required"sv) == true) |                 if (parameter.get_bool("required"sv) == true) | ||||||
|                     min_argument_count++; |                     min_argument_count++; | ||||||
|             }); |             }); | ||||||
|             function_generator.set("min_argument_count", TRY(String::number(min_argument_count))); |             function_generator.set("min_argument_count", MUST(String::number(min_argument_count))); | ||||||
|             function_generator.set("max_argument_count", TRY(String::number(max_argument_count))); |             function_generator.set("max_argument_count", MUST(String::number(max_argument_count))); | ||||||
| 
 | 
 | ||||||
|             function_generator.append(R"~~~( |             function_generator.append(R"~~~( | ||||||
|         if (arguments.size() < @min_argument_count@ || arguments.size() > @max_argument_count@) { |         if (arguments.size() < @min_argument_count@ || arguments.size() > @max_argument_count@) { | ||||||
|  | @ -230,14 +229,14 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
| 
 | 
 | ||||||
|             size_t parameter_index = 0; |             size_t parameter_index = 0; | ||||||
|             StringView previous_parameter_type_string; |             StringView previous_parameter_type_string; | ||||||
|             TRY(parameters.try_for_each([&](JsonValue const& parameter_value) -> ErrorOr<void> { |             parameters.for_each([&](JsonValue const& parameter_value) { | ||||||
|                 auto& parameter = parameter_value.as_object(); |                 auto& parameter = parameter_value.as_object(); | ||||||
|                 auto parameter_type_string = parameter.get_deprecated_string("type"sv).value(); |                 auto parameter_type_string = parameter.get_deprecated_string("type"sv).value(); | ||||||
|                 auto parameter_required = parameter.get_bool("required"sv).value(); |                 auto parameter_required = parameter.get_bool("required"sv).value(); | ||||||
| 
 | 
 | ||||||
|                 auto parameter_generator = function_generator.fork(); |                 auto parameter_generator = function_generator.fork(); | ||||||
|                 parameter_generator.set("parameter_name", TRY(String::from_deprecated_string(parameter.get_deprecated_string("name"sv).value()))); |                 parameter_generator.set("parameter_name", parameter.get_deprecated_string("name"sv).value()); | ||||||
|                 parameter_generator.set("parameter_index", TRY(String::number(parameter_index))); |                 parameter_generator.set("parameter_index", MUST(String::number(parameter_index))); | ||||||
| 
 | 
 | ||||||
|                 bool parameter_is_calculation; |                 bool parameter_is_calculation; | ||||||
|                 if (parameter_type_string == "<rounding-strategy>") { |                 if (parameter_type_string == "<rounding-strategy>") { | ||||||
|  | @ -247,7 +246,7 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|                     parameter_generator.set("check_function", ".has_value()"_string); |                     parameter_generator.set("check_function", ".has_value()"_string); | ||||||
|                     parameter_generator.set("release_function", ".release_value()"_string); |                     parameter_generator.set("release_function", ".release_value()"_string); | ||||||
|                     if (auto default_value = parameter.get_deprecated_string("default"sv); default_value.has_value()) { |                     if (auto default_value = parameter.get_deprecated_string("default"sv); default_value.has_value()) { | ||||||
|                         parameter_generator.set("parameter_default", TRY(String::formatted(" = RoundingStrategy::{}", title_casify(default_value.value())))); |                         parameter_generator.set("parameter_default", MUST(String::formatted(" = RoundingStrategy::{}", title_casify(default_value.value())))); | ||||||
|                     } else { |                     } else { | ||||||
|                         parameter_generator.set("parameter_default", ""_string); |                         parameter_generator.set("parameter_default", ""_string); | ||||||
|                     } |                     } | ||||||
|  | @ -262,7 +261,7 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|                     // NOTE: We have exactly one default value in the data right now, and it's a `<calc-constant>`,
 |                     // NOTE: We have exactly one default value in the data right now, and it's a `<calc-constant>`,
 | ||||||
|                     //       so that's all we handle.
 |                     //       so that's all we handle.
 | ||||||
|                     if (auto default_value = parameter.get_deprecated_string("default"sv); default_value.has_value()) { |                     if (auto default_value = parameter.get_deprecated_string("default"sv); default_value.has_value()) { | ||||||
|                         parameter_generator.set("parameter_default", TRY(String::formatted(" = ConstantCalculationNode::create(CalculationNode::constant_type_from_string(\"{}\"sv).value())", TRY(String::from_deprecated_string(default_value.value()))))); |                         parameter_generator.set("parameter_default", MUST(String::formatted(" = ConstantCalculationNode::create(CalculationNode::constant_type_from_string(\"{}\"sv).value())", default_value.value()))); | ||||||
|                     } else { |                     } else { | ||||||
|                         parameter_generator.set("parameter_default", ""_string); |                         parameter_generator.set("parameter_default", ""_string); | ||||||
|                     } |                     } | ||||||
|  | @ -304,8 +303,8 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|                 if (parameter_is_calculation) { |                 if (parameter_is_calculation) { | ||||||
|                     auto parameter_type_variable = TRY(String::formatted("argument_type_{}", parameter_index)); |                     auto parameter_type_variable = MUST(String::formatted("argument_type_{}", parameter_index)); | ||||||
|                     parameter_generator.set("type_check", TRY(generate_calculation_type_check(parameter_type_variable, parameter_type_string))); |                     parameter_generator.set("type_check", generate_calculation_type_check(parameter_type_variable, parameter_type_string)); | ||||||
|                     parameter_generator.append(R"~~~( |                     parameter_generator.append(R"~~~( | ||||||
|         auto maybe_argument_type_@parameter_index@ = parameter_@parameter_index@->determine_type(property_id); |         auto maybe_argument_type_@parameter_index@ = parameter_@parameter_index@->determine_type(property_id); | ||||||
|         if (!maybe_argument_type_@parameter_index@.has_value()) { |         if (!maybe_argument_type_@parameter_index@.has_value()) { | ||||||
|  | @ -337,18 +336,17 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
| 
 | 
 | ||||||
|                 parameter_index++; |                 parameter_index++; | ||||||
|                 previous_parameter_type_string = parameter_type_string; |                 previous_parameter_type_string = parameter_type_string; | ||||||
|                 return {}; |             }); | ||||||
|             })); |  | ||||||
| 
 | 
 | ||||||
|             // Generate the call to the constructor
 |             // Generate the call to the constructor
 | ||||||
|             function_generator.append("        return @name:titlecase@CalculationNode::create("sv); |             function_generator.append("        return @name:titlecase@CalculationNode::create("sv); | ||||||
|             parameter_index = 0; |             parameter_index = 0; | ||||||
|             TRY(parameters.try_for_each([&](JsonValue const& parameter_value) -> ErrorOr<void> { |             parameters.for_each([&](JsonValue const& parameter_value) { | ||||||
|                 auto& parameter = parameter_value.as_object(); |                 auto& parameter = parameter_value.as_object(); | ||||||
|                 auto parameter_type_string = parameter.get_deprecated_string("type"sv).value(); |                 auto parameter_type_string = parameter.get_deprecated_string("type"sv).value(); | ||||||
| 
 | 
 | ||||||
|                 auto parameter_generator = function_generator.fork(); |                 auto parameter_generator = function_generator.fork(); | ||||||
|                 parameter_generator.set("parameter_index"sv, TRY(String::number(parameter_index))); |                 parameter_generator.set("parameter_index"sv, MUST(String::number(parameter_index))); | ||||||
| 
 | 
 | ||||||
|                 if (parameter_type_string == "<rounding-strategy>"sv) { |                 if (parameter_type_string == "<rounding-strategy>"sv) { | ||||||
|                     parameter_generator.set("release_value"sv, ""_string); |                     parameter_generator.set("release_value"sv, ""_string); | ||||||
|  | @ -363,14 +361,12 @@ OwnPtr<CalculationNode> Parser::parse_math_function(PropertyID property_id, Func | ||||||
|                     parameter_generator.append(", parameter_@parameter_index@@release_value@"sv); |                     parameter_generator.append(", parameter_@parameter_index@@release_value@"sv); | ||||||
|                 } |                 } | ||||||
|                 parameter_index++; |                 parameter_index++; | ||||||
|                 return {}; |             }); | ||||||
|             })); |  | ||||||
|             function_generator.append(R"~~~(); |             function_generator.append(R"~~~(); | ||||||
|     } |     } | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return nullptr; |     return nullptr; | ||||||
|  |  | ||||||
|  | @ -60,13 +60,12 @@ enum class MediaFeatureValueType { | ||||||
| 
 | 
 | ||||||
| enum class MediaFeatureID {)~~~"); | enum class MediaFeatureID {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     @name:titlecase@,)~~~"); |     @name:titlecase@,)~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| }; | }; | ||||||
|  | @ -98,16 +97,15 @@ namespace Web::CSS { | ||||||
| Optional<MediaFeatureID> media_feature_id_from_string(StringView string) | Optional<MediaFeatureID> media_feature_id_from_string(StringView string) | ||||||
| {)~~~"); | {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (Infra::is_ascii_case_insensitive_match(string, "@name@"sv)) |     if (Infra::is_ascii_case_insensitive_match(string, "@name@"sv)) | ||||||
|         return MediaFeatureID::@name:titlecase@; |         return MediaFeatureID::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return {}; |     return {}; | ||||||
|  | @ -117,15 +115,14 @@ StringView string_from_media_feature_id(MediaFeatureID media_feature_id) | ||||||
| { | { | ||||||
|     switch (media_feature_id) {)~~~"); |     switch (media_feature_id) {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case MediaFeatureID::@name:titlecase@: |     case MediaFeatureID::@name:titlecase@: | ||||||
|         return "@name@"sv;)~~~"); |         return "@name@"sv;)~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  | @ -136,7 +133,7 @@ bool media_feature_type_is_range(MediaFeatureID media_feature_id) | ||||||
| { | { | ||||||
|     switch (media_feature_id) {)~~~"); |     switch (media_feature_id) {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         auto& feature = value.as_object(); |         auto& feature = value.as_object(); | ||||||
| 
 | 
 | ||||||
|  | @ -149,8 +146,7 @@ bool media_feature_type_is_range(MediaFeatureID media_feature_id) | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case MediaFeatureID::@name:titlecase@: |     case MediaFeatureID::@name:titlecase@: | ||||||
|         return @is_range@;)~~~"); |         return @is_range@;)~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  | @ -161,7 +157,7 @@ bool media_feature_accepts_type(MediaFeatureID media_feature_id, MediaFeatureVal | ||||||
| { | { | ||||||
|     switch (media_feature_id) {)~~~"); |     switch (media_feature_id) {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto& member) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto& member) { | ||||||
|         VERIFY(member.is_object()); |         VERIFY(member.is_object()); | ||||||
|         auto& feature = member.as_object(); |         auto& feature = member.as_object(); | ||||||
| 
 | 
 | ||||||
|  | @ -172,13 +168,12 @@ bool media_feature_accepts_type(MediaFeatureID media_feature_id, MediaFeatureVal | ||||||
| 
 | 
 | ||||||
|         bool have_output_value_type_switch = false; |         bool have_output_value_type_switch = false; | ||||||
|         if (feature.has("values"sv)) { |         if (feature.has("values"sv)) { | ||||||
|             auto append_value_type_switch_if_needed = [&]() -> ErrorOr<void> { |             auto append_value_type_switch_if_needed = [&] { | ||||||
|                 if (!have_output_value_type_switch) { |                 if (!have_output_value_type_switch) { | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         switch (value_type) {)~~~"); |         switch (value_type) {)~~~"); | ||||||
|                 } |                 } | ||||||
|                 have_output_value_type_switch = true; |                 have_output_value_type_switch = true; | ||||||
|                 return {}; |  | ||||||
|             }; |             }; | ||||||
|             auto values = feature.get_array("values"sv); |             auto values = feature.get_array("values"sv); | ||||||
|             VERIFY(values.has_value()); |             VERIFY(values.has_value()); | ||||||
|  | @ -190,27 +185,27 @@ bool media_feature_accepts_type(MediaFeatureID media_feature_id, MediaFeatureVal | ||||||
|                 if (type_name[0] != '<') |                 if (type_name[0] != '<') | ||||||
|                     continue; |                     continue; | ||||||
|                 if (type_name == "<mq-boolean>") { |                 if (type_name == "<mq-boolean>") { | ||||||
|                     TRY(append_value_type_switch_if_needed()); |                     append_value_type_switch_if_needed(); | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         case MediaFeatureValueType::Boolean: |         case MediaFeatureValueType::Boolean: | ||||||
|             return true;)~~~"); |             return true;)~~~"); | ||||||
|                 } else if (type_name == "<integer>") { |                 } else if (type_name == "<integer>") { | ||||||
|                     TRY(append_value_type_switch_if_needed()); |                     append_value_type_switch_if_needed(); | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         case MediaFeatureValueType::Integer: |         case MediaFeatureValueType::Integer: | ||||||
|             return true;)~~~"); |             return true;)~~~"); | ||||||
|                 } else if (type_name == "<length>") { |                 } else if (type_name == "<length>") { | ||||||
|                     TRY(append_value_type_switch_if_needed()); |                     append_value_type_switch_if_needed(); | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         case MediaFeatureValueType::Length: |         case MediaFeatureValueType::Length: | ||||||
|             return true;)~~~"); |             return true;)~~~"); | ||||||
|                 } else if (type_name == "<ratio>") { |                 } else if (type_name == "<ratio>") { | ||||||
|                     TRY(append_value_type_switch_if_needed()); |                     append_value_type_switch_if_needed(); | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         case MediaFeatureValueType::Ratio: |         case MediaFeatureValueType::Ratio: | ||||||
|             return true;)~~~"); |             return true;)~~~"); | ||||||
|                 } else if (type_name == "<resolution>") { |                 } else if (type_name == "<resolution>") { | ||||||
|                     TRY(append_value_type_switch_if_needed()); |                     append_value_type_switch_if_needed(); | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         case MediaFeatureValueType::Resolution: |         case MediaFeatureValueType::Resolution: | ||||||
|             return true;)~~~"); |             return true;)~~~"); | ||||||
|  | @ -229,8 +224,7 @@ bool media_feature_accepts_type(MediaFeatureID media_feature_id, MediaFeatureVal | ||||||
|             member_generator.append(R"~~~( |             member_generator.append(R"~~~( | ||||||
|         return false;)~~~"); |         return false;)~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  | @ -241,7 +235,7 @@ bool media_feature_accepts_identifier(MediaFeatureID media_feature_id, ValueID i | ||||||
| { | { | ||||||
|     switch (media_feature_id) {)~~~"); |     switch (media_feature_id) {)~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(media_feature_data.try_for_each_member([&](auto& name, auto& member) -> ErrorOr<void> { |     media_feature_data.for_each_member([&](auto& name, auto& member) { | ||||||
|         VERIFY(member.is_object()); |         VERIFY(member.is_object()); | ||||||
|         auto& feature = member.as_object(); |         auto& feature = member.as_object(); | ||||||
| 
 | 
 | ||||||
|  | @ -252,13 +246,12 @@ bool media_feature_accepts_identifier(MediaFeatureID media_feature_id, ValueID i | ||||||
| 
 | 
 | ||||||
|         bool have_output_identifier_switch = false; |         bool have_output_identifier_switch = false; | ||||||
|         if (feature.has("values"sv)) { |         if (feature.has("values"sv)) { | ||||||
|             auto append_identifier_switch_if_needed = [&]() -> ErrorOr<void> { |             auto append_identifier_switch_if_needed = [&] { | ||||||
|                 if (!have_output_identifier_switch) { |                 if (!have_output_identifier_switch) { | ||||||
|                     member_generator.append(R"~~~( |                     member_generator.append(R"~~~( | ||||||
|         switch (identifier) {)~~~"); |         switch (identifier) {)~~~"); | ||||||
|                 } |                 } | ||||||
|                 have_output_identifier_switch = true; |                 have_output_identifier_switch = true; | ||||||
|                 return {}; |  | ||||||
|             }; |             }; | ||||||
|             auto values = feature.get_array("values"sv); |             auto values = feature.get_array("values"sv); | ||||||
|             VERIFY(values.has_value()); |             VERIFY(values.has_value()); | ||||||
|  | @ -269,7 +262,7 @@ bool media_feature_accepts_identifier(MediaFeatureID media_feature_id, ValueID i | ||||||
|                 // Skip types.
 |                 // Skip types.
 | ||||||
|                 if (identifier_name[0] == '<') |                 if (identifier_name[0] == '<') | ||||||
|                     continue; |                     continue; | ||||||
|                 TRY(append_identifier_switch_if_needed()); |                 append_identifier_switch_if_needed(); | ||||||
| 
 | 
 | ||||||
|                 auto ident_generator = member_generator.fork(); |                 auto ident_generator = member_generator.fork(); | ||||||
|                 ident_generator.set("identifier:titlecase", title_casify(identifier_name)); |                 ident_generator.set("identifier:titlecase", title_casify(identifier_name)); | ||||||
|  | @ -287,8 +280,7 @@ bool media_feature_accepts_identifier(MediaFeatureID media_feature_id, ValueID i | ||||||
|             member_generator.append(R"~~~( |             member_generator.append(R"~~~( | ||||||
|         return false;)~~~"); |         return false;)~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -13,10 +13,10 @@ | ||||||
| #include <LibCore/ArgsParser.h> | #include <LibCore/ArgsParser.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> replace_logical_aliases(JsonObject& properties); | void replace_logical_aliases(JsonObject& properties); | ||||||
| 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); | ||||||
| ErrorOr<void> generate_bounds_checking_function(JsonObject& properties, SourceGenerator& parent_generator, StringView css_type_name, StringView type_name, Optional<StringView> default_unit_name = {}, Optional<StringView> value_getter = {}); | void generate_bounds_checking_function(JsonObject& properties, SourceGenerator& parent_generator, StringView css_type_name, StringView type_name, Optional<StringView> default_unit_name = {}, Optional<StringView> value_getter = {}); | ||||||
| 
 | 
 | ||||||
| static bool type_name_is_enum(StringView type_name) | static bool type_name_is_enum(StringView type_name) | ||||||
| { | { | ||||||
|  | @ -42,7 +42,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||||
|     VERIFY(json.is_object()); |     VERIFY(json.is_object()); | ||||||
|     auto properties = json.as_object(); |     auto properties = json.as_object(); | ||||||
| 
 | 
 | ||||||
|     TRY(replace_logical_aliases(properties)); |     replace_logical_aliases(properties); | ||||||
| 
 | 
 | ||||||
|     auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write)); |     auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write)); | ||||||
|     auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write)); |     auto generated_implementation_file = TRY(Core::File::open(generated_implementation_path, Core::File::OpenMode::Write)); | ||||||
|  | @ -53,7 +53,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> replace_logical_aliases(JsonObject& properties) | void replace_logical_aliases(JsonObject& properties) | ||||||
| { | { | ||||||
|     AK::HashMap<DeprecatedString, DeprecatedString> logical_aliases; |     AK::HashMap<DeprecatedString, DeprecatedString> logical_aliases; | ||||||
|     properties.for_each_member([&](auto& name, auto& value) { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|  | @ -83,8 +83,6 @@ ErrorOr<void> replace_logical_aliases(JsonObject& properties) | ||||||
| 
 | 
 | ||||||
|         properties.set(name, alias_object); |         properties.set(name, alias_object); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     return {}; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> generate_header_file(JsonObject& properties, Core::File& file) | ErrorOr<void> generate_header_file(JsonObject& properties, Core::File& file) | ||||||
|  | @ -229,11 +227,11 @@ struct Traits<Web::CSS::PropertyID> : public GenericTraits<Web::CSS::PropertyID> | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> generate_bounds_checking_function(JsonObject& properties, SourceGenerator& parent_generator, StringView css_type_name, StringView type_name, Optional<StringView> default_unit_name, Optional<StringView> value_getter) | void generate_bounds_checking_function(JsonObject& properties, SourceGenerator& parent_generator, StringView css_type_name, StringView type_name, Optional<StringView> default_unit_name, Optional<StringView> value_getter) | ||||||
| { | { | ||||||
|     auto generator = parent_generator.fork(); |     auto generator = parent_generator.fork(); | ||||||
|     generator.set("css_type_name", TRY(String::from_utf8(css_type_name))); |     generator.set("css_type_name", css_type_name); | ||||||
|     generator.set("type_name", TRY(String::from_utf8(type_name))); |     generator.set("type_name", type_name); | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @type_name@ const& value) | bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @type_name@ const& value) | ||||||
|  | @ -241,7 +239,7 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @ | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, JsonValue const& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, JsonValue const& value) -> void { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         if (auto maybe_valid_types = value.as_object().get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) { |         if (auto maybe_valid_types = value.as_object().get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) { | ||||||
|             for (auto valid_type : maybe_valid_types->values()) { |             for (auto valid_type : maybe_valid_types->values()) { | ||||||
|  | @ -274,13 +272,13 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @ | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     auto output_check = [&](auto& value_string, StringView comparator) -> ErrorOr<void> { |                     auto output_check = [&](auto& value_string, StringView comparator) { | ||||||
|                         if (value_getter.has_value()) { |                         if (value_getter.has_value()) { | ||||||
|                             property_generator.set("value_number", TRY(String::from_utf8(value_string))); |                             property_generator.set("value_number", value_string); | ||||||
|                             property_generator.set("value_getter", TRY(String::from_utf8(value_getter.value()))); |                             property_generator.set("value_getter", value_getter.value()); | ||||||
|                             property_generator.set("comparator", TRY(String::from_utf8(comparator))); |                             property_generator.set("comparator", comparator); | ||||||
|                             property_generator.append("@value_getter@ @comparator@ @value_number@"); |                             property_generator.append("@value_getter@ @comparator@ @value_number@"); | ||||||
|                             return {}; |                             return; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         GenericLexer lexer { value_string }; |                         GenericLexer lexer { value_string }; | ||||||
|  | @ -289,19 +287,18 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @ | ||||||
|                         if (value_unit.is_empty()) |                         if (value_unit.is_empty()) | ||||||
|                             value_unit = default_unit_name.value(); |                             value_unit = default_unit_name.value(); | ||||||
|                         VERIFY(lexer.is_eof()); |                         VERIFY(lexer.is_eof()); | ||||||
|                         property_generator.set("value_number", TRY(String::from_utf8(value_number))); |                         property_generator.set("value_number", value_number); | ||||||
|                         property_generator.set("value_unit", title_casify(value_unit)); |                         property_generator.set("value_unit", title_casify(value_unit)); | ||||||
|                         property_generator.set("comparator", TRY(String::from_utf8(comparator))); |                         property_generator.set("comparator", comparator); | ||||||
|                         property_generator.append("value @comparator@ @type_name@(@value_number@, @type_name@::Type::@value_unit@)"); |                         property_generator.append("value @comparator@ @type_name@(@value_number@, @type_name@::Type::@value_unit@)"); | ||||||
|                         return {}; |  | ||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                     if (!min_value_string.is_empty()) |                     if (!min_value_string.is_empty()) | ||||||
|                         TRY(output_check(min_value_string, ">="sv)); |                         output_check(min_value_string, ">="sv); | ||||||
|                     if (!min_value_string.is_empty() && !max_value_string.is_empty()) |                     if (!min_value_string.is_empty() && !max_value_string.is_empty()) | ||||||
|                         property_generator.append(" && "); |                         property_generator.append(" && "); | ||||||
|                     if (!max_value_string.is_empty()) |                     if (!max_value_string.is_empty()) | ||||||
|                         TRY(output_check(max_value_string, "<="sv)); |                         output_check(max_value_string, "<="sv); | ||||||
|                     property_generator.appendln(";"); |                     property_generator.appendln(";"); | ||||||
|                 } else { |                 } else { | ||||||
|                     property_generator.appendln("true;"); |                     property_generator.appendln("true;"); | ||||||
|  | @ -309,8 +306,7 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @ | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -318,7 +314,6 @@ bool property_accepts_@css_type_name@(PropertyID property_id, [[maybe_unused]] @ | ||||||
|     } |     } | ||||||
| } | } | ||||||
| )~~~"); | )~~~"); | ||||||
|     return {}; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& file) | ErrorOr<void> generate_implementation_file(JsonObject& properties, Core::File& file) | ||||||
|  | @ -342,19 +337,18 @@ Optional<PropertyID> property_id_from_camel_case_string(StringView string) | ||||||
| { | { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.set("name:camelcase", camel_casify(name)); |         member_generator.set("name:camelcase", camel_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (string.equals_ignoring_ascii_case("@name:camelcase@"sv)) |     if (string.equals_ignoring_ascii_case("@name:camelcase@"sv)) | ||||||
|         return PropertyID::@name:titlecase@; |         return PropertyID::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return {}; |     return {}; | ||||||
|  | @ -366,18 +360,17 @@ Optional<PropertyID> property_id_from_string(StringView string) | ||||||
|         return PropertyID::All; |         return PropertyID::All; | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (Infra::is_ascii_case_insensitive_match(string, "@name@"sv)) |     if (Infra::is_ascii_case_insensitive_match(string, "@name@"sv)) | ||||||
|         return PropertyID::@name:titlecase@; |         return PropertyID::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return {}; |     return {}; | ||||||
|  | @ -387,18 +380,17 @@ StringView string_from_property_id(PropertyID property_id) { | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case PropertyID::@name:titlecase@: |     case PropertyID::@name:titlecase@: | ||||||
|         return "@name@"sv; |         return "@name@"sv; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -411,7 +403,7 @@ bool is_inherited_property(PropertyID property_id) | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         bool inherited = false; |         bool inherited = false; | ||||||
|  | @ -429,8 +421,7 @@ bool is_inherited_property(PropertyID property_id) | ||||||
|         return true; |         return true; | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -443,7 +434,7 @@ bool property_affects_layout(PropertyID property_id) | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         bool affects_layout = true; |         bool affects_layout = true; | ||||||
|  | @ -457,8 +448,7 @@ bool property_affects_layout(PropertyID property_id) | ||||||
|     case PropertyID::@name:titlecase@: |     case PropertyID::@name:titlecase@: | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|         return true; |         return true; | ||||||
|  | @ -472,7 +462,7 @@ bool property_affects_stacking_context(PropertyID property_id) | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         bool affects_stacking_context = false; |         bool affects_stacking_context = false; | ||||||
|  | @ -486,8 +476,7 @@ bool property_affects_stacking_context(PropertyID property_id) | ||||||
|     case PropertyID::@name:titlecase@: |     case PropertyID::@name:titlecase@: | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|         return true; |         return true; | ||||||
|  | @ -510,7 +499,7 @@ NonnullRefPtr<StyleValue> property_initial_value(JS::Realm& context_realm, Prope | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     auto output_initial_value_code = [&](auto& name, auto& object) -> ErrorOr<void> { |     auto output_initial_value_code = [&](auto& name, auto& object) { | ||||||
|         if (!object.has("initial"sv)) { |         if (!object.has("initial"sv)) { | ||||||
|             dbgln("No initial value specified for property '{}'", name); |             dbgln("No initial value specified for property '{}'", name); | ||||||
|             VERIFY_NOT_REACHED(); |             VERIFY_NOT_REACHED(); | ||||||
|  | @ -521,7 +510,7 @@ NonnullRefPtr<StyleValue> property_initial_value(JS::Realm& context_realm, Prope | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
|         member_generator.set("initial_value_string", TRY(String::from_deprecated_string(initial_value_string))); |         member_generator.set("initial_value_string", initial_value_string); | ||||||
|         member_generator.append( |         member_generator.append( | ||||||
|             R"~~~(        case PropertyID::@name:titlecase@: |             R"~~~(        case PropertyID::@name:titlecase@: | ||||||
|         { |         { | ||||||
|  | @ -532,14 +521,12 @@ NonnullRefPtr<StyleValue> property_initial_value(JS::Realm& context_realm, Prope | ||||||
|             return initial_value; |             return initial_value; | ||||||
|         } |         } | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         TRY(output_initial_value_code(name, value.as_object())); |         output_initial_value_code(name, value.as_object()); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append( |     generator.append( | ||||||
|         R"~~~(        default: VERIFY_NOT_REACHED(); |         R"~~~(        default: VERIFY_NOT_REACHED(); | ||||||
|  | @ -552,7 +539,7 @@ bool property_has_quirk(PropertyID property_id, Quirk quirk) | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         if (value.as_object().has("quirks"sv)) { |         if (value.as_object().has("quirks"sv)) { | ||||||
|             auto quirks_value = value.as_object().get_array("quirks"sv); |             auto quirks_value = value.as_object().get_array("quirks"sv); | ||||||
|  | @ -583,8 +570,7 @@ bool property_has_quirk(PropertyID property_id, Quirk quirk) | ||||||
| )~~~"); | )~~~"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -596,7 +582,7 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type) | ||||||
| { | { | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         auto& object = value.as_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()) { |         if (auto maybe_valid_types = object.get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) { | ||||||
|  | @ -665,8 +651,7 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type) | ||||||
|     } |     } | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         return false; |         return false; | ||||||
|  | @ -677,7 +662,7 @@ bool property_accepts_identifier(PropertyID property_id, ValueID identifier) | ||||||
| { | { | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         auto& object = value.as_object(); |         auto& object = value.as_object(); | ||||||
| 
 | 
 | ||||||
|  | @ -720,8 +705,7 @@ bool property_accepts_identifier(PropertyID property_id, ValueID identifier) | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         return false; |         return false; | ||||||
|  | @ -733,7 +717,7 @@ Optional<ValueType> property_resolves_percentages_relative_to(PropertyID propert | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         if (auto resolved_type = value.as_object().get_deprecated_string("percentages-resolve-to"sv); resolved_type.has_value()) { |         if (auto resolved_type = value.as_object().get_deprecated_string("percentages-resolve-to"sv); resolved_type.has_value()) { | ||||||
|             auto property_generator = generator.fork(); |             auto property_generator = generator.fork(); | ||||||
|  | @ -744,8 +728,7 @@ Optional<ValueType> property_resolves_percentages_relative_to(PropertyID propert | ||||||
|         return ValueType::@resolved_type:titlecase@; |         return ValueType::@resolved_type:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -758,21 +741,20 @@ size_t property_maximum_value_count(PropertyID property_id) | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
|         if (value.as_object().has("max-values"sv)) { |         if (value.as_object().has("max-values"sv)) { | ||||||
|             auto max_values = value.as_object().get("max-values"sv); |             auto max_values = value.as_object().get("max-values"sv); | ||||||
|             VERIFY(max_values.has_value() && max_values->is_number() && !max_values->is_double()); |             VERIFY(max_values.has_value() && max_values->is_number() && !max_values->is_double()); | ||||||
|             auto property_generator = generator.fork(); |             auto property_generator = generator.fork(); | ||||||
|             property_generator.set("name:titlecase", title_casify(name)); |             property_generator.set("name:titlecase", title_casify(name)); | ||||||
|             property_generator.set("max_values", TRY(String::from_deprecated_string(max_values->to_deprecated_string()))); |             property_generator.set("max_values", max_values->to_deprecated_string()); | ||||||
|             property_generator.append(R"~~~( |             property_generator.append(R"~~~( | ||||||
|     case PropertyID::@name:titlecase@: |     case PropertyID::@name:titlecase@: | ||||||
|         return @max_values@; |         return @max_values@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  | @ -780,21 +762,21 @@ size_t property_maximum_value_count(PropertyID property_id) | ||||||
|     } |     } | ||||||
| })~~~"); | })~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "angle"sv, "Angle"sv, "Deg"sv)); |     generate_bounds_checking_function(properties, generator, "angle"sv, "Angle"sv, "Deg"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "frequency"sv, "Frequency"sv, "Hertz"sv)); |     generate_bounds_checking_function(properties, generator, "frequency"sv, "Frequency"sv, "Hertz"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "integer"sv, "i64"sv, {}, "value"sv)); |     generate_bounds_checking_function(properties, generator, "integer"sv, "i64"sv, {}, "value"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "length"sv, "Length"sv, {}, "value.raw_value()"sv)); |     generate_bounds_checking_function(properties, generator, "length"sv, "Length"sv, {}, "value.raw_value()"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "number"sv, "double"sv, {}, "value"sv)); |     generate_bounds_checking_function(properties, generator, "number"sv, "double"sv, {}, "value"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "percentage"sv, "Percentage"sv, {}, "value.value()"sv)); |     generate_bounds_checking_function(properties, generator, "percentage"sv, "Percentage"sv, {}, "value.value()"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "resolution"sv, "Resolution"sv, "Dpi"sv)); |     generate_bounds_checking_function(properties, generator, "resolution"sv, "Resolution"sv, "Dpi"sv); | ||||||
|     TRY(generate_bounds_checking_function(properties, generator, "time"sv, "Time"sv, "S"sv)); |     generate_bounds_checking_function(properties, generator, "time"sv, "Time"sv, "S"sv); | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| Vector<PropertyID> longhands_for_shorthand(PropertyID property_id) | Vector<PropertyID> longhands_for_shorthand(PropertyID property_id) | ||||||
| { | { | ||||||
|     switch (property_id) { |     switch (property_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(properties.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     properties.for_each_member([&](auto& name, auto& value) { | ||||||
|         if (value.as_object().has("longhands"sv)) { |         if (value.as_object().has("longhands"sv)) { | ||||||
|             auto longhands = value.as_object().get("longhands"sv); |             auto longhands = value.as_object().get("longhands"sv); | ||||||
|             VERIFY(longhands.has_value() && longhands->is_array()); |             VERIFY(longhands.has_value() && longhands->is_array()); | ||||||
|  | @ -803,22 +785,21 @@ Vector<PropertyID> longhands_for_shorthand(PropertyID property_id) | ||||||
|             property_generator.set("name:titlecase", title_casify(name)); |             property_generator.set("name:titlecase", title_casify(name)); | ||||||
|             StringBuilder builder; |             StringBuilder builder; | ||||||
|             bool first = true; |             bool first = true; | ||||||
|             TRY(longhand_values.try_for_each([&](auto& longhand) -> ErrorOr<IterationDecision> { |             longhand_values.for_each([&](auto& longhand) { | ||||||
|                 if (first) |                 if (first) | ||||||
|                     first = false; |                     first = false; | ||||||
|                 else |                 else | ||||||
|                     builder.append(", "sv); |                     builder.append(", "sv); | ||||||
|                 TRY(builder.try_appendff("PropertyID::{}", title_casify(longhand.to_deprecated_string()))); |                 builder.appendff("PropertyID::{}", title_casify(longhand.to_deprecated_string())); | ||||||
|                 return IterationDecision::Continue; |                 return IterationDecision::Continue; | ||||||
|             })); |             }); | ||||||
|             property_generator.set("longhands", builder.to_deprecated_string()); |             property_generator.set("longhands", builder.to_deprecated_string()); | ||||||
|             property_generator.append(R"~~~( |             property_generator.append(R"~~~( | ||||||
|         case PropertyID::@name:titlecase@: |         case PropertyID::@name:titlecase@: | ||||||
|                 return { @longhands@ }; |                 return { @longhands@ }; | ||||||
| )~~~"); | )~~~"); | ||||||
|         } |         } | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|         default: |         default: | ||||||
|  |  | ||||||
|  | @ -53,13 +53,12 @@ namespace Web::CSS { | ||||||
| enum class PseudoClass { | enum class PseudoClass { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(pseudo_classes_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     pseudo_classes_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
| 
 | 
 | ||||||
|         member_generator.appendln("    @name:titlecase@,"); |         member_generator.appendln("    @name:titlecase@,"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -103,17 +102,16 @@ Optional<PseudoClass> pseudo_class_from_string(StringView string) | ||||||
| { | { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(pseudo_classes_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     pseudo_classes_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
| 
 | 
 | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (string.equals_ignoring_ascii_case("@name@"sv)) |     if (string.equals_ignoring_ascii_case("@name@"sv)) | ||||||
|         return PseudoClass::@name:titlecase@; |         return PseudoClass::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| 
 | 
 | ||||||
|  | @ -125,17 +123,16 @@ StringView pseudo_class_name(PseudoClass pseudo_class) | ||||||
|     switch (pseudo_class) { |     switch (pseudo_class) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(pseudo_classes_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     pseudo_classes_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify(name)); |         member_generator.set("name:titlecase", title_casify(name)); | ||||||
| 
 | 
 | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case PseudoClass::@name:titlecase@: |     case PseudoClass::@name:titlecase@: | ||||||
|         return "@name@"sv; |         return "@name@"sv; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  | @ -147,7 +144,7 @@ PseudoClassMetadata pseudo_class_metadata(PseudoClass pseudo_class) | ||||||
|     switch (pseudo_class) { |     switch (pseudo_class) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(pseudo_classes_data.try_for_each_member([&](auto& name, JsonValue const& value) -> ErrorOr<void> { |     pseudo_classes_data.for_each_member([&](auto& name, JsonValue const& value) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         auto& pseudo_class = value.as_object(); |         auto& pseudo_class = value.as_object(); | ||||||
|         auto argument_string = pseudo_class.get_deprecated_string("argument"sv).value(); |         auto argument_string = pseudo_class.get_deprecated_string("argument"sv).value(); | ||||||
|  | @ -195,8 +192,7 @@ PseudoClassMetadata pseudo_class_metadata(PseudoClass pseudo_class) | ||||||
|             .is_valid_as_identifier = @is_valid_as_identifier@, |             .is_valid_as_identifier = @is_valid_as_identifier@, | ||||||
|         }; |         }; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -65,12 +65,11 @@ namespace Web::CSS { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     generator.appendln("enum class TransformFunction {"); |     generator.appendln("enum class TransformFunction {"); | ||||||
|     TRY(transforms_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     transforms_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify_transform_function(name)); |         member_generator.set("name:titlecase", title_casify_transform_function(name)); | ||||||
|         member_generator.appendln("    @name:titlecase@,"); |         member_generator.appendln("    @name:titlecase@,"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.appendln("};"); |     generator.appendln("};"); | ||||||
| 
 | 
 | ||||||
|     generator.appendln("Optional<TransformFunction> transform_function_from_string(StringView);"); |     generator.appendln("Optional<TransformFunction> transform_function_from_string(StringView);"); | ||||||
|  | @ -117,16 +116,15 @@ namespace Web::CSS { | ||||||
| Optional<TransformFunction> transform_function_from_string(StringView name) | Optional<TransformFunction> transform_function_from_string(StringView name) | ||||||
| { | { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(transforms_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     transforms_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify_transform_function(name)); |         member_generator.set("name:titlecase", title_casify_transform_function(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     if (name.equals_ignoring_ascii_case("@name@"sv)) |     if (name.equals_ignoring_ascii_case("@name@"sv)) | ||||||
|         return TransformFunction::@name:titlecase@; |         return TransformFunction::@name:titlecase@; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
|  | @ -137,16 +135,15 @@ StringView to_string(TransformFunction transform_function) | ||||||
| { | { | ||||||
|     switch (transform_function) { |     switch (transform_function) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(transforms_data.try_for_each_member([&](auto& name, auto&) -> ErrorOr<void> { |     transforms_data.for_each_member([&](auto& name, auto&) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name))); |         member_generator.set("name", name); | ||||||
|         member_generator.set("name:titlecase", title_casify_transform_function(name)); |         member_generator.set("name:titlecase", title_casify_transform_function(name)); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case TransformFunction::@name:titlecase@: |     case TransformFunction::@name:titlecase@: | ||||||
|         return "@name@"sv; |         return "@name@"sv; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|  | @ -159,7 +156,7 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor | ||||||
| { | { | ||||||
|     switch (transform_function) { |     switch (transform_function) { | ||||||
| )~~~"); | )~~~"); | ||||||
|     TRY(transforms_data.try_for_each_member([&](auto& name, auto& value) -> ErrorOr<void> { |     transforms_data.for_each_member([&](auto& name, auto& value) { | ||||||
|         VERIFY(value.is_object()); |         VERIFY(value.is_object()); | ||||||
| 
 | 
 | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|  | @ -171,7 +168,7 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor | ||||||
| 
 | 
 | ||||||
|         JsonArray const& parameters = value.as_object().get_array("parameters"sv).value(); |         JsonArray const& parameters = value.as_object().get_array("parameters"sv).value(); | ||||||
|         bool first = true; |         bool first = true; | ||||||
|         TRY(parameters.try_for_each([&](JsonValue const& value) -> ErrorOr<void> { |         parameters.for_each([&](JsonValue const& value) { | ||||||
|             GenericLexer lexer { value.as_object().get_deprecated_string("type"sv).value() }; |             GenericLexer lexer { value.as_object().get_deprecated_string("type"sv).value() }; | ||||||
|             VERIFY(lexer.consume_specific('<')); |             VERIFY(lexer.consume_specific('<')); | ||||||
|             auto parameter_type_name = lexer.consume_until('>'); |             auto parameter_type_name = lexer.consume_until('>'); | ||||||
|  | @ -192,15 +189,13 @@ TransformFunctionMetadata transform_function_metadata(TransformFunction transfor | ||||||
|             member_generator.append(first ? " "sv : ", "sv); |             member_generator.append(first ? " "sv : ", "sv); | ||||||
|             first = false; |             first = false; | ||||||
| 
 | 
 | ||||||
|             member_generator.append(TRY(String::formatted("{{ TransformFunctionParameterType::{}, {}}}", parameter_type, value.as_object().get("required"sv)->to_deprecated_string()))); |             member_generator.append(MUST(String::formatted("{{ TransformFunctionParameterType::{}, {}}}", parameter_type, value.as_object().get("required"sv)->to_deprecated_string()))); | ||||||
|             return {}; |         }); | ||||||
|         })); |  | ||||||
| 
 | 
 | ||||||
|         member_generator.append(R"~~~( } |         member_generator.append(R"~~~( } | ||||||
|     }; |     }; | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|  |  | ||||||
|  | @ -55,15 +55,14 @@ enum class ValueID { | ||||||
|     Invalid, |     Invalid, | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(identifier_data.try_for_each([&](auto& name) -> ErrorOr<void> { |     identifier_data.for_each([&](auto& name) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); |         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); | ||||||
| 
 | 
 | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     @name:titlecase@, |     @name:titlecase@, | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| }; | }; | ||||||
|  | @ -94,15 +93,14 @@ namespace Web::CSS { | ||||||
| HashMap<StringView, ValueID, AK::CaseInsensitiveASCIIStringViewTraits> g_stringview_to_value_id_map { | HashMap<StringView, ValueID, AK::CaseInsensitiveASCIIStringViewTraits> g_stringview_to_value_id_map { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(identifier_data.try_for_each([&](auto& name) -> ErrorOr<void> { |     identifier_data.for_each([&](auto& name) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name.to_deprecated_string()))); |         member_generator.set("name", name.to_deprecated_string()); | ||||||
|         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); |         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     {"@name@"sv, ValueID::@name:titlecase@}, |     {"@name@"sv, ValueID::@name:titlecase@}, | ||||||
| )~~~"); | )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
| }; | }; | ||||||
|  | @ -116,16 +114,15 @@ StringView string_from_value_id(ValueID value_id) { | ||||||
|     switch (value_id) { |     switch (value_id) { | ||||||
| )~~~"); | )~~~"); | ||||||
| 
 | 
 | ||||||
|     TRY(identifier_data.try_for_each([&](auto& name) -> ErrorOr<void> { |     identifier_data.for_each([&](auto& name) { | ||||||
|         auto member_generator = generator.fork(); |         auto member_generator = generator.fork(); | ||||||
|         member_generator.set("name", TRY(String::from_deprecated_string(name.to_deprecated_string()))); |         member_generator.set("name", name.to_deprecated_string()); | ||||||
|         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); |         member_generator.set("name:titlecase", title_casify(name.to_deprecated_string())); | ||||||
|         member_generator.append(R"~~~( |         member_generator.append(R"~~~( | ||||||
|     case ValueID::@name:titlecase@: |     case ValueID::@name:titlecase@: | ||||||
|         return "@name@"sv; |         return "@name@"sv; | ||||||
|         )~~~"); |         )~~~"); | ||||||
|         return {}; |     }); | ||||||
|     })); |  | ||||||
| 
 | 
 | ||||||
|     generator.append(R"~~~( |     generator.append(R"~~~( | ||||||
|     default: |     default: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling