diff --git a/crates/biome_json_parser/src/lexer/mod.rs b/crates/biome_json_parser/src/lexer/mod.rs index 6303633bacd3..a80fd13864b9 100644 --- a/crates/biome_json_parser/src/lexer/mod.rs +++ b/crates/biome_json_parser/src/lexer/mod.rs @@ -731,7 +731,7 @@ impl<'src> Lexer<'src> { b'*' if self.peek_byte() == Some(b'/') => { self.advance(2); - if !self.options.allow_comments { + if !self.options.allow_comments() { self.diagnostics.push(ParseDiagnostic::new( "JSON standard does not allow comments.", start..self.text_position(), @@ -777,7 +777,7 @@ impl<'src> Lexer<'src> { } } - if !self.options.allow_comments { + if !self.options.allow_comments() { self.diagnostics.push(ParseDiagnostic::new( "JSON standard does not allow comments.", start..self.text_position(), diff --git a/crates/biome_json_parser/src/parser.rs b/crates/biome_json_parser/src/parser.rs index 04e92e97d732..453ec338264f 100644 --- a/crates/biome_json_parser/src/parser.rs +++ b/crates/biome_json_parser/src/parser.rs @@ -14,20 +14,28 @@ pub(crate) struct JsonParser<'source> { #[derive(Default, Debug, Clone, Copy)] pub struct JsonParserOptions { - pub allow_comments: bool, - pub allow_trailing_commas: bool, + pub allow_comments: Option, + pub allow_trailing_commas: Option, } impl JsonParserOptions { pub fn with_allow_comments(mut self) -> Self { - self.allow_comments = true; + self.allow_comments = Some(true); self } pub fn with_allow_trailing_commas(mut self) -> Self { - self.allow_trailing_commas = true; + self.allow_trailing_commas = Some(true); self } + + pub fn allow_comments(&self) -> bool { + self.allow_comments.unwrap_or_default() + } + + pub fn allow_trailing_commas(&self) -> bool { + self.allow_trailing_commas.unwrap_or_default() + } } impl From<&JsonFileSource> for JsonParserOptions { diff --git a/crates/biome_json_parser/src/syntax.rs b/crates/biome_json_parser/src/syntax.rs index c81eba6840cb..bccb37aaad8f 100644 --- a/crates/biome_json_parser/src/syntax.rs +++ b/crates/biome_json_parser/src/syntax.rs @@ -189,7 +189,7 @@ fn parse_sequence(p: &mut JsonParser, root_kind: SequenceKind) -> ParsedSyntax { match current.parse_item(p) { SequenceItem::Parsed(Absent) => { - if p.options().allow_trailing_commas && p.last() == Some(T![,]) { + if p.options().allow_trailing_commas() && p.last() == Some(T![,]) { break; } @@ -261,7 +261,7 @@ fn parse_object_member(p: &mut JsonParser) -> SequenceItem { let m = p.start(); if parse_member_name(p).is_absent() { - if !(p.options().allow_trailing_commas && p.last() == Some(T![,])) { + if !(p.options().allow_trailing_commas() && p.last() == Some(T![,])) { p.error(expected_property(p, p.cur_range())); } diff --git a/crates/biome_json_parser/src/token_source.rs b/crates/biome_json_parser/src/token_source.rs index 00aa8a524f89..c618e9114b6d 100644 --- a/crates/biome_json_parser/src/token_source.rs +++ b/crates/biome_json_parser/src/token_source.rs @@ -46,7 +46,7 @@ impl<'source> JsonTokenSource<'source> { // Not trivia break; } - Ok(trivia_kind) if trivia_kind.is_comment() && !self.options.allow_comments => { + Ok(trivia_kind) if trivia_kind.is_comment() && !self.options.allow_comments() => { self.set_current_token(token); // Not trivia diff --git a/crates/biome_json_parser/tests/spec_test.rs b/crates/biome_json_parser/tests/spec_test.rs index 90cdbbe3a4a4..75d49f0489af 100644 --- a/crates/biome_json_parser/tests/spec_test.rs +++ b/crates/biome_json_parser/tests/spec_test.rs @@ -35,11 +35,11 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_ let content = fs::read_to_string(test_case_path) .expect("Expected test path to be a readable file in UTF8 encoding"); - let parse_conifg = JsonParserOptions { - allow_comments: test_directory.contains("allow_comments"), - allow_trailing_commas: test_directory.contains("allow_trailing_commas"), + let parse_config = JsonParserOptions { + allow_comments: Some(test_directory.contains("allow_comments")), + allow_trailing_commas: Some(test_directory.contains("allow_trailing_commas")), }; - let parsed = parse_json(&content, parse_conifg); + let parsed = parse_json(&content, parse_config); let formatted_ast = format!("{:#?}", parsed.tree()); let mut snapshot = String::new(); diff --git a/crates/biome_service/src/file_handlers/json.rs b/crates/biome_service/src/file_handlers/json.rs index e86c728bc29d..58622789cec8 100644 --- a/crates/biome_service/src/file_handlers/json.rs +++ b/crates/biome_service/src/file_handlers/json.rs @@ -48,8 +48,8 @@ pub struct JsonFormatterSettings { #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsonParserSettings { - pub allow_comments: bool, - pub allow_trailing_commas: bool, + pub allow_comments: Option, + pub allow_trailing_commas: Option, } #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] @@ -179,10 +179,12 @@ fn parse( let overrides = settings.map(|s| &s.override_settings); let optional_json_file_source = file_source.to_json_file_source(); let options = JsonParserOptions { - allow_comments: parser.map(|p| p.allow_comments).unwrap_or_default() - || optional_json_file_source.map_or(false, |x| x.allow_comments()), - allow_trailing_commas: parser.map(|p| p.allow_trailing_commas).unwrap_or_default() - || optional_json_file_source.map_or(false, |x| x.allow_trailing_commas()), + allow_comments: parser + .and_then(|p| p.allow_comments) + .or(optional_json_file_source.map(|x| x.allow_comments())), + allow_trailing_commas: parser + .and_then(|p| p.allow_trailing_commas) + .or(optional_json_file_source.map(|x| x.allow_trailing_commas())), }; let options = if let Some(overrides) = overrides { overrides.to_override_json_parser_options(biome_path, options) diff --git a/crates/biome_service/src/settings.rs b/crates/biome_service/src/settings.rs index c1595369818b..2ea7aad0f5df 100644 --- a/crates/biome_service/src/settings.rs +++ b/crates/biome_service/src/settings.rs @@ -6,7 +6,7 @@ use biome_configuration::javascript::JsxRuntime; use biome_configuration::organize_imports::OrganizeImports; use biome_configuration::{ push_to_analyzer_rules, BiomeDiagnostic, CssConfiguration, FilesConfiguration, - FormatterConfiguration, JavascriptConfiguration, JsonConfiguration, LinterConfiguration, + FormatterConfiguration, JavascriptConfiguration, LinterConfiguration, OverrideFormatterConfiguration, OverrideLinterConfiguration, OverrideOrganizeImportsConfiguration, Overrides, PartialConfiguration, PartialCssConfiguration, PartialJavascriptConfiguration, PartialJsonConfiguration, PlainIndentStyle, Rules, @@ -212,7 +212,7 @@ impl Settings { } // json settings if let Some(json) = configuration.json { - self.languages.json = JsonConfiguration::from(json).into(); + self.languages.json = json.into(); } // css settings if let Some(css) = configuration.css { @@ -471,18 +471,24 @@ impl From for LanguageSettings { } } -impl From for LanguageSettings { - fn from(json: JsonConfiguration) -> Self { +impl From for LanguageSettings { + fn from(json: PartialJsonConfiguration) -> Self { let mut language_setting: LanguageSettings = LanguageSettings::default(); - language_setting.parser.allow_comments = json.parser.allow_comments; - language_setting.parser.allow_trailing_commas = json.parser.allow_trailing_commas; - language_setting.formatter.trailing_commas = json.formatter.trailing_commas; - language_setting.formatter.enabled = Some(json.formatter.enabled); - language_setting.formatter.line_width = json.formatter.line_width; - language_setting.formatter.indent_width = json.formatter.indent_width.map(Into::into); - language_setting.formatter.indent_style = json.formatter.indent_style.map(Into::into); - language_setting.linter.enabled = Some(json.linter.enabled); + if let Some(parser) = json.parser { + language_setting.parser.allow_comments = parser.allow_comments; + language_setting.parser.allow_trailing_commas = parser.allow_trailing_commas; + } + if let Some(formatter) = json.formatter { + language_setting.formatter.trailing_commas = formatter.trailing_commas; + language_setting.formatter.enabled = formatter.enabled; + language_setting.formatter.line_width = formatter.line_width; + language_setting.formatter.indent_width = formatter.indent_width.map(Into::into); + language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); + } + if let Some(linter) = json.linter { + language_setting.linter.enabled = linter.enabled; + } language_setting } @@ -1101,8 +1107,12 @@ impl OverrideSettingPattern { let json_parser = &self.languages.json.parser; - options.allow_trailing_commas = json_parser.allow_trailing_commas; - options.allow_comments = json_parser.allow_comments; + if let Some(allow_comments) = json_parser.allow_comments { + options.allow_comments = Some(allow_comments); + } + if let Some(allow_trailing_commas) = json_parser.allow_trailing_commas { + options.allow_trailing_commas = Some(allow_trailing_commas); + } if let Ok(mut writeonly_cache) = self.cached_json_parser_options.write() { let options = *options; @@ -1328,13 +1338,11 @@ fn to_json_language_settings( let parser = conf.parser.take().unwrap_or_default(); let parent_parser = &parent_settings.parser; - language_setting.parser.allow_comments = parser - .allow_comments - .unwrap_or(parent_parser.allow_comments); + language_setting.parser.allow_comments = parser.allow_comments.or(parent_parser.allow_comments); language_setting.parser.allow_trailing_commas = parser .allow_trailing_commas - .unwrap_or(parent_parser.allow_trailing_commas); + .or(parent_parser.allow_trailing_commas); language_setting }