From 4c92db20b91f139796451adb3f6d1511b1f2c0a2 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Fri, 1 Mar 2024 11:12:15 +0000 Subject: [PATCH] fix(format): correctly apply trailing comma to formatting (#1944) --- CHANGELOG.md | 17 +- Cargo.lock | 4 + crates/biome_cli/src/execute/migrate.rs | 8 +- .../execute/process_file/workspace_file.rs | 5 +- crates/biome_cli/src/execute/std_in.rs | 9 +- crates/biome_cli/tests/commands/format.rs | 69 ++-- .../applies_custom_bracket_same_line.snap | 4 +- .../applies_custom_jsx_quote_style.snap | 4 +- ...ormat_json_when_allow_trailing_commas.snap | 11 +- ...json_when_allow_trailing_commas_write.snap | 34 ++ crates/biome_css_syntax/Cargo.toml | 5 + crates/biome_css_syntax/src/file_source.rs | 10 +- crates/biome_js_parser/Cargo.toml | 2 +- crates/biome_js_syntax/Cargo.toml | 7 +- crates/biome_js_syntax/src/file_source.rs | 88 ++++- crates/biome_js_syntax/src/syntax_node.rs | 4 +- crates/biome_json_formatter/src/context.rs | 8 +- .../src/json/lists/array_element_list.rs | 11 +- .../src/json/lists/member_list.rs | 7 +- crates/biome_json_formatter/src/separated.rs | 13 +- crates/biome_json_syntax/Cargo.toml | 5 + crates/biome_json_syntax/src/file_source.rs | 26 +- .../biome_lsp/src/handlers/text_document.rs | 6 +- crates/biome_service/Cargo.toml | 4 +- crates/biome_service/src/diagnostics.rs | 21 +- .../biome_service/src/file_handlers/astro.rs | 24 +- crates/biome_service/src/file_handlers/css.rs | 37 +- .../src/file_handlers/javascript.rs | 132 +++---- .../biome_service/src/file_handlers/json.rs | 62 +-- crates/biome_service/src/file_handlers/mod.rs | 360 ++++++++++-------- .../biome_service/src/file_handlers/svelte.rs | 26 +- .../src/file_handlers/unknown.rs | 4 - crates/biome_service/src/file_handlers/vue.rs | 25 +- crates/biome_service/src/settings.rs | 9 +- crates/biome_service/src/workspace.rs | 12 +- crates/biome_service/src/workspace/server.rs | 87 +++-- crates/biome_service/tests/workspace.rs | 7 +- .../@biomejs/backend-jsonrpc/src/workspace.ts | 57 ++- packages/@biomejs/js-api/tsconfig.json | 4 +- .../src/content/docs/internals/changelog.md | 17 +- website/tsconfig.json | 6 +- 41 files changed, 785 insertions(+), 466 deletions(-) create mode 100644 crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas_write.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d88431fc58c..aca9d05ddd57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,10 +33,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ```diff @@ -47,10 +47,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ```diff
@@ -296,6 +296,7 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - Fix [#1218](https://github.com/biomejs/biome/issues/1218), by correctly preserving empty lines in member chains. Contributed by @ah-yu +- Fix [#1659](https://github.com/biomejs/biome/issues/1659) and [#1662](https://github.com/biomejs/biome/issues/1662), by correctly taking into account the leading comma inside the formatter options. Contributed by @ematipico ### JavaScript APIs diff --git a/Cargo.lock b/Cargo.lock index 1634fbc2877c..476177059d63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,6 +301,8 @@ name = "biome_css_syntax" version = "0.4.0" dependencies = [ "biome_rowan", + "schemars", + "serde", ] [[package]] @@ -675,6 +677,8 @@ name = "biome_json_syntax" version = "0.4.0" dependencies = [ "biome_rowan", + "schemars", + "serde", ] [[package]] diff --git a/crates/biome_cli/src/execute/migrate.rs b/crates/biome_cli/src/execute/migrate.rs index 2771ed6e0230..d1d96fa1b3e6 100644 --- a/crates/biome_cli/src/execute/migrate.rs +++ b/crates/biome_cli/src/execute/migrate.rs @@ -11,12 +11,10 @@ use biome_diagnostics::Diagnostic; use biome_diagnostics::{category, PrintDiagnostic}; use biome_fs::{BiomePath, ConfigName, FileSystemExt, OpenOptions}; use biome_json_parser::{parse_json_with_cache, JsonParserOptions}; -use biome_json_syntax::JsonRoot; +use biome_json_syntax::{JsonFileSource, JsonRoot}; use biome_migrate::{migrate_configuration, ControlFlow}; use biome_rowan::{AstNode, NodeCache}; -use biome_service::workspace::{ - ChangeFileParams, FixAction, FormatFileParams, Language, OpenFileParams, -}; +use biome_service::workspace::{ChangeFileParams, FixAction, FormatFileParams, OpenFileParams}; use biome_service::{PartialConfiguration, VERSION}; use std::borrow::Cow; use std::ffi::OsStr; @@ -65,7 +63,7 @@ pub(crate) fn run(migrate_payload: MigratePayload) -> Result<(), CliDiagnostic> path: biome_path.clone(), content: configuration_content.to_string(), version: 0, - language_hint: Language::Json, + document_file_source: JsonFileSource::json().into(), })?; let parsed = parse_json_with_cache( diff --git a/crates/biome_cli/src/execute/process_file/workspace_file.rs b/crates/biome_cli/src/execute/process_file/workspace_file.rs index 5b693c9b800d..29738d285d1b 100644 --- a/crates/biome_cli/src/execute/process_file/workspace_file.rs +++ b/crates/biome_cli/src/execute/process_file/workspace_file.rs @@ -2,8 +2,7 @@ use crate::execute::diagnostics::{ResultExt, ResultIoExt}; use crate::execute::process_file::SharedTraversalOptions; use biome_diagnostics::{category, Error}; use biome_fs::{BiomePath, File, OpenOptions}; -use biome_service::file_handlers::Language; -use biome_service::workspace::{FileGuard, OpenFileParams}; +use biome_service::workspace::{DocumentFileSource, FileGuard, OpenFileParams}; use biome_service::{Workspace, WorkspaceError}; use std::path::{Path, PathBuf}; @@ -37,7 +36,7 @@ impl<'ctx, 'app> WorkspaceFile<'ctx, 'app> { let guard = FileGuard::open( ctx.workspace, OpenFileParams { - language_hint: Language::from_path(&biome_path), + document_file_source: DocumentFileSource::from_path(&biome_path), path: biome_path, version: 0, content: input.clone(), diff --git a/crates/biome_cli/src/execute/std_in.rs b/crates/biome_cli/src/execute/std_in.rs index 9335a5603593..9456364e6834 100644 --- a/crates/biome_cli/src/execute/std_in.rs +++ b/crates/biome_cli/src/execute/std_in.rs @@ -8,8 +8,9 @@ use biome_diagnostics::Diagnostic; use biome_diagnostics::PrintDiagnostic; use biome_fs::BiomePath; use biome_service::workspace::{ - ChangeFileParams, FeaturesBuilder, FixFileParams, FormatFileParams, Language, OpenFileParams, - OrganizeImportsParams, PullDiagnosticsParams, RuleCategories, SupportsFeatureParams, + ChangeFileParams, DocumentFileSource, FeaturesBuilder, FixFileParams, FormatFileParams, + OpenFileParams, OrganizeImportsParams, PullDiagnosticsParams, RuleCategories, + SupportsFeatureParams, }; use biome_service::WorkspaceError; use std::borrow::Cow; @@ -48,7 +49,7 @@ pub(crate) fn run<'a>( path: biome_path.clone(), version: 0, content: content.into(), - language_hint: Language::default(), + document_file_source: DocumentFileSource::default(), })?; let printed = workspace.format_file(FormatFileParams { path: biome_path })?; @@ -71,7 +72,7 @@ pub(crate) fn run<'a>( path: biome_path.clone(), version: 0, content: content.into(), - language_hint: Language::default(), + document_file_source: DocumentFileSource::default(), })?; // apply fix file of the linter let file_features = workspace.file_features(SupportsFeatureParams { diff --git a/crates/biome_cli/tests/commands/format.rs b/crates/biome_cli/tests/commands/format.rs index df06c641058b..c669e89741b2 100644 --- a/crates/biome_cli/tests/commands/format.rs +++ b/crates/biome_cli/tests/commands/format.rs @@ -606,7 +606,7 @@ fn applies_custom_jsx_quote_style() { let mut fs = MemoryFileSystem::default(); let mut console = BufferConsole::default(); - let file_path = Path::new("file.js"); + let file_path = Path::new("file.jsx"); fs.insert(file_path.into(), APPLY_JSX_QUOTE_STYLE_BEFORE.as_bytes()); let result = run_cli( @@ -850,17 +850,8 @@ fn applies_custom_bracket_spacing() { assert!(result.is_ok(), "run_cli returned {result:?}"); - let mut file = fs - .open(file_path) - .expect("formatting target file was removed by the CLI"); - - let mut content = String::new(); - file.read_to_string(&mut content) - .expect("failed to read file from memory FS"); - - assert_eq!(content, APPLY_BRACKET_SPACING_AFTER); + assert_file_contents(&fs, file_path, APPLY_BRACKET_SPACING_AFTER); - drop(file); assert_cli_snapshot(SnapshotPayload::new( module_path!(), "applies_custom_bracket_spacing", @@ -875,7 +866,7 @@ fn applies_custom_bracket_same_line() { let mut fs = MemoryFileSystem::default(); let mut console = BufferConsole::default(); - let file_path = Path::new("file.js"); + let file_path = Path::new("file.jsx"); fs.insert(file_path.into(), APPLY_BRACKET_SAME_LINE_BEFORE.as_bytes()); let result = run_cli( @@ -895,17 +886,8 @@ fn applies_custom_bracket_same_line() { assert!(result.is_ok(), "run_cli returned {result:?}"); - let mut file = fs - .open(file_path) - .expect("formatting target file was removed by the CLI"); + assert_file_contents(&fs, file_path, APPLY_BRACKET_SAME_LINE_AFTER); - let mut content = String::new(); - file.read_to_string(&mut content) - .expect("failed to read file from memory FS"); - - assert_eq!(content, APPLY_BRACKET_SAME_LINE_AFTER); - - drop(file); assert_cli_snapshot(SnapshotPayload::new( module_path!(), "applies_custom_bracket_same_line", @@ -2251,6 +2233,49 @@ fn format_json_when_allow_trailing_commas() { )); } +#[test] +fn format_json_when_allow_trailing_commas_write() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let config_json = r#"{ + "json": { + "parser": { "allowTrailingCommas": true } + } +}"#; + let biome_config = "biome.json"; + let code = r#"{ "loreum_ipsum_lorem_ipsum": "bar", "loreum_ipsum_lorem_ipsum": "bar", "loreum_ipsum_lorem_ipsum": "bar", "loreum_ipsum_lorem_ipsum": "bar", "loreum_ipsum_lorem_ipsum": "bar", +}"#; + let file_path = Path::new("file.json"); + fs.insert(file_path.into(), code.as_bytes()); + fs.insert(biome_config.into(), config_json); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("format"), + "--write", + file_path.as_os_str().to_str().unwrap(), + ] + .as_slice(), + ), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_file_contents(&fs, Path::new(file_path), "{\n\t\"loreum_ipsum_lorem_ipsum\": \"bar\",\n\t\"loreum_ipsum_lorem_ipsum\": \"bar\",\n\t\"loreum_ipsum_lorem_ipsum\": \"bar\",\n\t\"loreum_ipsum_lorem_ipsum\": \"bar\",\n\t\"loreum_ipsum_lorem_ipsum\": \"bar\",\n}\n"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "format_json_when_allow_trailing_commas_write", + fs, + console, + result, + )); +} + #[test] fn treat_known_json_files_as_jsonc_files() { let mut fs = MemoryFileSystem::default(); diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/applies_custom_bracket_same_line.snap b/crates/biome_cli/tests/snapshots/main_commands_format/applies_custom_bracket_same_line.snap index 05046160ebd2..d62f284c4c63 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_format/applies_custom_bracket_same_line.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_format/applies_custom_bracket_same_line.snap @@ -2,9 +2,9 @@ source: crates/biome_cli/tests/snap_test.rs expression: content --- -## `file.js` +## `file.jsx` -```js +```jsx ; ``` diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas.snap b/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas.snap index de7222eb4d96..5b1c3d1f59b1 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas.snap @@ -40,11 +40,14 @@ file.json format ━━━━━━━━━━━━━━━━━━━━━ i Formatter would have printed the following content: - 3 3 │ 1, - 4 4 │ ], + 1 1 │ { + 2 │ - ····"array":·[ + 3 │ - ········1, + 4 │ - ····], 5 │ - } - 5 │ + } - 6 │ + + 2 │ + → "array":·[1], + 3 │ + } + 4 │ + ``` diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas_write.snap b/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas_write.snap new file mode 100644 index 000000000000..c266c6725bc3 --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_commands_format/format_json_when_allow_trailing_commas_write.snap @@ -0,0 +1,34 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: content +--- +## `biome.json` + +```json +{ + "json": { + "parser": { "allowTrailingCommas": true } + } +} +``` + +## `file.json` + +```json +{ + "loreum_ipsum_lorem_ipsum": "bar", + "loreum_ipsum_lorem_ipsum": "bar", + "loreum_ipsum_lorem_ipsum": "bar", + "loreum_ipsum_lorem_ipsum": "bar", + "loreum_ipsum_lorem_ipsum": "bar", +} + +``` + +# Emitted Messages + +```block +Formatted 1 file in