From 32fa75c910dc8c1af9f74bfeda5da5bf03bc57de Mon Sep 17 00:00:00 2001 From: Victorien Elvinger Date: Fri, 27 Oct 2023 14:48:30 +0200 Subject: [PATCH] refactor(json_deserialize): improve `map_to_*` API (#616) --- crates/biome_deserialize/src/json.rs | 34 ++++++------------- .../use_exhaustive_dependencies.rs | 2 +- .../style/use_naming_convention.rs | 5 ++- .../configuration/parse/json/configuration.rs | 16 ++++----- .../src/configuration/parse/json/formatter.rs | 2 +- .../parse/json/javascript/formatter.rs | 14 ++++---- .../parse/json/javascript/mod.rs | 11 ++---- .../configuration/parse/json/json_impl/mod.rs | 6 ++-- .../src/configuration/parse/json/linter.rs | 26 ++++---------- .../src/configuration/parse/json/overrides.rs | 16 ++++----- .../src/configuration/parse/json/rules.rs | 16 ++++----- .../src/configuration/parse/json/vcs.rs | 2 +- xtask/codegen/src/generate_configuration.rs | 2 +- 13 files changed, 61 insertions(+), 91 deletions(-) diff --git a/crates/biome_deserialize/src/json.rs b/crates/biome_deserialize/src/json.rs index f9841fc0df53..a243050d2973 100644 --- a/crates/biome_deserialize/src/json.rs +++ b/crates/biome_deserialize/src/json.rs @@ -65,18 +65,14 @@ pub trait VisitJsonNode: VisitNode { /// ## Errors /// /// The function will emit a generic diagnostic if the `visitor` doesn't implement [visit_member_value] - fn map_to_known_string( - &self, + fn map_to_known_string( + &mut self, value: &AnyJsonValue, name: &str, - visitor: &mut T, diagnostics: &mut Vec, - ) -> Option<()> - where - T: VisitNode, - { + ) -> Option<()> { if JsonStringValue::can_cast(value.syntax().kind()) { - visitor.visit_member_value(value.syntax(), diagnostics)?; + self.visit_member_value(value.syntax(), diagnostics)?; return Some(()); } diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value( @@ -395,16 +391,12 @@ pub trait VisitJsonNode: VisitNode { /// ## Errors /// This function will emit diagnostics if: /// - the `value` can't be cast to [JsonObjectValue] - fn map_to_object( + fn map_to_object( &mut self, value: &AnyJsonValue, name: &str, - visitor: &mut T, diagnostics: &mut Vec, - ) -> Option<()> - where - T: VisitNode, - { + ) -> Option<()> { let value = JsonObjectValue::cast_ref(value.syntax()).or_else(|| { diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value( name, @@ -415,7 +407,7 @@ pub trait VisitJsonNode: VisitNode { })?; for element in value.json_member_list() { let element = element.ok()?; - visitor.visit_map( + self.visit_map( element.name().ok()?.syntax(), element.value().ok()?.syntax(), diagnostics, @@ -424,16 +416,12 @@ pub trait VisitJsonNode: VisitNode { Some(()) } - fn map_to_array( - &self, + fn map_to_array( + &mut self, value: &AnyJsonValue, name: &str, - visitor: &mut V, diagnostics: &mut Vec, - ) -> Option<()> - where - V: VisitNode, - { + ) -> Option<()> { let array = JsonArrayValue::cast_ref(value.syntax()).or_else(|| { diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value( name, @@ -447,7 +435,7 @@ pub trait VisitJsonNode: VisitNode { } for element in array.elements() { let element = element.ok()?; - visitor.visit_array_member(element.syntax(), diagnostics); + self.visit_array_member(element.syntax(), diagnostics); } Some(()) diff --git a/crates/biome_js_analyze/src/semantic_analyzers/correctness/use_exhaustive_dependencies.rs b/crates/biome_js_analyze/src/semantic_analyzers/correctness/use_exhaustive_dependencies.rs index d0d2adfaecb7..bf6f368ffb96 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/correctness/use_exhaustive_dependencies.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/correctness/use_exhaustive_dependencies.rs @@ -339,7 +339,7 @@ impl VisitNode for HooksOptions { for element in array.elements() { let element = element.ok()?; let mut hooks = Hooks::default(); - self.map_to_object(&element, "hooks", &mut hooks, diagnostics)?; + hooks.map_to_object(&element, "hooks", diagnostics)?; self.hooks.push(hooks); } } diff --git a/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs b/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs index 224e9429b6ca..9d36d89dbda8 100644 --- a/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs +++ b/crates/biome_js_analyze/src/semantic_analyzers/style/use_naming_convention.rs @@ -512,9 +512,8 @@ impl VisitNode for NamingConventionOptions { self.strict_case = self.map_to_boolean(&value, name_text, diagnostics)? } "enumMemberCase" => { - let mut enum_member_case = EnumMemberCase::default(); - self.map_to_known_string(&value, name_text, &mut enum_member_case, diagnostics)?; - self.enum_member_case = enum_member_case; + self.enum_member_case + .map_to_known_string(&value, name_text, diagnostics)?; } _ => (), } diff --git a/crates/biome_service/src/configuration/parse/json/configuration.rs b/crates/biome_service/src/configuration/parse/json/configuration.rs index edc29f0b3306..7b164e7bcfe2 100644 --- a/crates/biome_service/src/configuration/parse/json/configuration.rs +++ b/crates/biome_service/src/configuration/parse/json/configuration.rs @@ -35,38 +35,38 @@ impl VisitNode for Configuration { } "files" => { let mut files = FilesConfiguration::default(); - self.map_to_object(&value, name_text, &mut files, diagnostics)?; + files.map_to_object(&value, name_text, diagnostics)?; self.files = Some(files); } "vcs" => { let mut vcs = VcsConfiguration::default(); - self.map_to_object(&value, name_text, &mut vcs, diagnostics)?; + vcs.map_to_object(&value, name_text, diagnostics)?; validate_vcs_configuration(&value, &mut vcs, diagnostics); self.vcs = Some(vcs); } "formatter" => { let mut formatter = FormatterConfiguration::default(); - self.map_to_object(&value, name_text, &mut formatter, diagnostics)?; + formatter.map_to_object(&value, name_text, diagnostics)?; self.formatter = Some(formatter); } "linter" => { let mut linter = LinterConfiguration::default(); - self.map_to_object(&value, name_text, &mut linter, diagnostics)?; + linter.map_to_object(&value, name_text, diagnostics)?; self.linter = Some(linter); } "javascript" => { let mut javascript = JavascriptConfiguration::default(); - self.map_to_object(&value, name_text, &mut javascript, diagnostics)?; + javascript.map_to_object(&value, name_text, diagnostics)?; self.javascript = Some(javascript); } "json" => { let mut json = JsonConfiguration::default(); - self.map_to_object(&value, name_text, &mut json, diagnostics)?; + json.map_to_object(&value, name_text, diagnostics)?; self.json = Some(json); } "organizeImports" => { let mut organize_imports = OrganizeImports::default(); - self.map_to_object(&value, name_text, &mut organize_imports, diagnostics)?; + organize_imports.map_to_object(&value, name_text, diagnostics)?; self.organize_imports = Some(organize_imports); } "extends" => { @@ -76,7 +76,7 @@ impl VisitNode for Configuration { } "overrides" => { let mut overrides = Overrides::default(); - self.map_to_array(&value, name_text, &mut overrides, diagnostics)?; + overrides.map_to_array(&value, name_text, diagnostics)?; self.overrides = Some(overrides); } _ => {} diff --git a/crates/biome_service/src/configuration/parse/json/formatter.rs b/crates/biome_service/src/configuration/parse/json/formatter.rs index 289710571ec1..56667fa72827 100644 --- a/crates/biome_service/src/configuration/parse/json/formatter.rs +++ b/crates/biome_service/src/configuration/parse/json/formatter.rs @@ -41,7 +41,7 @@ impl VisitNode for FormatterConfiguration { "indentStyle" => { let mut indent_style = PlainIndentStyle::default(); - self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?; + indent_style.map_to_known_string(&value, name_text, diagnostics)?; self.indent_style = Some(indent_style); } "indentSize" => { diff --git a/crates/biome_service/src/configuration/parse/json/javascript/formatter.rs b/crates/biome_service/src/configuration/parse/json/javascript/formatter.rs index 2681ad9e24b5..dbb050a8a4ba 100644 --- a/crates/biome_service/src/configuration/parse/json/javascript/formatter.rs +++ b/crates/biome_service/src/configuration/parse/json/javascript/formatter.rs @@ -33,32 +33,32 @@ impl VisitNode for JavascriptFormatter { match name_text { "jsxQuoteStyle" => { let mut jsx_quote_style = QuoteStyle::default(); - self.map_to_known_string(&value, name_text, &mut jsx_quote_style, diagnostics)?; + jsx_quote_style.map_to_known_string(&value, name_text, diagnostics)?; self.jsx_quote_style = Some(jsx_quote_style); } "quoteStyle" => { let mut quote_style = QuoteStyle::default(); - self.map_to_known_string(&value, name_text, &mut quote_style, diagnostics)?; + quote_style.map_to_known_string(&value, name_text, diagnostics)?; self.quote_style = Some(quote_style); } "trailingComma" => { let mut trailing_comma = TrailingComma::default(); - self.map_to_known_string(&value, name_text, &mut trailing_comma, diagnostics)?; + trailing_comma.map_to_known_string(&value, name_text, diagnostics)?; self.trailing_comma = Some(trailing_comma); } "quoteProperties" => { let mut quote_properties = QuoteProperties::default(); - self.map_to_known_string(&value, name_text, &mut quote_properties, diagnostics)?; + quote_properties.map_to_known_string(&value, name_text, diagnostics)?; self.quote_properties = Some(quote_properties); } "semicolons" => { let mut semicolons = Semicolons::default(); - self.map_to_known_string(&value, name_text, &mut semicolons, diagnostics)?; + semicolons.map_to_known_string(&value, name_text, diagnostics)?; self.semicolons = Some(semicolons); } "arrowParentheses" => { let mut arrow_parentheses = ArrowParentheses::default(); - self.map_to_known_string(&value, name_text, &mut arrow_parentheses, diagnostics)?; + arrow_parentheses.map_to_known_string(&value, name_text, diagnostics)?; self.arrow_parentheses = Some(arrow_parentheses); } @@ -68,7 +68,7 @@ impl VisitNode for JavascriptFormatter { "indentStyle" => { let mut indent_style = PlainIndentStyle::default(); - self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?; + indent_style.map_to_known_string(&value, name_text, diagnostics)?; self.indent_style = Some(indent_style); } "indentSize" => { diff --git a/crates/biome_service/src/configuration/parse/json/javascript/mod.rs b/crates/biome_service/src/configuration/parse/json/javascript/mod.rs index a92b848e6aa7..8d790c98cee6 100644 --- a/crates/biome_service/src/configuration/parse/json/javascript/mod.rs +++ b/crates/biome_service/src/configuration/parse/json/javascript/mod.rs @@ -28,13 +28,13 @@ impl VisitNode for JavascriptConfiguration { match name_text { "formatter" => { let mut javascript_formatter = JavascriptFormatter::default(); - self.map_to_object(&value, name_text, &mut javascript_formatter, diagnostics)?; + javascript_formatter.map_to_object(&value, name_text, diagnostics)?; self.formatter = Some(javascript_formatter); } "parser" => { let mut parser = JavascriptParser::default(); - self.map_to_object(&value, name_text, &mut parser, diagnostics)?; + parser.map_to_object(&value, name_text, diagnostics)?; self.parser = Some(parser); } @@ -45,12 +45,7 @@ impl VisitNode for JavascriptConfiguration { } "organizeImports" => { let mut javascript_organize_imports = JavascriptOrganizeImports::default(); - self.map_to_object( - &value, - name_text, - &mut javascript_organize_imports, - diagnostics, - )?; + javascript_organize_imports.map_to_object(&value, name_text, diagnostics)?; self.organize_imports = Some(javascript_organize_imports); } _ => {} diff --git a/crates/biome_service/src/configuration/parse/json/json_impl/mod.rs b/crates/biome_service/src/configuration/parse/json/json_impl/mod.rs index 4ad8a757b446..d36155df9dd8 100644 --- a/crates/biome_service/src/configuration/parse/json/json_impl/mod.rs +++ b/crates/biome_service/src/configuration/parse/json/json_impl/mod.rs @@ -27,12 +27,12 @@ impl VisitNode for JsonConfiguration { match name_text { "parser" => { let mut parser = JsonParser::default(); - self.map_to_object(&value, name_text, &mut parser, diagnostics)?; + parser.map_to_object(&value, name_text, diagnostics)?; self.parser = Some(parser); } "formatter" => { let mut formatter = JsonFormatter::default(); - self.map_to_object(&value, name_text, &mut formatter, diagnostics)?; + formatter.map_to_object(&value, name_text, diagnostics)?; self.formatter = Some(formatter); } @@ -98,7 +98,7 @@ impl VisitNode for JsonFormatter { "indentStyle" => { let mut indent_style = PlainIndentStyle::default(); - self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?; + indent_style.map_to_known_string(&value, name_text, diagnostics)?; self.indent_style = Some(indent_style); } "indentSize" => { diff --git a/crates/biome_service/src/configuration/parse/json/linter.rs b/crates/biome_service/src/configuration/parse/json/linter.rs index a52520ee4d14..1d1ba06109d5 100644 --- a/crates/biome_service/src/configuration/parse/json/linter.rs +++ b/crates/biome_service/src/configuration/parse/json/linter.rs @@ -40,15 +40,14 @@ impl VisitNode for LinterConfiguration { self.enabled = self.map_to_boolean(&value, name_text, diagnostics); } "rules" => { - let mut rules = Rules::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut rules, diagnostics)?; + let mut rules = Rules::default(); + rules.map_to_object(&value, name_text, diagnostics)?; self.rules = Some(rules); } } _ => {} } - Some(()) } } @@ -62,9 +61,7 @@ impl RuleConfiguration { ) -> Option<()> { match value { AnyJsonValue::JsonStringValue(_) => { - let mut configuration = RuleConfiguration::default(); - self.map_to_known_string(value, rule_name, &mut configuration, diagnostics)?; - *self = configuration; + self.map_to_known_string(value, rule_name, diagnostics)?; } AnyJsonValue::JsonObjectValue(_) => { let with_options = RuleWithOptions { @@ -72,7 +69,7 @@ impl RuleConfiguration { options: PossibleOptions::new_from_rule_name(rule_name), }; let mut configuration = RuleConfiguration::WithOptions(with_options); - self.map_to_object(value, rule_name, &mut configuration, diagnostics)?; + configuration.map_to_object(value, rule_name, diagnostics)?; *self = configuration; } _ => { @@ -126,17 +123,8 @@ impl VisitNode for RulePlainConfiguration { diagnostics: &mut Vec, ) -> Option<()> { let node = with_only_known_variants(node, RulePlainConfiguration::KNOWN_KEYS, diagnostics)?; - match node.inner_string_text().ok()?.text() { - "error" => { - *self = RulePlainConfiguration::Error; - } - "warn" => { - *self = RulePlainConfiguration::Warn; - } - "off" => { - *self = RulePlainConfiguration::Off; - } - _ => {} + if let Ok(value) = node.inner_string_text().ok()?.text().parse::() { + *self = value; } Some(()) } @@ -167,7 +155,7 @@ impl VisitNode for RuleWithOptions { } "options" => { let mut possible_options = self.options.take()?; - self.map_to_object(&value, name_text, &mut possible_options, diagnostics); + possible_options.map_to_object(&value, name_text, diagnostics); self.options = Some(possible_options); } _ => {} diff --git a/crates/biome_service/src/configuration/parse/json/overrides.rs b/crates/biome_service/src/configuration/parse/json/overrides.rs index 5c0efb41c8cd..f41b25a5bcf6 100644 --- a/crates/biome_service/src/configuration/parse/json/overrides.rs +++ b/crates/biome_service/src/configuration/parse/json/overrides.rs @@ -20,7 +20,7 @@ impl VisitNode for Overrides { ) -> Option<()> { let mut pattern = OverridePattern::default(); let element = AnyJsonValue::cast_ref(element)?; - self.map_to_object(&element, "overrides", &mut pattern, diagnostics)?; + pattern.map_to_object(&element, "overrides", diagnostics)?; self.0.push(pattern); Some(()) } @@ -56,27 +56,27 @@ impl VisitNode for OverridePattern { } "formatter" => { let mut formatter = OverrideFormatterConfiguration::default(); - self.map_to_object(&value, name_text, &mut formatter, diagnostics)?; + formatter.map_to_object(&value, name_text, diagnostics)?; self.formatter = Some(formatter); } "linter" => { let mut linter = OverrideLinterConfiguration::default(); - self.map_to_object(&value, name_text, &mut linter, diagnostics)?; + linter.map_to_object(&value, name_text, diagnostics)?; self.linter = Some(linter); } "organizeImports" => { let mut organize_imports = OverrideOrganizeImportsConfiguration::default(); - self.map_to_object(&value, name_text, &mut organize_imports, diagnostics)?; + organize_imports.map_to_object(&value, name_text, diagnostics)?; self.organize_imports = Some(organize_imports); } "javascript" => { let mut javascript = JavascriptConfiguration::default(); - self.map_to_object(&value, name_text, &mut javascript, diagnostics)?; + javascript.map_to_object(&value, name_text, diagnostics)?; self.javascript = Some(javascript); } "json" => { let mut json = JsonConfiguration::default(); - self.map_to_object(&value, name_text, &mut json, diagnostics)?; + json.map_to_object(&value, name_text, diagnostics)?; self.json = Some(json); } _ => {} @@ -114,7 +114,7 @@ impl VisitNode for OverrideFormatterConfiguration { "indentStyle" => { let mut indent_style = PlainIndentStyle::default(); - self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?; + indent_style.map_to_known_string(&value, name_text, diagnostics)?; self.indent_style = Some(indent_style); } "indentSize" => { @@ -179,7 +179,7 @@ impl VisitNode for OverrideLinterConfiguration { "rules" => { let mut rules = Rules::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut rules, diagnostics)?; + rules.map_to_object(&value, name_text, diagnostics)?; self.rules = Some(rules); } } diff --git a/crates/biome_service/src/configuration/parse/json/rules.rs b/crates/biome_service/src/configuration/parse/json/rules.rs index aaaa031d6b7b..5bd8f11bfeaf 100644 --- a/crates/biome_service/src/configuration/parse/json/rules.rs +++ b/crates/biome_service/src/configuration/parse/json/rules.rs @@ -48,56 +48,56 @@ impl VisitNode for Rules { "a11y" => { let mut visitor = A11y::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.a11y = Some(visitor); } } "complexity" => { let mut visitor = Complexity::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.complexity = Some(visitor); } } "correctness" => { let mut visitor = Correctness::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.correctness = Some(visitor); } } "nursery" => { let mut visitor = Nursery::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.nursery = Some(visitor); } } "performance" => { let mut visitor = Performance::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.performance = Some(visitor); } } "security" => { let mut visitor = Security::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.security = Some(visitor); } } "style" => { let mut visitor = Style::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.style = Some(visitor); } } "suspicious" => { let mut visitor = Suspicious::default(); if are_recommended_and_all_correct(&value, name_text, diagnostics)? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.suspicious = Some(visitor); } } diff --git a/crates/biome_service/src/configuration/parse/json/vcs.rs b/crates/biome_service/src/configuration/parse/json/vcs.rs index fe79940dee7b..206c7dd7cefc 100644 --- a/crates/biome_service/src/configuration/parse/json/vcs.rs +++ b/crates/biome_service/src/configuration/parse/json/vcs.rs @@ -25,7 +25,7 @@ impl VisitNode for VcsConfiguration { match name_text { "clientKind" => { let mut client_kind = VcsClientKind::default(); - self.map_to_known_string(&value, name_text, &mut client_kind, diagnostics)?; + client_kind.map_to_known_string(&value, name_text, diagnostics)?; self.client_kind = Some(client_kind); } "enabled" => { diff --git a/xtask/codegen/src/generate_configuration.rs b/xtask/codegen/src/generate_configuration.rs index b4dc9cae1a85..e1e771947beb 100644 --- a/xtask/codegen/src/generate_configuration.rs +++ b/xtask/codegen/src/generate_configuration.rs @@ -142,7 +142,7 @@ pub(crate) fn generate_rules_configuration(mode: Mode) -> Result<()> { name_text, diagnostics, )? { - self.map_to_object(&value, name_text, &mut visitor, diagnostics)?; + visitor.map_to_object(&value, name_text, diagnostics)?; self.#property_group_name = Some(visitor); } }