From 5e9416a35cd3063b27aca27e13fced4c40f466d8 Mon Sep 17 00:00:00 2001 From: Ze-Zheng Wu Date: Sun, 30 Jun 2024 14:43:48 +0800 Subject: [PATCH] refactor: configuration, settings and options --- crates/biome_cli/src/changed.rs | 4 +- crates/biome_cli/src/commands/check.rs | 22 +- crates/biome_cli/src/commands/ci.rs | 36 +- crates/biome_cli/src/commands/format.rs | 29 +- crates/biome_cli/src/commands/init.rs | 4 +- crates/biome_cli/src/commands/lint.rs | 36 +- crates/biome_cli/src/commands/mod.rs | 99 +- crates/biome_cli/src/commands/rage.rs | 89 +- crates/biome_cli/src/commands/search.rs | 10 +- crates/biome_cli/src/execute/migrate.rs | 12 +- .../biome_cli/src/execute/migrate/eslint.rs | 14 +- .../src/execute/migrate/eslint_to_biome.rs | 22 +- .../biome_cli/src/execute/migrate/prettier.rs | 48 +- crates/biome_cli/tests/commands/init.rs | 8 +- crates/biome_cli/tests/snap_test.rs | 4 +- crates/biome_configuration/src/bool.rs | 79 + crates/biome_configuration/src/css.rs | 123 +- crates/biome_configuration/src/diagnostics.rs | 22 +- .../biome_configuration/src/editorconfig.rs | 12 +- crates/biome_configuration/src/file_size.rs | 65 + crates/biome_configuration/src/formatter.rs | 162 +- crates/biome_configuration/src/graphql.rs | 131 +- .../src/javascript/formatter.rs | 156 +- .../biome_configuration/src/javascript/mod.rs | 110 +- crates/biome_configuration/src/json.rs | 145 +- crates/biome_configuration/src/lib.rs | 318 ++- crates/biome_configuration/src/linter/mod.rs | 56 +- .../src/organize_imports.rs | 46 +- crates/biome_configuration/src/overrides.rs | 57 +- crates/biome_configuration/src/vcs.rs | 65 +- crates/biome_css_analyze/src/lib.rs | 6 +- crates/biome_css_analyze/tests/spec_tests.rs | 22 +- crates/biome_css_formatter/src/lib.rs | 4 +- crates/biome_css_formatter/tests/language.rs | 4 +- .../biome_css_formatter/tests/quick_test.rs | 4 +- crates/biome_css_formatter/tests/spec_test.rs | 12 +- crates/biome_css_parser/src/lexer/mod.rs | 8 +- crates/biome_css_parser/src/lexer/tests.rs | 10 +- crates/biome_css_parser/src/lib.rs | 14 +- crates/biome_css_parser/src/parser.rs | 10 +- crates/biome_css_parser/src/syntax/mod.rs | 6 +- crates/biome_css_parser/src/token_source.rs | 4 +- crates/biome_css_parser/tests/spec_test.rs | 15 +- crates/biome_deserialize/README.md | 28 +- crates/biome_deserialize/src/json.rs | 116 +- crates/biome_deserialize/src/lib.rs | 14 +- crates/biome_deserialize_macros/src/lib.rs | 4 +- .../src/merge_derive.rs | 25 +- .../biome_formatter/src/comments/builder.rs | 6 +- crates/biome_formatter/src/lib.rs | 5 +- crates/biome_formatter_test/src/spec.rs | 9 +- .../tests/spec_test.rs | 12 +- .../biome_grit_patterns/src/grit_js_parser.rs | 6 +- .../biome_grit_patterns/tests/quick_test.rs | 4 +- crates/biome_js_analyze/src/lib.rs | 16 +- .../lint/correctness/no_constant_condition.rs | 4 +- crates/biome_js_analyze/src/react/hooks.rs | 10 +- crates/biome_js_analyze/src/utils.rs | 26 +- crates/biome_js_analyze/src/utils/tests.rs | 24 +- crates/biome_js_analyze/tests/quick_test.rs | 4 +- crates/biome_js_analyze/tests/spec_tests.rs | 24 +- crates/biome_js_formatter/src/lib.rs | 14 +- crates/biome_js_formatter/src/parentheses.rs | 6 +- .../biome_js_formatter/src/syntax_rewriter.rs | 8 +- .../src/utils/binary_like_expression.rs | 6 +- crates/biome_js_formatter/src/utils/jsx.rs | 6 +- crates/biome_js_formatter/tests/language.rs | 4 +- crates/biome_js_formatter/tests/quick_test.rs | 4 +- crates/biome_js_parser/src/lib.rs | 2 +- crates/biome_js_parser/src/options.rs | 4 +- crates/biome_js_parser/src/parse.rs | 40 +- crates/biome_js_parser/src/parser.rs | 14 +- crates/biome_js_parser/src/tests.rs | 40 +- crates/biome_js_semantic/src/events.rs | 4 +- .../src/semantic_model/closure.rs | 6 +- .../src/semantic_model/is_constant.rs | 4 +- .../src/semantic_model/model.rs | 12 +- .../src/semantic_model/tests.rs | 10 +- .../biome_js_semantic/src/tests/assertions.rs | 4 +- crates/biome_js_syntax/src/expr_ext.rs | 6 +- crates/biome_js_transform/src/lib.rs | 4 +- crates/biome_js_transform/tests/spec_tests.rs | 14 +- crates/biome_json_analyze/src/lib.rs | 4 +- crates/biome_json_analyze/tests/spec_tests.rs | 6 +- crates/biome_json_formatter/src/lib.rs | 4 +- crates/biome_json_formatter/tests/language.rs | 4 +- .../biome_json_formatter/tests/quick_test.rs | 4 +- crates/biome_json_parser/src/lexer/mod.rs | 8 +- crates/biome_json_parser/src/lib.rs | 10 +- crates/biome_json_parser/src/parser.rs | 12 +- crates/biome_json_parser/src/token_source.rs | 6 +- crates/biome_json_parser/tests/spec_test.rs | 4 +- crates/biome_lsp/src/session.rs | 4 +- crates/biome_migrate/src/lib.rs | 4 +- crates/biome_migrate/tests/spec_tests.rs | 6 +- .../tests/manifest_spec_tests.rs | 4 +- crates/biome_service/src/configuration.rs | 61 +- .../biome_service/src/file_handlers/astro.rs | 4 +- crates/biome_service/src/file_handlers/css.rs | 80 +- .../src/file_handlers/graphql.rs | 46 +- .../src/file_handlers/javascript.rs | 78 +- .../biome_service/src/file_handlers/json.rs | 61 +- crates/biome_service/src/file_handlers/mod.rs | 9 +- .../biome_service/src/file_handlers/svelte.rs | 4 +- crates/biome_service/src/file_handlers/vue.rs | 4 +- crates/biome_service/src/matcher/mod.rs | 96 +- crates/biome_service/src/settings.rs | 1950 ++++++++++------- crates/biome_service/src/workspace.rs | 68 +- crates/biome_service/src/workspace/server.rs | 27 +- crates/biome_service/tests/spec_tests.rs | 22 +- crates/biome_test_utils/src/lib.rs | 10 +- xtask/bench/src/language.rs | 18 +- xtask/codegen/src/generate_bindings.rs | 4 +- xtask/codegen/src/generate_schema.rs | 8 +- xtask/coverage/src/js/test262.rs | 4 +- xtask/coverage/src/jsx/jsx_babel.rs | 4 +- xtask/coverage/src/runner.rs | 8 +- xtask/coverage/src/symbols/msts.rs | 4 +- xtask/coverage/src/ts/ts_babel.rs | 4 +- xtask/coverage/src/ts/ts_microsoft.rs | 4 +- xtask/rules_check/src/lib.rs | 12 +- 121 files changed, 2809 insertions(+), 2513 deletions(-) create mode 100644 crates/biome_configuration/src/bool.rs create mode 100644 crates/biome_configuration/src/file_size.rs diff --git a/crates/biome_cli/src/changed.rs b/crates/biome_cli/src/changed.rs index b3eae9f37621..3cafcd955ead 100644 --- a/crates/biome_cli/src/changed.rs +++ b/crates/biome_cli/src/changed.rs @@ -1,12 +1,12 @@ use crate::CliDiagnostic; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_fs::FileSystem; use biome_service::DynRef; use std::ffi::OsString; pub(crate) fn get_changed_files( fs: &DynRef<'_, dyn FileSystem>, - configuration: &PartialConfiguration, + configuration: &Configuration, since: Option, ) -> Result, CliDiagnostic> { let default_branch = configuration diff --git a/crates/biome_cli/src/commands/check.rs b/crates/biome_cli/src/commands/check.rs index f61175111ed5..20ed4bf163ed 100644 --- a/crates/biome_cli/src/commands/check.rs +++ b/crates/biome_cli/src/commands/check.rs @@ -7,13 +7,12 @@ use crate::{ execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, }; use biome_configuration::{ - organize_imports::PartialOrganizeImports, PartialConfiguration, PartialFormatterConfiguration, - PartialLinterConfiguration, + organize_imports::OrganizeImports, Configuration, FormatterConfiguration, LinterConfiguration, }; use biome_console::{markup, ConsoleExt}; use biome_deserialize::Merge; use biome_diagnostics::PrintDiagnostic; -use biome_service::configuration::{load_editorconfig, PartialConfigurationExt}; +use biome_service::configuration::{load_editorconfig, ConfigurationExt}; use biome_service::workspace::RegisterProjectFolderParams; use biome_service::{ configuration::{load_configuration, LoadedConfiguration}, @@ -30,7 +29,7 @@ pub(crate) struct CheckCommandPayload { pub(crate) fix: bool, pub(crate) unsafe_: bool, pub(crate) cli_options: CliOptions, - pub(crate) configuration: Option, + pub(crate) configuration: Option, pub(crate) paths: Vec, pub(crate) stdin_file_path: Option, pub(crate) formatter_enabled: Option, @@ -103,7 +102,8 @@ pub(crate) fn check( .as_ref() .and_then(|f| f.use_editorconfig) .unwrap_or_default(), - ); + ) + .into(); let mut fs_configuration = if should_use_editorconfig { let (editorconfig, editorconfig_diagnostics) = { let search_path = editorconfig_search_path.unwrap_or_else(|| { @@ -126,26 +126,26 @@ pub(crate) fn check( let formatter = fs_configuration .formatter - .get_or_insert_with(PartialFormatterConfiguration::default); + .get_or_insert_with(FormatterConfiguration::default); if formatter_enabled.is_some() { - formatter.enabled = formatter_enabled; + formatter.enabled = formatter_enabled.map(Into::into); } let linter = fs_configuration .linter - .get_or_insert_with(PartialLinterConfiguration::default); + .get_or_insert_with(LinterConfiguration::default); if linter_enabled.is_some() { - linter.enabled = linter_enabled; + linter.enabled = linter_enabled.map(Into::into); } let organize_imports = fs_configuration .organize_imports - .get_or_insert_with(PartialOrganizeImports::default); + .get_or_insert_with(OrganizeImports::default); if organize_imports_enabled.is_some() { - organize_imports.enabled = organize_imports_enabled; + organize_imports.enabled = organize_imports_enabled.map(Into::into); } if let Some(mut configuration) = configuration { diff --git a/crates/biome_cli/src/commands/ci.rs b/crates/biome_cli/src/commands/ci.rs index c618343db524..35174cf7cba0 100644 --- a/crates/biome_cli/src/commands/ci.rs +++ b/crates/biome_cli/src/commands/ci.rs @@ -3,12 +3,10 @@ use crate::cli_options::CliOptions; use crate::commands::{resolve_manifest, validate_configuration_diagnostics}; use crate::execute::VcsTargeted; use crate::{execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution}; -use biome_configuration::{organize_imports::PartialOrganizeImports, PartialConfiguration}; -use biome_configuration::{PartialFormatterConfiguration, PartialLinterConfiguration}; +use biome_configuration::{organize_imports::OrganizeImports, Configuration}; +use biome_configuration::{FormatterConfiguration, LinterConfiguration}; use biome_deserialize::Merge; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; +use biome_service::configuration::{load_configuration, ConfigurationExt, LoadedConfiguration}; use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; use std::ffi::OsString; @@ -17,7 +15,8 @@ pub(crate) struct CiCommandPayload { pub(crate) linter_enabled: Option, pub(crate) organize_imports_enabled: Option, pub(crate) paths: Vec, - pub(crate) configuration: Option, + // TODO(zzwu): What's the purpose of this option? + pub(crate) configuration: Option, pub(crate) cli_options: CliOptions, pub(crate) changed: bool, pub(crate) since: Option, @@ -54,35 +53,36 @@ pub(crate) fn ci(session: CliSession, payload: CiCommandPayload) -> Result<(), C } = loaded_configuration; let formatter = fs_configuration .formatter - .get_or_insert_with(PartialFormatterConfiguration::default); + .get_or_insert_with(FormatterConfiguration::default); if formatter_enabled.is_some() { - formatter.enabled = formatter_enabled; + formatter.enabled = formatter_enabled.map(Into::into); } let linter = fs_configuration .linter - .get_or_insert_with(PartialLinterConfiguration::default); + .get_or_insert_with(LinterConfiguration::default); if linter_enabled.is_some() { - linter.enabled = linter_enabled; + linter.enabled = linter_enabled.map(Into::into); } let organize_imports = fs_configuration .organize_imports - .get_or_insert_with(PartialOrganizeImports::default); + .get_or_insert_with(OrganizeImports::default); if organize_imports_enabled.is_some() { - organize_imports.enabled = organize_imports_enabled; + organize_imports.enabled = organize_imports_enabled.map(Into::into); } + // TODO(zzwu): We shouldn't bail because overrides can re-enable these options // no point in doing the traversal if all the checks have been disabled - if fs_configuration.is_formatter_disabled() - && fs_configuration.is_linter_disabled() - && fs_configuration.is_organize_imports_disabled() - { - return Err(CliDiagnostic::incompatible_end_configuration("Formatter, linter and organize imports are disabled, can't perform the command. This is probably and error.")); - } + // if !fs_configuration.is_formatter_enabled() + // && !fs_configuration.is_linter_enabled() + // && !fs_configuration.is_organize_imports_enabled() + // { + // return Err(CliDiagnostic::incompatible_end_configuration("Formatter, linter and organize imports are disabled, can't perform the command. This is probably and error.")); + // } if let Some(mut configuration) = configuration { if let Some(linter) = configuration.linter.as_mut() { diff --git a/crates/biome_cli/src/commands/format.rs b/crates/biome_cli/src/commands/format.rs index f865f712c378..8745ff50da89 100644 --- a/crates/biome_cli/src/commands/format.rs +++ b/crates/biome_cli/src/commands/format.rs @@ -7,16 +7,16 @@ use crate::execute::VcsTargeted; use crate::{ execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, }; -use biome_configuration::vcs::PartialVcsConfiguration; +use biome_configuration::vcs::VcsConfiguration; use biome_configuration::{ - PartialCssFormatter, PartialFilesConfiguration, PartialFormatterConfiguration, - PartialGraphqlFormatter, PartialJavascriptFormatter, PartialJsonFormatter, + CssFormatterConfiguration, FilesConfiguration, FormatterConfiguration, + GraphqlFormatterConfiguration, JsFormatterConfiguration, JsonFormatterConfiguration, }; use biome_console::{markup, ConsoleExt}; use biome_deserialize::Merge; use biome_diagnostics::PrintDiagnostic; use biome_service::configuration::{ - load_configuration, load_editorconfig, LoadedConfiguration, PartialConfigurationExt, + load_configuration, load_editorconfig, ConfigurationExt, LoadedConfiguration, }; use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; use std::ffi::OsString; @@ -24,13 +24,13 @@ use std::ffi::OsString; use super::check_fix_incompatible_arguments; pub(crate) struct FormatCommandPayload { - pub(crate) javascript_formatter: Option, - pub(crate) json_formatter: Option, - pub(crate) css_formatter: Option, - pub(crate) graphql_formatter: Option, - pub(crate) formatter_configuration: Option, - pub(crate) vcs_configuration: Option, - pub(crate) files_configuration: Option, + pub(crate) javascript_formatter: Option, + pub(crate) json_formatter: Option, + pub(crate) css_formatter: Option, + pub(crate) graphql_formatter: Option, + pub(crate) formatter_configuration: Option, + pub(crate) vcs_configuration: Option, + pub(crate) files_configuration: Option, pub(crate) stdin_file_path: Option, pub(crate) write: bool, pub(crate) fix: bool, @@ -99,7 +99,8 @@ pub(crate) fn format( .as_ref() .and_then(|f| f.use_editorconfig) .unwrap_or_default(), - ); + ) + .into(); let mut fs_configuration = if should_use_editorconfig { let (editorconfig, editorconfig_diagnostics) = { let search_path = editorconfig_search_path.unwrap_or_else(|| { @@ -185,14 +186,14 @@ pub(crate) fn format( if !configuration .formatter .as_ref() - .is_some_and(PartialFormatterConfiguration::is_disabled) + .is_some_and(FormatterConfiguration::is_disabled) { let formatter = configuration.formatter.get_or_insert_with(Default::default); if let Some(formatter_configuration) = formatter_configuration { formatter.merge_with(formatter_configuration); } - formatter.enabled = Some(true); + formatter.enabled = Some(true.into()); } if css_formatter.is_some() { let css = configuration.css.get_or_insert_with(Default::default); diff --git a/crates/biome_cli/src/commands/init.rs b/crates/biome_cli/src/commands/init.rs index e0f1e66904c1..e8eab6a033b2 100644 --- a/crates/biome_cli/src/commands/init.rs +++ b/crates/biome_cli/src/commands/init.rs @@ -1,12 +1,12 @@ use crate::{CliDiagnostic, CliSession}; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::{markup, ConsoleExt}; use biome_fs::ConfigName; use biome_service::configuration::create_config; pub(crate) fn init(mut session: CliSession, emit_jsonc: bool) -> Result<(), CliDiagnostic> { let fs = &mut session.app.fs; - create_config(fs, PartialConfiguration::init(), emit_jsonc)?; + create_config(fs, Configuration::init(), emit_jsonc)?; let file_created = if emit_jsonc { ConfigName::biome_jsonc() } else { diff --git a/crates/biome_cli/src/commands/lint.rs b/crates/biome_cli/src/commands/lint.rs index 07dfdb14283b..0f98c26ae42d 100644 --- a/crates/biome_cli/src/commands/lint.rs +++ b/crates/biome_cli/src/commands/lint.rs @@ -6,19 +6,15 @@ use crate::execute::VcsTargeted; use crate::{ execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, }; -use biome_configuration::css::PartialCssLinter; -use biome_configuration::javascript::PartialJavascriptLinter; -use biome_configuration::json::PartialJsonLinter; +use biome_configuration::css::CssLinterConfiguration; +use biome_configuration::graphql::GraphqlLinterConfiguration; +use biome_configuration::javascript::JsLinterConfiguration; +use biome_configuration::json::JsonLinterConfiguration; use biome_configuration::linter::RuleSelector; -use biome_configuration::vcs::PartialVcsConfiguration; -use biome_configuration::{ - PartialConfiguration, PartialFilesConfiguration, PartialGraphqlLinter, - PartialLinterConfiguration, -}; +use biome_configuration::vcs::VcsConfiguration; +use biome_configuration::{Configuration, FilesConfiguration, LinterConfiguration}; use biome_deserialize::Merge; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; +use biome_service::configuration::{load_configuration, ConfigurationExt, LoadedConfiguration}; use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; use std::ffi::OsString; @@ -31,9 +27,9 @@ pub(crate) struct LintCommandPayload { pub(crate) fix: bool, pub(crate) unsafe_: bool, pub(crate) cli_options: CliOptions, - pub(crate) linter_configuration: Option, - pub(crate) vcs_configuration: Option, - pub(crate) files_configuration: Option, + pub(crate) linter_configuration: Option, + pub(crate) vcs_configuration: Option, + pub(crate) files_configuration: Option, pub(crate) paths: Vec, pub(crate) only: Vec, pub(crate) skip: Vec, @@ -41,10 +37,10 @@ pub(crate) struct LintCommandPayload { pub(crate) staged: bool, pub(crate) changed: bool, pub(crate) since: Option, - pub(crate) javascript_linter: Option, - pub(crate) json_linter: Option, - pub(crate) css_linter: Option, - pub(crate) graphql_linter: Option, + pub(crate) javascript_linter: Option, + pub(crate) json_linter: Option, + pub(crate) css_linter: Option, + pub(crate) graphql_linter: Option, } /// Handler for the "lint" command of the Biome CLI @@ -98,11 +94,11 @@ pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<( directory_path: configuration_path, .. } = loaded_configuration; - fs_configuration.merge_with(PartialConfiguration { + fs_configuration.merge_with(Configuration { linter: if fs_configuration .linter .as_ref() - .is_some_and(PartialLinterConfiguration::is_disabled) + .is_some_and(LinterConfiguration::is_disabled) { None } else { diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 2f3103ac7468..2f407f473b6a 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -4,21 +4,20 @@ use crate::diagnostics::{DeprecatedArgument, DeprecatedConfigurationFile}; use crate::execute::Stdin; use crate::logging::LoggingKind; use crate::{CliDiagnostic, CliSession, LoggingLevel, VERSION}; -use biome_configuration::css::PartialCssLinter; -use biome_configuration::javascript::PartialJavascriptLinter; -use biome_configuration::json::PartialJsonLinter; +use biome_configuration::css::CssLinterConfiguration; +use biome_configuration::graphql::graphql_formatter_configuration; +use biome_configuration::javascript::JsLinterConfiguration; +use biome_configuration::json::JsonLinterConfiguration; use biome_configuration::linter::RuleSelector; use biome_configuration::{ - css::partial_css_formatter, css::partial_css_linter, graphql::partial_graphql_formatter, - graphql::partial_graphql_linter, javascript::partial_javascript_formatter, - javascript::partial_javascript_linter, json::partial_json_formatter, json::partial_json_linter, - partial_configuration, partial_files_configuration, partial_formatter_configuration, - partial_linter_configuration, vcs::partial_vcs_configuration, vcs::PartialVcsConfiguration, - PartialCssFormatter, PartialFilesConfiguration, PartialFormatterConfiguration, - PartialGraphqlFormatter, PartialGraphqlLinter, PartialJavascriptFormatter, - PartialJsonFormatter, PartialLinterConfiguration, + configuration, css::css_formatter_configuration, css::css_linter_configuration, + files_configuration, formatter_configuration, javascript::js_formatter_configuration, + javascript::js_linter_configuration, json::json_formatter_configuration, + json::json_linter_configuration, linter_configuration, vcs::vcs_configuration, + vcs::VcsConfiguration, CssFormatterConfiguration, FilesConfiguration, FormatterConfiguration, + JsFormatterConfiguration, JsonFormatterConfiguration, LinterConfiguration, }; -use biome_configuration::{BiomeDiagnostic, PartialConfiguration}; +use biome_configuration::{BiomeDiagnostic, Configuration, GraphqlFormatterConfiguration}; use biome_console::{markup, Console, ConsoleExt}; use biome_diagnostics::{Diagnostic, PrintDiagnostic}; use biome_fs::{BiomePath, FileSystem}; @@ -120,8 +119,8 @@ pub enum BiomeCommand { hide_usage )] organize_imports_enabled: Option, - #[bpaf(external(partial_configuration), hide_usage, optional)] - configuration: Option, + #[bpaf(external(configuration), hide_usage, optional)] + configuration: Option, #[bpaf(external, hide_usage)] cli_options: CliOptions, /// Use this option when you want to format code piped from `stdin`, and print the output to `stdout`. @@ -174,26 +173,26 @@ pub enum BiomeCommand { #[bpaf(long("apply-unsafe"), switch, hide_usage)] apply_unsafe: bool, - #[bpaf(external(partial_linter_configuration), hide_usage, optional)] - linter_configuration: Option, + #[bpaf(external(linter_configuration), hide_usage, optional)] + linter_configuration: Option, - #[bpaf(external(partial_vcs_configuration), optional, hide_usage)] - vcs_configuration: Option, + #[bpaf(external(vcs_configuration), optional, hide_usage)] + vcs_configuration: Option, - #[bpaf(external(partial_files_configuration), optional, hide_usage)] - files_configuration: Option, + #[bpaf(external(files_configuration), optional, hide_usage)] + files_configuration: Option, - #[bpaf(external(partial_javascript_linter), optional, hide_usage)] - javascript_linter: Option, + #[bpaf(external(js_linter_configuration), optional, hide_usage)] + javascript_linter: Option, - #[bpaf(external(partial_json_linter), optional, hide_usage)] - json_linter: Option, + #[bpaf(external(json_linter_configuration), optional, hide_usage)] + json_linter: Option, - #[bpaf(external(partial_css_linter), optional, hide_usage, hide)] - css_linter: Option, + #[bpaf(external(css_linter_configuration), optional, hide_usage, hide)] + css_linter: Option, - #[bpaf(external(partial_graphql_linter), optional, hide_usage, hide)] - graphql_linter: Option, + #[bpaf(external(graphql_linter_configuration), optional, hide_usage, hide)] + graphql_linter: Option, #[bpaf(external, hide_usage)] cli_options: CliOptions, @@ -239,26 +238,26 @@ pub enum BiomeCommand { /// Run the formatter on a set of files. #[bpaf(command)] Format { - #[bpaf(external(partial_formatter_configuration), optional, hide_usage)] - formatter_configuration: Option, + #[bpaf(external(formatter_configuration), optional, hide_usage)] + formatter_configuration: Option, - #[bpaf(external(partial_javascript_formatter), optional, hide_usage)] - javascript_formatter: Option, + #[bpaf(external(js_formatter_configuration), optional, hide_usage)] + javascript_formatter: Option, - #[bpaf(external(partial_json_formatter), optional, hide_usage)] - json_formatter: Option, + #[bpaf(external(json_formatter_configuration), optional, hide_usage)] + json_formatter: Option, - #[bpaf(external(partial_css_formatter), optional, hide_usage, hide)] - css_formatter: Option, + #[bpaf(external(css_formatter_configuration), optional, hide_usage, hide)] + css_formatter: Option, - #[bpaf(external(partial_graphql_formatter), optional, hide_usage, hide)] - graphql_formatter: Option, + #[bpaf(external(graphql_formatter_configuration), optional, hide_usage, hide)] + graphql_formatter: Option, - #[bpaf(external(partial_vcs_configuration), optional, hide_usage)] - vcs_configuration: Option, + #[bpaf(external(vcs_configuration), optional, hide_usage)] + vcs_configuration: Option, - #[bpaf(external(partial_files_configuration), optional, hide_usage)] - files_configuration: Option, + #[bpaf(external(files_configuration), optional, hide_usage)] + files_configuration: Option, /// Use this option when you want to format code piped from `stdin`, and print the output to `stdout`. /// /// The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to format the code. @@ -312,8 +311,8 @@ pub enum BiomeCommand { #[bpaf(long("organize-imports-enabled"), argument("true|false"), optional)] organize_imports_enabled: Option, - #[bpaf(external(partial_configuration), hide_usage, optional)] - configuration: Option, + #[bpaf(external(configuration), hide_usage, optional)] + configuration: Option, #[bpaf(external, hide_usage)] cli_options: CliOptions, @@ -374,11 +373,11 @@ pub enum BiomeCommand { #[bpaf(external, hide_usage)] cli_options: CliOptions, - #[bpaf(external(partial_files_configuration), optional, hide_usage)] - files_configuration: Option, + #[bpaf(external(files_configuration), optional, hide_usage)] + files_configuration: Option, - #[bpaf(external(partial_vcs_configuration), optional, hide_usage)] - vcs_configuration: Option, + #[bpaf(external(vcs_configuration), optional, hide_usage)] + vcs_configuration: Option, /// Use this option when you want to search through code piped from /// `stdin`, and print the output to `stdout`. @@ -528,7 +527,7 @@ impl BiomeCommand { } } -/// It accepts a [LoadedPartialConfiguration] and it prints the diagnostics emitted during parsing and deserialization. +/// It accepts a [LoadedConfiguration] and it prints the diagnostics emitted during parsing and deserialization. /// /// If it contains errors, it return an error. pub(crate) fn validate_configuration_diagnostics( @@ -625,7 +624,7 @@ fn get_files_to_process( changed: bool, staged: bool, fs: &DynRef<'_, dyn FileSystem>, - configuration: &PartialConfiguration, + configuration: &Configuration, ) -> Result>, CliDiagnostic> { if since.is_some() { if !changed { diff --git a/crates/biome_cli/src/commands/rage.rs b/crates/biome_cli/src/commands/rage.rs index 86a46b16b3ec..8b4207d7848e 100644 --- a/crates/biome_cli/src/commands/rage.rs +++ b/crates/biome_cli/src/commands/rage.rs @@ -200,10 +200,10 @@ impl Display for RageConfiguration<'_, '_> { markup! ( {KeyValuePair("Status", status)} - {KeyValuePair("Formatter disabled", markup!({DebugDisplay(configuration.is_formatter_disabled())}))} - {KeyValuePair("Linter disabled", markup!({DebugDisplay(configuration.is_linter_disabled())}))} - {KeyValuePair("Organize imports disabled", markup!({DebugDisplay(configuration.is_organize_imports_disabled())}))} - {KeyValuePair("VCS disabled", markup!({DebugDisplay(configuration.is_vcs_disabled())}))} + {KeyValuePair("Formatter disabled", markup!({DebugDisplay(!configuration.is_formatter_enabled())}))} + {KeyValuePair("Linter disabled", markup!({DebugDisplay(!configuration.is_linter_enabled())}))} + {KeyValuePair("Organize imports disabled", markup!({DebugDisplay(!configuration.is_organize_imports_enabled())}))} + {KeyValuePair("VCS disabled", markup!({DebugDisplay(!configuration.is_vcs_enabled())}))} ).fmt(fmt)?; // Print formatter configuration if --formatter option is true @@ -211,35 +211,41 @@ impl Display for RageConfiguration<'_, '_> { let formatter_configuration = configuration.get_formatter_configuration(); markup! ( {Section("Formatter")} - {KeyValuePair("Format with errors", markup!({DebugDisplay(configuration.get_formatter_configuration().format_with_errors)}))} - {KeyValuePair("Indent style", markup!({DebugDisplay(formatter_configuration.indent_style)}))} - {KeyValuePair("Indent width", markup!({DebugDisplay(formatter_configuration.indent_width)}))} - {KeyValuePair("Line ending", markup!({DebugDisplay(formatter_configuration.line_ending)}))} - {KeyValuePair("Line width", markup!({DebugDisplay(formatter_configuration.line_width.value())}))} - {KeyValuePair("Attribute position", markup!({DebugDisplay(formatter_configuration.attribute_position)}))} - {KeyValuePair("Bracket spacing", markup!({DebugDisplay(formatter_configuration.bracket_spacing)}))} - {KeyValuePair("Ignore", markup!({DebugDisplay(formatter_configuration.ignore.iter().collect::>())}))} - {KeyValuePair("Include", markup!({DebugDisplay(formatter_configuration.include.iter().collect::>())}))} + // Should display resolved values + {KeyValuePair("Format with errors", markup!({DebugDisplay(formatter_configuration.format_with_errors_resolved())}))} + {KeyValuePair("Indent style", markup!({DebugDisplay(formatter_configuration.indent_style_resolved())}))} + {KeyValuePair("Indent width", markup!({DebugDisplay(formatter_configuration.indent_width_resolved())}))} + {KeyValuePair("Line ending", markup!({DebugDisplay(formatter_configuration.line_ending_resolved())}))} + {KeyValuePair("Line width", markup!({DebugDisplay(formatter_configuration.line_width_resolved())}))} + {KeyValuePair("Attribute position", markup!({DebugDisplay(formatter_configuration.attribute_position_resolved())}))} + {KeyValuePair("Bracket spacing", markup!({DebugDisplay(formatter_configuration.bracket_spacing_resolved())}))} + {KeyValuePair("Ignore", markup!({DebugDisplay(formatter_configuration.ignore_resolved().iter().collect::>())}))} + {KeyValuePair("Include", markup!({DebugDisplay(formatter_configuration.include_resolved().iter().collect::>())}))} ).fmt(fmt)?; let javascript_formatter_configuration = configuration.get_javascript_formatter_configuration(); markup! ( {Section("JavaScript Formatter")} - {KeyValuePair("Enabled", markup!({DebugDisplay(javascript_formatter_configuration.enabled)}))} - {KeyValuePair("JSX quote style", markup!({DebugDisplay(javascript_formatter_configuration.jsx_quote_style)}))} - {KeyValuePair("Quote properties", markup!({DebugDisplay(javascript_formatter_configuration.quote_properties)}))} - {KeyValuePair("Trailing commas", markup!({DebugDisplay(javascript_formatter_configuration.trailing_commas)}))} - {KeyValuePair("Semicolons", markup!({DebugDisplay(javascript_formatter_configuration.semicolons)}))} - {KeyValuePair("Arrow parentheses", markup!({DebugDisplay(javascript_formatter_configuration.arrow_parentheses)}))} - {KeyValuePair("Bracket spacing", markup!({DebugDisplayOption(javascript_formatter_configuration.bracket_spacing)}))} - {KeyValuePair("Bracket same line", markup!({DebugDisplay(javascript_formatter_configuration.bracket_same_line)}))} - {KeyValuePair("Quote style", markup!({DebugDisplay(javascript_formatter_configuration.quote_style)}))} + // Enabled + {KeyValuePair("Enabled", markup!({DebugDisplay(javascript_formatter_configuration.enabled_resolved())}))} + // These options will fallback to their language agnostic counterparts when they're `None`, + // So we should use `DebugDisplayOption` to indicate whether values are unset + // instead of resolving them to a concrete value {KeyValuePair("Indent style", markup!({DebugDisplayOption(javascript_formatter_configuration.indent_style)}))} {KeyValuePair("Indent width", markup!({DebugDisplayOption(javascript_formatter_configuration.indent_width)}))} {KeyValuePair("Line ending", markup!({DebugDisplayOption(javascript_formatter_configuration.line_ending)}))} - {KeyValuePair("Line width", markup!({DebugDisplayOption(javascript_formatter_configuration.line_width.map(|lw| lw.value()))}))} + {KeyValuePair("Line width", markup!({DebugDisplayOption(javascript_formatter_configuration.line_width)}))} {KeyValuePair("Attribute position", markup!({DebugDisplayOption(javascript_formatter_configuration.attribute_position)}))} + {KeyValuePair("Bracket spacing", markup!({DebugDisplayOption(javascript_formatter_configuration.bracket_spacing)}))} + // Should use `DebugDisplay` to display resolved values + {KeyValuePair("JSX quote style", markup!({DebugDisplay(javascript_formatter_configuration.jsx_quote_style_resolved())}))} + {KeyValuePair("Quote properties", markup!({DebugDisplay(javascript_formatter_configuration.quote_properties_resolved())}))} + {KeyValuePair("Trailing commas", markup!({DebugDisplay(javascript_formatter_configuration.trailing_commas_resolved())}))} + {KeyValuePair("Semicolons", markup!({DebugDisplay(javascript_formatter_configuration.semicolons_resolved())}))} + {KeyValuePair("Arrow parentheses", markup!({DebugDisplay(javascript_formatter_configuration.arrow_parentheses_resolved())}))} + {KeyValuePair("Bracket same line", markup!({DebugDisplay(javascript_formatter_configuration.bracket_same_line_resolved())}))} + {KeyValuePair("Quote style", markup!({DebugDisplay(javascript_formatter_configuration.quote_style_resolved())}))} ) .fmt(fmt)?; @@ -247,37 +253,52 @@ impl Display for RageConfiguration<'_, '_> { configuration.get_json_formatter_configuration(); markup! ( {Section("JSON Formatter")} - {KeyValuePair("Enabled", markup!({DebugDisplay(json_formatter_configuration.enabled)}))} + // Enabled + {KeyValuePair("Enabled", markup!({DebugDisplay(json_formatter_configuration.enabled_resolved())}))} + // These options will fallback to their language agnostic counterparts when they're `None`, + // So we should use `DebugDisplayOption` to indicate whether values are unset + // instead of resolving them to a concrete value {KeyValuePair("Indent style", markup!({DebugDisplayOption(json_formatter_configuration.indent_style)}))} {KeyValuePair("Indent width", markup!({DebugDisplayOption(json_formatter_configuration.indent_width)}))} {KeyValuePair("Line ending", markup!({DebugDisplayOption(json_formatter_configuration.line_ending)}))} - {KeyValuePair("Line width", markup!({DebugDisplayOption(json_formatter_configuration.line_width.map(|lw| lw.value()))}))} - {KeyValuePair("Trailing Commas", markup!({DebugDisplayOption(json_formatter_configuration.trailing_commas)}))} + {KeyValuePair("Line width", markup!({DebugDisplayOption(json_formatter_configuration.line_width)}))} + // Should use `DebugDisplay` to display resolved values + {KeyValuePair("Trailing Commas", markup!({DebugDisplay(json_formatter_configuration.trailing_commas_resolved())}))} ).fmt(fmt)?; let css_formatter_configuration = configuration.get_css_formatter_configuration(); markup! ( {Section("CSS Formatter")} - {KeyValuePair("Enabled", markup!({DebugDisplay(css_formatter_configuration.enabled)}))} + // Enabled + {KeyValuePair("Enabled", markup!({DebugDisplay(css_formatter_configuration.enabled_resolved())}))} + // These options will fallback to their language agnostic counterparts when they're `None`, + // So we should use `DebugDisplayOption` to indicate whether values are unset + // instead of resolving them to a concrete value {KeyValuePair("Indent style", markup!({DebugDisplayOption(css_formatter_configuration.indent_style)}))} {KeyValuePair("Indent width", markup!({DebugDisplayOption(css_formatter_configuration.indent_width)}))} {KeyValuePair("Line ending", markup!({DebugDisplayOption(css_formatter_configuration.line_ending)}))} {KeyValuePair("Line width", markup!({DebugDisplayOption(css_formatter_configuration.line_width)}))} - {KeyValuePair("Quote style", markup!({DebugDisplay(css_formatter_configuration.quote_style)}))} + // Should use `DebugDisplay` to display resolved values + {KeyValuePair("Quote style", markup!({DebugDisplay(css_formatter_configuration.quote_style_resolved())}))} ).fmt(fmt)?; let graphql_formatter_configuration = configuration.get_graphql_formatter_configuration(); markup! ( {Section("GraphQL Formatter")} - {KeyValuePair("Enabled", markup!({DebugDisplayOption(graphql_formatter_configuration.enabled)}))} + // Enabled + {KeyValuePair("Enabled", markup!({DebugDisplay(graphql_formatter_configuration.enabled_resolved())}))} + // These options will fallback to their language agnostic counterparts when they're `None`, + // So we should use `DebugDisplayOption` to indicate whether values are unset + // instead of resolving them to a concrete value {KeyValuePair("Indent style", markup!({DebugDisplayOption(graphql_formatter_configuration.indent_style)}))} {KeyValuePair("Indent width", markup!({DebugDisplayOption(graphql_formatter_configuration.indent_width)}))} {KeyValuePair("Line ending", markup!({DebugDisplayOption(graphql_formatter_configuration.line_ending)}))} {KeyValuePair("Line width", markup!({DebugDisplayOption(graphql_formatter_configuration.line_width)}))} {KeyValuePair("Bracket spacing", markup!({DebugDisplayOption(graphql_formatter_configuration.bracket_spacing)}))} - {KeyValuePair("Quote style", markup!({DebugDisplayOption(graphql_formatter_configuration.quote_style)}))} + // Should use `DebugDisplay` to display resolved values + {KeyValuePair("Quote style", markup!({DebugDisplay(graphql_formatter_configuration.quote_style_resolved())}))} ).fmt(fmt)?; } @@ -291,10 +312,10 @@ impl Display for RageConfiguration<'_, '_> { let graphq_linter = configuration.get_graphql_linter_configuration(); markup! ( {Section("Linter")} - {KeyValuePair("JavaScript enabled", markup!({DebugDisplay(javascript_linter.enabled)}))} - {KeyValuePair("JSON enabled", markup!({DebugDisplay(json_linter.enabled)}))} - {KeyValuePair("CSS enabled", markup!({DebugDisplay(css_linter.enabled)}))} - {KeyValuePair("GraphQL enabled", markup!({DebugDisplayOption(graphq_linter.enabled)}))} + {KeyValuePair("JavaScript enabled", markup!({DebugDisplay(javascript_linter.enabled_resolved())}))} + {KeyValuePair("JSON enabled", markup!({DebugDisplay(json_linter.enabled_resolved())}))} + {KeyValuePair("CSS enabled", markup!({DebugDisplay(css_linter.enabled_resolved())}))} + {KeyValuePair("GraphQL enabled", markup!({DebugDisplay(graphq_linter.enabled_resolved())}))} {KeyValuePair("Recommended", markup!({DebugDisplay(linter_configuration.recommended.unwrap_or_default())}))} {KeyValuePair("All", markup!({DebugDisplay(linter_configuration.all.unwrap_or_default())}))} {RageConfigurationLintRules("Enabled rules",linter_configuration)} diff --git a/crates/biome_cli/src/commands/search.rs b/crates/biome_cli/src/commands/search.rs index c599962cd2d1..a90181c8e893 100644 --- a/crates/biome_cli/src/commands/search.rs +++ b/crates/biome_cli/src/commands/search.rs @@ -3,11 +3,9 @@ use crate::commands::{get_stdin, resolve_manifest, validate_configuration_diagno use crate::{ execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, }; -use biome_configuration::{vcs::PartialVcsConfiguration, PartialFilesConfiguration}; +use biome_configuration::{vcs::VcsConfiguration, FilesConfiguration}; use biome_deserialize::Merge; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; +use biome_service::configuration::{load_configuration, ConfigurationExt, LoadedConfiguration}; use biome_service::workspace::{ ParsePatternParams, RegisterProjectFolderParams, UpdateSettingsParams, }; @@ -15,11 +13,11 @@ use std::ffi::OsString; pub(crate) struct SearchCommandPayload { pub(crate) cli_options: CliOptions, - pub(crate) files_configuration: Option, + pub(crate) files_configuration: Option, pub(crate) paths: Vec, pub(crate) pattern: String, pub(crate) stdin_file_path: Option, - pub(crate) vcs_configuration: Option, + pub(crate) vcs_configuration: Option, } /// Handler for the "search" command of the Biome CLI diff --git a/crates/biome_cli/src/execute/migrate.rs b/crates/biome_cli/src/execute/migrate.rs index ed088458c044..201175b7bee0 100644 --- a/crates/biome_cli/src/execute/migrate.rs +++ b/crates/biome_cli/src/execute/migrate.rs @@ -2,7 +2,7 @@ use crate::commands::MigrateSubCommand; use crate::diagnostics::MigrationDiagnostic; use crate::execute::diagnostics::{ContentDiffAdvice, MigrateDiffDiagnostic}; use crate::{CliDiagnostic, CliSession}; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::{markup, ConsoleExt}; use biome_deserialize::json::deserialize_from_json_ast; use biome_deserialize::Merge; @@ -10,7 +10,7 @@ use biome_diagnostics::Diagnostic; use biome_diagnostics::{category, PrintDiagnostic}; use biome_formatter::ParseFormatNumberError; use biome_fs::{BiomePath, ConfigName, FileSystemExt, OpenOptions}; -use biome_json_parser::{parse_json_with_cache, JsonParserOptions}; +use biome_json_parser::{parse_json_with_cache, JsonParseOptions}; use biome_json_syntax::{JsonFileSource, JsonRoot}; use biome_migrate::{migrate_configuration, ControlFlow}; use biome_rowan::{AstNode, NodeCache}; @@ -74,7 +74,7 @@ pub(crate) fn run(migrate_payload: MigratePayload) -> Result<(), CliDiagnostic> let parsed = parse_json_with_cache( &biome_config_content, &mut cache, - JsonParserOptions::default(), + JsonParseOptions::default(), ); match sub_command { @@ -84,8 +84,7 @@ pub(crate) fn run(migrate_payload: MigratePayload) -> Result<(), CliDiagnostic> data: prettier_config, } = prettier::read_config_file(fs, console)?; let biome_config = - deserialize_from_json_ast::(&parsed.tree(), "") - .into_deserialized(); + deserialize_from_json_ast::(&parsed.tree(), "").into_deserialized(); let Some(mut biome_config) = biome_config else { return Ok(()); }; @@ -164,8 +163,7 @@ pub(crate) fn run(migrate_payload: MigratePayload) -> Result<(), CliDiagnostic> data: eslint_config, } = eslint::read_eslint_config(fs, console)?; let biome_config = - deserialize_from_json_ast::(&parsed.tree(), "") - .into_deserialized(); + deserialize_from_json_ast::(&parsed.tree(), "").into_deserialized(); let Some(mut biome_config) = biome_config else { return Ok(()); }; diff --git a/crates/biome_cli/src/execute/migrate/eslint.rs b/crates/biome_cli/src/execute/migrate/eslint.rs index 9f69addb28dd..75955c79b799 100644 --- a/crates/biome_cli/src/execute/migrate/eslint.rs +++ b/crates/biome_cli/src/execute/migrate/eslint.rs @@ -3,7 +3,7 @@ use biome_deserialize::json::deserialize_from_json_str; use biome_deserialize::Merge; use biome_diagnostics::{DiagnosticExt, PrintDiagnostic}; use biome_fs::{FileSystem, OpenOptions}; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_service::DynRef; use std::borrow::Cow; use std::path::{Path, PathBuf}; @@ -122,7 +122,7 @@ fn load_flat_config_data( let node::Resolution { content, .. } = node::load_config(&path.to_string_lossy())?; let (deserialized, diagnostics) = deserialize_from_json_str::( &content, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .consume(); @@ -164,7 +164,7 @@ fn load_legacy_config_data( let (deserialized, diagnostics) = deserialize_from_json_str::( &content, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_trailing_commas() .with_allow_comments(), "", @@ -184,7 +184,7 @@ fn load_legacy_config_data( } else { deserialize_from_json_str::( &content, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_trailing_commas() .with_allow_comments(), "", @@ -196,7 +196,7 @@ fn load_legacy_config_data( let node::Resolution { content, .. } = node::load_config(&path.to_string_lossy())?; deserialize_from_json_str::( &content, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .consume() @@ -285,7 +285,7 @@ fn load_eslint_extends_config( } = node::load_config(&module_name)?; let deserialized = deserialize_from_json_str::( &content, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .into_deserialized(); @@ -314,7 +314,7 @@ fn load_eslint_extends_config( } = node::load_config(&module_name)?; let deserialized = deserialize_from_json_str::( &content, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .into_deserialized(); diff --git a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs index 01b00db35082..d867b8dec279 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs @@ -30,7 +30,7 @@ impl eslint_eslint::AnyConfigData { pub(crate) fn into_biome_config( self, options: &MigrationOptions, - ) -> (biome_config::PartialConfiguration, MigrationResults) { + ) -> (biome_config::Configuration, MigrationResults) { match self { Self::Flat(config) => config.into_biome_config(options), Self::Legacy(config) => config.into_biome_config(options), @@ -42,10 +42,10 @@ impl eslint_eslint::FlatConfigData { pub(crate) fn into_biome_config( self, options: &MigrationOptions, - ) -> (biome_config::PartialConfiguration, MigrationResults) { + ) -> (biome_config::Configuration, MigrationResults) { let mut results = MigrationResults::default(); - let mut biome_config = biome_config::PartialConfiguration::default(); - let mut linter = biome_config::PartialLinterConfiguration::default(); + let mut biome_config = biome_config::Configuration::default(); + let mut linter = biome_config::LinterConfiguration::default(); let mut overrides = biome_config::Overrides::default(); let global_config_object = if self.0.len() == 1 { // If there is a single config object, then we use it as the global config @@ -63,7 +63,7 @@ impl eslint_eslint::FlatConfigData { let mut override_pat = biome_config::OverridePattern::default(); if let Some(language_options) = flat_config_object.language_options { let globals = language_options.globals.enabled().collect::(); - let js_config = biome_config::PartialJavascriptConfiguration { + let js_config = biome_config::JsConfiguration { globals: Some(globals), ..Default::default() }; @@ -99,7 +99,7 @@ impl eslint_eslint::FlatConfigData { }; if let Some(language_options) = global_config_object.language_options { let globals = language_options.globals.enabled().collect::(); - let js_config = biome_config::PartialJavascriptConfiguration { + let js_config = biome_config::JsConfiguration { globals: Some(globals), ..Default::default() }; @@ -122,18 +122,18 @@ impl eslint_eslint::LegacyConfigData { pub(crate) fn into_biome_config( self, options: &MigrationOptions, - ) -> (biome_config::PartialConfiguration, MigrationResults) { + ) -> (biome_config::Configuration, MigrationResults) { let mut results = MigrationResults::default(); - let mut biome_config = biome_config::PartialConfiguration::default(); + let mut biome_config = biome_config::Configuration::default(); if !self.globals.is_empty() { let globals = self.globals.enabled().collect::(); - let js_config = biome_config::PartialJavascriptConfiguration { + let js_config = biome_config::JsConfiguration { globals: Some(globals), ..Default::default() }; biome_config.javascript = Some(js_config) } - let mut linter = biome_config::PartialLinterConfiguration::default(); + let mut linter = biome_config::LinterConfiguration::default(); let mut rules = self.rules.into_biome_rules(options, &mut results); rules.recommended = Some(false); linter.rules = Some(rules); @@ -151,7 +151,7 @@ impl eslint_eslint::LegacyConfigData { let mut override_pattern = biome_config::OverridePattern::default(); if !override_elt.globals.is_empty() { let globals = override_elt.globals.enabled().collect::(); - let js_config = biome_config::PartialJavascriptConfiguration { + let js_config = biome_config::JsConfiguration { globals: Some(globals), ..Default::default() }; diff --git a/crates/biome_cli/src/execute/migrate/prettier.rs b/crates/biome_cli/src/execute/migrate/prettier.rs index 0a7a09d31ee5..bc319f33b29f 100644 --- a/crates/biome_cli/src/execute/migrate/prettier.rs +++ b/crates/biome_cli/src/execute/migrate/prettier.rs @@ -10,7 +10,7 @@ use biome_formatter::{ }; use biome_fs::{FileSystem, OpenOptions}; use biome_js_formatter::context::{ArrowParentheses, QuoteProperties, Semicolons, TrailingCommas}; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_service::DynRef; use std::path::Path; @@ -187,10 +187,10 @@ impl From for QuoteProperties { } } -impl TryFrom for biome_configuration::PartialConfiguration { +impl TryFrom for biome_configuration::Configuration { type Error = ParseFormatNumberError; fn try_from(value: PrettierConfiguration) -> Result { - let mut result = biome_configuration::PartialConfiguration::default(); + let mut result = biome_configuration::Configuration::default(); let line_width = LineWidth::try_from(value.print_width)?; let indent_width = IndentWidth::try_from(value.tab_width)?; @@ -199,19 +199,19 @@ impl TryFrom for biome_configuration::PartialConfiguratio } else { biome_configuration::PlainIndentStyle::Space }; - let formatter = biome_configuration::PartialFormatterConfiguration { + let formatter = biome_configuration::FormatterConfiguration { indent_width: Some(indent_width), line_width: Some(line_width), indent_style: Some(indent_style), line_ending: Some(value.end_of_line.into()), attribute_position: Some(AttributePosition::default()), - format_with_errors: Some(false), + format_with_errors: Some(false.into()), ignore: None, include: None, - enabled: Some(true), + enabled: Some(true.into()), // editorconfig support is intentionally set to true, because prettier always reads the editorconfig file // see: https://github.com/prettier/prettier/issues/15255 - use_editorconfig: Some(true), + use_editorconfig: Some(true.into()), // deprecated indent_size: None, bracket_spacing: Some(BracketSpacing::default()), @@ -233,7 +233,7 @@ impl TryFrom for biome_configuration::PartialConfiguratio } else { QuoteStyle::Double }; - let js_formatter = biome_configuration::PartialJavascriptFormatter { + let js_formatter = biome_configuration::JsFormatterConfiguration { indent_width: None, line_width: None, indent_style: None, @@ -243,7 +243,7 @@ impl TryFrom for biome_configuration::PartialConfiguratio indent_size: None, // js ones - bracket_same_line: Some(value.bracket_line), + bracket_same_line: Some(value.bracket_line.into()), arrow_parentheses: Some(value.arrow_parens.into()), semicolons: Some(semicolons), trailing_commas: Some(value.trailing_comma.into()), @@ -255,7 +255,7 @@ impl TryFrom for biome_configuration::PartialConfiguratio jsx_quote_style: Some(jsx_quote_style), attribute_position: Some(AttributePosition::default()), }; - let js_config = biome_configuration::PartialJavascriptConfiguration { + let js_config = biome_configuration::JsConfiguration { formatter: Some(js_formatter), ..Default::default() }; @@ -306,7 +306,7 @@ impl TryFrom for biome_configuration::OverridePattern { indent_width, line_width, indent_style, - line_ending: options.end_of_line.map(|end_of_line| end_of_line.into()), + line_ending: options.end_of_line.map(Into::into), ..Default::default() }; result.formatter = Some(formatter); @@ -345,19 +345,17 @@ impl TryFrom for biome_configuration::OverridePattern { QuoteStyle::Double } }); - let js_formatter = biome_configuration::PartialJavascriptFormatter { - bracket_same_line: options.bracket_line, - arrow_parentheses: options.arrow_parens.map(|arrow_parens| arrow_parens.into()), + let js_formatter = biome_configuration::JsFormatterConfiguration { + bracket_same_line: options.bracket_line.map(Into::into), + arrow_parentheses: options.arrow_parens.map(Into::into), semicolons, - trailing_commas: options - .trailing_comma - .map(|trailing_comma| trailing_comma.into()), + trailing_commas: options.trailing_comma.map(Into::into), quote_style, - quote_properties: options.quote_props.map(|quote_props| quote_props.into()), + quote_properties: options.quote_props.map(Into::into), jsx_quote_style, ..Default::default() }; - let js_config = biome_configuration::PartialJavascriptConfiguration { + let js_config = biome_configuration::JsConfiguration { formatter: Some(js_formatter), ..Default::default() }; @@ -425,7 +423,7 @@ fn load_config( if path.file_name().is_some_and(|name| name == PACKAGE_JSON) { let (deserialized, _) = deserialize_from_json_str::( &content, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_trailing_commas() .with_allow_comments(), "", @@ -438,7 +436,7 @@ fn load_config( } else { deserialize_from_json_str::( &content, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_trailing_commas() .with_allow_comments(), "", @@ -450,7 +448,7 @@ fn load_config( let node::Resolution { content, .. } = node::load_config(&path.to_string_lossy())?; deserialize_from_json_str::( &content, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .consume() @@ -505,13 +503,13 @@ fn load_config( mod tests { use crate::execute::migrate::prettier::{PrettierConfiguration, PrettierTrailingComma}; use biome_deserialize::json::deserialize_from_json_str; - use biome_json_parser::JsonParserOptions; + use biome_json_parser::JsonParseOptions; #[test] fn ok() { let configuration = deserialize_from_json_str::( r#"{ "useTabs": true }"#, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .into_deserialized() @@ -537,7 +535,7 @@ mod tests { "jsxSingleQuote": true } "#, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ) .into_deserialized() diff --git a/crates/biome_cli/tests/commands/init.rs b/crates/biome_cli/tests/commands/init.rs index 0e0ee38a5220..8471432a7f18 100644 --- a/crates/biome_cli/tests/commands/init.rs +++ b/crates/biome_cli/tests/commands/init.rs @@ -4,7 +4,7 @@ use crate::snap_test::{assert_cli_snapshot, assert_file_contents, SnapshotPayloa use biome_console::BufferConsole; use biome_fs::MemoryFileSystem; use biome_json_formatter::context::JsonFormatOptions; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use biome_service::DynRef; use bpaf::Args; use std::path::Path; @@ -44,7 +44,7 @@ fn creates_config_file() { assert!(result.is_ok(), "run_cli returned {result:?}"); let file_path = Path::new("biome.json"); - let parsed = parse_json(CONFIG_INIT_DEFAULT, JsonParserOptions::default()); + let parsed = parse_json(CONFIG_INIT_DEFAULT, JsonParseOptions::default()); let formatted = biome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax()) .expect("valid format document") @@ -77,7 +77,7 @@ fn creates_config_jsonc_file() { let file_path = Path::new("biome.jsonc"); let parsed = parse_json( CONFIG_INIT_DEFAULT, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), ); @@ -117,7 +117,7 @@ fn creates_config_file_when_biome_installed_via_package_manager() { let parsed = parse_json( CONFIG_INIT_DEFAULT_WHEN_INSTALLED, - JsonParserOptions::default(), + JsonParseOptions::default(), ); let formatted = biome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax()) diff --git a/crates/biome_cli/tests/snap_test.rs b/crates/biome_cli/tests/snap_test.rs index 7791f075521d..39aea7147251 100644 --- a/crates/biome_cli/tests/snap_test.rs +++ b/crates/biome_cli/tests/snap_test.rs @@ -7,7 +7,7 @@ use biome_formatter::{IndentStyle, IndentWidth}; use biome_fs::{ConfigName, FileSystemExt, MemoryFileSystem}; use biome_json_formatter::context::JsonFormatOptions; use biome_json_formatter::format_node; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use lazy_static::lazy_static; use regex::Regex; use std::borrow::Cow; @@ -62,7 +62,7 @@ impl CliSnapshot { let parsed = parse_json( &redacted, - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), ); diff --git a/crates/biome_configuration/src/bool.rs b/crates/biome_configuration/src/bool.rs new file mode 100644 index 000000000000..7f14de33f38e --- /dev/null +++ b/crates/biome_configuration/src/bool.rs @@ -0,0 +1,79 @@ +use biome_deserialize::{Deserializable, DeserializableValue, DeserializationDiagnostic}; +use biome_deserialize_macros::Merge; +use std::{ + fmt, + str::{FromStr, ParseBoolError}, +}; + +/// A `bool` type wrapper with a configurable default value (`true` or `false`) +/// +/// The const generic indicates the default bool value of this wrapper type +#[derive( + Clone, Copy, Eq, Merge, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema, +)] +pub struct Bool(pub bool); + +impl Bool { + pub fn value(&self) -> bool { + self.0 + } +} + +impl Default for Bool { + fn default() -> Self { + Self(true) + } +} + +impl Default for Bool { + fn default() -> Self { + Self(false) + } +} + +impl FromStr for Bool { + type Err = ParseBoolError; + fn from_str(s: &str) -> Result { + Ok(Self(bool::from_str(s)?)) + } +} + +impl Deserializable for Bool { + fn deserialize( + value: &impl DeserializableValue, + name: &str, + diagnostics: &mut Vec, + ) -> Option { + bool::deserialize(value, name, diagnostics).map(Self) + } +} + +impl fmt::Debug for Bool { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.value().fmt(f) + } +} + +impl From for Bool { + fn from(value: bool) -> Self { + Self(value) + } +} + +impl From> for bool { + fn from(value: Bool) -> Self { + value.value() + } +} + +impl From> for Bool { + fn from(value: Bool) -> Self { + Self(value.value()) + } +} + +impl From> for Bool { + fn from(value: Bool) -> Self { + Self(value.value()) + } +} diff --git a/crates/biome_configuration/src/css.rs b/crates/biome_configuration/src/css.rs index 02c0d7f62245..5ed3897ad1ff 100644 --- a/crates/biome_configuration/src/css.rs +++ b/crates/biome_configuration/src/css.rs @@ -1,114 +1,119 @@ -use crate::PlainIndentStyle; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use crate::{bool::Bool, PlainIndentStyle}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::{IndentWidth, LineEnding, LineWidth, QuoteStyle}; use bpaf::Bpaf; use serde::{Deserialize, Serialize}; /// Options applied to CSS files -#[derive(Clone, Default, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct CssConfiguration { /// CSS parsing options - #[partial(type, bpaf(external(partial_css_parser), optional))] - pub parser: CssParser, + #[bpaf(external(css_parser_configuration), optional)] + pub parser: Option, /// CSS formatter options - #[partial(type, bpaf(external(partial_css_formatter), optional))] - pub formatter: CssFormatter, + #[bpaf(external(css_formatter_configuration), optional)] + pub formatter: Option, /// CSS linter options - #[partial(type, bpaf(external(partial_css_linter), optional))] - pub linter: CssLinter, + #[bpaf(external(css_linter_configuration), optional)] + pub linter: Option, } +pub type AllowWrongLineCommentsEnabled = Bool; +pub type CssModulesEnabled = Bool; + /// Options that changes how the CSS parser behaves -#[derive(Clone, Default, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct CssParser { +#[derive( + Bpaf, Clone, Default, Debug, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct CssParserConfiguration { /// Allow comments to appear on incorrect lines in `.css` files - #[partial(bpaf(hide))] - pub allow_wrong_line_comments: bool, + #[bpaf(hide)] + pub allow_wrong_line_comments: Option, /// Enables parsing of CSS Modules specific features. - #[partial(bpaf(hide))] - pub css_modules: bool, + #[bpaf(hide)] + pub css_modules: Option, } +pub type CssFormatterEnabled = Bool; + /// Options that changes how the CSS formatter behaves -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct CssFormatter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct CssFormatterConfiguration { /// Control the formatter for CSS (and its super languages) files. - #[partial(bpaf(long("css-formatter-enabled"), argument("true|false"), optional))] - pub enabled: bool, + #[bpaf(long("css-formatter-enabled"), argument("true|false"))] + pub enabled: Option, /// The indent style applied to CSS (and its super languages) files. - #[partial(bpaf(long("css-formatter-indent-style"), argument("tab|space"), optional))] + #[bpaf(long("css-formatter-indent-style"), argument("tab|space"))] pub indent_style: Option, /// The size of the indentation applied to CSS (and its super languages) files. Default to 2. - #[partial(bpaf(long("css-formatter-indent-width"), argument("NUMBER"), optional))] + #[bpaf(long("css-formatter-indent-width"), argument("NUMBER"))] pub indent_width: Option, /// The type of line ending applied to CSS (and its super languages) files. - #[partial(bpaf(long("css-formatter-line-ending"), argument("lf|crlf|cr"), optional))] + #[bpaf(long("css-formatter-line-ending"), argument("lf|crlf|cr"))] pub line_ending: Option, /// What's the max width of a line applied to CSS (and its super languages) files. Defaults to 80. - #[partial(bpaf(long("css-formatter-line-width"), argument("NUMBER"), optional))] + #[bpaf(long("css-formatter-line-width"), argument("NUMBER"))] pub line_width: Option, /// The type of quotes used in CSS code. Defaults to double. - #[partial(bpaf(long("css-formatter-quote-style"), argument("double|single"), optional))] - pub quote_style: QuoteStyle, + #[bpaf(long("css-formatter-quote-style"), argument("double|single"))] + pub quote_style: Option, } -impl PartialCssFormatter { - pub fn get_formatter_configuration(&self) -> CssFormatter { - CssFormatter { - enabled: self.enabled.unwrap_or_default(), - indent_style: self.indent_style, - indent_width: self.indent_width, - line_ending: self.line_ending, - line_width: self.line_width, - quote_style: self.quote_style.unwrap_or_default(), - } +impl CssFormatterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() + } + + pub fn quote_style_resolved(&self) -> QuoteStyle { + self.quote_style.unwrap_or_default() } } +pub type CssLinterEnabled = Bool; /// Options that changes how the CSS linter behaves -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Default, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct CssLinter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct CssLinterConfiguration { /// Control the linter for CSS (and its super languages) files. - #[partial(bpaf(long("css-linter-enabled"), argument("true|false"), optional))] - pub enabled: bool, + #[bpaf(long("css-linter-enabled"), argument("true|false"))] + pub enabled: Option, } -impl PartialCssLinter { - pub fn get_linter_configuration(&self) -> CssLinter { - CssLinter { - enabled: self.enabled.unwrap_or_default(), - } +impl CssLinterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } } #[test] fn default_css() { - let css_configuration = CssFormatter::default(); + let css_configuration = CssFormatterConfiguration::default(); - assert!(!css_configuration.enabled); + assert!(!css_configuration.enabled_resolved()); assert_eq!(css_configuration.indent_style, None); assert_eq!(css_configuration.indent_width, None); assert_eq!(css_configuration.line_ending, None); assert_eq!(css_configuration.line_width, None); - assert_eq!(css_configuration.quote_style, QuoteStyle::Double); + assert_eq!(css_configuration.quote_style, None); } diff --git a/crates/biome_configuration/src/diagnostics.rs b/crates/biome_configuration/src/diagnostics.rs index 8cb699d0103b..b6da41e31058 100644 --- a/crates/biome_configuration/src/diagnostics.rs +++ b/crates/biome_configuration/src/diagnostics.rs @@ -329,10 +329,10 @@ pub struct InvalidGlobPatternDiagnostic { #[cfg(test)] mod test { - use crate::{BiomeDiagnostic, PartialConfiguration}; + use crate::{BiomeDiagnostic, Configuration}; use biome_deserialize::json::deserialize_from_json_str; use biome_diagnostics::{print_diagnostic_to_string, DiagnosticExt, Error}; - use biome_json_parser::JsonParserOptions; + use biome_json_parser::JsonParseOptions; fn snap_diagnostic(test_name: &str, diagnostic: Error) { let content = print_diagnostic_to_string(&diagnostic); @@ -360,11 +360,8 @@ mod test { #[test] fn deserialization_error() { let content = "{ \n\n\"formatter\" }"; - let result = deserialize_from_json_str::( - content, - JsonParserOptions::default(), - "", - ); + let result = + deserialize_from_json_str::(content, JsonParseOptions::default(), ""); assert!(result.has_errors()); for diagnostic in result.into_diagnostics() { @@ -387,12 +384,9 @@ mod test { } } }"#; - let _result = deserialize_from_json_str::( - content, - JsonParserOptions::default(), - "", - ) - .into_deserialized() - .unwrap_or_default(); + let _result = + deserialize_from_json_str::(content, JsonParseOptions::default(), "") + .into_deserialized() + .unwrap_or_default(); } } diff --git a/crates/biome_configuration/src/editorconfig.rs b/crates/biome_configuration/src/editorconfig.rs index f1961b34efc6..95339795c14c 100644 --- a/crates/biome_configuration/src/editorconfig.rs +++ b/crates/biome_configuration/src/editorconfig.rs @@ -17,8 +17,8 @@ use serde::{Deserialize, Deserializer}; use crate::{ diagnostics::{EditorConfigDiagnostic, ParseFailedDiagnostic}, - OverrideFormatterConfiguration, OverridePattern, Overrides, PartialConfiguration, - PartialFormatterConfiguration, PlainIndentStyle, + Configuration, FormatterConfiguration, OverrideFormatterConfiguration, OverridePattern, + Overrides, PlainIndentStyle, }; pub fn parse_str(s: &str) -> Result { @@ -41,10 +41,10 @@ pub struct EditorConfig { } impl EditorConfig { - pub fn to_biome(mut self) -> (Option, Vec) { + pub fn to_biome(mut self) -> (Option, Vec) { let diagnostics = self.validate(); - let mut config = PartialConfiguration { + let mut config = Configuration { formatter: self.options.remove("*").map(|o| o.to_biome()), ..Default::default() }; @@ -95,8 +95,8 @@ pub struct EditorConfigOptions { } impl EditorConfigOptions { - pub fn to_biome(self) -> PartialFormatterConfiguration { - PartialFormatterConfiguration { + pub fn to_biome(self) -> FormatterConfiguration { + FormatterConfiguration { indent_style: self.indent_style, indent_width: self.indent_size, line_ending: self.end_of_line, diff --git a/crates/biome_configuration/src/file_size.rs b/crates/biome_configuration/src/file_size.rs new file mode 100644 index 000000000000..5d0fa3c59868 --- /dev/null +++ b/crates/biome_configuration/src/file_size.rs @@ -0,0 +1,65 @@ +use biome_deserialize::{Deserializable, DeserializableValue, DeserializationDiagnostic}; +use biome_deserialize_macros::Merge; +use std::{ + fmt, + num::{NonZeroU64, ParseIntError}, + str::FromStr, +}; + +/// Limit the size of files to 1.0 MiB by default +pub const DEFAULT_FILE_SIZE_LIMIT: NonZeroU64 = + // SAFETY: This constant is initialized with a non-zero value + unsafe { NonZeroU64::new_unchecked(1024 * 1024) }; + +/// A `bool` type wrapper with a configurable default value (`true` or `false`) +#[derive( + Clone, Copy, Eq, Merge, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema, +)] +pub struct FileSize(pub NonZeroU64); + +impl Default for FileSize { + fn default() -> Self { + Self(DEFAULT_FILE_SIZE_LIMIT) + } +} + +impl FromStr for FileSize { + type Err = ParseIntError; + fn from_str(s: &str) -> Result { + Ok(Self(NonZeroU64::from_str(s)?)) + } +} + +impl Deserializable for FileSize { + fn deserialize( + value: &impl DeserializableValue, + name: &str, + diagnostics: &mut Vec, + ) -> Option { + NonZeroU64::deserialize(value, name, diagnostics).map(Self) + } +} + +impl fmt::Debug for FileSize { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl From for FileSize { + fn from(value: NonZeroU64) -> Self { + Self(value) + } +} + +impl From for NonZeroU64 { + fn from(value: FileSize) -> Self { + value.0 + } +} + +impl From for usize { + fn from(value: FileSize) -> Self { + Self::try_from(NonZeroU64::from(value).get()).unwrap_or(Self::MAX) + } +} diff --git a/crates/biome_configuration/src/formatter.rs b/crates/biome_configuration/src/formatter.rs index 33f230706e32..2bd0aa92fc65 100644 --- a/crates/biome_configuration/src/formatter.rs +++ b/crates/biome_configuration/src/formatter.rs @@ -1,5 +1,6 @@ +use crate::bool::Bool; use biome_deserialize::StringSet; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::{ AttributePosition, BracketSpacing, IndentStyle, IndentWidth, LineEnding, LineWidth, }; @@ -7,123 +8,113 @@ use bpaf::Bpaf; use serde::{Deserialize, Serialize}; use std::str::FromStr; +pub type FormatterEnabled = Bool; +pub type UseEditorconfigEnabled = Bool; +pub type FormatWithErrorsEnabled = Bool; + /// Generic options applied to all files -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +#[derive( + Bpaf, Clone, Deserializable, Debug, Default, Deserialize, Eq, PartialEq, Merge, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct FormatterConfiguration { // if `false`, it disables the feature. `true` by default - #[partial(bpaf(hide))] - pub enabled: bool, - - #[partial(bpaf(long("use-editorconfig"), argument("true|false"), optional))] - /// Use any `.editorconfig` files to configure the formatter. Configuration in `biome.json` will override `.editorconfig` configuration. Default: false. - pub use_editorconfig: bool, + #[bpaf(hide)] + pub enabled: Option, /// Stores whether formatting should be allowed to proceed if a given file /// has syntax errors - #[partial(bpaf(hide))] - pub format_with_errors: bool, + #[bpaf(hide)] + pub format_with_errors: Option, /// The indent style. - #[partial(bpaf(long("indent-style"), argument("tab|space"), optional))] - pub indent_style: PlainIndentStyle, + #[bpaf(long("indent-style"), argument("tab|space"))] + pub indent_style: Option, /// The size of the indentation, 2 by default (deprecated, use `indent-width`) - #[partial(bpaf(long("indent-size"), argument("NUMBER"), optional))] - #[partial(deserializable(deprecated(use_instead = "formatter.indentWidth")))] - pub indent_size: IndentWidth, + #[bpaf(long("indent-size"), argument("NUMBER"))] + #[deserializable(deprecated(use_instead = "formatter.indentWidth"))] + pub indent_size: Option, /// The size of the indentation, 2 by default - #[partial(bpaf(long("indent-width"), argument("NUMBER"), optional))] - pub indent_width: IndentWidth, + #[bpaf(long("indent-width"), argument("NUMBER"))] + pub indent_width: Option, /// The type of line ending. - #[partial(bpaf(long("line-ending"), argument("lf|crlf|cr"), optional))] - pub line_ending: LineEnding, + #[bpaf(long("line-ending"), argument("lf|crlf|cr"))] + pub line_ending: Option, /// What's the max width of a line. Defaults to 80. - #[partial(bpaf(long("line-width"), argument("NUMBER"), optional))] - pub line_width: LineWidth, + #[bpaf(long("line-width"), argument("NUMBER"))] + pub line_width: Option, /// The attribute position style in HTMLish languages. By default auto. - #[partial(bpaf(long("attribute-position"), argument("multiline|auto"), optional))] - pub attribute_position: AttributePosition, + #[bpaf(long("attribute-position"), argument("multiline|auto"))] + pub attribute_position: Option, /// Whether to insert spaces around brackets in object literals. Defaults to true. - #[partial(bpaf(long("bracket-spacing"), argument("true|false"), optional))] - pub bracket_spacing: BracketSpacing, + #[bpaf(long("bracket-spacing"), argument("true|false"))] + pub bracket_spacing: Option, + + /// Use any `.editorconfig` files to configure the formatter. Configuration in `biome.json` will override `.editorconfig` configuration. Default: false. + #[bpaf(long("use-editorconfig"), argument("true|false"))] + pub use_editorconfig: Option, /// A list of Unix shell style patterns. The formatter will ignore files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub ignore: StringSet, + #[bpaf(hide)] + pub ignore: Option, /// A list of Unix shell style patterns. The formatter will include files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub include: StringSet, + #[bpaf(hide)] + pub include: Option, } -impl PartialFormatterConfiguration { - pub const fn is_disabled(&self) -> bool { - matches!(self.enabled, Some(false)) +impl FormatterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } - pub fn get_formatter_configuration(&self) -> FormatterConfiguration { - FormatterConfiguration { - enabled: self.enabled.unwrap_or_default(), - format_with_errors: self.format_with_errors.unwrap_or_default(), - indent_style: self.indent_style.unwrap_or_default(), - indent_size: self.indent_size.unwrap_or_default(), - indent_width: self.indent_width.unwrap_or_default(), - line_ending: self.line_ending.unwrap_or_default(), - line_width: self.line_width.unwrap_or_default(), - attribute_position: self.attribute_position.unwrap_or_default(), - bracket_spacing: self.bracket_spacing.unwrap_or_default(), - ignore: self.ignore.clone().unwrap_or_default(), - include: self.include.clone().unwrap_or_default(), - use_editorconfig: self.use_editorconfig.unwrap_or_default(), - } + pub fn format_with_errors_resolved(&self) -> bool { + self.format_with_errors.unwrap_or_default().into() } -} -impl Default for FormatterConfiguration { - fn default() -> Self { - Self { - enabled: true, - format_with_errors: false, - indent_size: IndentWidth::default(), - indent_width: IndentWidth::default(), - indent_style: PlainIndentStyle::default(), - line_ending: LineEnding::default(), - line_width: LineWidth::default(), - attribute_position: AttributePosition::default(), - bracket_spacing: Default::default(), - ignore: Default::default(), - include: Default::default(), - // TODO: Biome 2.0: change to true - use_editorconfig: Default::default(), - } + pub fn indent_style_resolved(&self) -> PlainIndentStyle { + self.indent_style.unwrap_or_default() } -} -/// Required by [Bpaf]. -impl FromStr for FormatterConfiguration { - type Err = &'static str; + pub fn indent_width_resolved(&self) -> IndentWidth { + self.indent_width.unwrap_or_default() + } - fn from_str(_s: &str) -> Result { - Ok(Self::default()) + pub fn line_ending_resolved(&self) -> LineEnding { + self.line_ending.unwrap_or_default() } -} -impl From for IndentStyle { - fn from(value: PlainIndentStyle) -> Self { - match value { - PlainIndentStyle::Tab => IndentStyle::Tab, - PlainIndentStyle::Space => IndentStyle::Space, - } + pub fn line_width_resolved(&self) -> LineWidth { + self.line_width.unwrap_or_default() + } + + pub fn attribute_position_resolved(&self) -> AttributePosition { + self.attribute_position.unwrap_or_default() + } + + pub fn bracket_spacing_resolved(&self) -> BracketSpacing { + self.bracket_spacing.unwrap_or_default() + } + + pub fn use_editorconfig_resolved(&self) -> bool { + self.use_editorconfig.unwrap_or_default().into() + } + + pub fn ignore_resolved(&self) -> StringSet { + self.ignore.clone().unwrap_or_default() + } + + pub fn include_resolved(&self) -> StringSet { + self.include.clone().unwrap_or_default() } } @@ -151,3 +142,12 @@ impl FromStr for PlainIndentStyle { } } } + +impl From for IndentStyle { + fn from(value: PlainIndentStyle) -> Self { + match value { + PlainIndentStyle::Tab => IndentStyle::Tab, + PlainIndentStyle::Space => IndentStyle::Space, + } + } +} diff --git a/crates/biome_configuration/src/graphql.rs b/crates/biome_configuration/src/graphql.rs index acc808812449..500f5c9f7deb 100644 --- a/crates/biome_configuration/src/graphql.rs +++ b/crates/biome_configuration/src/graphql.rs @@ -1,132 +1,99 @@ -use crate::PlainIndentStyle; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use crate::{bool::Bool, PlainIndentStyle}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::{BracketSpacing, IndentWidth, LineEnding, LineWidth, QuoteStyle}; use bpaf::Bpaf; use serde::{Deserialize, Serialize}; /// Options applied to GraphQL files -#[derive(Clone, Default, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +#[derive( + Bpaf, Clone, Default, Debug, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct GraphqlConfiguration { /// GraphQL formatter options - #[partial(type, bpaf(external(partial_graphql_formatter), optional))] - pub formatter: GraphqlFormatter, + #[bpaf(external(graphql_formatter_configuration), optional)] + pub formatter: Option, // GraphQL linter options - #[partial(type, bpaf(external(partial_graphql_linter), optional))] - pub linter: GraphqlLinter, + #[bpaf(external(graphql_linter_configuration), optional)] + pub linter: Option, } +pub type GraphqlFormatterEnabled = Bool; + /// Options that changes how the GraphQL formatter behaves -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct GraphqlFormatter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct GraphqlFormatterConfiguration { /// Control the formatter for GraphQL files. - #[partial(bpaf(long("graphql-formatter-enabled"), argument("true|false"), optional))] - pub enabled: Option, + #[bpaf(long("graphql-formatter-enabled"), argument("true|false"))] + pub enabled: Option, /// The indent style applied to GraphQL files. - #[partial(bpaf( - long("graphql-formatter-indent-style"), - argument("tab|space"), - optional - ))] + #[bpaf(long("graphql-formatter-indent-style"), argument("tab|space"))] pub indent_style: Option, /// The size of the indentation applied to GraphQL files. Default to 2. - #[partial(bpaf(long("graphql-formatter-indent-width"), argument("NUMBER"), optional))] + #[bpaf(long("graphql-formatter-indent-width"), argument("NUMBER"))] pub indent_width: Option, /// The type of line ending applied to GraphQL files. - #[partial(bpaf( - long("graphql-formatter-line-ending"), - argument("lf|crlf|cr"), - optional - ))] + #[bpaf(long("graphql-formatter-line-ending"), argument("lf|crlf|cr"))] pub line_ending: Option, /// What's the max width of a line applied to GraphQL files. Defaults to 80. - #[partial(bpaf(long("graphql-formatter-line-width"), argument("NUMBER"), optional))] + #[bpaf(long("graphql-formatter-line-width"), argument("NUMBER"))] pub line_width: Option, /// The type of quotes used in GraphQL code. Defaults to double. - #[partial(bpaf( - long("graphql-formatter-quote-style"), - argument("double|single"), - optional - ))] + #[bpaf(long("graphql-formatter-quote-style"), argument("double|single"))] pub quote_style: Option, // it's also a top-level configurable property. /// Whether to insert spaces around brackets in object literals. Defaults to true. - #[partial(bpaf(long("bracket-spacing"), argument("true|false"), optional))] + #[bpaf(long("bracket-spacing"), argument("true|false"))] pub bracket_spacing: Option, } -impl Default for GraphqlFormatter { - fn default() -> Self { - Self { - enabled: Some(false), - indent_style: Default::default(), - indent_width: Default::default(), - line_ending: Default::default(), - line_width: Default::default(), - quote_style: Default::default(), - bracket_spacing: Default::default(), - } +impl GraphqlFormatterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } -} -impl PartialGraphqlFormatter { - pub fn get_formatter_configuration(&self) -> GraphqlFormatter { - GraphqlFormatter { - enabled: self.enabled, - indent_style: self.indent_style, - indent_width: self.indent_width, - line_ending: self.line_ending, - line_width: self.line_width, - quote_style: self.quote_style, - bracket_spacing: self.bracket_spacing, - } + pub fn quote_style_resolved(&self) -> QuoteStyle { + self.quote_style.unwrap_or_default() } } +pub type GraphqlLinterEnabled = Bool; + /// Options that changes how the GraphQL linter behaves -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct GraphqlLinter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct GraphqlLinterConfiguration { /// Control the formatter for GraphQL files. - #[partial(bpaf(long("graphql-linter-enabled"), argument("true|false"), optional))] - pub enabled: Option, -} - -impl Default for GraphqlLinter { - fn default() -> Self { - Self { - enabled: Some(false), - } - } + #[bpaf(long("graphql-linter-enabled"), argument("true|false"))] + pub enabled: Option, } -impl PartialGraphqlLinter { - pub fn get_linter_configuration(&self) -> GraphqlLinter { - GraphqlLinter { - enabled: self.enabled, - } +impl GraphqlLinterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } } #[test] fn default_graphql_formatter() { - let graphql_configuration = GraphqlFormatter::default(); + let graphql_configuration = GraphqlFormatterConfiguration::default(); - assert_eq!(graphql_configuration.enabled, Some(false)); + assert!(!graphql_configuration.enabled_resolved()); assert_eq!(graphql_configuration.indent_style, None); assert_eq!(graphql_configuration.indent_width, None); assert_eq!(graphql_configuration.line_ending, None); @@ -136,7 +103,7 @@ fn default_graphql_formatter() { #[test] fn default_graphql_linter() { - let graphql_configuration = GraphqlLinter::default(); + let graphql_configuration = GraphqlLinterConfiguration::default(); - assert_eq!(graphql_configuration.enabled, Some(false)); + assert!(!graphql_configuration.enabled_resolved()); } diff --git a/crates/biome_configuration/src/javascript/formatter.rs b/crates/biome_configuration/src/javascript/formatter.rs index 2fc55a891c96..c8486585686f 100644 --- a/crates/biome_configuration/src/javascript/formatter.rs +++ b/crates/biome_configuration/src/javascript/formatter.rs @@ -1,5 +1,5 @@ -use crate::PlainIndentStyle; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use crate::{bool::Bool, PlainIndentStyle}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::{ AttributePosition, BracketSpacing, IndentWidth, LineEnding, LineWidth, QuoteStyle, }; @@ -9,143 +9,131 @@ use biome_js_formatter::context::{ use bpaf::Bpaf; use serde::{Deserialize, Serialize}; +pub type JsFormatterEnabled = Bool; +pub type BracketSameLineEnabled = Bool; + /// Formatting options specific to the JavaScript files -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JavascriptFormatter { +#[derive( + Bpaf, Clone, Default, Debug, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsFormatterConfiguration { + /// Control the formatter for JavaScript (and its super languages) files. + #[bpaf(long("javascript-formatter-enabled"), argument("true|false"))] + pub enabled: Option, + /// The type of quotes used in JSX. Defaults to double. - #[partial(bpaf(long("jsx-quote-style"), argument("double|single"), optional))] - pub jsx_quote_style: QuoteStyle, + #[bpaf(long("jsx-quote-style"), argument("double|single"))] + pub jsx_quote_style: Option, /// When properties in objects are quoted. Defaults to asNeeded. - #[partial(bpaf(long("quote-properties"), argument("preserve|as-needed"), optional))] - pub quote_properties: QuoteProperties, + #[bpaf(long("quote-properties"), argument("preserve|as-needed"))] + pub quote_properties: Option, // TODO: Remove in 2.0.0 /// Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to "all". - #[partial(bpaf(long("trailing-comma"), argument("all|es5|none"), optional))] - #[partial(deserializable(deprecated(use_instead = "javascript.formatter.trailingCommas")))] - pub trailing_comma: TrailingCommas, + #[bpaf(long("trailing-comma"), argument("all|es5|none"))] + #[deserializable(deprecated(use_instead = "javascript.formatter.trailingCommas"))] + pub trailing_comma: Option, /// Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to "all". - #[partial(bpaf(long("trailing-commas"), argument("all|es5|none"), optional))] - pub trailing_commas: TrailingCommas, + #[bpaf(long("trailing-commas"), argument("all|es5|none"))] + pub trailing_commas: Option, /// Whether the formatter prints semicolons for all statements or only in for statements where it is necessary because of ASI. - #[partial(bpaf(long("semicolons"), argument("always|as-needed"), optional))] - pub semicolons: Semicolons, + #[bpaf(long("semicolons"), argument("always|as-needed"))] + pub semicolons: Option, /// Whether to add non-necessary parentheses to arrow functions. Defaults to "always". - #[partial(bpaf(long("arrow-parentheses"), argument("always|as-needed"), optional))] - pub arrow_parentheses: ArrowParentheses, + #[bpaf(long("arrow-parentheses"), argument("always|as-needed"))] + pub arrow_parentheses: Option, /// Whether to hug the closing bracket of multiline HTML/JSX tags to the end of the last line, rather than being alone on the following line. Defaults to false. - #[partial(bpaf(long("bracket-same-line"), argument("true|false"), optional))] - pub bracket_same_line: bool, - - /// Control the formatter for JavaScript (and its super languages) files. - #[partial(bpaf(long("javascript-formatter-enabled"), argument("true|false"), optional))] - pub enabled: bool, + #[bpaf(long("bracket-same-line"), argument("true|false"))] + pub bracket_same_line: Option, /// The indent style applied to JavaScript (and its super languages) files. - #[partial(bpaf( + #[bpaf( long("javascript-formatter-indent-style"), argument("tab|space"), optional - ))] + )] pub indent_style: Option, // TODO: Remove in 2.0.0 /// The size of the indentation applied to JavaScript (and its super languages) files. Default to 2. - #[partial(deserializable(deprecated(use_instead = "javascript.formatter.indentWidth")))] - #[partial(bpaf(long("javascript-formatter-indent-size"), argument("NUMBER"), optional))] + #[deserializable(deprecated(use_instead = "javascript.formatter.indentWidth"))] + #[bpaf(long("javascript-formatter-indent-size"), argument("NUMBER"))] pub indent_size: Option, /// The size of the indentation applied to JavaScript (and its super languages) files. Default to 2. - #[partial(bpaf( + #[bpaf( long("javascript-formatter-indent-width"), argument("NUMBER"), optional - ))] + )] pub indent_width: Option, /// The type of line ending applied to JavaScript (and its super languages) files. - #[partial(bpaf( + #[bpaf( long("javascript-formatter-line-ending"), argument("lf|crlf|cr"), optional - ))] + )] pub line_ending: Option, /// What's the max width of a line applied to JavaScript (and its super languages) files. Defaults to 80. - #[partial(bpaf(long("javascript-formatter-line-width"), argument("NUMBER"), optional))] + #[bpaf(long("javascript-formatter-line-width"), argument("NUMBER"))] pub line_width: Option, // TODO: Rename the argument to `javascript-formatter-quote-style` once // it's also a top-level configurable property. /// The type of quotes used in JavaScript code. Defaults to double. - #[partial(bpaf(long("quote-style"), argument("double|single"), optional))] - pub quote_style: QuoteStyle, + #[bpaf(long("quote-style"), argument("double|single"))] + pub quote_style: Option, // it's also a top-level configurable property. /// The attribute position style in jsx elements. Defaults to auto. - #[partial(bpaf( - long("javascript-attribute-position"), - argument("multiline|auto"), - optional - ))] + #[bpaf(long("javascript-attribute-position"), argument("multiline|auto"))] pub attribute_position: Option, // it's also a top-level configurable property. /// Whether to insert spaces around brackets in object literals. Defaults to true. - #[partial(bpaf(long("bracket-spacing"), argument("true|false"), optional))] + #[bpaf(long("bracket-spacing"), argument("true|false"))] pub bracket_spacing: Option, } -impl PartialJavascriptFormatter { - pub fn get_formatter_configuration(&self) -> JavascriptFormatter { - JavascriptFormatter { - enabled: self.enabled.unwrap_or_default(), - jsx_quote_style: self.jsx_quote_style.unwrap_or_default(), - quote_properties: self.quote_properties.unwrap_or_default(), - trailing_comma: self.trailing_comma.unwrap_or_default(), - trailing_commas: self.trailing_commas.unwrap_or_default(), - semicolons: self.semicolons.unwrap_or_default(), - arrow_parentheses: self.arrow_parentheses.unwrap_or_default(), - bracket_spacing: self.bracket_spacing, - bracket_same_line: self.bracket_same_line.unwrap_or_default(), - indent_style: self.indent_style, - indent_size: self.indent_size, - indent_width: self.indent_width, - line_ending: self.line_ending, - line_width: self.line_width, - quote_style: self.quote_style.unwrap_or_default(), - attribute_position: self.attribute_position, - } +impl JsFormatterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() + } + + pub fn jsx_quote_style_resolved(&self) -> QuoteStyle { + self.jsx_quote_style.unwrap_or_default() + } + + pub fn quote_properties_resolved(&self) -> QuoteProperties { + self.quote_properties.unwrap_or_default() + } + + pub fn trailing_commas_resolved(&self) -> TrailingCommas { + self.trailing_commas.unwrap_or_default() + } + + pub fn semicolons_resolved(&self) -> Semicolons { + self.semicolons.unwrap_or_default() + } + + pub fn arrow_parentheses_resolved(&self) -> ArrowParentheses { + self.arrow_parentheses.unwrap_or_default() + } + + pub fn bracket_same_line_resolved(&self) -> bool { + self.bracket_same_line.unwrap_or_default().into() } -} -impl Default for JavascriptFormatter { - fn default() -> Self { - Self { - enabled: true, - jsx_quote_style: Default::default(), - quote_properties: Default::default(), - trailing_comma: Default::default(), - trailing_commas: Default::default(), - semicolons: Default::default(), - arrow_parentheses: Default::default(), - bracket_spacing: Default::default(), - bracket_same_line: Default::default(), - indent_style: Default::default(), - indent_size: Default::default(), - indent_width: Default::default(), - line_ending: Default::default(), - line_width: Default::default(), - quote_style: Default::default(), - attribute_position: Default::default(), - } + pub fn quote_style_resolved(&self) -> QuoteStyle { + self.quote_style.unwrap_or_default() } } diff --git a/crates/biome_configuration/src/javascript/mod.rs b/crates/biome_configuration/src/javascript/mod.rs index 87c5307c88ca..8ed4d8006335 100644 --- a/crates/biome_configuration/src/javascript/mod.rs +++ b/crates/biome_configuration/src/javascript/mod.rs @@ -1,64 +1,67 @@ mod formatter; - -use std::str::FromStr; - +use crate::bool::Bool; use biome_deserialize::StringSet; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; use bpaf::Bpaf; -pub use formatter::{ - partial_javascript_formatter, JavascriptFormatter, PartialJavascriptFormatter, -}; +pub use formatter::*; use serde::{Deserialize, Serialize}; +use std::str::FromStr; /// A set of options applied to the JavaScript files -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JavascriptConfiguration { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsConfiguration { + /// Parsing options + #[bpaf(external(js_parser_configuration), optional)] + pub parser: Option, + /// Formatting options - #[partial(type, bpaf(external(partial_javascript_formatter), optional))] - pub formatter: JavascriptFormatter, + #[bpaf(external(js_formatter_configuration), optional)] + pub formatter: Option, /// Linter options - #[partial(type, bpaf(external(partial_javascript_linter), optional))] - pub linter: JavascriptLinter, - - /// Parsing options - #[partial(type, bpaf(external(partial_javascript_parser), optional))] - pub parser: JavascriptParser, + #[bpaf(external(js_linter_configuration), optional)] + pub linter: Option, /// A list of global bindings that should be ignored by the analyzers /// /// If defined here, they should not emit diagnostics. - #[partial(bpaf(hide))] - pub globals: StringSet, + #[bpaf(hide)] + pub globals: Option, /// Indicates the type of runtime or transformation used for interpreting JSX. - #[partial(bpaf(hide))] - pub jsx_runtime: JsxRuntime, + #[bpaf(hide)] + pub jsx_runtime: Option, - #[partial(type, bpaf(external(partial_javascript_organize_imports), optional))] - pub organize_imports: JavascriptOrganizeImports, + #[bpaf(external(js_organize_imports_configuration), optional)] + pub organize_imports: Option, } -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(default, deny_unknown_fields))] -pub struct JavascriptOrganizeImports {} +// TODO(zzwu): Revisit this +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(default, deny_unknown_fields)] +pub struct JsOrganizeImportsConfiguration {} + +pub type UnsafeParameterDecoratorsEnabled = Bool; /// Options that changes how the JavaScript parser behaves -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JavascriptParser { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsParserConfiguration { /// It enables the experimental and unsafe parsing of parameter decorators /// /// These decorators belong to an old proposal, and they are subject to change. - #[partial(bpaf(hide))] - pub unsafe_parameter_decorators_enabled: bool, + #[bpaf(hide)] + pub unsafe_parameter_decorators_enabled: Option, } /// Indicates the type of runtime or transformation used for interpreting JSX. @@ -96,27 +99,22 @@ impl FromStr for JsxRuntime { } } +pub type JsLinterEnabled = Bool; + /// Linter options specific to the JavaScript linter -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JavascriptLinter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsLinterConfiguration { /// Control the linter for JavaScript (and its super languages) files. - #[partial(bpaf(long("javascript-linter-enabled"), argument("true|false"), optional))] - pub enabled: bool, -} - -impl Default for JavascriptLinter { - fn default() -> Self { - Self { enabled: true } - } + #[bpaf(long("javascript-linter-enabled"), argument("true|false"))] + pub enabled: Option, } -impl PartialJavascriptLinter { - pub fn get_linter_configuration(&self) -> JavascriptLinter { - JavascriptLinter { - enabled: self.enabled.unwrap_or_default(), - } +impl JsLinterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } } diff --git a/crates/biome_configuration/src/json.rs b/crates/biome_configuration/src/json.rs index 51ac891275d0..f2c14d38e791 100644 --- a/crates/biome_configuration/src/json.rs +++ b/crates/biome_configuration/src/json.rs @@ -1,136 +1,113 @@ -use crate::PlainIndentStyle; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use crate::{bool::Bool, PlainIndentStyle}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::{IndentWidth, LineEnding, LineWidth}; use biome_json_formatter::context::TrailingCommas; use bpaf::Bpaf; use serde::{Deserialize, Serialize}; /// Options applied to JSON files -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(default, deny_unknown_fields))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(default, deny_unknown_fields)] pub struct JsonConfiguration { /// Parsing options - #[partial(type, bpaf(external(partial_json_parser), optional))] - pub parser: JsonParser, + #[bpaf(external(json_parser_configuration), optional)] + pub parser: Option, /// Formatting options - #[partial(type, bpaf(external(partial_json_formatter), optional))] - pub formatter: JsonFormatter, + #[bpaf(external(json_formatter_configuration), optional)] + pub formatter: Option, /// Linting options - #[partial(type, bpaf(external(partial_json_linter), optional))] - pub linter: JsonLinter, + #[bpaf(external(json_linter_configuration), optional)] + pub linter: Option, } +pub type AllowCommentsEnabled = Bool; +pub type AllowTrailingCommasEnabled = Bool; + /// Options that changes how the JSON parser behaves -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JsonParser { - #[partial(bpaf(hide))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsonParserConfiguration { + #[bpaf(hide)] /// Allow parsing comments in `.json` files - pub allow_comments: bool, + pub allow_comments: Option, - #[partial(bpaf(hide))] + #[bpaf(hide)] /// Allow parsing trailing commas in `.json` files - pub allow_trailing_commas: bool, + pub allow_trailing_commas: Option, } -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JsonFormatter { +pub type JsonFormatterEnabled = Bool; + +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsonFormatterConfiguration { /// Control the formatter for JSON (and its super languages) files. - #[partial(bpaf(long("json-formatter-enabled"), argument("true|false"), optional))] - pub enabled: bool, + #[bpaf(long("json-formatter-enabled"), argument("true|false"))] + pub enabled: Option, /// The indent style applied to JSON (and its super languages) files. - #[partial(bpaf(long("json-formatter-indent-style"), argument("tab|space"), optional))] + #[bpaf(long("json-formatter-indent-style"), argument("tab|space"))] pub indent_style: Option, /// The size of the indentation applied to JSON (and its super languages) files. Default to 2. - #[partial(bpaf(long("json-formatter-indent-width"), argument("NUMBER"), optional))] + #[bpaf(long("json-formatter-indent-width"), argument("NUMBER"))] pub indent_width: Option, /// The size of the indentation applied to JSON (and its super languages) files. Default to 2. - #[partial(bpaf(long("json-formatter-indent-size"), argument("NUMBER"), optional))] - #[partial(deserializable(deprecated(use_instead = "json.formatter.indentWidth")))] + #[bpaf(long("json-formatter-indent-size"), argument("NUMBER"))] + #[deserializable(deprecated(use_instead = "json.formatter.indentWidth"))] pub indent_size: Option, /// The type of line ending applied to JSON (and its super languages) files. - #[partial(bpaf(long("json-formatter-line-ending"), argument("lf|crlf|cr"), optional))] + #[bpaf(long("json-formatter-line-ending"), argument("lf|crlf|cr"))] pub line_ending: Option, /// What's the max width of a line applied to JSON (and its super languages) files. Defaults to 80. - #[partial(bpaf(long("json-formatter-line-width"), argument("NUMBER"), optional))] + #[bpaf(long("json-formatter-line-width"), argument("NUMBER"))] pub line_width: Option, /// Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to "none". - #[partial(bpaf(long("json-formatter-trailing-commas"), argument("none|all"), optional))] + #[bpaf(long("json-formatter-trailing-commas"), argument("none|all"))] pub trailing_commas: Option, } -impl PartialJsonFormatter { - pub fn get_formatter_configuration(&self) -> JsonFormatter { - JsonFormatter { - enabled: self.enabled.unwrap_or_default(), - indent_style: self.indent_style, - indent_width: self.indent_width, - indent_size: self.indent_size, - line_ending: self.line_ending, - line_width: self.line_width, - trailing_commas: self.trailing_commas, - } +impl JsonFormatterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } -} -impl Default for JsonFormatter { - fn default() -> Self { - Self { - enabled: true, - indent_style: Default::default(), - indent_width: Default::default(), - indent_size: Default::default(), - line_ending: Default::default(), - line_width: Default::default(), - trailing_commas: Default::default(), - } + pub fn trailing_commas_resolved(&self) -> TrailingCommas { + self.trailing_commas.unwrap_or_default() } } +pub type JsonLinterEnabled = Bool; + /// Linter options specific to the JSON linter -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] -pub struct JsonLinter { +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] +pub struct JsonLinterConfiguration { /// Control the linter for JSON (and its super languages) files. - #[partial(bpaf(long("json-linter-enabled"), argument("true|false"), optional))] - pub enabled: bool, -} - -impl PartialJsonFormatter { - pub fn get_linter_configuration(&self) -> JsonLinter { - JsonLinter { - enabled: self.enabled.unwrap_or_default(), - } - } -} - -impl Default for JsonLinter { - fn default() -> Self { - Self { enabled: true } - } + #[bpaf(long("json-linter-enabled"), argument("true|false"))] + pub enabled: Option, } -impl PartialJsonLinter { - pub fn get_linter_configuration(&self) -> JsonLinter { - JsonLinter { - enabled: self.enabled.unwrap_or_default(), - } +impl JsonLinterConfiguration { + pub fn enabled_resolved(&self) -> bool { + self.enabled.unwrap_or_default().into() } } diff --git a/crates/biome_configuration/src/lib.rs b/crates/biome_configuration/src/lib.rs index b986ac30ca51..1654b3c0f0cf 100644 --- a/crates/biome_configuration/src/lib.rs +++ b/crates/biome_configuration/src/lib.rs @@ -2,9 +2,11 @@ //! //! The configuration is divided by "tool", and then it's possible to further customise it //! by language. The language might further options divided by tool. +pub mod bool; pub mod css; pub mod diagnostics; pub mod editorconfig; +pub mod file_size; pub mod formatter; pub mod generated; pub mod graphql; @@ -15,41 +17,36 @@ pub mod organize_imports; mod overrides; pub mod vcs; -use crate::css::CssLinter; pub use crate::diagnostics::BiomeDiagnostic; pub use crate::diagnostics::CantLoadExtendFile; pub use crate::generated::push_to_analyzer_rules; -use crate::javascript::JavascriptLinter; -use crate::json::JsonLinter; -use crate::organize_imports::{partial_organize_imports, OrganizeImports, PartialOrganizeImports}; -use crate::vcs::{partial_vcs_configuration, PartialVcsConfiguration, VcsConfiguration}; +use crate::organize_imports::{organize_imports, OrganizeImports}; +use crate::vcs::{vcs_configuration, VcsConfiguration}; use biome_deserialize::{Deserialized, StringSet}; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; +use bool::Bool; use bpaf::Bpaf; pub use css::{ - partial_css_configuration, CssConfiguration, CssFormatter, PartialCssConfiguration, - PartialCssFormatter, -}; -pub use formatter::{ - partial_formatter_configuration, FormatterConfiguration, PartialFormatterConfiguration, - PlainIndentStyle, + css_configuration, CssConfiguration, CssFormatterConfiguration, CssLinterConfiguration, + CssParserConfiguration, }; +pub use file_size::FileSize; +pub use formatter::{formatter_configuration, FormatterConfiguration, PlainIndentStyle}; pub use graphql::{ - partial_graphql_configuration, GraphqlConfiguration, GraphqlFormatter, GraphqlLinter, - PartialGraphqlConfiguration, PartialGraphqlFormatter, PartialGraphqlLinter, + graphql_configuration, GraphqlConfiguration, GraphqlFormatterConfiguration, + GraphqlLinterConfiguration, }; pub use javascript::{ - partial_javascript_configuration, JavascriptConfiguration, JavascriptFormatter, - PartialJavascriptConfiguration, PartialJavascriptFormatter, + js_configuration, JsConfiguration, JsFormatterConfiguration, JsLinterConfiguration, + JsParserConfiguration, }; pub use json::{ - partial_json_configuration, JsonConfiguration, JsonFormatter, PartialJsonConfiguration, - PartialJsonFormatter, + json_configuration, JsonConfiguration, JsonFormatterConfiguration, JsonLinterConfiguration, + JsonParserConfiguration, }; pub use linter::{ - partial_linter_configuration, LinterConfiguration, PartialLinterConfiguration, - RuleConfiguration, RuleFixConfiguration, RulePlainConfiguration, RuleWithFixOptions, - RuleWithOptions, Rules, + linter_configuration, LinterConfiguration, RuleConfiguration, RuleFixConfiguration, + RulePlainConfiguration, RuleWithFixOptions, RuleWithOptions, Rules, }; pub use overrides::{ OverrideFormatterConfiguration, OverrideLinterConfiguration, @@ -57,83 +54,75 @@ pub use overrides::{ }; use serde::{Deserialize, Serialize}; use std::fmt::Debug; -use std::num::NonZeroU64; use std::path::PathBuf; -/// Limit the size of files to 1.0 MiB by default -pub const DEFAULT_FILE_SIZE_LIMIT: NonZeroU64 = - // SAFETY: This constant is initialized with a non-zero value - unsafe { NonZeroU64::new_unchecked(1024 * 1024) }; - /// The configuration that is contained inside the file `biome.json` -#[derive(Clone, Debug, Default, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(deny_unknown_fields, rename_all = "camelCase"))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct Configuration { /// A field for the [JSON schema](https://json-schema.org/) specification - #[partial(serde(rename = "$schema"))] - #[partial(bpaf(hide))] - pub schema: String, + #[serde(rename = "$schema")] + #[bpaf(hide)] + pub schema: Option, /// The configuration of the VCS integration - #[partial(type, bpaf(external(partial_vcs_configuration), optional, hide_usage))] - pub vcs: VcsConfiguration, + #[bpaf(external(vcs_configuration), optional, hide_usage)] + pub vcs: Option, /// The configuration of the filesystem - #[partial( - type, - bpaf(external(partial_files_configuration), optional, hide_usage) - )] - pub files: FilesConfiguration, + #[bpaf(external(files_configuration), optional, hide_usage)] + pub files: Option, /// The configuration of the formatter - #[partial(type, bpaf(external(partial_formatter_configuration), optional))] - pub formatter: FormatterConfiguration, + #[bpaf(external(formatter_configuration), optional)] + pub formatter: Option, /// The configuration of the import sorting - #[partial(type, bpaf(external(partial_organize_imports), optional))] - pub organize_imports: OrganizeImports, + #[bpaf(external(organize_imports), optional)] + pub organize_imports: Option, /// The configuration for the linter - #[partial(type, bpaf(external(partial_linter_configuration), optional))] - pub linter: LinterConfiguration, + #[bpaf(external(linter_configuration), optional)] + pub linter: Option, /// Specific configuration for the JavaScript language - #[partial(type, bpaf(external(partial_javascript_configuration), optional))] - pub javascript: JavascriptConfiguration, + #[bpaf(external(js_configuration), optional)] + pub javascript: Option, /// Specific configuration for the Json language - #[partial(type, bpaf(external(partial_json_configuration), optional))] - pub json: JsonConfiguration, + #[bpaf(external(json_configuration), optional)] + pub json: Option, /// Specific configuration for the Css language - #[partial(type, bpaf(external(partial_css_configuration), optional))] - pub css: CssConfiguration, + #[bpaf(external(css_configuration), optional)] + pub css: Option, /// Specific configuration for the GraphQL language - #[partial(type, bpaf(external(partial_graphql_configuration), optional))] - pub graphql: GraphqlConfiguration, + #[bpaf(external(graphql_configuration), optional)] + pub graphql: Option, /// A list of paths to other JSON files, used to extends the current configuration. - #[partial(bpaf(hide))] - pub extends: StringSet, + #[bpaf(hide)] + pub extends: Option, /// A list of granular patterns that should be applied only to a sub set of files - #[partial(bpaf(hide))] - pub overrides: Overrides, + #[bpaf(hide)] + pub overrides: Option, } -impl PartialConfiguration { +impl Configuration { /// Returns the initial configuration as generated by `biome init`. pub fn init() -> Self { Self { - organize_imports: Some(PartialOrganizeImports { - enabled: Some(true), + organize_imports: Some(OrganizeImports { + enabled: Some(true.into()), ..Default::default() }), - linter: Some(PartialLinterConfiguration { - enabled: Some(true), + linter: Some(LinterConfiguration { + enabled: Some(true.into()), rules: Some(Rules { recommended: Some(true), ..Default::default() @@ -144,178 +133,171 @@ impl PartialConfiguration { } } - pub fn is_formatter_disabled(&self) -> bool { - self.formatter.as_ref().map_or(false, |f| f.is_disabled()) + pub fn is_formatter_enabled(&self) -> bool { + self.formatter + .as_ref() + .and_then(|formatter| formatter.enabled) + .unwrap_or_default() + .into() } pub fn get_formatter_configuration(&self) -> FormatterConfiguration { - self.formatter + self.formatter.clone().unwrap_or_default() + } + + pub fn is_linter_enabled(&self) -> bool { + self.linter .as_ref() - .map(|f| f.get_formatter_configuration()) + .and_then(|linter| linter.enabled) .unwrap_or_default() + .into() } - pub fn get_javascript_formatter_configuration(&self) -> JavascriptFormatter { - self.javascript + pub fn get_linter_rules(&self) -> Rules { + self.linter .as_ref() - .map(|f| { - f.formatter - .as_ref() - .map(|f| f.get_formatter_configuration()) - .unwrap_or_default() - }) + .and_then(|linter| linter.rules.as_ref()) + .cloned() .unwrap_or_default() } - pub fn get_javascript_linter_configuration(&self) -> JavascriptLinter { - self.javascript + pub fn is_organize_imports_enabled(&self) -> bool { + self.organize_imports .as_ref() - .map(|f| { - f.linter - .as_ref() - .map(|f| f.get_linter_configuration()) - .unwrap_or_default() - }) + .and_then(|organize_imports| organize_imports.enabled) .unwrap_or_default() + .into() } - pub fn get_json_formatter_configuration(&self) -> JsonFormatter { - self.json + pub fn is_vcs_enabled(&self) -> bool { + self.vcs .as_ref() - .map(|f| { - f.formatter - .as_ref() - .map(|f| f.get_formatter_configuration()) - .unwrap_or_default() - }) + .and_then(|vcs| vcs.enabled) .unwrap_or_default() + .into() } - pub fn get_json_linter_configuration(&self) -> JsonLinter { - self.json + pub fn get_javascript_parser_configuration(&self) -> JsParserConfiguration { + self.javascript .as_ref() - .map(|f| { - f.linter - .as_ref() - .map(|f| f.get_linter_configuration()) - .unwrap_or_default() - }) + .and_then(|lang| lang.parser.as_ref()) + .cloned() .unwrap_or_default() } - pub fn get_css_formatter_configuration(&self) -> CssFormatter { - self.css + pub fn get_javascript_formatter_configuration(&self) -> JsFormatterConfiguration { + self.javascript .as_ref() - .map(|f| { - f.formatter - .as_ref() - .map(|f| f.get_formatter_configuration()) - .unwrap_or_default() - }) + .and_then(|lang| lang.formatter.as_ref()) + .cloned() .unwrap_or_default() } - pub fn get_css_linter_configuration(&self) -> CssLinter { - self.css + pub fn get_javascript_linter_configuration(&self) -> JsLinterConfiguration { + self.javascript .as_ref() - .map(|f| { - f.linter - .as_ref() - .map(|f| f.get_linter_configuration()) - .unwrap_or_default() - }) + .and_then(|lang| lang.linter.as_ref()) + .cloned() .unwrap_or_default() } - pub fn get_graphql_linter_configuration(&self) -> GraphqlLinter { - self.graphql + + pub fn get_json_parser_configuration(&self) -> JsonParserConfiguration { + self.json .as_ref() - .map(|f| { - f.linter - .as_ref() - .map(|f| f.get_linter_configuration()) - .unwrap_or_default() - }) + .and_then(|lang| lang.parser.as_ref()) + .cloned() .unwrap_or_default() } - pub fn get_graphql_formatter_configuration(&self) -> GraphqlFormatter { - self.graphql + pub fn get_json_formatter_configuration(&self) -> JsonFormatterConfiguration { + self.json .as_ref() - .map(|f| { - f.formatter - .as_ref() - .map(|f| f.get_formatter_configuration()) - .unwrap_or_default() - }) + .and_then(|lang| lang.formatter.as_ref()) + .cloned() .unwrap_or_default() } - pub fn is_linter_disabled(&self) -> bool { - self.linter.as_ref().map_or(false, |f| f.is_disabled()) + pub fn get_json_linter_configuration(&self) -> JsonLinterConfiguration { + self.json + .as_ref() + .and_then(|lang| lang.linter.as_ref()) + .cloned() + .unwrap_or_default() } - pub fn get_linter_rules(&self) -> Rules { - self.linter + pub fn get_css_parser_configuration(&self) -> CssParserConfiguration { + self.css .as_ref() - .map(|f| f.get_rules()) + .and_then(|lang| lang.parser.as_ref()) + .cloned() .unwrap_or_default() } - pub fn is_organize_imports_disabled(&self) -> bool { - self.organize_imports + pub fn get_css_formatter_configuration(&self) -> CssFormatterConfiguration { + self.css .as_ref() - .map_or(false, |f| f.is_disabled()) + .and_then(|lang| lang.formatter.as_ref()) + .cloned() + .unwrap_or_default() } - pub fn is_vcs_disabled(&self) -> bool { - self.vcs.as_ref().map_or(true, |f| f.is_disabled()) + pub fn get_css_linter_configuration(&self) -> CssLinterConfiguration { + self.css + .as_ref() + .and_then(|lang| lang.linter.as_ref()) + .cloned() + .unwrap_or_default() } - pub fn is_vcs_enabled(&self) -> bool { - !self.is_vcs_disabled() + pub fn get_graphql_formatter_configuration(&self) -> GraphqlFormatterConfiguration { + self.graphql + .as_ref() + .and_then(|lang| lang.formatter.as_ref()) + .cloned() + .unwrap_or_default() + } + + pub fn get_graphql_linter_configuration(&self) -> GraphqlLinterConfiguration { + self.graphql + .as_ref() + .and_then(|lang| lang.linter.as_ref()) + .cloned() + .unwrap_or_default() } } +pub type IgnoreUnknownEnabled = Bool; + /// The configuration of the filesystem -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct FilesConfiguration { /// The maximum allowed size for source code files in bytes. Files above /// this limit will be ignored for performance reasons. Defaults to 1 MiB - #[partial(bpaf(long("files-max-size"), argument("NUMBER")))] - pub max_size: NonZeroU64, + #[bpaf(long("files-max-size"), argument("NUMBER"))] + pub max_size: Option, /// A list of Unix shell style patterns. Biome will ignore files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub ignore: StringSet, + #[bpaf(hide)] + pub ignore: Option, /// A list of Unix shell style patterns. Biome will handle only those files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub include: StringSet, + #[bpaf(hide)] + pub include: Option, /// Tells Biome to not emit diagnostics when handling files that doesn't know - #[partial(bpaf(long("files-ignore-unknown"), argument("true|false"), optional))] - pub ignore_unknown: bool, -} - -impl Default for FilesConfiguration { - fn default() -> Self { - Self { - max_size: DEFAULT_FILE_SIZE_LIMIT, - ignore: Default::default(), - include: Default::default(), - ignore_unknown: false, - } - } + #[bpaf(long("files-ignore-unknown"), argument("true|false"))] + pub ignore_unknown: Option, } pub struct ConfigurationPayload { /// The result of the deserialization - pub deserialized: Deserialized, + pub deserialized: Deserialized, /// The path of where the `biome.json` or `biome.jsonc` file was found. This contains the file name. pub configuration_file_path: PathBuf, /// The base path where the external configuration in a package should be resolved from diff --git a/crates/biome_configuration/src/linter/mod.rs b/crates/biome_configuration/src/linter/mod.rs index 9dba813c1a36..af7ed252db0c 100644 --- a/crates/biome_configuration/src/linter/mod.rs +++ b/crates/biome_configuration/src/linter/mod.rs @@ -1,12 +1,12 @@ #[rustfmt::skip] mod rules; - +use crate::bool::Bool; pub use crate::linter::rules::Rules; use biome_analyze::options::RuleOptions; use biome_analyze::{FixKind, RuleFilter}; use biome_deserialize::{Deserializable, StringSet}; use biome_deserialize::{DeserializableValue, DeserializationDiagnostic, Merge, VisitableType}; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; use biome_diagnostics::Severity; use bpaf::Bpaf; pub use rules::*; @@ -15,54 +15,36 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::str::FromStr; -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +pub type LinterEnabled = Bool; + +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct LinterConfiguration { /// if `false`, it disables the feature and the linter won't be executed. `true` by default - #[partial(bpaf(hide))] - pub enabled: bool, + #[bpaf(hide)] + pub enabled: Option, /// List of rules - #[partial(bpaf(pure(Default::default()), optional, hide))] - pub rules: Rules, + #[bpaf(pure(Default::default()), hide)] + pub rules: Option, /// A list of Unix shell style patterns. The formatter will ignore files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub ignore: StringSet, + #[bpaf(hide)] + pub ignore: Option, /// A list of Unix shell style patterns. The formatter will include files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub include: StringSet, + #[bpaf(hide)] + pub include: Option, } impl LinterConfiguration { - pub const fn is_disabled(&self) -> bool { - !self.enabled - } -} - -impl Default for LinterConfiguration { - fn default() -> Self { - Self { - enabled: true, - rules: Default::default(), - ignore: Default::default(), - include: Default::default(), - } - } -} - -impl PartialLinterConfiguration { - pub const fn is_disabled(&self) -> bool { - matches!(self.enabled, Some(false)) - } - - pub fn get_rules(&self) -> Rules { - self.rules.as_ref().unwrap_or(&Rules::default()).clone() + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } } diff --git a/crates/biome_configuration/src/organize_imports.rs b/crates/biome_configuration/src/organize_imports.rs index 2c415d7337f8..7e30b018e640 100644 --- a/crates/biome_configuration/src/organize_imports.rs +++ b/crates/biome_configuration/src/organize_imports.rs @@ -1,44 +1,34 @@ +use crate::bool::Bool; use biome_deserialize::StringSet; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; use bpaf::Bpaf; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(rename_all = "camelCase", default, deny_unknown_fields))] +pub type OrganizeImportsEnabled = Bool; + +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(rename_all = "camelCase", default, deny_unknown_fields)] pub struct OrganizeImports { /// Enables the organization of imports - #[partial(bpaf(hide))] - pub enabled: bool, + #[bpaf(hide)] + pub enabled: Option, /// A list of Unix shell style patterns. The formatter will ignore files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub ignore: StringSet, + #[bpaf(hide)] + pub ignore: Option, /// A list of Unix shell style patterns. The formatter will include files/folders that will /// match these patterns. - #[partial(bpaf(hide))] - pub include: StringSet, -} - -impl Default for OrganizeImports { - fn default() -> Self { - Self { - enabled: true, - ignore: Default::default(), - include: Default::default(), - } - } + #[bpaf(hide)] + pub include: Option, } -impl PartialOrganizeImports { - pub const fn is_disabled(&self) -> bool { - matches!(self.enabled, Some(false)) - } - - pub const fn is_enabled(&self) -> bool { - !self.is_disabled() +impl OrganizeImports { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } } diff --git a/crates/biome_configuration/src/overrides.rs b/crates/biome_configuration/src/overrides.rs index 12026af7d37b..b2f2eb7b61b2 100644 --- a/crates/biome_configuration/src/overrides.rs +++ b/crates/biome_configuration/src/overrides.rs @@ -1,9 +1,10 @@ -use super::javascript::PartialJavascriptConfiguration; -use super::json::PartialJsonConfiguration; -use super::{PartialCssConfiguration, PartialGraphqlConfiguration}; +use crate::formatter::{FormatWithErrorsEnabled, FormatterEnabled}; +use crate::linter::LinterEnabled; +use crate::organize_imports::OrganizeImportsEnabled; use crate::{ - partial_css_configuration, partial_graphql_configuration, partial_javascript_configuration, - partial_json_configuration, PlainIndentStyle, Rules, + css_configuration, graphql_configuration, js_configuration, json_configuration, + CssConfiguration, GraphqlConfiguration, JsConfiguration, JsonConfiguration, PlainIndentStyle, + Rules, }; use biome_deserialize::StringSet; use biome_deserialize_macros::{Deserializable, Merge}; @@ -47,37 +48,37 @@ pub struct OverridePattern { /// Specific configuration for the JavaScript language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(partial_javascript_configuration), optional, hide)] - pub javascript: Option, + #[bpaf(external(js_configuration), hide, optional)] + pub javascript: Option, /// Specific configuration for the Json language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(partial_json_configuration), optional, hide)] - pub json: Option, + #[bpaf(external(json_configuration), hide, optional)] + pub json: Option, /// Specific configuration for the Css language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(partial_css_configuration), optional, hide)] - pub css: Option, + #[bpaf(external(css_configuration), hide, optional)] + pub css: Option, /// Specific configuration for the Graphql language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(partial_graphql_configuration), optional, hide)] - pub graphql: Option, + #[bpaf(external(graphql_configuration), hide, optional)] + pub graphql: Option, /// Specific configuration for the Json language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(override_formatter_configuration), optional, hide)] + #[bpaf(external(override_formatter_configuration), hide, optional)] pub formatter: Option, /// Specific configuration for the Json language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(override_linter_configuration), optional, hide)] + #[bpaf(external(override_linter_configuration), hide, optional)] pub linter: Option, /// Specific configuration for the Json language #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(external(override_organize_imports_configuration), optional, hide)] + #[bpaf(external(override_organize_imports_configuration), hide, optional)] pub organize_imports: Option, } @@ -98,48 +99,48 @@ pub struct OverrideFormatterConfiguration { // if `false`, it disables the feature. `true` by default #[serde(skip_serializing_if = "Option::is_none")] #[bpaf(hide)] - pub enabled: Option, + pub enabled: Option, /// Stores whether formatting should be allowed to proceed if a given file /// has syntax errors #[serde(skip_serializing_if = "Option::is_none")] #[bpaf(hide)] - pub format_with_errors: Option, + pub format_with_errors: Option, /// The indent style. #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("indent-style"), argument("tab|space"), optional)] + #[bpaf(long("indent-style"), argument("tab|space"))] pub indent_style: Option, /// The size of the indentation, 2 by default (deprecated, use `indent-width`) #[serde(skip_serializing_if = "Option::is_none")] #[deserializable(deprecated(use_instead = "formatter.indentWidth"))] - #[bpaf(long("indent-size"), argument("NUMBER"), optional)] + #[bpaf(long("indent-size"), argument("NUMBER"))] pub indent_size: Option, /// The size of the indentation, 2 by default #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("indent-width"), argument("NUMBER"), optional)] + #[bpaf(long("indent-width"), argument("NUMBER"))] pub indent_width: Option, /// The type of line ending. #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("line-ending"), argument("lf|crlf|cr"), optional)] + #[bpaf(long("line-ending"), argument("lf|crlf|cr"))] pub line_ending: Option, /// What's the max width of a line. Defaults to 80. #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("line-width"), argument("NUMBER"), optional)] + #[bpaf(long("line-width"), argument("NUMBER"))] pub line_width: Option, /// The attribute position style. #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("attribute-position"), argument("multiline|auto"), optional)] + #[bpaf(long("attribute-position"), argument("multiline|auto"))] pub attribute_position: Option, /// Whether to insert spaces around brackets in object literals. Defaults to true. #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(long("bracket-spacing"), argument("true|false"), optional)] + #[bpaf(long("bracket-spacing"), argument("true|false"))] pub bracket_spacing: Option, } @@ -152,11 +153,11 @@ pub struct OverrideLinterConfiguration { /// if `false`, it disables the feature and the linter won't be executed. `true` by default #[serde(skip_serializing_if = "Option::is_none")] #[bpaf(hide)] - pub enabled: Option, + pub enabled: Option, /// List of rules #[serde(skip_serializing_if = "Option::is_none")] - #[bpaf(pure(Rules::default()), optional, hide)] + #[bpaf(pure(Rules::default()), hide)] pub rules: Option, } @@ -169,5 +170,5 @@ pub struct OverrideOrganizeImportsConfiguration { /// if `false`, it disables the feature and the linter won't be executed. `true` by default #[serde(skip_serializing_if = "Option::is_none")] #[bpaf(hide)] - pub enabled: Option, + pub enabled: Option, } diff --git a/crates/biome_configuration/src/vcs.rs b/crates/biome_configuration/src/vcs.rs index dc0bf42517bf..45eb1e8ca769 100644 --- a/crates/biome_configuration/src/vcs.rs +++ b/crates/biome_configuration/src/vcs.rs @@ -1,31 +1,36 @@ +use crate::bool::Bool; use biome_deserialize::{DeserializableValidator, DeserializationDiagnostic}; -use biome_deserialize_macros::{Deserializable, Merge, Partial}; +use biome_deserialize_macros::{Deserializable, Merge}; use bpaf::Bpaf; use serde::{Deserialize, Serialize}; use std::str::FromStr; const GIT_IGNORE_FILE_NAME: &str = ".gitignore"; +pub type VcsEnabled = Bool; +pub type UseIgnoreFileEnabled = Bool; + /// Set of properties to integrate Biome with a VCS software. -#[derive(Clone, Debug, Deserialize, Eq, Partial, PartialEq, Serialize)] -#[partial(derive(Bpaf, Clone, Deserializable, Eq, Merge, PartialEq))] -#[partial(deserializable(with_validator))] -#[partial(cfg_attr(feature = "schema", derive(schemars::JsonSchema)))] -#[partial(serde(deny_unknown_fields, rename_all = "camelCase"))] +#[derive( + Bpaf, Clone, Debug, Default, Deserializable, Deserialize, Eq, Merge, PartialEq, Serialize, +)] +#[deserializable(with_validator)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[serde(deny_unknown_fields, rename_all = "camelCase")] pub struct VcsConfiguration { /// The kind of client. - #[partial(bpaf(long("vcs-client-kind"), argument("git"), optional))] - #[partial(deserializable(bail_on_error))] - pub client_kind: VcsClientKind, + #[bpaf(long("vcs-client-kind"), argument("git"))] + #[deserializable(bail_on_error)] + pub client_kind: Option, /// Whether Biome should integrate itself with the VCS client - #[partial(bpaf(long("vcs-enabled"), argument("true|false")))] - pub enabled: bool, + #[bpaf(long("vcs-enabled"), argument("true|false"))] + pub enabled: Option, /// Whether Biome should use the VCS ignore file. When [true], Biome will ignore the files /// specified in the ignore file. - #[partial(bpaf(long("vcs-use-ignore-file"), argument("true|false")))] - pub use_ignore_file: bool, + #[bpaf(long("vcs-use-ignore-file"), argument("true|false"))] + pub use_ignore_file: Option, /// The folder where Biome should check for VCS files. By default, Biome will use the same /// folder where `biome.json` was found. @@ -33,39 +38,25 @@ pub struct VcsConfiguration { /// If Biome can't find the configuration, it will attempt to use the current working directory. /// If no current working directory can't be found, Biome won't use the VCS integration, and a diagnostic /// will be emitted - #[partial(bpaf(long("vcs-root"), argument("PATH"), optional))] - pub root: String, + #[bpaf(long("vcs-root"), argument("PATH"))] + pub root: Option, /// The main branch of the project - #[partial(bpaf(long("vcs-default-branch"), argument("BRANCH"), optional))] - pub default_branch: String, + #[bpaf(long("vcs-default-branch"), argument("BRANCH"))] + pub default_branch: Option, } -impl Default for VcsConfiguration { - fn default() -> Self { - Self { - client_kind: VcsClientKind::Git, - enabled: false, - use_ignore_file: true, - root: Default::default(), - default_branch: Default::default(), - } +impl VcsConfiguration { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } -} -impl PartialVcsConfiguration { - pub const fn is_enabled(&self) -> bool { - matches!(self.enabled, Some(true)) - } - pub const fn is_disabled(&self) -> bool { - !self.is_enabled() - } - pub const fn ignore_file_disabled(&self) -> bool { - matches!(self.use_ignore_file, Some(false)) + pub fn should_use_ignore_file(&self) -> bool { + self.use_ignore_file.unwrap_or_default().into() } } -impl DeserializableValidator for PartialVcsConfiguration { +impl DeserializableValidator for VcsConfiguration { fn validate( &mut self, _name: &str, diff --git a/crates/biome_css_analyze/src/lib.rs b/crates/biome_css_analyze/src/lib.rs index 823d10b146de..0699eac8b30a 100644 --- a/crates/biome_css_analyze/src/lib.rs +++ b/crates/biome_css_analyze/src/lib.rs @@ -138,7 +138,7 @@ mod tests { use biome_analyze::{AnalyzerOptions, Never, RuleFilter}; use biome_console::fmt::{Formatter, Termcolor}; use biome_console::{markup, Markup}; - use biome_css_parser::{parse_css, CssParserOptions}; + use biome_css_parser::{parse_css, CssParseOptions}; use biome_css_syntax::TextRange; use biome_diagnostics::termcolor::NoColor; use biome_diagnostics::{Diagnostic, DiagnosticExt, PrintDiagnostic, Severity}; @@ -169,7 +169,7 @@ mod tests { :popover-open {} .test::-webkit-scrollbar-button:horizontal:decrement {} @page :first { } - + /* invalid */ a:unknown { } a:pseudo-class { } @@ -178,7 +178,7 @@ mod tests { @page :blank:unknown { } "#; - let parsed = parse_css(SOURCE, CssParserOptions::default()); + let parsed = parse_css(SOURCE, CssParseOptions::default()); let mut error_ranges: Vec = Vec::new(); let rule_filter = RuleFilter::Rule("nursery", "noUnknownPseudoClassSelector"); diff --git a/crates/biome_css_analyze/tests/spec_tests.rs b/crates/biome_css_analyze/tests/spec_tests.rs index 3d455587dd45..ed567b4e835a 100644 --- a/crates/biome_css_analyze/tests/spec_tests.rs +++ b/crates/biome_css_analyze/tests/spec_tests.rs @@ -1,5 +1,5 @@ use biome_analyze::{AnalysisFilter, AnalyzerAction, ControlFlow, Never, RuleFilter}; -use biome_css_parser::{parse_css, CssParserOptions}; +use biome_css_parser::{parse_css, CssParseOptions}; use biome_css_syntax::{CssFileSource, CssLanguage}; use biome_diagnostics::advice::CodeSuggestionAdvice; use biome_diagnostics::{DiagnosticExt, Severity}; @@ -64,7 +64,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { file_name, input_file, CheckActionType::Lint, - parser_options, + CssParseOptions::default(), ); } @@ -81,7 +81,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { file_name, input_file, CheckActionType::Lint, - parser_options, + CssParseOptions::default(), ) }; @@ -106,9 +106,9 @@ pub(crate) fn analyze_and_snap( file_name: &str, input_file: &Path, check_action_type: CheckActionType, - parser_options: CssParserOptions, + parse_options: CssParseOptions, ) -> usize { - let parsed = parse_css(input_code, parser_options); + let parsed = parse_css(input_code, parse_options); let root = parsed.tree(); let mut diagnostics = Vec::new(); @@ -125,12 +125,12 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &action, - parser_options, + parse_options, ); diag = diag.add_code_suggestion(CodeSuggestionAdvice::from(action)); } } else if !action.is_suppression() { - check_code_action(input_file, input_code, source_type, &action, parser_options); + check_code_action(input_file, input_code, source_type, &action, parse_options); diag = diag.add_code_suggestion(CodeSuggestionAdvice::from(action)); } } @@ -143,11 +143,11 @@ pub(crate) fn analyze_and_snap( for action in event.actions() { if check_action_type.is_suppression() { if action.category.matches("quickfix.suppressRule") { - check_code_action(input_file, input_code, source_type, &action, parser_options); + check_code_action(input_file, input_code, source_type, &action, parse_options); code_fixes.push(code_fix_to_string(input_code, action)); } } else if !action.category.matches("quickfix.suppressRule") { - check_code_action(input_file, input_code, source_type, &action, parser_options); + check_code_action(input_file, input_code, source_type, &action, parse_options); code_fixes.push(code_fix_to_string(input_code, action)); } } @@ -175,7 +175,7 @@ fn check_code_action( source: &str, _source_type: CssFileSource, action: &AnalyzerAction, - options: CssParserOptions, + options: CssParseOptions, ) { let (new_tree, text_edit) = match action .mutation @@ -231,7 +231,7 @@ pub(crate) fn run_suppression_test(input: &'static str, _: &str, _: &str, _: &st file_name, input_file, CheckActionType::Suppression, - CssParserOptions::default(), + CssParseOptions::default(), ); insta::with_settings!({ diff --git a/crates/biome_css_formatter/src/lib.rs b/crates/biome_css_formatter/src/lib.rs index 1b324dbff52c..b74e45eb5b9a 100644 --- a/crates/biome_css_formatter/src/lib.rs +++ b/crates/biome_css_formatter/src/lib.rs @@ -373,12 +373,12 @@ pub fn format_sub_tree(options: CssFormatOptions, root: &CssSyntaxNode) -> Forma mod tests { use crate::context::CssFormatOptions; use crate::format_node; - use biome_css_parser::{parse_css, CssParserOptions}; + use biome_css_parser::{parse_css, CssParseOptions}; #[test] fn smoke_test() { let src = r#"html {}"#; - let parse = parse_css(src, CssParserOptions::default()); + let parse = parse_css(src, CssParseOptions::default()); let options = CssFormatOptions::default(); let formatted = format_node(options, &parse.syntax()).unwrap(); assert_eq!(formatted.print().unwrap().as_code(), "html {\n}\n"); diff --git a/crates/biome_css_formatter/tests/language.rs b/crates/biome_css_formatter/tests/language.rs index bdacd11c84f4..b10b972777aa 100644 --- a/crates/biome_css_formatter/tests/language.rs +++ b/crates/biome_css_formatter/tests/language.rs @@ -1,6 +1,6 @@ use biome_css_formatter::context::CssFormatContext; use biome_css_formatter::CssFormatLanguage; -use biome_css_parser::{parse_css, CssParserOptions}; +use biome_css_parser::{parse_css, CssParseOptions}; use biome_css_syntax::{CssFileSource, CssLanguage}; use biome_formatter_test::TestFormatLanguage; use biome_fs::BiomePath; @@ -21,7 +21,7 @@ impl TestFormatLanguage for CssTestFormatLanguage { type FormatLanguage = CssFormatLanguage; fn parse(&self, text: &str) -> AnyParse { - let options = CssParserOptions::default() + let options = CssParseOptions::default() .allow_wrong_line_comments() .allow_css_modules(); diff --git a/crates/biome_css_formatter/tests/quick_test.rs b/crates/biome_css_formatter/tests/quick_test.rs index 495e773e2895..7a4d09bb5596 100644 --- a/crates/biome_css_formatter/tests/quick_test.rs +++ b/crates/biome_css_formatter/tests/quick_test.rs @@ -1,6 +1,6 @@ use biome_css_formatter::format_node; use biome_css_formatter::{context::CssFormatOptions, CssFormatLanguage}; -use biome_css_parser::{parse_css, CssParserOptions}; +use biome_css_parser::{parse_css, CssParseOptions}; use biome_formatter::{IndentStyle, LineWidth}; use biome_formatter_test::check_reformat::CheckReformat; @@ -19,7 +19,7 @@ fn quick_test() { } } "#; - let parse = parse_css(src, CssParserOptions::default()); + let parse = parse_css(src, CssParseOptions::default()); println!("{parse:#?}"); let options = CssFormatOptions::default() diff --git a/crates/biome_css_formatter/tests/spec_test.rs b/crates/biome_css_formatter/tests/spec_test.rs index bb79a8e678ab..d5b79f96b48c 100644 --- a/crates/biome_css_formatter/tests/spec_test.rs +++ b/crates/biome_css_formatter/tests/spec_test.rs @@ -1,5 +1,5 @@ -use biome_configuration::{PartialConfiguration, PartialCssConfiguration, PartialCssFormatter}; -use biome_css_formatter::{context::CssFormatOptions, CssFormatLanguage}; +use biome_configuration::{Configuration, CssConfiguration, CssFormatterConfiguration}; +use biome_css_formatter::context::CssFormatOptions; use biome_formatter_test::spec::{SpecSnapshot, SpecTestFile}; use biome_service::workspace::UpdateSettingsParams; use std::path::Path; @@ -28,10 +28,10 @@ mod language { pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, _file_type: &str) { let root_path = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/specs/")); let settings = UpdateSettingsParams { - configuration: PartialConfiguration { - css: Some(PartialCssConfiguration { - formatter: Some(PartialCssFormatter { - enabled: Some(true), + configuration: Configuration { + css: Some(CssConfiguration { + formatter: Some(CssFormatterConfiguration { + enabled: Some(true.into()), ..Default::default() }), ..Default::default() diff --git a/crates/biome_css_parser/src/lexer/mod.rs b/crates/biome_css_parser/src/lexer/mod.rs index a047cb450da9..3e43da3b8208 100644 --- a/crates/biome_css_parser/src/lexer/mod.rs +++ b/crates/biome_css_parser/src/lexer/mod.rs @@ -2,7 +2,7 @@ #[rustfmt::skip] mod tests; -use crate::CssParserOptions; +use crate::CssParseOptions; use biome_css_syntax::{CssSyntaxKind, CssSyntaxKind::*, TextLen, TextSize, T}; use biome_parser::diagnostic::ParseDiagnostic; use biome_parser::lexer::{ @@ -88,7 +88,7 @@ pub(crate) struct CssLexer<'src> { diagnostics: Vec, - options: CssParserOptions, + options: CssParseOptions, } impl<'src> Lexer<'src> for CssLexer<'src> { @@ -209,11 +209,11 @@ impl<'src> CssLexer<'src> { current_flags: TokenFlags::empty(), position: 0, diagnostics: vec![], - options: CssParserOptions::default(), + options: CssParseOptions::default(), } } - pub(crate) fn with_options(self, options: CssParserOptions) -> Self { + pub(crate) fn with_options(self, options: CssParseOptions) -> Self { Self { options, ..self } } diff --git a/crates/biome_css_parser/src/lexer/tests.rs b/crates/biome_css_parser/src/lexer/tests.rs index e47068eee100..a623324304cc 100644 --- a/crates/biome_css_parser/src/lexer/tests.rs +++ b/crates/biome_css_parser/src/lexer/tests.rs @@ -3,7 +3,7 @@ use super::{CssLexer, TextSize}; use crate::lexer::CssLexContext; -use crate::CssParserOptions; +use crate::CssParseOptions; use biome_css_syntax::CssSyntaxKind::EOF; use biome_parser::lexer::Lexer; use quickcheck_macros::quickcheck; @@ -15,7 +15,7 @@ use std::time::Duration; // and make sure the tokens yielded are fully lossless and the source can be reconstructed from only the tokens macro_rules! assert_lex { ($src:expr, $($kind:ident:$len:expr $(,)?)*) => {{ - let options = CssParserOptions::default().allow_wrong_line_comments().allow_css_modules(); + let options = CssParseOptions::default().allow_wrong_line_comments().allow_css_modules(); let mut lexer = CssLexer::from_str($src).with_options(options); let mut idx = 0; let mut tok_idx = TextSize::default(); @@ -88,11 +88,7 @@ fn losslessness(string: String) -> bool { }); let token_ranges = receiver .recv_timeout(Duration::from_secs(2)) - .unwrap_or_else(|_| { - panic!( - "Lexer is infinitely recursing with this code: ->{string}<-" - ) - }); + .unwrap_or_else(|_| panic!("Lexer is infinitely recursing with this code: ->{string}<-")); let mut new_str = String::with_capacity(string.len()); let mut idx = TextSize::from(0); diff --git a/crates/biome_css_parser/src/lib.rs b/crates/biome_css_parser/src/lib.rs index 255747acdafa..d2997f52974a 100644 --- a/crates/biome_css_parser/src/lib.rs +++ b/crates/biome_css_parser/src/lib.rs @@ -8,7 +8,7 @@ use biome_css_syntax::{CssLanguage, CssRoot, CssSyntaxNode}; pub use biome_parser::prelude::*; use biome_parser::{tree_sink::LosslessTreeSink, AnyParse}; use biome_rowan::{AstNode, NodeCache}; -pub use parser::CssParserOptions; +pub use parser::CssParseOptions; mod lexer; mod parser; @@ -20,7 +20,7 @@ mod token_source; pub(crate) type CssLosslessTreeSink<'source> = LosslessTreeSink<'source, CssLanguage, CssSyntaxFactory>; -pub fn parse_css(source: &str, options: CssParserOptions) -> CssParse { +pub fn parse_css(source: &str, options: CssParseOptions) -> CssParse { let mut cache = NodeCache::default(); parse_css_with_cache(source, &mut cache, options) } @@ -29,7 +29,7 @@ pub fn parse_css(source: &str, options: CssParserOptions) -> CssParse { pub fn parse_css_with_cache( source: &str, cache: &mut NodeCache, - options: CssParserOptions, + options: CssParseOptions, ) -> CssParse { tracing::debug_span!("Parsing phase").in_scope(move || { let mut parser = CssParser::new(source, options); @@ -67,8 +67,8 @@ impl CssParse { /// /// # fn main() -> Result<(), SyntaxError> { /// use biome_css_syntax::CssSyntaxKind; - /// use biome_css_parser::CssParserOptions; - /// let parse = parse_css(r#""#, CssParserOptions::default()); + /// use biome_css_parser::CssParseOptions; + /// let parse = parse_css(r#""#, CssParseOptions::default()); /// /// let root_value = parse.tree().rules(); /// @@ -121,13 +121,13 @@ impl From for AnyParse { #[cfg(test)] mod tests { - use crate::{parse_css, CssParserOptions}; + use crate::{parse_css, CssParseOptions}; #[test] fn parser_smoke_test() { let src = r#" "#; - let _css = parse_css(src, CssParserOptions::default()); + let _css = parse_css(src, CssParseOptions::default()); } } diff --git a/crates/biome_css_parser/src/parser.rs b/crates/biome_css_parser/src/parser.rs index 7f5bca1393d6..db8a7641c77e 100644 --- a/crates/biome_css_parser/src/parser.rs +++ b/crates/biome_css_parser/src/parser.rs @@ -12,11 +12,11 @@ pub(crate) struct CssParser<'source> { context: ParserContext, source: CssTokenSource<'source>, state: CssParserState, - options: CssParserOptions, + options: CssParseOptions, } #[derive(Default, Debug, Clone, Copy)] -pub struct CssParserOptions { +pub struct CssParseOptions { /// If this is `true`, **wrong** comments starting with `//` will be treated /// as a comment. /// @@ -35,7 +35,7 @@ pub struct CssParserOptions { pub grit_metavariable: bool, } -impl CssParserOptions { +impl CssParseOptions { /// Allows the parser to parse wrong line comments. pub fn allow_wrong_line_comments(mut self) -> Self { self.allow_wrong_line_comments = true; @@ -66,7 +66,7 @@ impl CssParserOptions { } impl<'source> CssParser<'source> { - pub fn new(source: &'source str, options: CssParserOptions) -> Self { + pub fn new(source: &'source str, options: CssParseOptions) -> Self { Self { context: ParserContext::default(), source: CssTokenSource::from_str(source, options), @@ -75,7 +75,7 @@ impl<'source> CssParser<'source> { } } - pub fn options(&self) -> &CssParserOptions { + pub fn options(&self) -> &CssParseOptions { &self.options } diff --git a/crates/biome_css_parser/src/syntax/mod.rs b/crates/biome_css_parser/src/syntax/mod.rs index 0776b36f1f6b..0f40624c9dbf 100644 --- a/crates/biome_css_parser/src/syntax/mod.rs +++ b/crates/biome_css_parser/src/syntax/mod.rs @@ -590,7 +590,7 @@ pub(crate) fn try_parse( #[cfg(test)] mod tests { - use crate::{parser::CssParser, CssParserOptions}; + use crate::{parser::CssParser, CssParseOptions}; use biome_css_syntax::{CssSyntaxKind, T}; use biome_parser::prelude::ParsedSyntax::{Absent, Present}; use biome_parser::Parser; @@ -599,7 +599,7 @@ mod tests { #[test] fn try_parse_rewinds_to_checkpoint() { - let mut p = CssParser::new("width: blue;", CssParserOptions::default()); + let mut p = CssParser::new("width: blue;", CssParseOptions::default()); let pre_try_range = p.cur_range(); let result = try_parse(&mut p, |p| { @@ -624,7 +624,7 @@ mod tests { #[test] fn try_parse_preserves_position_on_success() { - let mut p = CssParser::new("width: 100;", CssParserOptions::default()); + let mut p = CssParser::new("width: 100;", CssParseOptions::default()); let pre_try_range = p.cur_range(); let result = try_parse(&mut p, |p| { diff --git a/crates/biome_css_parser/src/token_source.rs b/crates/biome_css_parser/src/token_source.rs index 05dd5e80cb45..691481325265 100644 --- a/crates/biome_css_parser/src/token_source.rs +++ b/crates/biome_css_parser/src/token_source.rs @@ -1,5 +1,5 @@ use crate::lexer::{CssLexContext, CssLexer, CssReLexContext}; -use crate::CssParserOptions; +use crate::CssParseOptions; use biome_css_syntax::CssSyntaxKind::EOF; use biome_css_syntax::{CssSyntaxKind, TextRange}; use biome_parser::diagnostic::ParseDiagnostic; @@ -28,7 +28,7 @@ impl<'src> CssTokenSource<'src> { } /// Creates a new token source for the given string - pub fn from_str(source: &'src str, options: CssParserOptions) -> Self { + pub fn from_str(source: &'src str, options: CssParseOptions) -> Self { let lexer = CssLexer::from_str(source).with_options(options); let buffered = BufferedLexer::new(lexer); diff --git a/crates/biome_css_parser/tests/spec_test.rs b/crates/biome_css_parser/tests/spec_test.rs index 8b88ac43f042..afcec7d557a0 100644 --- a/crates/biome_css_parser/tests/spec_test.rs +++ b/crates/biome_css_parser/tests/spec_test.rs @@ -1,7 +1,7 @@ -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::fmt::{Formatter, Termcolor}; use biome_console::markup; -use biome_css_parser::{parse_css, CssParserOptions}; +use biome_css_parser::{parse_css, CssParseOptions}; use biome_deserialize::json::deserialize_from_str; use biome_diagnostics::display::PrintDiagnostic; use biome_diagnostics::DiagnosticExt; @@ -40,7 +40,7 @@ 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 mut options = CssParserOptions::default() + let mut options = CssParseOptions::default() // it is an internal option that cannot be configured via options.json // TODO: find a way to make it configurable .allow_grit_metavariables(); @@ -52,10 +52,9 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_ let mut settings = Settings::default(); // SAFETY: we checked its existence already, we assume we have rights to read it - let (test_options, diagnostics) = deserialize_from_str::( - options_path.get_buffer_from_file().as_str(), - ) - .consume(); + let (test_options, diagnostics) = + deserialize_from_str::(options_path.get_buffer_from_file().as_str()) + .consume(); settings .merge_with_configuration(test_options.unwrap_or_default(), None, None, &[]) @@ -179,7 +178,7 @@ pub fn quick_test() { let root = parse_css( code, - CssParserOptions::default() + CssParseOptions::default() .allow_wrong_line_comments() .allow_css_modules() .allow_grit_metavariables(), diff --git a/crates/biome_deserialize/README.md b/crates/biome_deserialize/README.md index c0725a154fc9..cb4d42f42098 100644 --- a/crates/biome_deserialize/README.md +++ b/crates/biome_deserialize/README.md @@ -50,13 +50,13 @@ In the following example, we deserialize a boolean, an array of integers, and an ```rust use biome_deserialize::json::deserialize_from_json_str; use biome_deserialize::Deserialized; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; let json = "false"; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert_eq!(deserialized, Some(false)); assert!(diagnostics.is_empty()); @@ -64,7 +64,7 @@ let json = "[0, 1]"; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::>(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::>(&source, JsonParseOptions::default()); assert_eq!(deserialized, Some(vec![0, 1])); assert!(diagnostics.is_empty()); @@ -73,7 +73,7 @@ let json = r#"{ "a": 0, "b": 1 }"#; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::>(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::>(&source, JsonParseOptions::default()); assert_eq!(deserialized, Some(HashMap::from([("a".to_string(), 0), ("b".to_string(), 1)]))); assert!(diagnostics.is_empty()); ``` @@ -206,13 +206,13 @@ impl Deserializable for Day { use biome_deserialize::json::deserialize_from_json_str; use biome_deserialize::Deserialized; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; let json = "42"; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert_eq!(deserialized, Some(Day(42))); assert!(diagnostics.is_empty()); @@ -220,7 +220,7 @@ let json = "999"; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert_eq!(deserialized, None); assert_eq!(diagnostics..len(), 1); ``` @@ -260,15 +260,15 @@ impl Deserializable for Union { } use biome_deserialize::json::deserialize_from_json_str; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; let source = r#" "string" "#; -let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default()); +let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert!(!deserialized.has_errors()); assert_eq!(deserialized.into_deserialized(), Some(Union::Str("string".to_string()))); let source = "true"; -let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default()); +let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert!(!deserialized.has_errors()); assert_eq!(deserialized.into_deserialized(), Some(Union::Bool(true))); ``` @@ -374,13 +374,13 @@ impl Deserializable for Variant { use biome_deserialize::json::deserialize_from_json_str; use biome_deserialize::Deserialized; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; let json = "\"A\""; let Deserialized { deserialized, diagnostics, -} = deserialize_from_json_str::(&source, JsonParserOptions::default()); +} = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert_eq!(deserialized, Some(Variant::A)); assert!(diagnostics.is_empty()); ``` @@ -519,10 +519,10 @@ impl DeserializationVisitor for PersonVisitor { } use biome_deserialize::json::deserialize_from_json_str; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; let source = r#"{ "name": "Isaac Asimov" }"#; -let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default()); +let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default()); assert!(!deserialized.has_errors()); assert_eq!(deserialized.into_deserialized(), Some(Person { name: "Isaac Asimov".to_string() })); ``` diff --git a/crates/biome_deserialize/src/json.rs b/crates/biome_deserialize/src/json.rs index b40df64da979..12bf0587b718 100644 --- a/crates/biome_deserialize/src/json.rs +++ b/crates/biome_deserialize/src/json.rs @@ -4,7 +4,7 @@ use crate::{ Deserialized, Text, TextNumber, VisitableType, }; use biome_diagnostics::{DiagnosticExt, Error}; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use biome_json_syntax::{AnyJsonValue, JsonMemberName, JsonRoot, T}; use biome_rowan::{AstNode, AstSeparatedList, TokenText}; @@ -22,7 +22,7 @@ use biome_rowan::{AstNode, AstSeparatedList, TokenText}; /// ``` /// use biome_deserialize::json::deserialize_from_json_str; /// use biome_deserialize_macros::Deserializable; -/// use biome_json_parser::JsonParserOptions; +/// use biome_json_parser::JsonParseOptions; /// /// #[derive(Debug, Default, Deserializable, Eq, PartialEq)] /// struct NewConfiguration { @@ -30,13 +30,13 @@ use biome_rowan::{AstNode, AstSeparatedList, TokenText}; /// } /// /// let source = r#"{ "lorem": "ipsum" }"#; -/// let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); +/// let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); /// assert!(!deserialized.has_errors()); /// assert_eq!(deserialized.into_deserialized().unwrap(), NewConfiguration { lorem: "ipsum".to_string() }); /// ``` pub fn deserialize_from_json_str( source: &str, - options: JsonParserOptions, + options: JsonParseOptions, name: &str, ) -> Deserialized { let parse = parse_json(source, options); @@ -58,7 +58,7 @@ pub fn deserialize_from_json_str( } pub fn deserialize_from_str(source: &str) -> Deserialized { - deserialize_from_json_str(source, JsonParserOptions::default(), "") + deserialize_from_json_str(source, JsonParseOptions::default(), "") } /// Attempts to deserialize a JSON AST, given the `Output`. @@ -275,7 +275,7 @@ mod tests { }; use super::*; - use biome_json_parser::JsonParserOptions; + use biome_json_parser::JsonParseOptions; use indexmap::{IndexMap, IndexSet}; #[test] @@ -284,7 +284,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::<()>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::<()>(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -308,7 +308,7 @@ mod tests { } let source = "0"; let Deserialized { deserialized, .. } = - deserialize_from_json_str::(source, JsonParserOptions::default(), "root"); + deserialize_from_json_str::(source, JsonParseOptions::default(), "root"); assert_eq!( deserialized, Some(Name { @@ -323,7 +323,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert!(deserialized.unwrap()); @@ -331,7 +331,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -342,7 +342,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0.5)); } @@ -353,7 +353,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0.5)); } @@ -364,7 +364,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(-1)); @@ -372,7 +372,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -383,7 +383,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(-1)); @@ -391,7 +391,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -402,7 +402,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(-1)); @@ -410,7 +410,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -421,7 +421,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(-1)); @@ -429,7 +429,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -440,7 +440,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(-1)); @@ -448,7 +448,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -459,7 +459,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0)); @@ -467,7 +467,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -478,7 +478,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0)); @@ -486,7 +486,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -497,7 +497,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0)); @@ -505,7 +505,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -516,7 +516,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0)); @@ -524,7 +524,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -535,7 +535,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, Some(0)); @@ -543,7 +543,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -554,7 +554,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, NonZeroU8::new(1)); @@ -562,7 +562,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -573,7 +573,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, NonZeroU16::new(1)); @@ -581,7 +581,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -592,7 +592,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, NonZeroU32::new(1)); @@ -600,7 +600,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -611,7 +611,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, NonZeroU64::new(1)); @@ -619,7 +619,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -630,7 +630,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized, NonZeroUsize::new(1)); @@ -638,7 +638,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -649,7 +649,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized.unwrap().text(), u128::MAX.to_string()); @@ -657,7 +657,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -668,7 +668,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized.unwrap(), "string"); @@ -676,7 +676,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -687,7 +687,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized.unwrap(), vec![0, 1]); @@ -695,7 +695,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -706,7 +706,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized.unwrap(), HashSet::from([0, 1])); @@ -714,7 +714,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -725,7 +725,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(diagnostics.is_empty()); assert_eq!(deserialized.unwrap(), IndexSet::from([0, 1])); @@ -733,7 +733,7 @@ mod tests { let Deserialized { deserialized, diagnostics, - } = deserialize_from_json_str::>(source, JsonParserOptions::default(), ""); + } = deserialize_from_json_str::>(source, JsonParseOptions::default(), ""); assert!(!diagnostics.is_empty()); assert!(deserialized.is_none()); } @@ -746,7 +746,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(diagnostics.is_empty()); @@ -761,7 +761,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(!diagnostics.is_empty()); @@ -776,7 +776,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(diagnostics.is_empty()); @@ -791,7 +791,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(!diagnostics.is_empty()); @@ -806,7 +806,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(diagnostics.is_empty()); @@ -821,7 +821,7 @@ mod tests { diagnostics, } = deserialize_from_json_str::>( source, - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); assert!(!diagnostics.is_empty()); diff --git a/crates/biome_deserialize/src/lib.rs b/crates/biome_deserialize/src/lib.rs index c77705001064..e71f200402c1 100644 --- a/crates/biome_deserialize/src/lib.rs +++ b/crates/biome_deserialize/src/lib.rs @@ -67,10 +67,10 @@ pub use validator::*; /// } /// /// use biome_deserialize::json::deserialize_from_json_str; -/// use biome_json_parser::JsonParserOptions; +/// use biome_json_parser::JsonParseOptions; /// /// let source = r#""a""#; -/// let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); +/// let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); /// assert!(!deserialized.has_errors()); /// assert!(matches!(deserialized.into_deserialized(), Some(Variant::A))); /// ``` @@ -181,10 +181,10 @@ pub trait DeserializableValue: Sized { /// } /// /// use biome_deserialize::json::deserialize_from_json_str; -/// use biome_json_parser::JsonParserOptions; +/// use biome_json_parser::JsonParseOptions; /// /// let source = r#"{ "name": "Isaac Asimov" }"#; -/// let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); +/// let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); /// assert!(!deserialized.has_errors()); /// assert_eq!(deserialized.into_deserialized(), Some(Person { name: "Isaac Asimov".to_string() })); /// ``` @@ -236,15 +236,15 @@ pub trait DeserializableValue: Sized { /// } /// /// use biome_deserialize::json::deserialize_from_json_str; -/// use biome_json_parser::JsonParserOptions; +/// use biome_json_parser::JsonParseOptions; /// /// let source = r#" "string" "#; -/// let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); +/// let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); /// assert!(!deserialized.has_errors()); /// assert_eq!(deserialized.into_deserialized(), Some(Union::Str("string".to_string()))); /// /// let source = "true"; -/// let deserialized = deserialize_from_json_str::(&source, JsonParserOptions::default(), ""); +/// let deserialized = deserialize_from_json_str::(&source, JsonParseOptions::default(), ""); /// assert!(!deserialized.has_errors()); /// assert_eq!(deserialized.into_deserialized(), Some(Union::Bool(true))); /// ``` diff --git a/crates/biome_deserialize_macros/src/lib.rs b/crates/biome_deserialize_macros/src/lib.rs index dce53eefd3e0..844ccdc420e5 100644 --- a/crates/biome_deserialize_macros/src/lib.rs +++ b/crates/biome_deserialize_macros/src/lib.rs @@ -437,8 +437,8 @@ pub fn derive_mergeable(input: TokenStream) -> TokenStream { /// using the `#[partial(type)]`. /// /// In the example above, where `CssConfiguration` has a field of type -/// `CssParser`, this will make sure the `PartialCssConfiguration` uses -/// `PartialCssParser` instead. +/// `CssParser`, this will make sure the `CssConfiguration` uses +/// `CssParserConfiguration` instead. /// /// If you need to use a fully custom in the partial struct instead, you can do /// so using `#[partial(type = "MyPartialType")]`. diff --git a/crates/biome_deserialize_macros/src/merge_derive.rs b/crates/biome_deserialize_macros/src/merge_derive.rs index 6ece724cac35..e196093ec0fa 100644 --- a/crates/biome_deserialize_macros/src/merge_derive.rs +++ b/crates/biome_deserialize_macros/src/merge_derive.rs @@ -1,7 +1,7 @@ use proc_macro2::{Ident, TokenStream}; use proc_macro_error::*; use quote::quote; -use syn::{Data, Fields}; +use syn::{Data, Fields, Generics}; pub enum MergeableData { Enum, @@ -11,6 +11,7 @@ pub enum MergeableData { pub(crate) struct DeriveInput { pub ident: Ident, + pub generics: Generics, pub data: MergeableData, } @@ -30,6 +31,7 @@ impl DeriveInput { Self { ident: input.ident, + generics: input.generics, data, } } @@ -37,15 +39,16 @@ impl DeriveInput { pub(crate) fn generate_merge(input: DeriveInput) -> TokenStream { match input.data { - MergeableData::Enum => generate_merge_enum(input.ident), - MergeableData::Newtype => generate_merge_newtype(input.ident), - MergeableData::Struct(fields) => generate_merge_struct(input.ident, fields), + MergeableData::Enum => generate_merge_enum(input.ident, input.generics), + MergeableData::Newtype => generate_merge_newtype(input.ident, input.generics), + MergeableData::Struct(fields) => generate_merge_struct(input.ident, input.generics, fields), } } -fn generate_merge_enum(ident: Ident) -> TokenStream { +fn generate_merge_enum(ident: Ident, generics: Generics) -> TokenStream { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); quote! { - impl biome_deserialize::Merge for #ident { + impl #impl_generics biome_deserialize::Merge for #ident #ty_generics #where_clause { fn merge_with(&mut self, other: Self) { *self = other; } @@ -53,9 +56,10 @@ fn generate_merge_enum(ident: Ident) -> TokenStream { } } -fn generate_merge_newtype(ident: Ident) -> TokenStream { +fn generate_merge_newtype(ident: Ident, generics: Generics) -> TokenStream { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); quote! { - impl biome_deserialize::Merge for #ident { + impl #impl_generics biome_deserialize::Merge for #ident #ty_generics #where_clause { fn merge_with(&mut self, other: Self) { self.0 = other.0; } @@ -63,10 +67,11 @@ fn generate_merge_newtype(ident: Ident) -> TokenStream { } } -fn generate_merge_struct(ident: Ident, fields: Fields) -> TokenStream { +fn generate_merge_struct(ident: Ident, generics: Generics, fields: Fields) -> TokenStream { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let field_idents = fields.into_iter().filter_map(|field| field.ident); quote! { - impl biome_deserialize::Merge for #ident { + impl #impl_generics biome_deserialize::Merge for #ident #ty_generics #where_clause { fn merge_with(&mut self, other: Self) { #( biome_deserialize::Merge::merge_with(&mut self.#field_idents, other.#field_idents); )* } diff --git a/crates/biome_formatter/src/comments/builder.rs b/crates/biome_formatter/src/comments/builder.rs index 33d1fdf72858..5e3c6137997b 100644 --- a/crates/biome_formatter/src/comments/builder.rs +++ b/crates/biome_formatter/src/comments/builder.rs @@ -644,7 +644,7 @@ mod tests { DecoratedComment, SourceComment, }; use crate::{TextSize, TransformSourceMap, TransformSourceMapBuilder}; - use biome_js_parser::{parse_module, JsParserOptions}; + use biome_js_parser::{parse_module, JsParseOptions}; use biome_js_syntax::{ JsIdentifierExpression, JsLanguage, JsParameters, JsParenthesizedExpression, JsPropertyObjectMember, JsReferenceIdentifier, JsSequenceExpression, @@ -858,7 +858,7 @@ b;"#; let source_map = source_map_builder.finish(); - let root = parse_module(source, JsParserOptions::default()).syntax(); + let root = parse_module(source, JsParseOptions::default()).syntax(); // A lot of code that simply removes the parenthesized expression and moves the parens // trivia to the identifiers leading / trailing trivia. @@ -1037,7 +1037,7 @@ b;"#; Vec>, CommentsMap>, ) { - let tree = parse_module(source, JsParserOptions::default()); + let tree = parse_module(source, JsParseOptions::default()); let style = TestCommentStyle::default(); let builder = CommentsBuilderVisitor::new(&style, source_map); diff --git a/crates/biome_formatter/src/lib.rs b/crates/biome_formatter/src/lib.rs index 8e831f92b8a0..b9e8eb1ea00b 100644 --- a/crates/biome_formatter/src/lib.rs +++ b/crates/biome_formatter/src/lib.rs @@ -363,14 +363,13 @@ impl biome_console::fmt::Display for LineWidth { impl Display for LineWidth { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let value = self.value(); - f.write_str(&std::format!("{value}")) + std::fmt::Display::fmt(&self.value(), f) } } impl Debug for LineWidth { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self, f) + std::fmt::Debug::fmt(&self.value(), f) } } diff --git a/crates/biome_formatter_test/src/spec.rs b/crates/biome_formatter_test/src/spec.rs index da0bc0eb9dd0..0a0065c57695 100644 --- a/crates/biome_formatter_test/src/spec.rs +++ b/crates/biome_formatter_test/src/spec.rs @@ -2,7 +2,7 @@ use crate::check_reformat::CheckReformat; use crate::snapshot_builder::{SnapshotBuilder, SnapshotOutput}; use crate::utils::strip_rome_placeholders; use crate::TestFormatLanguage; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::EnvConsole; use biome_deserialize::json::deserialize_from_str; use biome_diagnostics::print_diagnostic_to_string; @@ -241,10 +241,9 @@ where let mut settings = Settings::default(); // SAFETY: we checked its existence already, we assume we have rights to read it - let (test_options, diagnostics) = deserialize_from_str::( - options_path.get_buffer_from_file().as_str(), - ) - .consume(); + let (test_options, diagnostics) = + deserialize_from_str::(options_path.get_buffer_from_file().as_str()) + .consume(); settings .merge_with_configuration(test_options.unwrap_or_default(), None, None, &[]) .unwrap(); diff --git a/crates/biome_graphql_formatter/tests/spec_test.rs b/crates/biome_graphql_formatter/tests/spec_test.rs index 55905cf1c4bf..0bae7defefb9 100644 --- a/crates/biome_graphql_formatter/tests/spec_test.rs +++ b/crates/biome_graphql_formatter/tests/spec_test.rs @@ -1,6 +1,4 @@ -use biome_configuration::{ - PartialConfiguration, PartialGraphqlConfiguration, PartialGraphqlFormatter, -}; +use biome_configuration::{Configuration, GraphqlConfiguration, GraphqlFormatterConfiguration}; use biome_formatter_test::spec::{SpecSnapshot, SpecTestFile}; use biome_graphql_formatter::{context::GraphqlFormatOptions, GraphqlFormatLanguage}; use biome_service::workspace::UpdateSettingsParams; @@ -30,10 +28,10 @@ mod language { pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, _file_type: &str) { let root_path = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/specs/")); let settings = UpdateSettingsParams { - configuration: PartialConfiguration { - graphql: Some(PartialGraphqlConfiguration { - formatter: Some(PartialGraphqlFormatter { - enabled: Some(true), + configuration: Configuration { + graphql: Some(GraphqlConfiguration { + formatter: Some(GraphqlFormatterConfiguration { + enabled: Some(true.into()), ..Default::default() }), ..Default::default() diff --git a/crates/biome_grit_patterns/src/grit_js_parser.rs b/crates/biome_grit_patterns/src/grit_js_parser.rs index 87b85004650e..5ab081787abe 100644 --- a/crates/biome_grit_patterns/src/grit_js_parser.rs +++ b/crates/biome_grit_patterns/src/grit_js_parser.rs @@ -2,7 +2,7 @@ use crate::{ grit_analysis_ext::GritAnalysisExt, grit_target_language::GritTargetParser, grit_tree::GritTargetTree, }; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; use biome_parser::AnyParse; use grit_util::{AnalysisLogs, FileOrigin, Parser, SnippetTree}; @@ -35,7 +35,7 @@ impl Parser for GritJsParser { logs: &mut AnalysisLogs, _old_tree: FileOrigin<'_, GritTargetTree>, ) -> Option { - let parse_result = parse(body, JsFileSource::tsx(), JsParserOptions::default()); + let parse_result = parse(body, JsFileSource::tsx(), JsParseOptions::default()); for diagnostic in parse_result.diagnostics() { logs.push(diagnostic.to_log(path)); @@ -58,7 +58,7 @@ impl Parser for GritJsParser { |src: &str| src.len() as u32 }; - let parse_result = parse(&context, JsFileSource::tsx(), JsParserOptions::default()); + let parse_result = parse(&context, JsFileSource::tsx(), JsParseOptions::default()); SnippetTree { tree: GritTargetTree::new(parse_result.syntax().into()), diff --git a/crates/biome_grit_patterns/tests/quick_test.rs b/crates/biome_grit_patterns/tests/quick_test.rs index 7ba6434394d3..a29190640d66 100644 --- a/crates/biome_grit_patterns/tests/quick_test.rs +++ b/crates/biome_grit_patterns/tests/quick_test.rs @@ -1,6 +1,6 @@ use biome_grit_parser::parse_grit; use biome_grit_patterns::{GritQuery, GritTargetFile, GritTargetLanguage, JsTargetLanguage}; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; // Use this test to quickly execute a Grit query against a source snippet. @@ -32,7 +32,7 @@ function hello() { let file = GritTargetFile { path: "test.js".into(), - parse: parse(body, JsFileSource::tsx(), JsParserOptions::default()).into(), + parse: parse(body, JsFileSource::tsx(), JsParseOptions::default()).into(), }; let results = query.execute(file).expect("could not execute query"); diff --git a/crates/biome_js_analyze/src/lib.rs b/crates/biome_js_analyze/src/lib.rs index 05d0669a88ed..59e15c3d2986 100644 --- a/crates/biome_js_analyze/src/lib.rs +++ b/crates/biome_js_analyze/src/lib.rs @@ -177,7 +177,7 @@ mod tests { use biome_diagnostics::category; use biome_diagnostics::termcolor::NoColor; use biome_diagnostics::{Diagnostic, DiagnosticExt, PrintDiagnostic, Severity}; - use biome_js_parser::{parse, JsParserOptions}; + use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, TextRange, TextSize}; use biome_project::{Dependencies, PackageJson}; use std::slice; @@ -200,7 +200,7 @@ mod tests { const SOURCE: &str = r#"import buffer from "buffer"; "#; - let parsed = parse(SOURCE, JsFileSource::tsx(), JsParserOptions::default()); + let parsed = parse(SOURCE, JsFileSource::tsx(), JsParseOptions::default()); let mut error_ranges: Vec = Vec::new(); let mut options = AnalyzerOptions::default(); @@ -306,11 +306,7 @@ mod tests { } "; - let parsed = parse( - SOURCE, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(SOURCE, JsFileSource::js_module(), JsParseOptions::default()); let mut lint_ranges: Vec = Vec::new(); let mut parse_ranges: Vec = Vec::new(); @@ -391,11 +387,7 @@ mod tests { a == b; "; - let parsed = parse( - SOURCE, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(SOURCE, JsFileSource::js_module(), JsParseOptions::default()); let filter = AnalysisFilter { categories: RuleCategoriesBuilder::default().with_syntax().build(), diff --git a/crates/biome_js_analyze/src/lint/correctness/no_constant_condition.rs b/crates/biome_js_analyze/src/lint/correctness/no_constant_condition.rs index 1d8852df7137..f7d7bf424d4b 100644 --- a/crates/biome_js_analyze/src/lint/correctness/no_constant_condition.rs +++ b/crates/biome_js_analyze/src/lint/correctness/no_constant_condition.rs @@ -483,14 +483,14 @@ fn get_boolean_value(node: &AnyJsLiteralExpression) -> bool { #[cfg(test)] mod tests { - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_syntax::{AnyJsLiteralExpression, JsFileSource}; use biome_rowan::SyntaxNodeCast; use super::get_boolean_value; fn assert_boolean_value(code: &str, value: bool) { - let source = biome_js_parser::parse(code, JsFileSource::tsx(), JsParserOptions::default()); + let source = biome_js_parser::parse(code, JsFileSource::tsx(), JsParseOptions::default()); if source.has_errors() { panic!("syntax error") diff --git a/crates/biome_js_analyze/src/react/hooks.rs b/crates/biome_js_analyze/src/react/hooks.rs index 1bf1e38a3de6..a339dc276505 100644 --- a/crates/biome_js_analyze/src/react/hooks.rs +++ b/crates/biome_js_analyze/src/react/hooks.rs @@ -483,7 +483,7 @@ pub fn is_binding_react_stable( mod test { use super::*; use crate::react::hooks::is_react_hook_call; - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_semantic::{semantic_model, SemanticModelOptions}; use biome_js_syntax::JsFileSource; @@ -493,7 +493,7 @@ mod test { let r = biome_js_parser::parse( r#"useRef();"#, JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let node = r .syntax() @@ -509,7 +509,7 @@ mod test { let r = biome_js_parser::parse( r#"userCredentials();"#, JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let node = r .syntax() @@ -530,7 +530,7 @@ mod test { const ref = useRef(); "#, JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let node = r .syntax() @@ -560,7 +560,7 @@ mod test { const ref = React.useRef(); "#, JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let node = r .syntax() diff --git a/crates/biome_js_analyze/src/utils.rs b/crates/biome_js_analyze/src/utils.rs index 069d7d22e0d9..427097812ec9 100644 --- a/crates/biome_js_analyze/src/utils.rs +++ b/crates/biome_js_analyze/src/utils.rs @@ -115,18 +115,14 @@ pub(crate) fn find_variable_position( #[cfg(test)] mod test { use crate::utils::{find_variable_position, VariablePosition}; - use biome_js_parser::{parse, JsParserOptions}; + use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsBinaryExpression, JsFileSource}; use biome_rowan::AstNode; #[test] fn find_variable_position_matches_on_left() { let source = "(a) + b"; - let parsed = parse( - source, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(source, JsFileSource::js_module(), JsParseOptions::default()); let binary_expression = parsed .syntax() @@ -145,11 +141,7 @@ mod test { #[test] fn find_variable_position_matches_on_right() { let source = "a + b"; - let parsed = parse( - source, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(source, JsFileSource::js_module(), JsParseOptions::default()); let binary_expression = parsed .syntax() @@ -168,11 +160,7 @@ mod test { #[test] fn find_variable_position_not_match() { let source = "a + b"; - let parsed = parse( - source, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(source, JsFileSource::js_module(), JsParseOptions::default()); let binary_expression = parsed .syntax() @@ -191,11 +179,7 @@ mod test { #[test] fn find_variable_position_when_the_operator_has_no_spaces_around() { let source = "l-c"; - let parsed = parse( - source, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let parsed = parse(source, JsFileSource::js_module(), JsParseOptions::default()); let binary_expression = parsed .syntax() diff --git a/crates/biome_js_analyze/src/utils/tests.rs b/crates/biome_js_analyze/src/utils/tests.rs index 89ccdc61f459..2f5999b385d6 100644 --- a/crates/biome_js_analyze/src/utils/tests.rs +++ b/crates/biome_js_analyze/src/utils/tests.rs @@ -1,6 +1,6 @@ use super::rename::*; use crate::utils::batch::JsBatchMutation; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_semantic::{semantic_model, SemanticModelOptions}; use biome_js_syntax::{ AnyJsObjectMember, JsFileSource, JsFormalParameter, JsIdentifierBinding, JsLanguage, @@ -13,11 +13,7 @@ use std::{any::type_name, fmt::Debug}; /// Search and renames alls bindings where the name contains "a" replacing it to "b". /// Asserts the renaming worked. pub fn assert_rename_binding_a_to_b_ok(before: &str, expected: &str) { - let r = biome_js_parser::parse( - before, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let r = biome_js_parser::parse(before, JsFileSource::js_module(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let bindings: Vec = r @@ -46,7 +42,7 @@ pub fn assert_rename_binding_a_to_b_ok(before: &str, expected: &str) { } pub fn assert_rename_ts_binding_a_to_b_ok(before: &str, expected: &str) { - let r = biome_js_parser::parse(before, JsFileSource::tsx(), JsParserOptions::default()); + let r = biome_js_parser::parse(before, JsFileSource::tsx(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let bindings: Vec = r @@ -77,11 +73,7 @@ pub fn assert_rename_ts_binding_a_to_b_ok(before: &str, expected: &str) { /// Search and renames one binding named "a" to "b". /// Asserts the renaming fails. pub fn assert_rename_binding_a_to_b_nok(before: &str) { - let r = biome_js_parser::parse( - before, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let r = biome_js_parser::parse(before, JsFileSource::js_module(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let binding_a = r @@ -101,11 +93,7 @@ pub fn assert_remove_identifier_a_ok + Debug before: &str, expected: &str, ) { - let r = biome_js_parser::parse( - before, - JsFileSource::js_module(), - JsParserOptions::default(), - ); + let r = biome_js_parser::parse(before, JsFileSource::js_module(), JsParseOptions::default()); let identifiers_a: Vec = r .syntax() @@ -188,7 +176,7 @@ pub fn ok_find_attributes_by_name() { let r = biome_js_parser::parse( r#""#, JsFileSource::jsx(), - JsParserOptions::default(), + JsParseOptions::default(), ); let list = r .syntax() diff --git a/crates/biome_js_analyze/tests/quick_test.rs b/crates/biome_js_analyze/tests/quick_test.rs index 0df26776f155..652dbe442727 100644 --- a/crates/biome_js_analyze/tests/quick_test.rs +++ b/crates/biome_js_analyze/tests/quick_test.rs @@ -1,7 +1,7 @@ use biome_analyze::{AnalysisFilter, ControlFlow, Never, RuleFilter}; use biome_diagnostics::advice::CodeSuggestionAdvice; use biome_diagnostics::{DiagnosticExt, Severity}; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; use biome_test_utils::{ code_fix_to_string, create_analyzer_options, diagnostic_to_string, load_manifest, @@ -63,7 +63,7 @@ fn analyze( file_name: &str, input_file: &Path, ) { - let parsed = parse(input_code, source_type, JsParserOptions::default()); + let parsed = parse(input_code, source_type, JsParseOptions::default()); let root = parsed.tree(); let mut diagnostics = Vec::new(); diff --git a/crates/biome_js_analyze/tests/spec_tests.rs b/crates/biome_js_analyze/tests/spec_tests.rs index 349d088080c9..4501911770e2 100644 --- a/crates/biome_js_analyze/tests/spec_tests.rs +++ b/crates/biome_js_analyze/tests/spec_tests.rs @@ -1,7 +1,7 @@ use biome_analyze::{AnalysisFilter, AnalyzerAction, ControlFlow, Never, RuleFilter}; use biome_diagnostics::advice::CodeSuggestionAdvice; use biome_diagnostics::{DiagnosticExt, Severity}; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, JsLanguage, ModuleKind}; use biome_project::PackageType; use biome_rowan::AstNode; @@ -56,7 +56,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { file_name, input_file, CheckActionType::Lint, - JsParserOptions::default(), + JsParseOptions::default(), ); } @@ -73,7 +73,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { file_name, input_file, CheckActionType::Lint, - JsParserOptions::default(), + JsParseOptions::default(), ) }; @@ -98,21 +98,21 @@ pub(crate) fn analyze_and_snap( file_name: &str, input_file: &Path, check_action_type: CheckActionType, - parser_options: JsParserOptions, + parse_options: JsParseOptions, ) -> usize { let mut diagnostics = Vec::new(); let mut code_fixes = Vec::new(); let manifest = load_manifest(input_file, &mut diagnostics); if let Some(manifest) = &manifest { - if manifest.r#type == Some(PackageType::Commonjs) && + if manifest.r#type == Some(PackageType::Commonjs) && // At the moment we treat JS and JSX at the same way (source_type.file_extension() == "js" || source_type.file_extension() == "jsx" ) { source_type.set_module_kind(ModuleKind::Script) } } - let parsed = parse(input_code, source_type, parser_options.clone()); + let parsed = parse(input_code, source_type, parse_options.clone()); let root = parsed.tree(); let options = create_analyzer_options(input_file, &mut diagnostics); @@ -128,7 +128,7 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &action, - parser_options.clone(), + parse_options.clone(), ); diag = diag.add_code_suggestion(CodeSuggestionAdvice::from(action)); } @@ -138,7 +138,7 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &action, - parser_options.clone(), + parse_options.clone(), ); diag = diag.add_code_suggestion(CodeSuggestionAdvice::from(action)); } @@ -157,7 +157,7 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &action, - parser_options.clone(), + parse_options.clone(), ); code_fixes.push(code_fix_to_string(input_code, action)); } @@ -167,7 +167,7 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &action, - parser_options.clone(), + parse_options.clone(), ); code_fixes.push(code_fix_to_string(input_code, action)); } @@ -196,7 +196,7 @@ fn check_code_action( source: &str, source_type: JsFileSource, action: &AnalyzerAction, - options: JsParserOptions, + options: JsParseOptions, ) { let (new_tree, text_edit) = match action .mutation @@ -262,7 +262,7 @@ pub(crate) fn run_suppression_test(input: &'static str, _: &str, _: &str, _: &st file_name, input_file, CheckActionType::Suppression, - JsParserOptions::default(), + JsParseOptions::default(), ); insta::with_settings!({ diff --git a/crates/biome_js_formatter/src/lib.rs b/crates/biome_js_formatter/src/lib.rs index 8c87e4abb93a..0110f81f366c 100644 --- a/crates/biome_js_formatter/src/lib.rs +++ b/crates/biome_js_formatter/src/lib.rs @@ -562,7 +562,7 @@ mod tests { use crate::context::JsFormatOptions; use biome_formatter::IndentStyle; - use biome_js_parser::{parse, parse_script, JsParserOptions}; + use biome_js_parser::{parse, parse_script, JsParseOptions}; use biome_js_syntax::JsFileSource; use biome_rowan::{TextRange, TextSize}; @@ -596,7 +596,7 @@ while( let range_start = TextSize::try_from(input.find("let").unwrap() - 2).unwrap(); let range_end = TextSize::try_from(input.find("const").unwrap()).unwrap(); - let tree = parse_script(input, JsParserOptions::default()); + let tree = parse_script(input, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) @@ -630,7 +630,7 @@ function() { let range_start = TextSize::try_from(input.find("const").unwrap()).unwrap(); let range_end = TextSize::try_from(input.find('}').unwrap()).unwrap(); - let tree = parse_script(input, JsParserOptions::default()); + let tree = parse_script(input, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) @@ -659,7 +659,7 @@ function() { let range_start = TextSize::from(5); let range_end = TextSize::from(5); - let tree = parse_script(input, JsParserOptions::default()); + let tree = parse_script(input, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) @@ -689,7 +689,7 @@ function() { }"# ); - let tree = parse_script(input, JsParserOptions::default()); + let tree = parse_script(input, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) @@ -722,7 +722,7 @@ function() { debug_assert_eq!(&input[range], r#" quux (); //"#); - let tree = parse_script(input, JsParserOptions::default()); + let tree = parse_script(input, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) @@ -744,7 +744,7 @@ function() { let src = "statement();"; let syntax = JsFileSource::js_module(); - let tree = parse(src, syntax, JsParserOptions::default()); + let tree = parse(src, syntax, JsParseOptions::default()); let result = format_range( JsFormatOptions::new(syntax), diff --git a/crates/biome_js_formatter/src/parentheses.rs b/crates/biome_js_formatter/src/parentheses.rs index 89f4c0dabacb..318ca8ddc2fe 100644 --- a/crates/biome_js_formatter/src/parentheses.rs +++ b/crates/biome_js_formatter/src/parentheses.rs @@ -1055,7 +1055,7 @@ pub(crate) fn debug_assert_is_parent(node: &JsSyntaxNode, parent: &JsSyntaxNode) pub(crate) mod tests { use super::NeedsParentheses; use crate::transform; - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_rowan::AstNode; @@ -1066,7 +1066,7 @@ pub(crate) mod tests { index: Option, source_type: JsFileSource, ) { - let parse = biome_js_parser::parse(input, source_type, JsParserOptions::default()); + let parse = biome_js_parser::parse(input, source_type, JsParseOptions::default()); let diagnostics = parse.diagnostics(); assert!( @@ -1107,7 +1107,7 @@ pub(crate) mod tests { index: Option, source_type: JsFileSource, ) { - let parse = biome_js_parser::parse(input, source_type, JsParserOptions::default()); + let parse = biome_js_parser::parse(input, source_type, JsParseOptions::default()); let diagnostics = parse.diagnostics(); assert!( diff --git a/crates/biome_js_formatter/src/syntax_rewriter.rs b/crates/biome_js_formatter/src/syntax_rewriter.rs index 46ccf13dad1d..eb299a388db5 100644 --- a/crates/biome_js_formatter/src/syntax_rewriter.rs +++ b/crates/biome_js_formatter/src/syntax_rewriter.rs @@ -461,7 +461,7 @@ mod tests { use super::JsFormatSyntaxRewriter; use crate::{format_node, JsFormatOptions, TextRange}; use biome_formatter::{SourceMarker, TransformSourceMap}; - use biome_js_parser::{parse, parse_module, JsParserOptions}; + use biome_js_parser::{parse, parse_module, JsParseOptions}; use biome_js_syntax::{ JsArrayExpression, JsBinaryExpression, JsExpressionStatement, JsFileSource, JsIdentifierExpression, JsLogicalExpression, JsSequenceExpression, @@ -471,7 +471,7 @@ mod tests { #[test] fn rebalances_logical_expressions() { - let root = parse_module("a && (b && c)", JsParserOptions::default()).syntax(); + let root = parse_module("a && (b && c)", JsParseOptions::default()).syntax(); let transformed = JsFormatSyntaxRewriter::default().transform(root.clone()); @@ -500,7 +500,7 @@ mod tests { #[test] fn only_rebalances_logical_expressions_with_same_operator() { - let root = parse_module("a && (b || c)", JsParserOptions::default()).syntax(); + let root = parse_module("a && (b || c)", JsParseOptions::default()).syntax(); let transformed = JsFormatSyntaxRewriter::default().transform(root); // Removes parentheses @@ -824,7 +824,7 @@ mod tests { } fn source_map_test(input: &str) -> (JsSyntaxNode, TransformSourceMap) { - let tree = parse(input, JsFileSource::jsx(), JsParserOptions::default()).syntax(); + let tree = parse(input, JsFileSource::jsx(), JsParseOptions::default()).syntax(); let mut rewriter = JsFormatSyntaxRewriter::default(); let transformed = rewriter.transform(tree); diff --git a/crates/biome_js_formatter/src/utils/binary_like_expression.rs b/crates/biome_js_formatter/src/utils/binary_like_expression.rs index 9ea6e15b8688..63926821b34b 100644 --- a/crates/biome_js_formatter/src/utils/binary_like_expression.rs +++ b/crates/biome_js_formatter/src/utils/binary_like_expression.rs @@ -897,13 +897,13 @@ impl FusedIterator for BinaryLikePreorder {} mod tests { use crate::utils::binary_like_expression::{BinaryLikePreorder, VisitEvent}; use crate::utils::AnyJsBinaryLikeExpression; - use biome_js_parser::{parse_module, JsParserOptions}; + use biome_js_parser::{parse_module, JsParseOptions}; use biome_js_syntax::JsLogicalExpression; use biome_rowan::AstNode; #[test] fn in_order_visits_every_binary_like_expression() { - let parse = parse_module("a && b && c || d", JsParserOptions::default()); + let parse = parse_module("a && b && c || d", JsParseOptions::default()); let root = parse .syntax() .descendants() @@ -951,7 +951,7 @@ mod tests { #[test] fn in_order_skip_subtree() { - let parse = parse_module("a && b && c || d", JsParserOptions::default()); + let parse = parse_module("a && b && c || d", JsParseOptions::default()); let root = parse .syntax() .descendants() diff --git a/crates/biome_js_formatter/src/utils/jsx.rs b/crates/biome_js_formatter/src/utils/jsx.rs index c8f31cb3636d..f8cc4f192435 100644 --- a/crates/biome_js_formatter/src/utils/jsx.rs +++ b/crates/biome_js_formatter/src/utils/jsx.rs @@ -577,7 +577,7 @@ mod tests { jsx_split_children, JsxChild, JsxChildrenIterator, JsxSplitChunksIterator, JsxTextChunk, }; use biome_formatter::comments::Comments; - use biome_js_parser::{parse, JsParserOptions}; + use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, JsxChildList, JsxText}; use biome_rowan::{AstNode, TextSize}; @@ -609,7 +609,7 @@ mod tests { let parse = parse( &std::format!("<>{text}"), JsFileSource::jsx(), - JsParserOptions::default(), + JsParseOptions::default(), ); assert!( !parse.has_errors(), @@ -684,7 +684,7 @@ mod tests { let parse = parse( &std::format!("
{children}
"), JsFileSource::jsx(), - JsParserOptions::default(), + JsParseOptions::default(), ); assert!( diff --git a/crates/biome_js_formatter/tests/language.rs b/crates/biome_js_formatter/tests/language.rs index a94792bea95b..45c17112a677 100644 --- a/crates/biome_js_formatter/tests/language.rs +++ b/crates/biome_js_formatter/tests/language.rs @@ -2,7 +2,7 @@ use biome_formatter_test::TestFormatLanguage; use biome_fs::BiomePath; use biome_js_formatter::context::JsFormatContext; use biome_js_formatter::JsFormatLanguage; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_parser::AnyParse; use biome_service::{ @@ -26,7 +26,7 @@ impl TestFormatLanguage for JsTestFormatLanguage { type FormatLanguage = JsFormatLanguage; fn parse(&self, text: &str) -> AnyParse { - let options = JsParserOptions::default().with_parse_class_parameter_decorators(); + let options = JsParseOptions::default().with_parse_class_parameter_decorators(); parse(text, self.source_type, options).into() } diff --git a/crates/biome_js_formatter/tests/quick_test.rs b/crates/biome_js_formatter/tests/quick_test.rs index e2b38d871768..832dd472e79a 100644 --- a/crates/biome_js_formatter/tests/quick_test.rs +++ b/crates/biome_js_formatter/tests/quick_test.rs @@ -2,7 +2,7 @@ use biome_formatter::{AttributePosition, IndentStyle, LineWidth, QuoteStyle}; use biome_formatter_test::check_reformat::CheckReformat; use biome_js_formatter::context::{ArrowParentheses, JsFormatOptions, Semicolons}; use biome_js_formatter::{format_node, JsFormatLanguage}; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; mod language { @@ -29,7 +29,7 @@ function outerFunctionToForceIndent() { let tree = parse( src, source_type, - JsParserOptions::default().with_parse_class_parameter_decorators(), + JsParseOptions::default().with_parse_class_parameter_decorators(), ); let options = JsFormatOptions::new(source_type) .with_indent_style(IndentStyle::Space) diff --git a/crates/biome_js_parser/src/lib.rs b/crates/biome_js_parser/src/lib.rs index 8773b6022521..a55fa22d917f 100644 --- a/crates/biome_js_parser/src/lib.rs +++ b/crates/biome_js_parser/src/lib.rs @@ -132,7 +132,7 @@ use crate::prelude::*; pub(crate) use crate::ParsedSyntax::{Absent, Present}; pub use crate::{ lexer::{JsLexContext, JsReLexContext}, - options::JsParserOptions, + options::JsParseOptions, parse::*, }; use biome_js_factory::JsSyntaxFactory; diff --git a/crates/biome_js_parser/src/options.rs b/crates/biome_js_parser/src/options.rs index b52f45233cb5..04938a0c534a 100644 --- a/crates/biome_js_parser/src/options.rs +++ b/crates/biome_js_parser/src/options.rs @@ -1,14 +1,14 @@ /// Options to pass to the JavaScript parser #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct JsParserOptions { +pub struct JsParseOptions { /// Whether the parsing of the class parameter decorators should happen. /// /// This parameter decorators belong to the old language proposal. pub parse_class_parameter_decorators: bool, } -impl JsParserOptions { +impl JsParseOptions { pub fn with_parse_class_parameter_decorators(mut self) -> Self { self.parse_class_parameter_decorators = true; self diff --git a/crates/biome_js_parser/src/parse.rs b/crates/biome_js_parser/src/parse.rs index f03a143abcde..6636a2cd4eba 100644 --- a/crates/biome_js_parser/src/parse.rs +++ b/crates/biome_js_parser/src/parse.rs @@ -45,7 +45,7 @@ impl Parse { /// The syntax node represented by this Parse result /// /// ``` - /// use biome_js_parser::{JsParserOptions, parse_script}; + /// use biome_js_parser::{JsParseOptions, parse_script}; /// use biome_js_syntax::{JsIfStatement, JsSyntaxKind}; /// use biome_rowan::{AstNode, AstNodeList}; /// @@ -55,7 +55,7 @@ impl Parse { /// /* something */ /// } /// ", - /// JsParserOptions::default() + /// JsParseOptions::default() /// ); /// /// // The first stmt in the root syntax node (Script) is the if statement. @@ -128,7 +128,7 @@ impl From> for AnyParse { fn parse_common( text: &str, source_type: JsFileSource, - options: JsParserOptions, + options: JsParseOptions, ) -> (Vec>, Vec, Vec) { let mut parser = JsParser::new(text, source_type, options); syntax::program::parse(&mut parser); @@ -142,11 +142,11 @@ fn parse_common( /// Or turned into a typed [`JsScript`](JsScript) with [`tree`](Parse::tree). /// /// ``` -/// use biome_js_parser::{JsParserOptions, parse_script}; +/// use biome_js_parser::{JsParseOptions, parse_script}; /// use biome_js_syntax::{JsSyntaxToken, JsFileSource, JsSyntaxList, JsComputedMemberExpression}; /// use biome_rowan::{AstNode, Direction}; /// -/// let parse = parse_script("foo.bar[2]", JsParserOptions::default()); +/// let parse = parse_script("foo.bar[2]", JsParseOptions::default()); /// // Parse returns a JS Root which contains two lists, the directives and the statements, let's get the statements /// let stmt = parse.syntax().children().nth(1).unwrap(); /// // The untyped syntax node of `foo.bar[2]`, the root node is `Script`. @@ -169,7 +169,7 @@ fn parse_common( /// /// assert_eq!(&tokens, &vec!["foo", ".", "bar", "[", "2", "]"]); /// ``` -pub fn parse_script(text: &str, options: JsParserOptions) -> Parse { +pub fn parse_script(text: &str, options: JsParseOptions) -> Parse { parse( text, JsFileSource::js_module().with_module_kind(ModuleKind::Script), @@ -185,14 +185,14 @@ pub fn parse_script(text: &str, options: JsParserOptions) -> Parse { /// /// Check the diagnostics emitted by the code /// ``` -/// use biome_js_parser::{JsParserOptions, parse_module}; +/// use biome_js_parser::{JsParseOptions, parse_module}; /// let source = r#" /// import { someModule } from "./someModule.js"; /// /// someModule(); /// "#; /// -/// let parse = parse_module(source, JsParserOptions::default()); +/// let parse = parse_module(source, JsParseOptions::default()); /// /// // Retrieve the diagnostics emitted /// assert_eq!(parse.diagnostics().len(), 0); @@ -200,7 +200,7 @@ pub fn parse_script(text: &str, options: JsParserOptions) -> Parse { /// /// Retrieve the emitted AST and check its kind: /// ``` -/// use biome_js_parser::{JsParserOptions, parse_module}; +/// use biome_js_parser::{JsParseOptions, parse_module}; /// use biome_js_syntax::JsSyntaxKind; /// use biome_rowan::AstNode; /// let source = r#" @@ -208,14 +208,14 @@ pub fn parse_script(text: &str, options: JsParserOptions) -> Parse { /// /// someModule(); /// "#; -/// let parse = parse_module(source, JsParserOptions::default()); +/// let parse = parse_module(source, JsParseOptions::default()); /// /// let tree = parse.tree(); /// /// assert_eq!(tree.syntax().kind(), JsSyntaxKind::JS_MODULE); /// ``` /// -pub fn parse_module(text: &str, options: JsParserOptions) -> Parse { +pub fn parse_module(text: &str, options: JsParseOptions) -> Parse { parse(text, JsFileSource::js_module(), options) .cast::() .unwrap() @@ -226,25 +226,25 @@ pub fn parse_module(text: &str, options: JsParserOptions) -> Parse { /// ### Examples /// /// ``` -/// use biome_js_parser::{JsParserOptions, parse}; +/// use biome_js_parser::{JsParseOptions, parse}; /// use biome_js_syntax::{LanguageVariant, LanguageVersion, ModuleKind, JsFileSource}; /// // parse source text as TypeScript /// let mut module = JsFileSource::ts(); -/// let mut parsed = parse("type F = {}", module, JsParserOptions::default()); +/// let mut parsed = parse("type F = {}", module, JsParseOptions::default()); /// assert_eq!(parsed.diagnostics().len(), 0); /// // parse source text as JSX /// module = JsFileSource::jsx(); -/// parsed = parse("", module, JsParserOptions::default()); +/// parsed = parse("", module, JsParseOptions::default()); /// assert_eq!(parsed.diagnostics().len(), 0); /// // parse source text with granular control /// module = JsFileSource::default() /// .with_version(LanguageVersion::ESNext) /// .with_module_kind(ModuleKind::Module) /// .with_variant(LanguageVariant::Jsx); -/// parsed = parse("foo[bar]", module, JsParserOptions::default()); +/// parsed = parse("foo[bar]", module, JsParseOptions::default()); /// assert_eq!(parsed.diagnostics().len(), 0); /// ``` -pub fn parse(text: &str, source_type: JsFileSource, options: JsParserOptions) -> Parse { +pub fn parse(text: &str, source_type: JsFileSource, options: JsParseOptions) -> Parse { let mut cache = NodeCache::default(); parse_js_with_cache(text, source_type, options, &mut cache) } @@ -254,7 +254,7 @@ pub fn parse(text: &str, source_type: JsFileSource, options: JsParserOptions) -> /// ### Examples /// /// ``` -/// use biome_js_parser::{JsParserOptions, parse_js_with_cache}; +/// use biome_js_parser::{JsParseOptions, parse_js_with_cache}; /// use biome_js_syntax::JsFileSource; /// use biome_rowan::NodeCache; /// @@ -262,17 +262,17 @@ pub fn parse(text: &str, source_type: JsFileSource, options: JsParserOptions) -> /// let mut cache = NodeCache::default(); /// let mut source = "function f() { return 2 }"; /// -/// let parsed = parse_js_with_cache(source, source_type, JsParserOptions::default(), &mut cache); +/// let parsed = parse_js_with_cache(source, source_type, JsParseOptions::default(), &mut cache); /// assert_eq!(parsed.diagnostics().len(), 0); /// /// source = "function bar() { return 3 }"; -/// let parsed = parse_js_with_cache(source, source_type, JsParserOptions::default(), &mut cache); +/// let parsed = parse_js_with_cache(source, source_type, JsParseOptions::default(), &mut cache); /// assert_eq!(parsed.diagnostics().len(), 0); /// ``` pub fn parse_js_with_cache( text: &str, source_type: JsFileSource, - options: JsParserOptions, + options: JsParseOptions, cache: &mut NodeCache, ) -> Parse { tracing::debug_span!("parse").in_scope(move || { diff --git a/crates/biome_js_parser/src/parser.rs b/crates/biome_js_parser/src/parser.rs index faa1c5ae1109..59bc8756ce44 100644 --- a/crates/biome_js_parser/src/parser.rs +++ b/crates/biome_js_parser/src/parser.rs @@ -35,12 +35,12 @@ pub struct JsParser<'source> { pub source_type: JsFileSource, context: ParserContext, source: JsTokenSource<'source>, - options: JsParserOptions, + options: JsParseOptions, } impl<'source> JsParser<'source> { /// Creates a new parser that parses the `source`. - pub fn new(source: &'source str, source_type: JsFileSource, options: JsParserOptions) -> Self { + pub fn new(source: &'source str, source_type: JsFileSource, options: JsParseOptions) -> Self { let source = JsTokenSource::from_str(source); JsParser { @@ -56,7 +56,7 @@ impl<'source> JsParser<'source> { &self.state } - pub(crate) fn options(&self) -> &JsParserOptions { + pub(crate) fn options(&self) -> &JsParseOptions { &self.options } @@ -218,7 +218,7 @@ pub struct JsParserCheckpoint { #[cfg(test)] mod tests { use crate::prelude::*; - use crate::JsParserOptions; + use crate::JsParseOptions; use biome_js_syntax::{JsFileSource, JsSyntaxKind}; #[test] @@ -229,7 +229,7 @@ mod tests { let mut parser = JsParser::new( "'use strict'", JsFileSource::default(), - JsParserOptions::default(), + JsParseOptions::default(), ); let _ = parser.start(); @@ -241,7 +241,7 @@ mod tests { let mut p = JsParser::new( "'use strict'", JsFileSource::default(), - JsParserOptions::default(), + JsParseOptions::default(), ); let m = p.start(); @@ -254,7 +254,7 @@ mod tests { let mut p = JsParser::new( "'use strict'", JsFileSource::default(), - JsParserOptions::default(), + JsParseOptions::default(), ); let m = p.start(); diff --git a/crates/biome_js_parser/src/tests.rs b/crates/biome_js_parser/src/tests.rs index 5df6860aef3b..f2d79e0c34a6 100644 --- a/crates/biome_js_parser/src/tests.rs +++ b/crates/biome_js_parser/src/tests.rs @@ -1,5 +1,5 @@ use crate::test_utils::has_bogus_nodes_or_empty_slots; -use crate::{parse, parse_module, test_utils::assert_errors_are_absent, JsParserOptions, Parse}; +use crate::{parse, parse_module, test_utils::assert_errors_are_absent, JsParseOptions, Parse}; use biome_console::fmt::{Formatter, Termcolor}; use biome_console::markup; use biome_diagnostics::DiagnosticExt; @@ -18,7 +18,7 @@ fn parser_smoke_test() { import "x" with { type: "json" } "#; - let module = parse(src, JsFileSource::tsx(), JsParserOptions::default()); + let module = parse(src, JsFileSource::tsx(), JsParseOptions::default()); assert_errors_are_absent(&module, Path::new("parser_smoke_test")); } @@ -28,7 +28,7 @@ fn parser_missing_smoke_test() { console.log("Hello world"; "#; - let module = parse_module(src, JsParserOptions::default()); + let module = parse_module(src, JsParseOptions::default()); let arg_list = module .syntax() @@ -48,7 +48,7 @@ fn parser_missing_smoke_test() { assert_eq!(closing, None); } -fn try_parse(path: &str, text: &str, options: JsParserOptions) -> Parse { +fn try_parse(path: &str, text: &str, options: JsParseOptions) -> Parse { let res = catch_unwind(|| { let path = Path::new(path); // Files containing a // SCRIPT comment are parsed as script and not as module @@ -77,7 +77,7 @@ fn try_parse(path: &str, text: &str, options: JsParserOptions) -> Parse (Parse, String) { catch_unwind(|| { let parse = try_parse(path, text, options.clone()); @@ -105,7 +105,7 @@ fn run_and_expect_no_errors(path: &str, _: &str, _: &str, _: &str) { let text = std::fs::read_to_string(&path).unwrap(); let options_path = path.with_extension("options.json"); - let options: JsParserOptions = std::fs::read_to_string(options_path) + let options: JsParseOptions = std::fs::read_to_string(options_path) .ok() .and_then(|options| serde_json::from_str(&options).ok()) .unwrap_or_default(); @@ -124,7 +124,7 @@ fn run_and_expect_errors(path: &str, _: &str, _: &str, _: &str) { let text = std::fs::read_to_string(&path).unwrap(); let options_path = path.with_extension("options.json"); - let options: JsParserOptions = std::fs::read_to_string(options_path) + let options: JsParseOptions = std::fs::read_to_string(options_path) .ok() .and_then(|options| serde_json::from_str(&options).ok()) .unwrap_or_default(); @@ -177,7 +177,7 @@ fn assert_errors_are_present(program: &Parse, path: &Path) { #[test] pub fn test_trivia_attached_to_tokens() { let text = "/**/let a = 1; // nice variable \n /*hey*/ let \t b = 2; // another nice variable"; - let m = parse_module(text, JsParserOptions::default()); + let m = parse_module(text, JsParseOptions::default()); let mut tokens = m.syntax().descendants_tokens(Direction::Next); let is_let = |x: &JsSyntaxToken| x.text_trimmed() == "let"; @@ -211,7 +211,7 @@ pub fn test_trivia_attached_to_tokens() { #[test] pub fn jsroot_display_text_and_trimmed() { let code = " let a = 1; \n "; - let root = parse_module(code, JsParserOptions::default()); + let root = parse_module(code, JsParseOptions::default()); let syntax = root.syntax(); assert_eq!(format!("{syntax}"), code); @@ -227,7 +227,7 @@ pub fn jsroot_display_text_and_trimmed() { pub fn jsroot_ranges() { // 0123456789A let code = " let a = 1;"; - let root = parse_module(code, JsParserOptions::default()); + let root = parse_module(code, JsParseOptions::default()); let syntax = root.syntax(); let first_let = syntax.first_token().unwrap(); @@ -256,7 +256,7 @@ pub fn jsroot_ranges() { pub fn node_range_must_be_correct() { // 0123456789A123456789B123456789 let text = " function foo() { let a = 1; }"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let var_decl = root .syntax() @@ -277,7 +277,7 @@ pub fn node_range_must_be_correct() { pub fn last_trivia_must_be_appended_to_eof() { // 0123456789A123456789B123456789CC let text = " function foo() { let a = 1; }\n"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); let range = syntax.text_range(); @@ -292,7 +292,7 @@ pub fn last_trivia_must_be_appended_to_eof() { pub fn just_trivia_must_be_appended_to_eof() { // 0123456789A123456789B123456789C123 let text = "// just trivia... nothing else...."; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); let range = syntax.text_range(); @@ -306,7 +306,7 @@ pub fn just_trivia_must_be_appended_to_eof() { #[test] pub fn node_contains_comments() { let text = "true && true // comment"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); assert!(syntax.has_comments_descendants()); @@ -315,7 +315,7 @@ pub fn node_contains_comments() { #[test] fn parser_regexp_after_operator() { fn assert_no_errors(src: &str) { - let module = parse(src, JsFileSource::js_script(), JsParserOptions::default()); + let module = parse(src, JsFileSource::js_script(), JsParseOptions::default()); assert_errors_are_absent(&module, Path::new("parser_regexp_after_operator")); } assert_no_errors(r#"a=/a/"#); @@ -328,7 +328,7 @@ fn parser_regexp_after_operator() { #[test] pub fn node_contains_trailing_comments() { let text = "true && (3 - 2 == 0) // comment"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); let node = syntax .descendants() @@ -347,7 +347,7 @@ pub fn node_contains_leading_comments() { let text = r"true && // comment (3 - 2 == 0)"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); let node = syntax .descendants() @@ -366,7 +366,7 @@ pub fn node_has_comments() { let text = r"true && // comment (3 - 2 == 0)"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); let syntax = root.syntax(); let node = syntax .descendants() @@ -383,7 +383,7 @@ pub fn node_has_comments() { fn diagnostics_print_correctly() { let text = r"const a"; - let root = parse_module(text, JsParserOptions::default()); + let root = parse_module(text, JsParseOptions::default()); for diagnostic in root.diagnostics() { let mut write = biome_diagnostics::termcolor::Buffer::no_color(); let error = diagnostic @@ -413,7 +413,7 @@ pub fn quick_test() { let root = parse( code, JsFileSource::ts(), - JsParserOptions::default().with_parse_class_parameter_decorators(), + JsParseOptions::default().with_parse_class_parameter_decorators(), ); let syntax = root.syntax(); dbg!(&syntax, root.diagnostics(), root.has_errors()); diff --git a/crates/biome_js_semantic/src/events.rs b/crates/biome_js_semantic/src/events.rs index e65cb579a20b..622d5b6fa560 100644 --- a/crates/biome_js_semantic/src/events.rs +++ b/crates/biome_js_semantic/src/events.rs @@ -130,7 +130,7 @@ impl SemanticEvent { /// use biome_js_parser::*; /// use biome_js_syntax::*; /// use biome_js_semantic::*; -/// let tree = parse("let a = 1", JsFileSource::js_script(), JsParserOptions::default()); +/// let tree = parse("let a = 1", JsFileSource::js_script(), JsParseOptions::default()); /// let mut extractor = SemanticEventExtractor::default(); /// for e in tree.syntax().preorder() { /// match e { @@ -1071,7 +1071,7 @@ impl Iterator for SemanticEventIterator { /// use biome_js_parser::*; /// use biome_js_syntax::*; /// use biome_js_semantic::*; -/// let tree = parse("let a = 1", JsFileSource::js_script(), JsParserOptions::default()); +/// let tree = parse("let a = 1", JsFileSource::js_script(), JsParseOptions::default()); /// for e in semantic_events(tree.syntax()) { /// dbg!(e); /// } diff --git a/crates/biome_js_semantic/src/semantic_model/closure.rs b/crates/biome_js_semantic/src/semantic_model/closure.rs index 646b3f2455ef..9e5503ab2448 100644 --- a/crates/biome_js_semantic/src/semantic_model/closure.rs +++ b/crates/biome_js_semantic/src/semantic_model/closure.rs @@ -338,12 +338,12 @@ impl ClosureExtensions for T {} #[cfg(test)] mod test { use super::*; - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsArrowFunctionExpression, JsFileSource, JsSyntaxKind}; use biome_rowan::SyntaxNodeCast; fn assert_closure(code: &str, name: &str, captures: &[&str]) { - let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParserOptions::default()); + let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let closure = if name != "ARROWFUNCTION" { @@ -386,7 +386,7 @@ mod test { } fn get_closure_children(code: &str, name: &str) -> Vec { - let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParserOptions::default()); + let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let closure = if name != "ARROWFUNCTION" { diff --git a/crates/biome_js_semantic/src/semantic_model/is_constant.rs b/crates/biome_js_semantic/src/semantic_model/is_constant.rs index d691c2b0989d..7131cab45eb4 100644 --- a/crates/biome_js_semantic/src/semantic_model/is_constant.rs +++ b/crates/biome_js_semantic/src/semantic_model/is_constant.rs @@ -12,7 +12,7 @@ pub fn is_constant(expr: &AnyJsExpression) -> bool { #[cfg(test)] mod tests { - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsFileSource, JsIdentifierBinding, JsVariableDeclarator}; use crate::{semantic_model, SemanticModelOptions}; @@ -20,7 +20,7 @@ mod tests { fn assert_is_const(code: &str, is_const: bool) { use biome_rowan::AstNode; use biome_rowan::SyntaxNodeCast; - let r = biome_js_parser::parse(code, JsFileSource::js_module(), JsParserOptions::default()); + let r = biome_js_parser::parse(code, JsFileSource::js_module(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let a_reference = r diff --git a/crates/biome_js_semantic/src/semantic_model/model.rs b/crates/biome_js_semantic/src/semantic_model/model.rs index 048c040233e8..de0fd4a05671 100644 --- a/crates/biome_js_semantic/src/semantic_model/model.rs +++ b/crates/biome_js_semantic/src/semantic_model/model.rs @@ -194,12 +194,12 @@ impl SemanticModel { /// Can also be called from [AstNode]::scope extension method. /// /// ```rust - /// use biome_js_parser::JsParserOptions; + /// use biome_js_parser::JsParseOptions; /// use biome_rowan::{AstNode, SyntaxNodeCast}; /// use biome_js_syntax::{JsFileSource, JsReferenceIdentifier}; /// use biome_js_semantic::{semantic_model, SemanticModelOptions, SemanticScopeExtensions}; /// - /// let r = biome_js_parser::parse("function f(){let a = arguments[0]; let b = a + 1;}", JsFileSource::js_module(), JsParserOptions::default()); + /// let r = biome_js_parser::parse("function f(){let a = arguments[0]; let b = a + 1;}", JsFileSource::js_module(), JsParseOptions::default()); /// let model = semantic_model(&r.tree(), SemanticModelOptions::default()); /// /// let arguments_reference = r @@ -248,12 +248,12 @@ impl SemanticModel { /// Can also be called from "binding" extension method. /// /// ```rust - /// use biome_js_parser::JsParserOptions; + /// use biome_js_parser::JsParseOptions; /// use biome_rowan::{AstNode, SyntaxNodeCast}; /// use biome_js_syntax::{JsFileSource, JsReferenceIdentifier}; /// use biome_js_semantic::{semantic_model, BindingExtensions, SemanticModelOptions}; /// - /// let r = biome_js_parser::parse("function f(){let a = arguments[0]; let b = a + 1;}", JsFileSource::js_module(), JsParserOptions::default()); + /// let r = biome_js_parser::parse("function f(){let a = arguments[0]; let b = a + 1;}", JsFileSource::js_module(), JsParseOptions::default()); /// let model = semantic_model(&r.tree(), SemanticModelOptions::default()); /// /// let arguments_reference = r @@ -401,12 +401,12 @@ impl SemanticModel { /// Returns all [FunctionCall] of a [AnyJsFunction]. /// /// ```rust - /// use biome_js_parser::JsParserOptions; + /// use biome_js_parser::JsParseOptions; /// use biome_rowan::{AstNode, SyntaxNodeCast}; /// use biome_js_syntax::{JsFileSource, AnyJsFunction}; /// use biome_js_semantic::{semantic_model, CallsExtensions, SemanticModelOptions}; /// - /// let r = biome_js_parser::parse("function f(){} f() f()", JsFileSource::js_module(), JsParserOptions::default()); + /// let r = biome_js_parser::parse("function f(){} f() f()", JsFileSource::js_module(), JsParseOptions::default()); /// let model = semantic_model(&r.tree(), SemanticModelOptions::default()); /// /// let f_declaration = r diff --git a/crates/biome_js_semantic/src/semantic_model/tests.rs b/crates/biome_js_semantic/src/semantic_model/tests.rs index 56712829d901..f8d9fbc51083 100644 --- a/crates/biome_js_semantic/src/semantic_model/tests.rs +++ b/crates/biome_js_semantic/src/semantic_model/tests.rs @@ -4,7 +4,7 @@ mod test { semantic_model, BindingExtensions, CanBeImportedExported, SemanticModelOptions, SemanticScopeExtensions, }; - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_js_syntax::{ JsFileSource, JsIdentifierAssignment, JsIdentifierBinding, JsReferenceIdentifier, JsSyntaxKind, TsIdentifierBinding, @@ -16,7 +16,7 @@ mod test { let r = biome_js_parser::parse( "function f(){let a = arguments[0]; let b = a + 1; b = 2; console.log(b)}", JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); @@ -120,7 +120,7 @@ mod test { let r = biome_js_parser::parse( "function f() {} function g() {}", JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); @@ -159,7 +159,7 @@ mod test { /// Finds the last time a token named "name" is used and see if its node is marked as exported fn assert_is_exported(is_exported: bool, name: &str, code: &str) { - let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParserOptions::default()); + let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParseOptions::default()); let model = semantic_model(&r.tree(), SemanticModelOptions::default()); let node = r @@ -258,7 +258,7 @@ mod test { let r = biome_js_parser::parse( "console.log()", JsFileSource::js_module(), - JsParserOptions::default(), + JsParseOptions::default(), ); let mut options = SemanticModelOptions::default(); diff --git a/crates/biome_js_semantic/src/tests/assertions.rs b/crates/biome_js_semantic/src/tests/assertions.rs index 0a39654ded5a..b61e0048f78f 100644 --- a/crates/biome_js_semantic/src/tests/assertions.rs +++ b/crates/biome_js_semantic/src/tests/assertions.rs @@ -4,7 +4,7 @@ use biome_diagnostics::location::AsSpan; use biome_diagnostics::{ Advices, Diagnostic, DiagnosticExt, Location, LogCategory, PrintDiagnostic, Visit, }; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{AnyJsRoot, JsFileSource, JsSyntaxToken, TextRange, TextSize, WalkEvent}; use biome_rowan::{AstNode, NodeOrToken}; use rustc_hash::FxHashMap; @@ -106,7 +106,7 @@ use std::collections::BTreeMap; /// if(true) ;/*NOEVENT*/; /// ``` pub fn assert(code: &str, test_name: &str) { - let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParserOptions::default()); + let r = biome_js_parser::parse(code, JsFileSource::tsx(), JsParseOptions::default()); if r.has_errors() { let mut console = EnvConsole::default(); diff --git a/crates/biome_js_syntax/src/expr_ext.rs b/crates/biome_js_syntax/src/expr_ext.rs index 3afab340e8c8..3ef468531a13 100644 --- a/crates/biome_js_syntax/src/expr_ext.rs +++ b/crates/biome_js_syntax/src/expr_ext.rs @@ -1987,11 +1987,11 @@ pub fn is_in_boolean_context(node: &JsSyntaxNode) -> Option { mod test { use biome_js_factory::syntax::{JsCallExpression, JsTemplateExpression}; use biome_js_parser::parse_module; - use biome_js_parser::JsParserOptions; + use biome_js_parser::JsParseOptions; use biome_rowan::AstNodeList; fn extract_call_expression(src: &str) -> JsCallExpression { - let result = parse_module(src, JsParserOptions::default()); + let result = parse_module(src, JsParseOptions::default()); let module = result.tree().items().first().unwrap(); module @@ -2007,7 +2007,7 @@ mod test { } fn extract_template(src: &str) -> JsTemplateExpression { - let result = parse_module(src, JsParserOptions::default()); + let result = parse_module(src, JsParseOptions::default()); let module = result.tree().items().first().unwrap(); module diff --git a/crates/biome_js_transform/src/lib.rs b/crates/biome_js_transform/src/lib.rs index 8090aae12cc0..49cb56d83e41 100644 --- a/crates/biome_js_transform/src/lib.rs +++ b/crates/biome_js_transform/src/lib.rs @@ -121,7 +121,7 @@ pub(crate) type JsBatchMutation = BatchMutation; #[cfg(test)] mod tests { use biome_analyze::{AnalyzerOptions, Never, RuleCategoriesBuilder, RuleFilter}; - use biome_js_parser::{parse, JsParserOptions}; + use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; use std::slice; @@ -132,7 +132,7 @@ mod tests { fn quick_test() { const SOURCE: &str = r#"enum Foo { Lorem, Ipsum }"#; - let parsed = parse(SOURCE, JsFileSource::tsx(), JsParserOptions::default()); + let parsed = parse(SOURCE, JsFileSource::tsx(), JsParseOptions::default()); let options = AnalyzerOptions::default(); let rule_filter = RuleFilter::Rule("transformations", "transformEnum"); diff --git a/crates/biome_js_transform/tests/spec_tests.rs b/crates/biome_js_transform/tests/spec_tests.rs index 97faa0c3f200..6003b7d3773f 100644 --- a/crates/biome_js_transform/tests/spec_tests.rs +++ b/crates/biome_js_transform/tests/spec_tests.rs @@ -1,7 +1,7 @@ use biome_analyze::{AnalysisFilter, AnalyzerTransformation, ControlFlow, Never, RuleFilter}; use biome_js_formatter::context::JsFormatOptions; use biome_js_formatter::format_node; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_rowan::AstNode; use biome_test_utils::{ @@ -53,7 +53,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { filter, file_name, input_file, - JsParserOptions::default(), + JsParseOptions::default(), ); } @@ -69,7 +69,7 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { filter, file_name, input_file, - JsParserOptions::default(), + JsParseOptions::default(), ) }; @@ -93,9 +93,9 @@ pub(crate) fn analyze_and_snap( filter: AnalysisFilter, file_name: &str, input_file: &Path, - parser_options: JsParserOptions, + parse_options: JsParseOptions, ) -> usize { - let parsed = parse(input_code, source_type, parser_options.clone()); + let parsed = parse(input_code, source_type, parse_options.clone()); let root = parsed.tree(); let mut diagnostics = Vec::new(); @@ -110,7 +110,7 @@ pub(crate) fn analyze_and_snap( input_code, source_type, &transformation, - parser_options.clone(), + parse_options.clone(), ); let node = transformation.mutation.commit(); @@ -140,7 +140,7 @@ fn check_transformation( source: &str, source_type: JsFileSource, transformation: &AnalyzerTransformation, - options: JsParserOptions, + options: JsParseOptions, ) { let (new_tree, text_edit) = match transformation .mutation diff --git a/crates/biome_json_analyze/src/lib.rs b/crates/biome_json_analyze/src/lib.rs index 1ac1c604bfeb..766787265fce 100644 --- a/crates/biome_json_analyze/src/lib.rs +++ b/crates/biome_json_analyze/src/lib.rs @@ -113,7 +113,7 @@ mod tests { use biome_console::{markup, Markup}; use biome_diagnostics::termcolor::NoColor; use biome_diagnostics::{Diagnostic, DiagnosticExt, PrintDiagnostic, Severity}; - use biome_json_parser::{parse_json, JsonParserOptions}; + use biome_json_parser::{parse_json, JsonParseOptions}; use biome_json_syntax::{JsonFileSource, TextRange}; use std::slice; @@ -138,7 +138,7 @@ mod tests { } "#; - let parsed = parse_json(SOURCE, JsonParserOptions::default()); + let parsed = parse_json(SOURCE, JsonParseOptions::default()); let mut error_ranges: Vec = Vec::new(); let rule_filter = RuleFilter::Rule("nursery", "noDuplicateJsonKeys"); diff --git a/crates/biome_json_analyze/tests/spec_tests.rs b/crates/biome_json_analyze/tests/spec_tests.rs index 23fb3560f070..d39932368b2c 100644 --- a/crates/biome_json_analyze/tests/spec_tests.rs +++ b/crates/biome_json_analyze/tests/spec_tests.rs @@ -1,7 +1,7 @@ use biome_analyze::{AnalysisFilter, AnalyzerAction, ControlFlow, Never, RuleFilter}; use biome_diagnostics::advice::CodeSuggestionAdvice; use biome_diagnostics::{DiagnosticExt, Severity}; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use biome_json_syntax::{JsonFileSource, JsonLanguage}; use biome_rowan::AstNode; use biome_test_utils::{ @@ -78,7 +78,7 @@ pub(crate) fn analyze_and_snap( file_name: &str, input_file: &Path, ) -> usize { - let parsed = parse_json(input_code, JsonParserOptions::default()); + let parsed = parse_json(input_code, JsonParseOptions::default()); let root = parsed.tree(); let mut diagnostics = Vec::new(); @@ -149,6 +149,6 @@ fn check_code_action(path: &Path, source: &str, action: &AnalyzerAction AnyParse { - parse_json(text, JsonParserOptions::default().with_allow_comments()).into() + parse_json(text, JsonParseOptions::default().with_allow_comments()).into() } fn to_format_language( diff --git a/crates/biome_json_formatter/tests/quick_test.rs b/crates/biome_json_formatter/tests/quick_test.rs index 6b1253f4539a..9224a5b6271a 100644 --- a/crates/biome_json_formatter/tests/quick_test.rs +++ b/crates/biome_json_formatter/tests/quick_test.rs @@ -1,7 +1,7 @@ use biome_formatter_test::check_reformat::CheckReformat; use biome_json_formatter::format_node; use biome_json_formatter::{context::JsonFormatOptions, JsonFormatLanguage}; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; mod language { include!("language.rs"); @@ -15,7 +15,7 @@ fn quick_test() { // comment { "test": "test"} /** comment **/ "#; - let parse = parse_json(src, JsonParserOptions::default().with_allow_comments()); + let parse = parse_json(src, JsonParseOptions::default().with_allow_comments()); let options = JsonFormatOptions::default(); let result = format_node(options.clone(), &parse.syntax()) .unwrap() diff --git a/crates/biome_json_parser/src/lexer/mod.rs b/crates/biome_json_parser/src/lexer/mod.rs index ea5656ab1e01..ae327c35ee34 100644 --- a/crates/biome_json_parser/src/lexer/mod.rs +++ b/crates/biome_json_parser/src/lexer/mod.rs @@ -10,7 +10,7 @@ use std::iter::FusedIterator; use std::ops::Add; use unicode_bom::Bom; -use crate::JsonParserOptions; +use crate::JsonParseOptions; pub struct Token { kind: JsonSyntaxKind, @@ -37,7 +37,7 @@ pub(crate) struct Lexer<'src> { position: usize, diagnostics: Vec, - options: JsonParserOptions, + options: JsonParseOptions, } impl<'src> Lexer<'src> { @@ -47,7 +47,7 @@ impl<'src> Lexer<'src> { source: string, position: 0, diagnostics: vec![], - options: JsonParserOptions::default(), + options: JsonParseOptions::default(), } } @@ -790,7 +790,7 @@ impl<'src> Lexer<'src> { } } - pub(crate) fn with_options(mut self, options: JsonParserOptions) -> Self { + pub(crate) fn with_options(mut self, options: JsonParseOptions) -> Self { self.options = options; self } diff --git a/crates/biome_json_parser/src/lib.rs b/crates/biome_json_parser/src/lib.rs index c1df88182aa0..9094ae4d2a85 100644 --- a/crates/biome_json_parser/src/lib.rs +++ b/crates/biome_json_parser/src/lib.rs @@ -7,7 +7,7 @@ use biome_json_syntax::{JsonLanguage, JsonRoot, JsonSyntaxNode}; pub use biome_parser::prelude::*; use biome_parser::{tree_sink::LosslessTreeSink, AnyParse}; use biome_rowan::{AstNode, NodeCache}; -pub use parser::JsonParserOptions; +pub use parser::JsonParseOptions; mod lexer; mod parser; @@ -18,7 +18,7 @@ mod token_source; pub(crate) type JsonLosslessTreeSink<'source> = LosslessTreeSink<'source, JsonLanguage, JsonSyntaxFactory>; -pub fn parse_json(source: &str, options: JsonParserOptions) -> JsonParse { +pub fn parse_json(source: &str, options: JsonParseOptions) -> JsonParse { let mut cache = NodeCache::default(); parse_json_with_cache(source, &mut cache, options) } @@ -27,7 +27,7 @@ pub fn parse_json(source: &str, options: JsonParserOptions) -> JsonParse { pub fn parse_json_with_cache( source: &str, cache: &mut NodeCache, - config: JsonParserOptions, + config: JsonParseOptions, ) -> JsonParse { tracing::debug_span!("parse").in_scope(move || { let mut parser = JsonParser::new(source, config); @@ -65,8 +65,8 @@ impl JsonParse { /// /// # fn main() -> Result<(), SyntaxError> { /// use biome_json_syntax::JsonSyntaxKind; - /// use biome_json_parser::JsonParserOptions; - /// let parse = parse_json(r#"["a", 1]"#, JsonParserOptions::default()); + /// use biome_json_parser::JsonParseOptions; + /// let parse = parse_json(r#"["a", 1]"#, JsonParseOptions::default()); /// /// // Get the root value /// let root_value = parse.tree().value()?; diff --git a/crates/biome_json_parser/src/parser.rs b/crates/biome_json_parser/src/parser.rs index 04e92e97d732..e95276b2e844 100644 --- a/crates/biome_json_parser/src/parser.rs +++ b/crates/biome_json_parser/src/parser.rs @@ -9,16 +9,16 @@ use biome_parser::ParserContext; pub(crate) struct JsonParser<'source> { context: ParserContext, source: JsonTokenSource<'source>, - options: JsonParserOptions, + options: JsonParseOptions, } #[derive(Default, Debug, Clone, Copy)] -pub struct JsonParserOptions { +pub struct JsonParseOptions { pub allow_comments: bool, pub allow_trailing_commas: bool, } -impl JsonParserOptions { +impl JsonParseOptions { pub fn with_allow_comments(mut self) -> Self { self.allow_comments = true; self @@ -30,7 +30,7 @@ impl JsonParserOptions { } } -impl From<&JsonFileSource> for JsonParserOptions { +impl From<&JsonFileSource> for JsonParseOptions { fn from(file_source: &JsonFileSource) -> Self { let options = Self::default(); if file_source.allow_comments() { @@ -44,7 +44,7 @@ impl From<&JsonFileSource> for JsonParserOptions { } impl<'source> JsonParser<'source> { - pub fn new(source: &'source str, options: JsonParserOptions) -> Self { + pub fn new(source: &'source str, options: JsonParseOptions) -> Self { Self { context: ParserContext::default(), source: JsonTokenSource::from_str(source, options), @@ -67,7 +67,7 @@ impl<'source> JsonParser<'source> { (events, diagnostics, trivia) } - pub fn options(&self) -> &JsonParserOptions { + pub fn options(&self) -> &JsonParseOptions { &self.options } } diff --git a/crates/biome_json_parser/src/token_source.rs b/crates/biome_json_parser/src/token_source.rs index 00aa8a524f89..719d00b0b8f2 100644 --- a/crates/biome_json_parser/src/token_source.rs +++ b/crates/biome_json_parser/src/token_source.rs @@ -1,5 +1,5 @@ use crate::lexer::{Lexer, Token}; -use crate::JsonParserOptions; +use crate::JsonParseOptions; use biome_json_syntax::JsonSyntaxKind::{EOF, TOMBSTONE}; use biome_json_syntax::{JsonSyntaxKind, TextRange}; use biome_parser::diagnostic::ParseDiagnostic; @@ -13,11 +13,11 @@ pub(crate) struct JsonTokenSource<'source> { current: JsonSyntaxKind, current_range: TextRange, preceding_line_break: bool, - options: JsonParserOptions, + options: JsonParseOptions, } impl<'source> JsonTokenSource<'source> { - pub fn from_str(source: &'source str, options: JsonParserOptions) -> Self { + pub fn from_str(source: &'source str, options: JsonParseOptions) -> Self { let lexer = Lexer::from_str(source).with_options(options); let mut source = Self { diff --git a/crates/biome_json_parser/tests/spec_test.rs b/crates/biome_json_parser/tests/spec_test.rs index ddb1e428cba4..c372ab6e23de 100644 --- a/crates/biome_json_parser/tests/spec_test.rs +++ b/crates/biome_json_parser/tests/spec_test.rs @@ -3,7 +3,7 @@ use biome_console::markup; use biome_diagnostics::display::PrintDiagnostic; use biome_diagnostics::termcolor; use biome_diagnostics::DiagnosticExt; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use biome_rowan::SyntaxKind; use std::fmt::Write; use std::fs; @@ -35,7 +35,7 @@ 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_config = JsonParserOptions { + let parse_config = JsonParseOptions { allow_comments: test_directory.contains("allow_comments"), allow_trailing_commas: test_directory.contains("allow_trailing_commas"), }; diff --git a/crates/biome_lsp/src/session.rs b/crates/biome_lsp/src/session.rs index 9c2b845eed0c..813f6b9de5d6 100644 --- a/crates/biome_lsp/src/session.rs +++ b/crates/biome_lsp/src/session.rs @@ -9,9 +9,7 @@ use biome_configuration::ConfigurationPathHint; use biome_console::markup; use biome_diagnostics::PrintDescription; use biome_fs::{BiomePath, FileSystem}; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; +use biome_service::configuration::{load_configuration, ConfigurationExt, LoadedConfiguration}; use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler}; use biome_service::workspace::{ FeaturesBuilder, GetFileContentParams, OpenProjectParams, PullDiagnosticsParams, diff --git a/crates/biome_migrate/src/lib.rs b/crates/biome_migrate/src/lib.rs index 2367b5506b0c..1099edd6a98e 100644 --- a/crates/biome_migrate/src/lib.rs +++ b/crates/biome_migrate/src/lib.rs @@ -131,7 +131,7 @@ mod test { use biome_console::{markup, Markup}; use biome_diagnostics::termcolor::NoColor; use biome_diagnostics::{DiagnosticExt, PrintDiagnostic, Severity}; - use biome_json_parser::{parse_json, JsonParserOptions}; + use biome_json_parser::{parse_json, JsonParseOptions}; use std::path::Path; fn markup_to_string(markup: Markup) -> String { @@ -168,7 +168,7 @@ mod test { } "#; - let parsed = parse_json(source, JsonParserOptions::default()); + let parsed = parse_json(source, JsonParseOptions::default()); migrate_configuration( &parsed.tree(), diff --git a/crates/biome_migrate/tests/spec_tests.rs b/crates/biome_migrate/tests/spec_tests.rs index 8efce878780f..b7fd204e5632 100644 --- a/crates/biome_migrate/tests/spec_tests.rs +++ b/crates/biome_migrate/tests/spec_tests.rs @@ -1,7 +1,7 @@ use biome_analyze::{AnalyzerAction, ControlFlow, Never}; use biome_diagnostics::advice::CodeSuggestionAdvice; use biome_diagnostics::{DiagnosticExt, Severity}; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use biome_json_syntax::JsonLanguage; use biome_rowan::AstNode; use biome_test_utils::{ @@ -54,7 +54,7 @@ pub(crate) fn analyze_and_snap( file_name: &str, input_file: &Path, ) -> usize { - let parsed = parse_json(input_code, JsonParserOptions::default()); + let parsed = parse_json(input_code, JsonParseOptions::default()); let root = parsed.tree(); let mut diagnostics = Vec::new(); @@ -125,6 +125,6 @@ fn check_code_action(path: &Path, source: &str, action: &AnalyzerAction { - let parsed = parse_json(input_code.as_str(), JsonParserOptions::default()); + let parsed = parse_json(input_code.as_str(), JsonParseOptions::default()); project.from_root(&parsed.tree()); } _ => { diff --git a/crates/biome_service/src/configuration.rs b/crates/biome_service/src/configuration.rs index 60b7c9611c42..998893405c74 100644 --- a/crates/biome_service/src/configuration.rs +++ b/crates/biome_service/src/configuration.rs @@ -4,8 +4,8 @@ use crate::{DynRef, WorkspaceError, VERSION}; use biome_analyze::AnalyzerRules; use biome_configuration::diagnostics::{CantLoadExtendFile, EditorConfigDiagnostic}; use biome_configuration::{ - push_to_analyzer_rules, BiomeDiagnostic, ConfigurationPathHint, ConfigurationPayload, - PartialConfiguration, + push_to_analyzer_rules, BiomeDiagnostic, Configuration, ConfigurationPathHint, + ConfigurationPayload, }; use biome_console::markup; use biome_css_analyze::metadata as css_lint_metadata; @@ -15,7 +15,7 @@ use biome_diagnostics::{DiagnosticExt, Error, Severity}; use biome_fs::{AutoSearchResult, ConfigName, FileSystem, OpenOptions}; use biome_js_analyze::metadata as js_lint_metadata; use biome_json_formatter::context::JsonFormatOptions; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use std::ffi::OsStr; use std::fmt::Debug; use std::io::ErrorKind; @@ -33,7 +33,7 @@ pub struct LoadedConfiguration { /// If present, the path of the file where it was found pub file_path: Option, /// The Deserialized configuration - pub configuration: PartialConfiguration, + pub configuration: Configuration, /// All diagnostics that were emitted during parsing and deserialization pub diagnostics: Vec, } @@ -108,21 +108,21 @@ impl LoadedConfiguration { configuration_file_path, deserialized, } = value; - let (partial_configuration, mut diagnostics) = deserialized.consume(); + let (configuration, mut diagnostics) = deserialized.consume(); Ok(Self { - configuration: match partial_configuration { - Some(mut partial_configuration) => { - partial_configuration.apply_extends( + configuration: match configuration { + Some(mut configuration) => { + configuration.apply_extends( fs, &configuration_file_path, &external_resolution_base_path, &mut diagnostics, )?; - partial_configuration.migrate_deprecated_fields(); - partial_configuration + configuration.migrate_deprecated_fields(); + configuration } - None => PartialConfiguration::default(), + None => Configuration::default(), }, diagnostics: diagnostics .into_iter() @@ -186,14 +186,14 @@ fn load_config( if let ConfigurationPathHint::FromUser(ref configuration_file_path) = base_path { if file_system.path_is_file(configuration_file_path) { let content = file_system.read_file_from_path(configuration_file_path)?; - let parser_options = match configuration_file_path.extension().and_then(OsStr::to_str) { - Some("json") => JsonParserOptions::default(), - _ => JsonParserOptions::default() + let parse_options = match configuration_file_path.extension().and_then(OsStr::to_str) { + Some("json") => JsonParseOptions::default(), + _ => JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), }; let deserialized = - deserialize_from_json_str::(&content, parser_options, ""); + deserialize_from_json_str::(&content, parse_options, ""); return Ok(Some(ConfigurationPayload { deserialized, configuration_file_path: PathBuf::from(configuration_file_path), @@ -239,15 +239,14 @@ fn load_config( } { let AutoSearchResult { content, file_path } = auto_search_result; - let parser_options = match file_path.extension().and_then(OsStr::to_str) { - Some("json") => JsonParserOptions::default(), - _ => JsonParserOptions::default() + let parse_options = match file_path.extension().and_then(OsStr::to_str) { + Some("json") => JsonParseOptions::default(), + _ => JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), }; - let deserialized = - deserialize_from_json_str::(&content, parser_options, ""); + let deserialized = deserialize_from_json_str::(&content, parse_options, ""); Ok(Some(ConfigurationPayload { deserialized, @@ -262,7 +261,7 @@ fn load_config( pub fn load_editorconfig( file_system: &DynRef<'_, dyn FileSystem>, workspace_root: PathBuf, -) -> Result<(Option, Vec), WorkspaceError> { +) -> Result<(Option, Vec), WorkspaceError> { // How .editorconfig is supposed to be resolved: https://editorconfig.org/#file-location // We currently don't support the `root` property, so we just search for the file like we do for biome.json if let Some(auto_search_result) = @@ -311,7 +310,7 @@ pub fn load_editorconfig( /// - the program doesn't have the write rights pub fn create_config( fs: &mut DynRef, - mut configuration: PartialConfiguration, + mut configuration: Configuration, emit_jsonc: bool, ) -> Result<(), WorkspaceError> { let json_path = PathBuf::from(ConfigName::biome_json()); @@ -347,7 +346,7 @@ pub fn create_config( let contents = serde_json::to_string_pretty(&configuration) .map_err(|_| BiomeDiagnostic::new_serialization_error())?; - let parsed = parse_json(&contents, JsonParserOptions::default()); + let parsed = parse_json(&contents, JsonParseOptions::default()); let formatted = biome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax())? .print() @@ -373,7 +372,7 @@ pub fn to_analyzer_rules(settings: &Settings, path: &Path) -> AnalyzerRules { overrides.override_analyzer_rules(path, analyzer_rules) } -pub trait PartialConfigurationExt { +pub trait ConfigurationExt { fn apply_extends( &mut self, fs: &DynRef<'_, dyn FileSystem>, @@ -387,7 +386,7 @@ pub trait PartialConfigurationExt { fs: &DynRef<'_, dyn FileSystem>, relative_resolution_base_path: &Path, external_resolution_base_path: &Path, - ) -> Result>, WorkspaceError>; + ) -> Result>, WorkspaceError>; fn migrate_deprecated_fields(&mut self); @@ -398,7 +397,7 @@ pub trait PartialConfigurationExt { ) -> Result<(Option, Vec), WorkspaceError>; } -impl PartialConfigurationExt for PartialConfiguration { +impl ConfigurationExt for Configuration { /// Mutates the configuration so that any fields that have not been configured explicitly are /// filled in with their values from configs listed in the `extends` field. /// @@ -452,7 +451,7 @@ impl PartialConfigurationExt for PartialConfiguration { fs: &DynRef<'_, dyn FileSystem>, relative_resolution_base_path: &Path, external_resolution_base_path: &Path, - ) -> Result>, WorkspaceError> { + ) -> Result>, WorkspaceError> { let Some(extends) = &self.extends else { return Ok(Vec::new()); }; @@ -507,14 +506,14 @@ impl PartialConfigurationExt for PartialConfiguration { ) })?; - let deserialized = deserialize_from_json_str::( + let deserialized = deserialize_from_json_str::( content.as_str(), match extend_configuration_file_path .extension() .and_then(OsStr::to_str) { - Some("json") => JsonParserOptions::default(), - _ => JsonParserOptions::default() + Some("json") => JsonParseOptions::default(), + _ => JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), }, @@ -580,7 +579,7 @@ impl PartialConfigurationExt for PartialConfiguration { (None, None) => return Err(WorkspaceError::vcs_disabled()), }; if let Some(client_kind) = &vcs.client_kind { - if !vcs.ignore_file_disabled() { + if vcs.should_use_ignore_file() { let result = file_system .auto_search(&vcs_base_path, &[client_kind.ignore_file()], false) .map_err(WorkspaceError::from)?; diff --git a/crates/biome_service/src/file_handlers/astro.rs b/crates/biome_service/src/file_handlers/astro.rs index bab20b8e54dd..e89313160f65 100644 --- a/crates/biome_service/src/file_handlers/astro.rs +++ b/crates/biome_service/src/file_handlers/astro.rs @@ -10,7 +10,7 @@ use crate::workspace::{ use crate::WorkspaceError; use biome_formatter::Printed; use biome_fs::BiomePath; -use biome_js_parser::{parse_js_with_cache, JsParserOptions}; +use biome_js_parser::{parse_js_with_cache, JsParseOptions}; use biome_js_syntax::{JsFileSource, TextRange, TextSize}; use biome_parser::AnyParse; use biome_rowan::NodeCache; @@ -107,7 +107,7 @@ fn parse( file_source .to_js_file_source() .unwrap_or(JsFileSource::ts()), - JsParserOptions::default(), + JsParseOptions::default(), cache, ); diff --git a/crates/biome_service/src/file_handlers/css.rs b/crates/biome_service/src/file_handlers/css.rs index 21abbf24c4bd..141e3f80fef9 100644 --- a/crates/biome_service/src/file_handlers/css.rs +++ b/crates/biome_service/src/file_handlers/css.rs @@ -8,7 +8,7 @@ use crate::file_handlers::{ AnalyzerCapabilities, Capabilities, FormatterCapabilities, ParserCapabilities, }; use crate::settings::{ - FormatSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, + FormatterSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, ServiceLanguage, Settings, WorkspaceSettingsHandle, }; use crate::workspace::{ @@ -21,10 +21,14 @@ use biome_analyze::{ AnalysisFilter, AnalyzerConfiguration, AnalyzerOptions, ControlFlow, Never, RuleCategoriesBuilder, RuleCategory, RuleError, }; +use biome_configuration::bool::Bool; +use biome_configuration::css::{ + AllowWrongLineCommentsEnabled, CssFormatterEnabled, CssLinterEnabled, CssModulesEnabled, +}; use biome_css_analyze::analyze; use biome_css_formatter::context::CssFormatOptions; use biome_css_formatter::format_node; -use biome_css_parser::CssParserOptions; +use biome_css_parser::CssParseOptions; use biome_css_syntax::{CssLanguage, CssRoot, CssSyntaxNode}; use biome_diagnostics::{category, Applicability, Diagnostic, DiagnosticExt, Severity}; use biome_formatter::{ @@ -38,7 +42,14 @@ use biome_rowan::{TextRange, TextSize, TokenAtOffset}; use std::borrow::Cow; use tracing::{debug_span, error, info, trace, trace_span}; -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct CssParserSettings { + pub allow_wrong_line_comments: Option, + pub css_modules: Option, +} + +#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct CssFormatterSettings { pub line_ending: Option, @@ -46,48 +57,39 @@ pub struct CssFormatterSettings { pub indent_width: Option, pub indent_style: Option, pub quote_style: Option, - pub enabled: Option, + pub enabled: Option, } -impl Default for CssFormatterSettings { - fn default() -> Self { - Self { - enabled: Some(false), - indent_style: Default::default(), - indent_width: Default::default(), - line_ending: Default::default(), - line_width: Default::default(), - quote_style: Default::default(), - } +impl CssFormatterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct CssLinterSettings { - pub enabled: Option, + pub enabled: Option, } -// NOTE: we want to make the linter opt-in for now -impl Default for CssLinterSettings { - fn default() -> Self { - Self { - enabled: Some(false), - } +impl CssLinterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } } +pub type CssOrganizeImportsEnabled = Bool; + #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct CssParserSettings { - pub allow_wrong_line_comments: Option, - pub css_modules: Option, +pub struct CssOrganizeImportsSettings { + pub enabled: Option, } impl ServiceLanguage for CssLanguage { type FormatterSettings = CssFormatterSettings; type LinterSettings = CssLinterSettings; - type OrganizeImportsSettings = (); + type OrganizeImportsSettings = CssOrganizeImportsSettings; type FormatOptions = CssFormatOptions; type ParserSettings = CssParserSettings; type EnvironmentSettings = (); @@ -97,7 +99,7 @@ impl ServiceLanguage for CssLanguage { } fn resolve_format_options( - global: Option<&FormatSettings>, + global: Option<&FormatterSettings>, overrides: Option<&OverrideSettings>, language: Option<&Self::FormatterSettings>, path: &BiomePath, @@ -138,7 +140,7 @@ impl ServiceLanguage for CssLanguage { } } - fn resolve_analyzer_options( + fn resolve_analyze_options( global: Option<&Settings>, _linter: Option<&LinterSettings>, _overrides: Option<&OverrideSettings>, @@ -215,19 +217,22 @@ fn parse( settings: Option<&Settings>, cache: &mut NodeCache, ) -> ParseResult { - let mut options = CssParserOptions { + // TODO(zzwu): implement resolve_parser_options + let mut options = CssParseOptions { allow_wrong_line_comments: settings .and_then(|s| s.languages.css.parser.allow_wrong_line_comments) - .unwrap_or_default(), + .unwrap_or_default() + .into(), css_modules: settings .and_then(|s| s.languages.css.parser.css_modules) - .unwrap_or_default(), + .unwrap_or_default() + .into(), grit_metavariable: false, }; if let Some(settings) = settings { options = settings .override_settings - .to_override_css_parser_options(biome_path, options); + .to_override_css_parse_options(biome_path, options); } let parse = biome_css_parser::parse_css_with_cache(text, cache, options); ParseResult { @@ -336,7 +341,7 @@ fn lint(params: LintParams) -> LintResults { move || { let workspace_settings = ¶ms.workspace; let analyzer_options = - workspace_settings.analyzer_options::(params.path, ¶ms.language); + workspace_settings.analyze_options::(params.path, ¶ms.language); let tree = params.parse.tree(); let mut diagnostics = params.parse.into_diagnostics(); @@ -489,13 +494,14 @@ pub(crate) fn code_actions(params: CodeActionsParams) -> PullActionsResult { let mut filter = AnalysisFilter::from_enabled_rules(filter.as_slice()); let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint(); - if settings.organize_imports.enabled { + // TODO(zzwu): take overrides into consideration + if settings.organize_imports.enabled.unwrap_or_default().into() { categories = categories.with_action(); } filter.categories = categories.build(); filter.range = Some(range); - let analyzer_options = workspace.analyzer_options::(path, &language); + let analyzer_options = workspace.analyze_options::(path, &language); let Some(_) = language.to_css_file_source() else { error!("Could not determine the file source of the file"); @@ -564,7 +570,7 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result(biome_path, &document_file_source); + workspace.analyze_options::(biome_path, &document_file_source); loop { let (action, _) = analyze(&tree, filter, &analyzer_options, |signal| { let current_diagnostic = signal.diagnostic(); @@ -661,7 +667,7 @@ mod test { #[test] fn inherit_global_format_settings() { let format_options = CssLanguage::resolve_format_options( - Some(&FormatSettings::default()), + Some(&FormatterSettings::default()), None, None, &BiomePath::new(""), diff --git a/crates/biome_service/src/file_handlers/graphql.rs b/crates/biome_service/src/file_handlers/graphql.rs index 8a01b9fc605b..6fff6a49e3e0 100644 --- a/crates/biome_service/src/file_handlers/graphql.rs +++ b/crates/biome_service/src/file_handlers/graphql.rs @@ -7,7 +7,7 @@ use crate::file_handlers::{ AnalyzerCapabilities, Capabilities, FormatterCapabilities, ParserCapabilities, }; use crate::settings::{ - FormatSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, + FormatterSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, ServiceLanguage, Settings, WorkspaceSettingsHandle, }; use crate::workspace::{ @@ -18,6 +18,7 @@ use biome_analyze::{ AnalysisFilter, AnalyzerConfiguration, AnalyzerOptions, ControlFlow, Never, RuleCategoriesBuilder, RuleCategory, RuleError, }; +use biome_configuration::graphql::{GraphqlFormatterEnabled, GraphqlLinterEnabled}; use biome_diagnostics::{category, Applicability, Diagnostic, DiagnosticExt, Severity}; use biome_formatter::{ BracketSpacing, FormatError, IndentStyle, IndentWidth, LineEnding, LineWidth, Printed, @@ -35,43 +36,27 @@ use biome_rowan::{AstNode, NodeCache, TokenAtOffset}; use std::borrow::Cow; use tracing::{debug_span, error, info, trace, trace_span}; -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct GraphqlFormatterSettings { + pub enabled: Option, pub line_ending: Option, pub line_width: Option, pub indent_width: Option, pub indent_style: Option, pub quote_style: Option, pub bracket_spacing: Option, - pub enabled: Option, } -impl Default for GraphqlFormatterSettings { - fn default() -> Self { - Self { - enabled: Some(false), - indent_style: Default::default(), - indent_width: Default::default(), - line_ending: Default::default(), - line_width: Default::default(), - quote_style: Default::default(), - bracket_spacing: Default::default(), - } - } -} - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct GraphqlLinterSettings { - pub enabled: Option, + pub enabled: Option, } -impl Default for GraphqlLinterSettings { - fn default() -> Self { - Self { - enabled: Some(false), - } +impl GraphqlLinterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() } } @@ -88,7 +73,7 @@ impl ServiceLanguage for GraphqlLanguage { } fn resolve_format_options( - global: Option<&FormatSettings>, + global: Option<&FormatterSettings>, overrides: Option<&OverrideSettings>, language: Option<&Self::FormatterSettings>, path: &BiomePath, @@ -135,7 +120,7 @@ impl ServiceLanguage for GraphqlLanguage { } } - fn resolve_analyzer_options( + fn resolve_analyze_options( _global: Option<&Settings>, _linter: Option<&LinterSettings>, _overrides: Option<&OverrideSettings>, @@ -294,7 +279,7 @@ fn lint(params: LintParams) -> LintResults { move || { let workspace_settings = ¶ms.workspace; let analyzer_options = workspace_settings - .analyzer_options::(params.path, ¶ms.language); + .analyze_options::(params.path, ¶ms.language); let tree = params.parse.tree(); let mut diagnostics = params.parse.into_diagnostics(); @@ -441,13 +426,14 @@ pub(crate) fn code_actions(params: CodeActionsParams) -> PullActionsResult { let mut filter = AnalysisFilter::from_enabled_rules(filter.as_slice()); let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint(); - if settings.organize_imports.enabled { + // TODO(zzwu): take overrides into consideration + if settings.organize_imports.enabled.unwrap_or_default().into() { categories = categories.with_action(); } filter.categories = categories.build(); filter.range = Some(range); - let analyzer_options = workspace.analyzer_options::(path, &language); + let analyzer_options = workspace.analyze_options::(path, &language); let Some(_) = language.to_graphql_file_source() else { error!("Could not determine the file source of the file"); @@ -516,7 +502,7 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result(biome_path, &document_file_source); + workspace.analyze_options::(biome_path, &document_file_source); loop { let (action, _) = analyze(&tree, filter, &analyzer_options, |signal| { let current_diagnostic = signal.diagnostic(); diff --git a/crates/biome_service/src/file_handlers/javascript.rs b/crates/biome_service/src/file_handlers/javascript.rs index 740b6712c19a..17c869cbdd1f 100644 --- a/crates/biome_service/src/file_handlers/javascript.rs +++ b/crates/biome_service/src/file_handlers/javascript.rs @@ -10,7 +10,7 @@ use crate::settings::{LinterSettings, OverrideSettings, Settings}; use crate::workspace::{DocumentFileSource, OrganizeImportsResult}; use crate::{ settings::{ - FormatSettings, LanguageListSettings, LanguageSettings, ServiceLanguage, + FormatterSettings, LanguageListSettings, LanguageSettings, ServiceLanguage, WorkspaceSettingsHandle, }, workspace::{ @@ -25,7 +25,10 @@ use biome_analyze::{ QueryMatch, Queryable, RegistryVisitor, RuleCategoriesBuilder, RuleCategory, RuleError, RuleFilter, RuleGroup, }; -use biome_configuration::javascript::JsxRuntime; +use biome_configuration::bool::Bool; +use biome_configuration::javascript::{ + JsFormatterEnabled, JsLinterEnabled, JsxRuntime, UnsafeParameterDecoratorsEnabled, +}; use biome_diagnostics::{category, Applicability, Diagnostic, DiagnosticExt, Severity}; use biome_formatter::{ AttributePosition, BracketSpacing, FormatError, IndentStyle, IndentWidth, LineEnding, @@ -39,7 +42,7 @@ use biome_js_formatter::context::{ ArrowParentheses, BracketSameLine, JsFormatOptions, QuoteProperties, Semicolons, }; use biome_js_formatter::format_node; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_semantic::{semantic_model, SemanticModelOptions}; use biome_js_syntax::{ AnyJsRoot, JsFileSource, JsLanguage, JsSyntaxNode, TextRange, TextSize, TokenAtOffset, @@ -67,35 +70,53 @@ pub struct JsFormatterSettings { pub line_width: Option, pub indent_width: Option, pub indent_style: Option, - pub enabled: Option, + pub enabled: Option, pub attribute_position: Option, } +impl JsFormatterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() + } +} + #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsParserSettings { - pub parse_class_parameter_decorators: bool, + pub parse_class_parameter_decorators: Option, } #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsLinterSettings { - pub enabled: Option, + pub enabled: Option, } +impl JsLinterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() + } +} + +pub type JsOrganizeImportsEnabled = Bool; + #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct JsOrganizeImportsSettings {} +pub struct JsOrganizeImportsSettings { + pub enabled: Option, +} #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsEnvironmentSettings { - pub jsx_runtime: JsxRuntime, + pub jsx_runtime: Option, } impl From for JsEnvironmentSettings { fn from(jsx_runtime: JsxRuntime) -> Self { - Self { jsx_runtime } + Self { + jsx_runtime: Some(jsx_runtime), + } } } @@ -112,7 +133,7 @@ impl ServiceLanguage for JsLanguage { } fn resolve_format_options( - global: Option<&FormatSettings>, + global: Option<&FormatterSettings>, overrides: Option<&OverrideSettings>, language: Option<&JsFormatterSettings>, path: &BiomePath, @@ -181,13 +202,13 @@ impl ServiceLanguage for JsLanguage { ); if let Some(overrides) = overrides { - overrides.override_js_format_options(path, options) + overrides.to_override_js_format_options(path, options) } else { options } } - fn resolve_analyzer_options( + fn resolve_analyze_options( global: Option<&Settings>, _linter: Option<&LinterSettings>, overrides: Option<&OverrideSettings>, @@ -215,9 +236,10 @@ impl ServiceLanguage for JsLanguage { if let (Some(overrides), Some(global)) = (overrides, global) { jsx_runtime = Some( - match overrides - .override_jsx_runtime(path, global.languages.javascript.environment.jsx_runtime) - { + match overrides.to_override_jsx_runtime( + path, + global.languages.javascript.environment.jsx_runtime, + ) { // In the future, we may wish to map an `Auto` variant to a concrete // analyzer value for easy access by the analyzer. JsxRuntime::Transparent => biome_analyze::options::JsxRuntime::Transparent, @@ -227,7 +249,7 @@ impl ServiceLanguage for JsLanguage { globals.extend( overrides - .override_js_globals(path, &global.languages.javascript.globals) + .to_override_js_globals(path, &global.languages.javascript.globals) .into_iter() .collect::>(), ); @@ -308,21 +330,23 @@ fn parse( settings: Option<&Settings>, cache: &mut NodeCache, ) -> ParseResult { - let mut options = JsParserOptions { + let mut options = JsParseOptions { + // TODO(zzwu): implement resolve_parse_options parse_class_parameter_decorators: settings - .map(|settings| { + .and_then(|settings| { settings .languages .javascript .parser .parse_class_parameter_decorators }) - .unwrap_or_default(), + .unwrap_or_default() + .into(), }; if let Some(settings) = settings { options = settings .override_settings - .to_override_js_parser_options(biome_path, options); + .to_override_js_parse_options(biome_path, options); } let file_source = file_source.to_js_file_source().unwrap_or_default(); @@ -419,14 +443,16 @@ pub(crate) fn lint(params: LintParams) -> LintResults { let mut diagnostics = params.parse.into_diagnostics(); let analyzer_options = ¶ms .workspace - .analyzer_options::(params.path, ¶ms.language); + .analyze_options::(params.path, ¶ms.language); let mut rules = None; let mut organize_imports_enabled = true; if let Some(settings) = params.workspace.settings() { // Compute final rules (taking `overrides` into account) rules = settings.as_rules(params.path.as_path()); - organize_imports_enabled = settings.organize_imports.enabled; + // TODO(zzwu): better way to handle overrides? + organize_imports_enabled = + settings.organize_imports.enabled.unwrap_or_default().into(); } let has_only_filter = !params.only.is_empty(); @@ -586,11 +612,11 @@ pub(crate) fn code_actions(params: CodeActionsParams) -> PullActionsResult { let tree = parse.tree(); trace_span!("Parsed file", tree =? tree).in_scope(move || { let analyzer_options = - workspace.analyzer_options::(params.path, ¶ms.language); + workspace.analyze_options::(params.path, ¶ms.language); let rules = settings.as_rules(params.path); let mut actions = Vec::new(); let mut enabled_rules = vec![]; - if settings.organize_imports.enabled { + if settings.organize_imports.enabled.unwrap_or_default().into() { enabled_rules.push(RuleFilter::Rule("correctness", "organizeImports")); } if let Some(rules) = rules.as_ref() { @@ -613,7 +639,7 @@ pub(crate) fn code_actions(params: CodeActionsParams) -> PullActionsResult { }; let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint(); - if settings.organize_imports.enabled { + if settings.organize_imports.enabled.unwrap_or_default().into() { categories = categories.with_action(); } filter.categories = categories.build(); @@ -703,7 +729,7 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result(biome_path, &document_file_source); + workspace.analyze_options::(biome_path, &document_file_source); loop { let (action, _) = analyze( &tree, diff --git a/crates/biome_service/src/file_handlers/json.rs b/crates/biome_service/src/file_handlers/json.rs index 07bf6afa860e..9a394e1b9f08 100644 --- a/crates/biome_service/src/file_handlers/json.rs +++ b/crates/biome_service/src/file_handlers/json.rs @@ -12,7 +12,7 @@ use crate::file_handlers::{ LintResults, ParserCapabilities, }; use crate::settings::{ - FormatSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, + FormatterSettings, LanguageListSettings, LanguageSettings, LinterSettings, OverrideSettings, ServiceLanguage, Settings, WorkspaceSettingsHandle, }; use crate::workspace::{ @@ -24,7 +24,11 @@ use biome_analyze::{ AnalysisFilter, AnalyzerConfiguration, AnalyzerOptions, ControlFlow, GroupCategory, Never, Queryable, RegistryVisitor, RuleCategoriesBuilder, RuleCategory, RuleFilter, RuleGroup, }; -use biome_configuration::PartialConfiguration; +use biome_configuration::bool::Bool; +use biome_configuration::json::{ + AllowCommentsEnabled, AllowTrailingCommasEnabled, JsonFormatterEnabled, JsonLinterEnabled, +}; +use biome_configuration::Configuration; use biome_deserialize::json::deserialize_from_json_ast; use biome_diagnostics::{category, Diagnostic, DiagnosticExt, Severity}; use biome_formatter::{FormatError, IndentStyle, IndentWidth, LineEnding, LineWidth, Printed}; @@ -33,7 +37,7 @@ use biome_json_analyze::analyze; use biome_json_analyze::visit_registry; use biome_json_formatter::context::{JsonFormatOptions, TrailingCommas}; use biome_json_formatter::format_node; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_json_syntax::{JsonFileSource, JsonLanguage, JsonRoot, JsonSyntaxNode}; use biome_parser::AnyParse; use biome_rowan::{AstNode, NodeCache}; @@ -48,26 +52,46 @@ pub struct JsonFormatterSettings { pub indent_width: Option, pub indent_style: Option, pub trailing_commas: Option, - pub enabled: Option, + pub enabled: Option, +} + +impl JsonFormatterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() + } } #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsonParserSettings { - pub allow_comments: Option, - pub allow_trailing_commas: Option, + pub allow_comments: Option, + pub allow_trailing_commas: Option, } #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct JsonLinterSettings { - pub enabled: Option, + pub enabled: Option, +} + +impl JsonLinterSettings { + pub fn is_enabled(&self) -> bool { + self.enabled.unwrap_or_default().into() + } +} + +pub type JsonOrganizeImportsEnabled = Bool; + +#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct JsonOrganizeImportsSettings { + pub enabled: Option, } impl ServiceLanguage for JsonLanguage { type FormatterSettings = JsonFormatterSettings; type LinterSettings = JsonLinterSettings; - type OrganizeImportsSettings = (); + type OrganizeImportsSettings = JsonOrganizeImportsSettings; type FormatOptions = JsonFormatOptions; type ParserSettings = JsonParserSettings; type EnvironmentSettings = (); @@ -77,7 +101,7 @@ impl ServiceLanguage for JsonLanguage { } fn resolve_format_options( - global: Option<&FormatSettings>, + global: Option<&FormatterSettings>, overrides: Option<&OverrideSettings>, language: Option<&JsonFormatterSettings>, path: &BiomePath, @@ -123,7 +147,7 @@ impl ServiceLanguage for JsonLanguage { } } - fn resolve_analyzer_options( + fn resolve_analyze_options( global: Option<&Settings>, _linter: Option<&LinterSettings>, _overrides: Option<&OverrideSettings>, @@ -185,18 +209,19 @@ fn parse( let parser = settings.map(|s| &s.languages.json.parser); let overrides = settings.map(|s| &s.override_settings); let optional_json_file_source = file_source.to_json_file_source(); - let options = JsonParserOptions { + // TODO: well-known files handle + let options = JsonParseOptions { allow_comments: parser.and_then(|p| p.allow_comments).map_or_else( || optional_json_file_source.map_or(false, |x| x.allow_comments()), - |value| value, + |value| value.into(), ), allow_trailing_commas: parser.and_then(|p| p.allow_trailing_commas).map_or_else( || optional_json_file_source.map_or(false, |x| x.allow_trailing_commas()), - |value| value, + |value| value.into(), ), }; let options = if let Some(overrides) = overrides { - overrides.to_override_json_parser_options(biome_path, options) + overrides.to_override_json_parse_options(biome_path, options) } else { options }; @@ -326,7 +351,7 @@ fn lint(params: LintParams) -> LintResults { || params.path.ends_with(ConfigName::biome_json()) || params.path.ends_with(ConfigName::biome_jsonc()) { - let deserialized = deserialize_from_json_ast::(&root, ""); + let deserialized = deserialize_from_json_ast::(&root, ""); diagnostics.extend( deserialized .into_diagnostics() @@ -338,7 +363,7 @@ fn lint(params: LintParams) -> LintResults { let analyzer_options = ¶ms .workspace - .analyzer_options::(params.path, ¶ms.language); + .analyze_options::(params.path, ¶ms.language); let mut rules = None; if let Some(settings) = params.workspace.settings() { @@ -490,7 +515,7 @@ fn code_actions(params: CodeActionsParams) -> PullActionsResult { let tree: JsonRoot = parse.tree(); trace_span!("Parsed file", tree =? tree).in_scope(move || { let analyzer_options = - workspace.analyzer_options::(params.path, ¶ms.language); + workspace.analyze_options::(params.path, ¶ms.language); let rules = settings.as_rules(params.path); let mut actions = Vec::new(); let mut enabled_rules = vec![]; @@ -515,7 +540,7 @@ fn code_actions(params: CodeActionsParams) -> PullActionsResult { }; let mut categories = RuleCategoriesBuilder::default().with_syntax().with_lint(); - if settings.organize_imports.enabled { + if settings.organize_imports.enabled.unwrap_or_default().into() { categories = categories.with_action(); } filter.categories = categories.build(); diff --git a/crates/biome_service/src/file_handlers/mod.rs b/crates/biome_service/src/file_handlers/mod.rs index 9500d6a8bed2..79446a1a76bb 100644 --- a/crates/biome_service/src/file_handlers/mod.rs +++ b/crates/biome_service/src/file_handlers/mod.rs @@ -28,7 +28,7 @@ use biome_formatter::Printed; use biome_fs::BiomePath; use biome_graphql_syntax::{GraphqlFileSource, GraphqlLanguage}; use biome_grit_patterns::{GritQuery, GritQueryResult, GritTargetFile}; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{EmbeddingKind, JsFileSource, JsLanguage, Language, TextRange, TextSize}; use biome_json_syntax::{JsonFileSource, JsonLanguage}; use biome_parser::AnyParse; @@ -38,6 +38,11 @@ pub use javascript::JsFormatterSettings; use std::ffi::OsStr; use std::path::Path; +pub use crate::file_handlers::{ + css::CssOrganizeImportsEnabled, javascript::JsOrganizeImportsEnabled, + json::JsonOrganizeImportsEnabled, +}; + mod astro; mod css; mod graphql; @@ -572,7 +577,7 @@ pub(crate) fn parse_lang_from_script_opening_tag(script_opening_tag: &str) -> La parse( script_opening_tag, JsFileSource::jsx(), - JsParserOptions::default(), + JsParseOptions::default(), ) .try_tree() .and_then(|tree| { diff --git a/crates/biome_service/src/file_handlers/svelte.rs b/crates/biome_service/src/file_handlers/svelte.rs index 7cf455595338..ae8d8be81d72 100644 --- a/crates/biome_service/src/file_handlers/svelte.rs +++ b/crates/biome_service/src/file_handlers/svelte.rs @@ -10,7 +10,7 @@ use crate::workspace::{ use crate::WorkspaceError; use biome_formatter::Printed; use biome_fs::BiomePath; -use biome_js_parser::{parse_js_with_cache, JsParserOptions}; +use biome_js_parser::{parse_js_with_cache, JsParseOptions}; use biome_js_syntax::{EmbeddingKind, JsFileSource, Language, TextRange, TextSize}; use biome_parser::AnyParse; use biome_rowan::NodeCache; @@ -124,7 +124,7 @@ fn parse( debug!("Parsing file with language {:?}", file_source); - let parse = parse_js_with_cache(script, file_source, JsParserOptions::default(), cache); + let parse = parse_js_with_cache(script, file_source, JsParseOptions::default(), cache); ParseResult { any_parse: parse.into(), diff --git a/crates/biome_service/src/file_handlers/vue.rs b/crates/biome_service/src/file_handlers/vue.rs index 64a4ca93914a..6ca0f3cd7619 100644 --- a/crates/biome_service/src/file_handlers/vue.rs +++ b/crates/biome_service/src/file_handlers/vue.rs @@ -10,7 +10,7 @@ use crate::workspace::{ use crate::WorkspaceError; use biome_formatter::Printed; use biome_fs::BiomePath; -use biome_js_parser::{parse_js_with_cache, JsParserOptions}; +use biome_js_parser::{parse_js_with_cache, JsParseOptions}; use biome_js_syntax::{EmbeddingKind, JsFileSource, Language, TextRange, TextSize}; use biome_parser::AnyParse; use biome_rowan::NodeCache; @@ -124,7 +124,7 @@ fn parse( debug!("Parsing file with language {:?}", file_source); - let parse = parse_js_with_cache(script, file_source, JsParserOptions::default(), cache); + let parse = parse_js_with_cache(script, file_source, JsParseOptions::default(), cache); ParseResult { any_parse: parse.into(), diff --git a/crates/biome_service/src/matcher/mod.rs b/crates/biome_service/src/matcher/mod.rs index 49663bcfc508..dd4e7a9fd407 100644 --- a/crates/biome_service/src/matcher/mod.rs +++ b/crates/biome_service/src/matcher/mod.rs @@ -11,8 +11,9 @@ use std::sync::RwLock; /// a unix shell style patterns #[derive(Debug, Default)] pub struct Matcher { + // TODO: where is this root used? root: Option, - patterns: Vec, + patterns: Option>, options: MatchOptions, /// Whether the string was already checked already_checked: RwLock>, @@ -24,20 +25,13 @@ impl Matcher { /// Check [glob website](https://docs.rs/glob/latest/glob/struct.MatchOptions.html) for [MatchOptions] pub fn new(options: MatchOptions) -> Self { Self { - root: None, - patterns: Vec::new(), options, - already_checked: RwLock::new(HashMap::default()), + ..Default::default() } } pub fn empty() -> Self { - Self { - root: None, - patterns: Vec::new(), - options: MatchOptions::default(), - already_checked: RwLock::new(HashMap::default()), - } + Self::default() } pub fn set_root(&mut self, root: PathBuf) { @@ -47,7 +41,8 @@ impl Matcher { /// It adds a unix shell style pattern pub fn add_pattern(&mut self, pattern: &str) -> Result<(), PatternError> { let pattern = Pattern::new(pattern)?; - self.patterns.push(pattern); + let patterns = self.patterns.get_or_insert(Default::default()); + patterns.push(pattern); Ok(()) } @@ -55,68 +50,69 @@ impl Matcher { /// /// It returns [true] if there's at least a match pub fn matches(&self, source: &str) -> bool { - let mut already_ignored = self.already_checked.write().unwrap(); - if let Some(matches) = already_ignored.get(source) { + let mut already_checked = self.already_checked.write().unwrap(); + if let Some(matches) = already_checked.get(source) { return *matches; } - for pattern in &self.patterns { - if pattern.matches_with(source, self.options) || source.contains(pattern.as_str()) { - already_ignored.insert(source.to_string(), true); - return true; + if let Some(patterns) = &self.patterns { + for pattern in patterns { + // TODO: this needs to be better handled + if pattern.matches_with(source, self.options) || source.contains(pattern.as_str()) { + already_checked.insert(source.to_string(), true); + return true; + } } } - already_ignored.insert(source.to_string(), false); + already_checked.insert(source.to_string(), false); false } - pub fn is_empty(&self) -> bool { - self.patterns.is_empty() + pub fn is_none(&self) -> bool { + self.patterns.is_none() } /// It matches the given path against the stored patterns /// /// It returns [true] if there's at least one match pub fn matches_path(&self, source: &Path) -> bool { - if self.is_empty() { - return false; - } let mut already_checked = self.already_checked.write().unwrap(); - let source_as_string = source.to_str(); - if let Some(source_as_string) = source_as_string { - if let Some(matches) = already_checked.get(source_as_string) { + let source_str = source.to_str(); + if let Some(source_str) = source_str { + if let Some(matches) = already_checked.get(source_str) { return *matches; } } let matches = self.run_match(source); - - if let Some(source_as_string) = source_as_string { - already_checked.insert(source_as_string.to_string(), matches); + if let Some(source_str) = source_str { + already_checked.insert(source_str.to_string(), matches); } - matches } fn run_match(&self, source: &Path) -> bool { - for pattern in &self.patterns { - let matches = if pattern.matches_path_with(source, self.options) { - true - } else { - // Here we cover cases where the user specifies single files inside the patterns. - // The pattern library doesn't support single files, we here we just do a check - // on contains - // - // Given the pattern `out`: - // - `out/index.html` -> matches - // - `out/` -> matches - // - `layout.tsx` -> does not match - // - `routes/foo.ts` -> does not match - source - .ancestors() - .any(|ancestor| ancestor.ends_with(pattern.as_str())) - }; - - if matches { - return true; + if let Some(patterns) = &self.patterns { + for pattern in patterns { + let matches = if pattern.matches_path_with(source, self.options) { + true + } else { + // TODO: this needs to be better handled + // Here we cover cases where the user specifies single files inside the patterns. + // The pattern library doesn't support single files, we here we just do a check + // on contains + // + // Given the pattern `out`: + // - `out/index.html` -> matches + // - `out/` -> matches + // - `layout.tsx` -> does not match + // - `routes/foo.ts` -> does not match + source + .ancestors() + // TODO: should this be starts_with? And what about "out_123/index.html"? + .any(|ancestor| ancestor.ends_with(pattern.as_str())) + }; + if matches { + return true; + } } } false diff --git a/crates/biome_service/src/settings.rs b/crates/biome_service/src/settings.rs index 19957e981d3b..68394edf72eb 100644 --- a/crates/biome_service/src/settings.rs +++ b/crates/biome_service/src/settings.rs @@ -1,18 +1,26 @@ +use crate::file_handlers::{ + CssOrganizeImportsEnabled, JsOrganizeImportsEnabled, JsonOrganizeImportsEnabled, +}; use crate::workspace::{DocumentFileSource, ProjectKey, WorkspaceData}; use crate::{Matcher, WorkspaceError}; use biome_analyze::{AnalyzerOptions, AnalyzerRules}; +use biome_configuration::bool::Bool; +use biome_configuration::css::{CssFormatterEnabled, CssLinterEnabled}; use biome_configuration::diagnostics::InvalidIgnorePattern; -use biome_configuration::javascript::JsxRuntime; -use biome_configuration::organize_imports::OrganizeImports; +use biome_configuration::file_size::FileSize; +use biome_configuration::formatter::{FormatWithErrorsEnabled, FormatterEnabled}; +use biome_configuration::javascript::{JsFormatterEnabled, JsLinterEnabled, JsxRuntime}; +use biome_configuration::json::{JsonFormatterEnabled, JsonLinterEnabled}; +use biome_configuration::linter::LinterEnabled; +use biome_configuration::organize_imports::{OrganizeImports, OrganizeImportsEnabled}; use biome_configuration::{ - push_to_analyzer_rules, BiomeDiagnostic, FilesConfiguration, FormatterConfiguration, - JavascriptConfiguration, LinterConfiguration, OverrideFormatterConfiguration, - OverrideLinterConfiguration, OverrideOrganizeImportsConfiguration, Overrides, - PartialConfiguration, PartialCssConfiguration, PartialGraphqlConfiguration, - PartialJavascriptConfiguration, PartialJsonConfiguration, PlainIndentStyle, Rules, + push_to_analyzer_rules, BiomeDiagnostic, Configuration, CssConfiguration, FilesConfiguration, + FormatterConfiguration, GraphqlConfiguration, IgnoreUnknownEnabled, JsConfiguration, + JsonConfiguration, LinterConfiguration, OverrideFormatterConfiguration, + OverrideLinterConfiguration, OverrideOrganizeImportsConfiguration, Overrides, Rules, }; use biome_css_formatter::context::CssFormatOptions; -use biome_css_parser::CssParserOptions; +use biome_css_parser::CssParseOptions; use biome_css_syntax::CssLanguage; use biome_deserialize::{Merge, StringSet}; use biome_diagnostics::Category; @@ -24,10 +32,10 @@ use biome_graphql_formatter::context::GraphqlFormatOptions; use biome_graphql_syntax::GraphqlLanguage; use biome_js_analyze::metadata; use biome_js_formatter::context::JsFormatOptions; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_json_formatter::context::JsonFormatOptions; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_json_syntax::JsonLanguage; use ignore::gitignore::{Gitignore, GitignoreBuilder}; use indexmap::IndexSet; @@ -35,10 +43,7 @@ use rustc_hash::FxHashMap; use std::borrow::Cow; use std::path::{Path, PathBuf}; use std::sync::RwLockWriteGuard; -use std::{ - num::NonZeroU64, - sync::{RwLock, RwLockReadGuard}, -}; +use std::sync::{RwLock, RwLockReadGuard}; use tracing::trace; #[derive(Debug, Default)] @@ -155,7 +160,7 @@ impl WorkspaceSettings { #[derive(Debug, Default)] pub struct Settings { /// Formatter settings applied to all files in the workspaces - pub formatter: FormatSettings, + pub formatter: FormatterSettings, /// Linter settings applied to all files in the workspace pub linter: LinterSettings, /// Language specific settings @@ -169,121 +174,216 @@ pub struct Settings { } impl Settings { - /// The [PartialConfiguration] is merged into the workspace + /// The [Configuration] is merged into the workspace #[tracing::instrument(level = "trace", skip(self))] pub fn merge_with_configuration( &mut self, - configuration: PartialConfiguration, + configuration: Configuration, working_directory: Option, vcs_path: Option, gitignore_matches: &[String], ) -> Result<(), WorkspaceError> { - // formatter part + // formatter settings if let Some(formatter) = configuration.formatter { - self.formatter = to_format_settings( - working_directory.clone(), - FormatterConfiguration::from(formatter), - )?; + self.formatter = to_formatter_settings(working_directory.clone(), formatter)?; } - // linter part + // linter settings if let Some(linter) = configuration.linter { - self.linter = - to_linter_settings(working_directory.clone(), LinterConfiguration::from(linter))?; + self.linter = to_linter_settings(working_directory.clone(), linter)?; } - // Filesystem settings - if let Some(files) = to_file_settings( - working_directory.clone(), - configuration.files.map(FilesConfiguration::from), - vcs_path, - gitignore_matches, - )? { - self.files = files; + // filesystem settings + if let Some(files) = configuration.files { + self.files = to_file_settings( + working_directory.clone(), + files, + vcs_path, + gitignore_matches, + )?; } + // organize imports settings if let Some(organize_imports) = configuration.organize_imports { - self.organize_imports = to_organize_imports_settings( - working_directory.clone(), - OrganizeImports::from(organize_imports), - )?; + self.organize_imports = + to_organize_imports_settings(working_directory.clone(), organize_imports)?; } // javascript settings if let Some(javascript) = configuration.javascript { - self.languages.javascript = JavascriptConfiguration::from(javascript).into(); + self.languages.javascript = javascript.into(); } + // json settings if let Some(json) = configuration.json { self.languages.json = json.into(); } + // css settings if let Some(css) = configuration.css { self.languages.css = css.into(); } + // graphql settings if let Some(graphql) = configuration.graphql { self.languages.graphql = graphql.into(); } - // NOTE: keep this last. Computing the overrides require reading the settings computed by the parent settings. + // overrides settings if let Some(overrides) = configuration.overrides { - self.override_settings = - to_override_settings(working_directory.clone(), overrides, self)?; + self.override_settings = to_override_settings(working_directory.clone(), overrides)?; } Ok(()) } - /// Retrieves the settings of the formatter - pub fn formatter(&self) -> &FormatSettings { - &self.formatter + /// Whether the format_with_errors is enabled for this file path + pub fn format_with_errors_enabled_for_this_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_format_with_errors_activity_for_this_file_path(path) + .or(self.formatter.format_with_errors) + .unwrap_or_default() + .into() + } + + /// Whether the files ignore_unknown is enabled + pub fn ignore_unknown_enabled(&self) -> bool { + self.files.ignore_unknown.unwrap_or_default().into() + } + + /// Whether the formatter is enabled for this file path + pub fn formatter_enabled_for_this_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_formatter_activity_for_this_file_path(path) + .or(self.formatter.enabled) + .unwrap_or_default() + .into() + } + + /// Whether the linter is enabled for this file path + pub fn linter_enabled_for_this_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_linter_activity_for_this_file_path(path) + .or(self.linter.enabled) + .unwrap_or_default() + .into() + } + + /// Whether the organize_imports is enabled for this file path + pub fn organize_imports_enabled_for_this_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_organize_imports_activity_for_this_file_path(path) + .or(self.linter.enabled) + .unwrap_or_default() + .into() + } + + /// Whether the formatter is enabled for this JavaScript file path + pub fn formatter_enabled_for_this_js_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_formatter_activity_for_this_js_file_path(path) + .or(check_feature_activity( + self.languages.javascript.formatter.enabled, + self.formatter.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the formatter is disabled for JavaScript files - pub fn javascript_formatter_disabled(&self) -> bool { - let enabled = self.languages.javascript.formatter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the linter is enabled for this JavaScript file path + pub fn linter_enabled_for_this_js_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_linter_activity_for_this_js_file_path(path) + .or(check_feature_activity( + self.languages.javascript.linter.enabled, + self.linter.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the formatter is disabled for JSON files - pub fn json_formatter_disabled(&self) -> bool { - let enabled = self.languages.json.formatter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the organize_imports is enabled for this JavaScript file path + pub fn organize_imports_enabled_for_this_js_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_organize_imports_activity_for_this_js_file_path(path) + .or(check_feature_activity( + self.languages.javascript.organize_imports.enabled, + self.organize_imports.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the formatter is disabled for CSS files - pub fn css_formatter_disabled(&self) -> bool { - let enabled = self.languages.css.formatter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the formatter is enabled for this JSON file path + pub fn formatter_enabled_for_this_json_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_json_file_path_formatter_activity(path) + .or(check_feature_activity( + self.languages.json.formatter.enabled, + self.formatter.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the linter is disabled for CSS files - pub fn javascript_linter_disabled(&self) -> bool { - let enabled = self.languages.javascript.linter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the linter is enabled for this JSON file path + pub fn linter_enabled_for_this_json_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_json_file_path_linter_activity(path) + .or(check_feature_activity( + self.languages.json.linter.enabled, + self.linter.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the linter is disabled for CSS files - pub fn json_linter_disabled(&self) -> bool { - let enabled = self.languages.json.linter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the organize_imports is enabled for this JSON file path + pub fn organize_imports_enabled_for_this_json_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_json_file_path_organize_imports_activity(path) + .or(check_feature_activity( + self.languages.json.organize_imports.enabled, + self.organize_imports.enabled, + )) + .unwrap_or_default() + .into() } - /// Whether the linter is disabled for CSS files - pub fn css_linter_disabled(&self) -> bool { - let enabled = self.languages.css.linter.enabled.as_ref(); - enabled == Some(&false) + /// Whether the formatter is enabled for this CSS file path + pub fn formatter_enabled_for_this_css_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_css_file_path_formatter_activity(path) + .or(check_feature_activity( + self.languages.css.formatter.enabled, + self.formatter.enabled, + )) + .unwrap_or_default() + .into() } - /// Retrieves the settings of the linter - pub fn linter(&self) -> &LinterSettings { - &self.linter + /// Whether the linter is enabled for this CSS file path + pub fn linter_enabled_for_this_css_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_css_file_path_linter_activity(path) + .or(check_feature_activity( + self.languages.css.linter.enabled, + self.linter.enabled, + )) + .unwrap_or_default() + .into() } - /// Retrieves the settings of the organize imports - pub fn organize_imports(&self) -> &OrganizeImportsSettings { - &self.organize_imports + /// Whether the organize_imports is enabled for this CSS file path + pub fn organize_imports_enabled_for_this_css_file_path(&self, path: &Path) -> bool { + self.override_settings + .check_css_file_path_organize_imports_activity(path) + .or(check_feature_activity( + self.languages.css.organize_imports.enabled, + self.organize_imports.enabled, + )) + .unwrap_or_default() + .into() } /// It retrieves the severity based on the `code` of the rule and the current configuration. @@ -325,14 +425,151 @@ impl Settings { } } -/// Formatter settings for the entire workspace +/// Handle object holding a temporary lock on the workspace settings until +/// the deferred language-specific options resolution is called #[derive(Debug)] -pub struct FormatSettings { +pub struct WorkspaceSettingsHandle<'a> { + inner: RwLockReadGuard<'a, WorkspaceSettings>, +} + +impl<'a> WorkspaceSettingsHandle<'a> { + pub(crate) fn new(settings: &'a RwLock) -> Self { + Self { + inner: settings.read().unwrap(), + } + } + + pub(crate) fn settings(&self) -> Option<&Settings> { + self.inner.get_current_settings() + } +} + +impl<'a> AsRef for WorkspaceSettingsHandle<'a> { + fn as_ref(&self) -> &WorkspaceSettings { + &self.inner + } +} + +impl<'a> WorkspaceSettingsHandle<'a> { + /// Resolve the formatting context for the given language + pub(crate) fn format_options( + &self, + path: &BiomePath, + file_source: &DocumentFileSource, + ) -> L::FormatOptions + where + L: ServiceLanguage, + { + let settings = self.inner.get_current_settings(); + let formatter = settings.map(|s| &s.formatter); + let overrides = settings.map(|s| &s.override_settings); + let editor_settings = settings + .map(|s| L::lookup_settings(&s.languages)) + .map(|result| &result.formatter); + L::resolve_format_options(formatter, overrides, editor_settings, path, file_source) + } + + pub(crate) fn analyze_options( + &self, + path: &BiomePath, + file_source: &DocumentFileSource, + ) -> AnalyzerOptions + where + L: ServiceLanguage, + { + let settings = self.inner.get_current_settings(); + let linter = settings.map(|s| &s.linter); + let overrides = settings.map(|s| &s.override_settings); + let editor_settings = settings + .map(|s| L::lookup_settings(&s.languages)) + .map(|result| &result.linter); + L::resolve_analyze_options( + settings, + linter, + overrides, + editor_settings, + path, + file_source, + ) + } +} + +pub struct WorkspaceSettingsHandleMut<'a> { + inner: RwLockWriteGuard<'a, WorkspaceSettings>, +} + +impl<'a> WorkspaceSettingsHandleMut<'a> { + pub(crate) fn new(settings: &'a RwLock) -> Self { + Self { + inner: settings.write().unwrap(), + } + } +} + +impl<'a> AsMut for WorkspaceSettingsHandleMut<'a> { + fn as_mut(&mut self) -> &mut WorkspaceSettings { + &mut self.inner + } +} + +/// Creates a [Matcher] from a [StringSet] +/// +/// ## Errors +/// +/// It can raise an error if the patterns aren't valid +pub fn to_matcher( + working_directory: Option, + string_set: Option<&StringSet>, +) -> Result { + let mut matcher = Matcher::empty(); + if let Some(working_directory) = working_directory { + matcher.set_root(working_directory) + } + if let Some(string_set) = string_set { + for pattern in string_set.iter() { + matcher.add_pattern(pattern).map_err(|err| { + BiomeDiagnostic::new_invalid_ignore_pattern( + pattern.to_string(), + err.msg.to_string(), + ) + })?; + } + } + Ok(matcher) +} + +fn to_git_ignore(path: PathBuf, matches: &[String]) -> Result { + let mut gitignore_builder = GitignoreBuilder::new(path.clone()); + + for the_match in matches { + gitignore_builder + .add_line(Some(path.clone()), the_match) + .map_err(|err| { + BiomeDiagnostic::InvalidIgnorePattern(InvalidIgnorePattern { + message: err.to_string(), + file_path: path.to_str().map(|s| s.to_string()), + }) + })?; + } + let gitignore = gitignore_builder.build().map_err(|err| { + BiomeDiagnostic::InvalidIgnorePattern(InvalidIgnorePattern { + message: err.to_string(), + file_path: path.to_str().map(|s| s.to_string()), + }) + })?; + Ok(gitignore) +} + +// region: Formatter settings (base) + +/// Formatter settings for the entire workspace +#[derive(Debug, Default)] +pub struct FormatterSettings { /// Enabled by default - pub enabled: bool, + pub enabled: Option, /// Stores whether formatting should be allowed to proceed if a given file /// has syntax errors - pub format_with_errors: bool, + pub format_with_errors: Option, pub indent_style: Option, pub indent_width: Option, pub line_ending: Option, @@ -345,31 +582,33 @@ pub struct FormatSettings { pub included_files: Matcher, } -impl Default for FormatSettings { - fn default() -> Self { - Self { - enabled: true, - format_with_errors: false, - indent_style: Some(IndentStyle::default()), - indent_width: Some(IndentWidth::default()), - line_ending: Some(LineEnding::default()), - line_width: Some(LineWidth::default()), - attribute_position: Some(AttributePosition::default()), - bracket_spacing: Some(BracketSpacing::default()), - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - } - } +pub fn to_formatter_settings( + working_directory: Option, + conf: FormatterConfiguration, +) -> Result { + Ok(FormatterSettings { + enabled: conf.enabled, + format_with_errors: conf.format_with_errors, + indent_style: conf.indent_style.map(Into::into), + indent_width: conf.indent_width, + line_ending: conf.line_ending, + line_width: conf.line_width, + attribute_position: conf.attribute_position, + bracket_spacing: conf.bracket_spacing, + ignored_files: to_matcher(working_directory.clone(), conf.ignore.as_ref())?, + included_files: to_matcher(working_directory, conf.include.as_ref())?, + }) } -/// Formatter settings for the entire workspace +// endregion + +// region: Formatter settings (override) + +/// Formatter settings in a override entry #[derive(Debug, Default)] -pub struct OverrideFormatSettings { - /// Enabled by default - pub enabled: Option, - /// Stores whether formatting should be allowed to proceed if a given file - /// has syntax errors - pub format_with_errors: bool, +pub struct OverrideFormatterSettings { + pub enabled: Option, + pub format_with_errors: Option, pub indent_style: Option, pub indent_width: Option, pub line_ending: Option, @@ -378,11 +617,30 @@ pub struct OverrideFormatSettings { pub attribute_position: Option, } +impl From for OverrideFormatterSettings { + fn from(conf: OverrideFormatterConfiguration) -> Self { + Self { + enabled: conf.enabled, + format_with_errors: conf.format_with_errors, + indent_style: conf.indent_style.map(Into::into), + indent_width: conf.indent_width, + line_ending: conf.line_ending, + line_width: conf.line_width, + bracket_spacing: conf.bracket_spacing, + attribute_position: conf.attribute_position, + } + } +} + +// endregion + +// region: Linter settings (base) + /// Linter settings for the entire workspace -#[derive(Debug)] +#[derive(Debug, Default)] pub struct LinterSettings { /// Enabled by default - pub enabled: bool, + pub enabled: Option, /// List of rules pub rules: Option, @@ -394,32 +652,48 @@ pub struct LinterSettings { pub included_files: Matcher, } -impl Default for LinterSettings { - fn default() -> Self { - Self { - enabled: true, - rules: Some(Rules::default()), - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - } - } +// TODO:Rules? +pub fn to_linter_settings( + working_directory: Option, + conf: LinterConfiguration, +) -> Result { + Ok(LinterSettings { + enabled: conf.enabled, + rules: Some(conf.rules.unwrap_or_default()), + ignored_files: to_matcher(working_directory.clone(), conf.ignore.as_ref())?, + included_files: to_matcher(working_directory, conf.include.as_ref())?, + }) } -/// Linter settings for the entire workspace +// endregion + +// region: Linter settings (override) + +/// Linter settings in an override entry #[derive(Debug, Default)] pub struct OverrideLinterSettings { - /// Enabled by default - pub enabled: Option, - - /// List of rules + pub enabled: Option, pub rules: Option, } -/// Linter settings for the entire workspace -#[derive(Debug)] +impl From for OverrideLinterSettings { + fn from(conf: OverrideLinterConfiguration) -> Self { + Self { + enabled: conf.enabled, + rules: conf.rules, + } + } +} + +// endregion + +// region: Organize import settings (base) + +/// Organize imports settings for the entire workspace +#[derive(Debug, Default)] pub struct OrganizeImportsSettings { /// Enabled by default - pub enabled: bool, + pub enabled: Option, /// List of ignored paths/files to match pub ignored_files: Matcher, @@ -428,69 +702,166 @@ pub struct OrganizeImportsSettings { pub included_files: Matcher, } -impl Default for OrganizeImportsSettings { - fn default() -> Self { - Self { - enabled: true, - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - } - } +pub fn to_organize_imports_settings( + working_directory: Option, + organize_imports: OrganizeImports, +) -> Result { + Ok(OrganizeImportsSettings { + enabled: organize_imports.enabled, + ignored_files: to_matcher(working_directory.clone(), organize_imports.ignore.as_ref())?, + included_files: to_matcher(working_directory, organize_imports.include.as_ref())?, + }) } -/// Linter settings for the entire workspace +// endregion + +// region: Organize import settings (override) + +/// Organize imports settings in an override entry #[derive(Debug, Default)] pub struct OverrideOrganizeImportsSettings { - /// Enabled by default - pub enabled: Option, + pub enabled: Option, } -/// Static map of language names to language-specific settings -#[derive(Debug, Default)] -pub struct LanguageListSettings { - pub javascript: LanguageSettings, - pub json: LanguageSettings, - pub css: LanguageSettings, - pub graphql: LanguageSettings, +impl From for OverrideOrganizeImportsSettings { + fn from(conf: OverrideOrganizeImportsConfiguration) -> Self { + Self { + enabled: conf.enabled, + } + } } -impl From for LanguageSettings { - fn from(javascript: JavascriptConfiguration) -> Self { - let mut language_setting: LanguageSettings = LanguageSettings::default(); - - let formatter = javascript.formatter; - language_setting.formatter.quote_style = Some(formatter.quote_style); - language_setting.formatter.jsx_quote_style = Some(formatter.jsx_quote_style); - language_setting.formatter.quote_properties = Some(formatter.quote_properties); - language_setting.formatter.trailing_commas = Some(formatter.trailing_commas); - language_setting.formatter.semicolons = Some(formatter.semicolons); - language_setting.formatter.arrow_parentheses = Some(formatter.arrow_parentheses); - language_setting.formatter.bracket_same_line = Some(formatter.bracket_same_line.into()); - language_setting.formatter.enabled = Some(formatter.enabled); - language_setting.formatter.line_width = formatter.line_width; - language_setting.formatter.bracket_spacing = formatter.bracket_spacing; - language_setting.formatter.attribute_position = formatter.attribute_position; - language_setting.formatter.indent_width = formatter.indent_width.map(Into::into); - language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); - language_setting.parser.parse_class_parameter_decorators = - javascript.parser.unsafe_parameter_decorators_enabled; - - language_setting.globals = Some(javascript.globals.into_index_set()); - language_setting.environment = javascript.jsx_runtime.into(); - language_setting.linter.enabled = Some(javascript.linter.enabled); +// endregion - language_setting - } -} +// region: File settings (base) -impl From for LanguageSettings { - fn from(json: PartialJsonConfiguration) -> Self { - let mut language_setting: LanguageSettings = LanguageSettings::default(); +/// Filesystem settings for the entire workspace +#[derive(Debug, Default)] +pub struct FilesSettings { + /// File size limit in bytes + pub max_size: Option, + + /// gitignore file patterns + pub git_ignore: Option, + + /// List of paths/files to matcher + pub ignored_files: Matcher, + + /// List of paths/files to matcher + pub included_files: Matcher, + + /// Files not recognized by Biome should not emit a diagnostic + pub ignore_unknown: Option, +} + +// TODO:Rethink about partial and defaults +fn to_file_settings( + working_directory: Option, + config: FilesConfiguration, + vcs_config_path: Option, + gitignore_matches: &[String], +) -> Result { + let git_ignore = if let Some(vcs_config_path) = vcs_config_path { + Some(to_git_ignore(vcs_config_path, gitignore_matches)?) + } else { + None + }; + + Ok(FilesSettings { + max_size: config.max_size, + git_ignore, + ignore_unknown: config.ignore_unknown, + ignored_files: to_matcher(working_directory.clone(), config.ignore.as_ref())?, + included_files: to_matcher(working_directory, config.include.as_ref())?, + }) +} + +// endregion + +// region: Language Settings + +#[derive(Debug, Default)] +pub struct LanguageSettings { + /// Parser settings for this language + pub parser: L::ParserSettings, + + /// Formatter settings for this language + pub formatter: L::FormatterSettings, + + /// Linter settings for this language + pub linter: L::LinterSettings, + + /// Globals variables/bindings that can be found in a file + pub globals: Option>, + + /// Organize imports settings for this language + pub organize_imports: L::OrganizeImportsSettings, + + /// Environment settings for this language + pub environment: L::EnvironmentSettings, +} + +/// Static map of language names to language-specific settings +#[derive(Debug, Default)] +pub struct LanguageListSettings { + pub javascript: LanguageSettings, + pub json: LanguageSettings, + pub css: LanguageSettings, + pub graphql: LanguageSettings, +} + +impl From for LanguageSettings { + fn from(javascript: JsConfiguration) -> Self { + let mut language_setting: LanguageSettings = LanguageSettings::default(); + + if let Some(parser) = javascript.parser { + language_setting.parser.parse_class_parameter_decorators = + parser.unsafe_parameter_decorators_enabled; + } + + if let Some(formatter) = javascript.formatter { + language_setting.formatter.enabled = formatter.enabled; + language_setting.formatter.quote_style = formatter.quote_style; + language_setting.formatter.jsx_quote_style = formatter.jsx_quote_style; + language_setting.formatter.quote_properties = formatter.quote_properties; + language_setting.formatter.trailing_commas = formatter.trailing_commas; + language_setting.formatter.semicolons = formatter.semicolons; + language_setting.formatter.arrow_parentheses = formatter.arrow_parentheses; + language_setting.formatter.bracket_same_line = + // TODO(zzwu): implement From trait for bracket_same_line + formatter.bracket_same_line.map(|v| bool::from(v).into()); + language_setting.formatter.line_width = formatter.line_width; + language_setting.formatter.bracket_spacing = formatter.bracket_spacing; + language_setting.formatter.attribute_position = formatter.attribute_position; + 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) = javascript.linter { + language_setting.linter.enabled = linter.enabled; + } + + if let Some(jsx_runtime) = javascript.jsx_runtime { + language_setting.environment = jsx_runtime.into(); + } + + if let Some(globals) = javascript.globals { + language_setting.globals = Some(globals.into_index_set()); + } + + language_setting + } +} + +impl From for LanguageSettings { + fn from(json: JsonConfiguration) -> Self { + let mut language_setting: LanguageSettings = LanguageSettings::default(); 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; @@ -498,6 +869,7 @@ impl From for LanguageSettings { 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; } @@ -506,39 +878,38 @@ impl From for LanguageSettings { } } -impl From for LanguageSettings { - fn from(css: PartialCssConfiguration) -> Self { +impl From for LanguageSettings { + fn from(css: CssConfiguration) -> Self { let mut language_setting: LanguageSettings = LanguageSettings::default(); if let Some(parser) = css.parser { language_setting.parser.allow_wrong_line_comments = parser.allow_wrong_line_comments; language_setting.parser.css_modules = parser.css_modules; } + if let Some(formatter) = css.formatter { - // TODO: change RHS to `formatter.enabled` when css formatting is enabled by default - language_setting.formatter.enabled = Some(formatter.enabled.unwrap_or_default()); + language_setting.formatter.enabled = formatter.enabled; language_setting.formatter.indent_width = formatter.indent_width; language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); language_setting.formatter.line_width = formatter.line_width; language_setting.formatter.line_ending = formatter.line_ending; language_setting.formatter.quote_style = formatter.quote_style; } + if let Some(linter) = css.linter { - // TODO: change RHS to `linter.enabled` when css linting is enabled by default - language_setting.linter.enabled = Some(linter.enabled.unwrap_or_default()); + language_setting.linter.enabled = linter.enabled; } language_setting } } -impl From for LanguageSettings { - fn from(graphql: PartialGraphqlConfiguration) -> Self { +impl From for LanguageSettings { + fn from(graphql: GraphqlConfiguration) -> Self { let mut language_setting: LanguageSettings = LanguageSettings::default(); if let Some(formatter) = graphql.formatter { - // TODO: change RHS to `formatter.enabled` when graphql formatting is enabled by default - language_setting.formatter.enabled = Some(formatter.enabled.unwrap_or_default()); + language_setting.formatter.enabled = formatter.enabled; language_setting.formatter.indent_width = formatter.indent_width; language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); language_setting.formatter.line_width = formatter.line_width; @@ -548,8 +919,7 @@ impl From for LanguageSettings { } if let Some(linter) = graphql.linter { - // TODO: change RHS to `linter.enabled` when graphql linting is enabled by default - language_setting.linter.enabled = Some(linter.enabled.unwrap_or_default()); + language_setting.linter.enabled = linter.enabled; } language_setting @@ -557,39 +927,40 @@ impl From for LanguageSettings { } pub trait ServiceLanguage: biome_rowan::Language { + /// Parser settings type for this language + type ParserSettings: Default; + /// Formatter settings type for this language type FormatterSettings: Default; + /// Linter settings type for this language type LinterSettings: Default; /// Organize imports settings type for this language type OrganizeImportsSettings: Default; - /// Fully resolved formatter options type for this language - type FormatOptions: biome_formatter::FormatOptions + Clone + std::fmt::Display; - - /// Settings that belong to the parser - type ParserSettings: Default; - /// Settings related to the environment/runtime in which the language is used. type EnvironmentSettings: Default; + /// Fully resolved formatter options type for this language + type FormatOptions: biome_formatter::FormatOptions + Clone + std::fmt::Display; + /// Read the settings type for this language from the [LanguageListSettings] map fn lookup_settings(languages: &LanguageListSettings) -> &LanguageSettings; - /// Resolve the formatter options from the global (workspace level), + /// Resolve the format options from the global (workspace level), /// per-language and editor provided formatter settings fn resolve_format_options( - global: Option<&FormatSettings>, + global: Option<&FormatterSettings>, overrides: Option<&OverrideSettings>, language: Option<&Self::FormatterSettings>, path: &BiomePath, file_source: &DocumentFileSource, ) -> Self::FormatOptions; - /// Resolve the linter options from the global (workspace level), - /// per-language and editor provided formatter settings - fn resolve_analyzer_options( + /// Resolve the analyze options from the global (workspace level), + /// per-language and editor provided analyzer settings + fn resolve_analyze_options( global: Option<&Settings>, linter: Option<&LinterSettings>, overrides: Option<&OverrideSettings>, @@ -599,208 +970,241 @@ pub trait ServiceLanguage: biome_rowan::Language { ) -> AnalyzerOptions; } -#[derive(Debug, Default)] -pub struct LanguageSettings { - /// Formatter settings for this language - pub formatter: L::FormatterSettings, - - /// Linter settings for this language - pub linter: L::LinterSettings, +// endregion - /// Globals variables/bindings that can be found in a file - pub globals: Option>, - - /// Organize imports settings for this language - pub organize_imports: L::OrganizeImportsSettings, - - /// Parser settings for this language - pub parser: L::ParserSettings, +// region: Overrides Settings - /// Environment settings for this language - pub environment: L::EnvironmentSettings, +#[derive(Debug, Default)] +pub struct OverrideSettings { + pub patterns: Vec, } -/// Filesystem settings for the entire workspace -#[derive(Debug)] -pub struct FilesSettings { - /// File size limit in bytes - pub max_size: NonZeroU64, - - /// gitignore file patterns - pub git_ignore: Option, +pub fn to_override_settings( + working_directory: Option, + overrides: Overrides, +) -> Result { + let mut override_settings = OverrideSettings::default(); + for pattern in overrides.0 { + let formatter = pattern.formatter.map(Into::into).unwrap_or_default(); - /// List of paths/files to matcher - pub ignored_files: Matcher, + let linter = pattern.linter.map(Into::into).unwrap_or_default(); - /// List of paths/files to matcher - pub included_files: Matcher, + let organize_imports = pattern.organize_imports.map(Into::into).unwrap_or_default(); - /// Files not recognized by Biome should not emit a diagnostic - pub ignore_unknown: bool, -} + let languages = LanguageListSettings { + javascript: pattern.javascript.unwrap_or_default().into(), + json: pattern.json.unwrap_or_default().into(), + css: pattern.css.unwrap_or_default().into(), + graphql: pattern.graphql.unwrap_or_default().into(), + }; -/// Limit the size of files to 1.0 MiB by default -pub(crate) const DEFAULT_FILE_SIZE_LIMIT: NonZeroU64 = - // SAFETY: This constant is initialized with a non-zero value - unsafe { NonZeroU64::new_unchecked(1024 * 1024) }; + let pattern_setting = OverrideSettingPattern { + include: to_matcher(working_directory.clone(), pattern.include.as_ref())?, + exclude: to_matcher(working_directory.clone(), pattern.ignore.as_ref())?, + formatter, + linter, + organize_imports, + languages, + ..OverrideSettingPattern::default() + }; -impl Default for FilesSettings { - fn default() -> Self { - Self { - max_size: DEFAULT_FILE_SIZE_LIMIT, - git_ignore: None, - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - ignore_unknown: false, - } + override_settings.patterns.push(pattern_setting); } -} -fn to_file_settings( - working_directory: Option, - config: Option, - vcs_config_path: Option, - gitignore_matches: &[String], -) -> Result, WorkspaceError> { - let config = if let Some(config) = config { - Some(config) - } else if vcs_config_path.is_some() { - Some(FilesConfiguration::default()) - } else { - None - }; - let git_ignore = if let Some(vcs_config_path) = vcs_config_path { - Some(to_git_ignore(vcs_config_path, gitignore_matches)?) - } else { - None - }; - Ok(if let Some(config) = config { - Some(FilesSettings { - max_size: config.max_size, - git_ignore, - ignored_files: to_matcher(working_directory.clone(), Some(&config.ignore))?, - included_files: to_matcher(working_directory, Some(&config.include))?, - ignore_unknown: config.ignore_unknown, - }) - } else { - None - }) + Ok(override_settings) } -/// Handle object holding a temporary lock on the workspace settings until -/// the deferred language-specific options resolution is called -#[derive(Debug)] -pub struct WorkspaceSettingsHandle<'a> { - inner: RwLockReadGuard<'a, WorkspaceSettings>, -} +impl OverrideSettings { + // region: Common methods -impl<'a> WorkspaceSettingsHandle<'a> { - pub(crate) fn new(settings: &'a RwLock) -> Self { - Self { - inner: settings.read().unwrap(), + /// Retrieves the options of lint rules that have been overridden + pub fn override_analyzer_rules( + &self, + path: &Path, + mut analyzer_rules: AnalyzerRules, + ) -> AnalyzerRules { + for pattern in self.patterns.iter() { + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + if let Some(rules) = pattern.linter.rules.as_ref() { + push_to_analyzer_rules(rules, metadata(), &mut analyzer_rules); + } + } } + analyzer_rules } - pub(crate) fn settings(&self) -> Option<&Settings> { - self.inner.get_current_settings() + /// Scans the overrides and checks if there's an override + /// that sets the top-level formatter "enabled" option + /// explicitly for this file path + fn check_formatter_activity_for_this_file_path(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + return self.patterns.iter().rev().find_map(|pattern| { + // Check the top-level option + pattern.formatter.enabled.and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }); } -} -impl<'a> AsRef for WorkspaceSettingsHandle<'a> { - fn as_ref(&self) -> &WorkspaceSettings { - &self.inner + /// Scans the overrides and checks if there's an override + /// that sets the top-level linter "enabled" option + /// explicitly for this file path + fn check_linter_activity_for_this_file_path(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + return self.patterns.iter().rev().find_map(|pattern| { + // Check the top-level option + pattern.linter.enabled.and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }); } -} -impl<'a> WorkspaceSettingsHandle<'a> { - /// Resolve the formatting context for the given language - pub(crate) fn format_options( + /// Scans the overrides and checks if there's an override + /// that sets the top-level organize_imports "enabled" option + /// explicitly for this file path + fn check_organize_imports_activity_for_this_file_path( &self, - path: &BiomePath, - file_source: &DocumentFileSource, - ) -> L::FormatOptions - where - L: ServiceLanguage, - { - let settings = self.inner.get_current_settings(); - let formatter = settings.map(|s| &s.formatter); - let overrides = settings.map(|s| &s.override_settings); - let editor_settings = settings - .map(|s| L::lookup_settings(&s.languages)) - .map(|result| &result.formatter); - L::resolve_format_options(formatter, overrides, editor_settings, path, file_source) + path: &Path, + ) -> Option { + // Reverse the traversal as only the last override takes effect + return self.patterns.iter().rev().find_map(|pattern| { + // Check the top-level option + pattern.organize_imports.enabled.and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }); } - pub(crate) fn analyzer_options( + /// Scans the overrides and checks if there's an override + /// that sets the top-level formatter "format_with_errors" option + /// explicitly for this file path + fn check_format_with_errors_activity_for_this_file_path( &self, - path: &BiomePath, - file_source: &DocumentFileSource, - ) -> AnalyzerOptions - where - L: ServiceLanguage, - { - let settings = self.inner.get_current_settings(); - let linter = settings.map(|s| &s.linter); - let overrides = settings.map(|s| &s.override_settings); - let editor_settings = settings - .map(|s| L::lookup_settings(&s.languages)) - .map(|result| &result.linter); - L::resolve_analyzer_options( - settings, - linter, - overrides, - editor_settings, - path, - file_source, - ) + path: &Path, + ) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + if let Some(enabled) = pattern.formatter.format_with_errors { + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + return Some(enabled); + } + } + None + }) } -} + // endregion -pub struct WorkspaceSettingsHandleMut<'a> { - inner: RwLockWriteGuard<'a, WorkspaceSettings>, -} + // region: Javascript-specific methods -impl<'a> WorkspaceSettingsHandleMut<'a> { - pub(crate) fn new(settings: &'a RwLock) -> Self { - Self { - inner: settings.write().unwrap(), - } + /// Scans the overrides and checks if there's an override + /// that sets the language-specific formatter "enabled" option + /// explicitly for this JavaScript file path + /// + /// The function also takes the top-level formatter "enabled" + /// option into consideration + fn check_formatter_activity_for_this_js_file_path( + &self, + path: &Path, + ) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.javascript.formatter.enabled, + pattern.formatter.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) } -} -impl<'a> AsMut for WorkspaceSettingsHandleMut<'a> { - fn as_mut(&mut self) -> &mut WorkspaceSettings { - &mut self.inner + /// Scans the overrides and checks if there's an override + /// that sets the language-specific linter "enabled" option + /// explicitly for this JavaScript file path + /// + /// The function also takes the top-level linter "enabled" + /// option into consideration + fn check_linter_activity_for_this_js_file_path(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.javascript.linter.enabled, + pattern.linter.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) } -} -#[derive(Debug, Default)] -pub struct OverrideSettings { - pub patterns: Vec, -} - -impl OverrideSettings { - /// Checks whether at least one override excludes the provided `path` - pub fn is_path_excluded(&self, path: &Path) -> Option { - for pattern in &self.patterns { - if pattern.exclude.matches_path(path) { - return Some(true); - } - } - None + /// Scans the overrides and checks if there's an override + /// that sets the language-specific organize_imports "enabled" option + /// explicitly for this JavaScript file path + /// + /// The function also takes the top-level organize_imports "enabled" + /// option into consideration + fn check_organize_imports_activity_for_this_js_file_path( + &self, + path: &Path, + ) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.javascript.organize_imports.enabled, + pattern.organize_imports.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) } - /// Checks whether at least one override include the provided `path` - pub fn is_path_included(&self, path: &Path) -> Option { - for pattern in &self.patterns { - if pattern.include.matches_path(path) { - return Some(true); + + /// Scans and aggregates all the overrides into a single `JsParseOptions` + pub fn to_override_js_parse_options( + &self, + path: &Path, + mut options: JsParseOptions, + ) -> JsParseOptions { + for pattern in self.patterns.iter() { + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + pattern.apply_overrides_to_js_parse_options(&mut options); } } - None + options } - /// It scans the current override rules and return the formatting options that of the first override is matched - pub fn override_js_format_options( + /// Scans and aggregates all the overrides into a single `JsFormatOptions` + pub fn to_override_js_format_options( &self, path: &Path, mut options: JsFormatOptions, @@ -813,180 +1217,280 @@ impl OverrideSettings { options } - pub fn override_js_globals( + /// Scans and uses the last override to override the `globals` + pub fn to_override_js_globals( &self, path: &BiomePath, - base_set: &Option>, + base_globals: &Option>, ) -> IndexSet { self.patterns .iter() // Reverse the traversal as only the last override takes effect .rev() .find_map(|pattern| { - if pattern.languages.javascript.globals.is_some() - && pattern.include.matches_path(path) - && !pattern.exclude.matches_path(path) - { - pattern.languages.javascript.globals.clone() + let globals = pattern.languages.javascript.globals.as_ref()?; + + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(globals.clone()) } else { None } }) - .or_else(|| base_set.clone()) + .or(base_globals.clone()) .unwrap_or_default() } - pub fn override_jsx_runtime(&self, path: &BiomePath, base_setting: JsxRuntime) -> JsxRuntime { + /// Scans and uses the last override to override the `JsxRuntime` + pub fn to_override_jsx_runtime( + &self, + path: &BiomePath, + base_jsx_runtime: Option, + ) -> JsxRuntime { self.patterns .iter() // Reverse the traversal as only the last override takes effect .rev() .find_map(|pattern| { if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - Some(pattern.languages.javascript.environment.jsx_runtime) + pattern.languages.javascript.environment.jsx_runtime } else { None } }) - .unwrap_or(base_setting) + .or(base_jsx_runtime) + .unwrap_or_default() } - /// It scans the current override rules and return the json format that of the first override is matched - pub fn to_override_json_format_options( + // endregion + + // region: JSON-specific methods + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific formatter "enabled" option + /// explicitly for this JSON file path + /// + /// The function also takes the top-level formatter "enabled" + /// option into consideration + fn check_json_file_path_formatter_activity(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.json.formatter.enabled, + pattern.formatter.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) + } + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific linter "enabled" option + /// explicitly for this JSON file path + /// + /// The function also takes the top-level linter "enabled" + /// option into consideration + fn check_json_file_path_linter_activity(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.json.linter.enabled, + pattern.linter.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) + } + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific organize_imports "enabled" option + /// explicitly for this JSON file path + /// + /// The function also takes the top-level organize_imports "enabled" + /// option into consideration + fn check_json_file_path_organize_imports_activity( &self, path: &Path, - mut options: JsonFormatOptions, - ) -> JsonFormatOptions { - for pattern in self.patterns.iter() { - if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_json_format_options(&mut options); - } - } - options + ) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.json.organize_imports.enabled, + pattern.organize_imports.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) } - /// It scans the current override rules and return the formatting options that of the first override is matched - pub fn to_override_css_format_options( + /// Scans and aggregates all the overrides into a single `JsonParseOptions` + pub fn to_override_json_parse_options( &self, path: &Path, - mut options: CssFormatOptions, - ) -> CssFormatOptions { + mut options: JsonParseOptions, + ) -> JsonParseOptions { for pattern in self.patterns.iter() { if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_css_format_options(&mut options); + pattern.apply_overrides_to_json_parse_options(&mut options); } } options } - /// It scans the current override rules and return the formatting options that of the first override is matched - pub fn to_override_graphql_format_options( + /// Scans and aggregates all the overrides into a single `JsonFormatOptions` + pub fn to_override_json_format_options( &self, path: &Path, - mut options: GraphqlFormatOptions, - ) -> GraphqlFormatOptions { + mut options: JsonFormatOptions, + ) -> JsonFormatOptions { for pattern in self.patterns.iter() { if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_graphql_format_options(&mut options); + pattern.apply_overrides_to_json_format_options(&mut options); } } options } - pub fn to_override_js_parser_options( + // endregion + + // region: CSS-specific methods + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific formatter "enabled" option + /// explicitly for this CSS file path + /// + /// The function also takes the top-level formatter "enabled" + /// option into consideration + fn check_css_file_path_formatter_activity(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.css.formatter.enabled, + pattern.formatter.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) + } + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific linter "enabled" option + /// explicitly for this CSS file path + /// + /// The function also takes the top-level linter "enabled" + /// option into consideration + fn check_css_file_path_linter_activity(&self, path: &Path) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity(pattern.languages.css.linter.enabled, pattern.linter.enabled) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) + } + + /// Scans the overrides and checks if there's an override + /// that sets the language-specific organize_imports "enabled" option + /// explicitly for this CSS file path + /// + /// The function also takes the top-level organize_imports "enabled" + /// option into consideration + fn check_css_file_path_organize_imports_activity( &self, path: &Path, - mut options: JsParserOptions, - ) -> JsParserOptions { - for pattern in self.patterns.iter() { - if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_js_parser_options(&mut options); - } - } - options + ) -> Option { + // Reverse the traversal as only the last override takes effect + self.patterns.iter().rev().find_map(|pattern| { + check_feature_activity( + pattern.languages.css.organize_imports.enabled, + pattern.organize_imports.enabled, + ) + .and_then(|enabled| { + // Then check whether the path satisfies + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + Some(enabled) + } else { + None + } + }) + }) } - pub fn to_override_json_parser_options( + /// Scans and aggregates all the overrides into a single `CssParseOptions` + pub fn to_override_css_parse_options( &self, path: &Path, - mut options: JsonParserOptions, - ) -> JsonParserOptions { + mut options: CssParseOptions, + ) -> CssParseOptions { for pattern in self.patterns.iter() { if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_json_parser_options(&mut options); + pattern.apply_overrides_to_css_parse_options(&mut options); } } options } - /// It scans the current override rules and return the parser options that of the first override is matched - pub fn to_override_css_parser_options( + /// Scans and aggregates all the overrides into a single `CssFormatOptions` + pub fn to_override_css_format_options( &self, path: &Path, - mut options: CssParserOptions, - ) -> CssParserOptions { + mut options: CssFormatOptions, + ) -> CssFormatOptions { for pattern in self.patterns.iter() { if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - pattern.apply_overrides_to_css_parser_options(&mut options); + pattern.apply_overrides_to_css_format_options(&mut options); } } options } - /// Retrieves the options of lint rules that have been overridden - pub fn override_analyzer_rules( + // endregion + + // region: GraphQL-specific methods + + /// Scans and aggregates all the overrides into a single `GraphqlFormatOptions` + pub fn to_override_graphql_format_options( &self, path: &Path, - mut analyzer_rules: AnalyzerRules, - ) -> AnalyzerRules { + mut options: GraphqlFormatOptions, + ) -> GraphqlFormatOptions { for pattern in self.patterns.iter() { - if !pattern.exclude.matches_path(path) && pattern.include.matches_path(path) { - if let Some(rules) = pattern.linter.rules.as_ref() { - push_to_analyzer_rules(rules, metadata(), &mut analyzer_rules); - } - } - } - analyzer_rules - } - - /// Scans the overrides and checks if there's an override that disable the formatter for `path` - pub fn formatter_disabled(&self, path: &Path) -> Option { - // Reverse the traversal as only the last override takes effect - self.patterns.iter().rev().find_map(|pattern| { - if let Some(enabled) = pattern.formatter.enabled { - if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - return Some(!enabled); - } - } - None - }) - } - - /// Scans the overrides and checks if there's an override that disable the linter for `path` - pub fn linter_disabled(&self, path: &Path) -> Option { - // Reverse the traversal as only the last override takes effect - self.patterns.iter().rev().find_map(|pattern| { - if let Some(enabled) = pattern.linter.enabled { - if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - return Some(!enabled); - } - } - None - }) - } - - /// Scans the overrides and checks if there's an override that disable the organize imports for `path` - pub fn organize_imports_disabled(&self, path: &Path) -> Option { - // Reverse the traversal as only the last override takes effect - self.patterns.iter().rev().find_map(|pattern| { - if let Some(enabled) = pattern.organize_imports.enabled { - if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { - return Some(!enabled); - } + if pattern.include.matches_path(path) && !pattern.exclude.matches_path(path) { + pattern.apply_overrides_to_graphql_format_options(&mut options); } - None - }) + } + options } + + // endregion } #[derive(Debug, Default)] @@ -994,7 +1498,7 @@ pub struct OverrideSettingPattern { pub exclude: Matcher, pub include: Matcher, /// Formatter settings applied to all files in the workspaces - pub formatter: OverrideFormatSettings, + pub formatter: OverrideFormatterSettings, /// Linter settings applied to all files in the workspace pub linter: OverrideLinterSettings, /// Linter settings applied to all files in the workspace @@ -1010,11 +1514,34 @@ pub struct OverrideSettingPattern { pub(crate) cached_json_format_options: RwLock>, pub(crate) cached_css_format_options: RwLock>, pub(crate) cached_graphql_format_options: RwLock>, - pub(crate) cached_js_parser_options: RwLock>, - pub(crate) _cached_json_parser_options: RwLock>, - pub(crate) cached_css_parser_options: RwLock>, + pub(crate) cached_js_parse_options: RwLock>, + pub(crate) _cached_json_parse_options: RwLock>, + pub(crate) cached_css_parse_options: RwLock>, } + impl OverrideSettingPattern { + // region: JavaScript + + fn apply_overrides_to_js_parse_options(&self, options: &mut JsParseOptions) { + if let Ok(readonly_cache) = self.cached_js_parse_options.read() { + if let Some(cached_options) = readonly_cache.as_ref() { + *options = cached_options.clone(); + return; + } + } + + let js_parser = &self.languages.javascript.parser; + + if let Some(parse_class_parameter_decorators) = js_parser.parse_class_parameter_decorators { + options.parse_class_parameter_decorators = parse_class_parameter_decorators.into() + } + + if let Ok(mut writeonly_cache) = self.cached_js_parse_options.write() { + let options = options.clone(); + let _ = writeonly_cache.insert(options); + } + } + fn apply_overrides_to_js_format_options(&self, options: &mut JsFormatOptions) { if let Ok(readonly_cache) = self.cached_js_format_options.read() { if let Some(cached_options) = readonly_cache.get(&options.source_type()) { @@ -1025,6 +1552,9 @@ impl OverrideSettingPattern { let js_formatter = &self.languages.javascript.formatter; let formatter = &self.formatter; + + // Formatter settings which are also in top-level + if let Some(indent_style) = js_formatter.indent_style.or(formatter.indent_style) { options.set_indent_style(indent_style); } @@ -1037,6 +1567,18 @@ impl OverrideSettingPattern { if let Some(line_width) = js_formatter.line_width.or(formatter.line_width) { options.set_line_width(line_width); } + if let Some(bracket_spacing) = js_formatter.bracket_spacing.or(formatter.bracket_spacing) { + options.set_bracket_spacing(bracket_spacing); + } + if let Some(attribute_position) = js_formatter + .attribute_position + .or(formatter.attribute_position) + { + options.set_attribute_position(attribute_position); + } + + // Formatter settings which are language-specific + if let Some(quote_style) = js_formatter.quote_style { options.set_quote_style(quote_style); } @@ -1055,18 +1597,9 @@ impl OverrideSettingPattern { if let Some(arrow_parentheses) = js_formatter.arrow_parentheses { options.set_arrow_parentheses(arrow_parentheses); } - if let Some(bracket_spacing) = js_formatter.bracket_spacing.or(formatter.bracket_spacing) { - options.set_bracket_spacing(bracket_spacing); - } if let Some(bracket_same_line) = js_formatter.bracket_same_line { options.set_bracket_same_line(bracket_same_line); } - if let Some(attribute_position) = js_formatter - .attribute_position - .or(formatter.attribute_position) - { - options.set_attribute_position(attribute_position); - } if let Ok(mut writeonly_cache) = self.cached_js_format_options.write() { let options = options.clone(); @@ -1074,6 +1607,34 @@ impl OverrideSettingPattern { } } + // endregion + + // region: JSON + + fn apply_overrides_to_json_parse_options(&self, options: &mut JsonParseOptions) { + // these options are no longer cached because it was causing incorrect override behavior, see #3260 + // if let Ok(readonly_cache) = self.cached_json_parse_options.read() { + // if let Some(cached_options) = readonly_cache.as_ref() { + // *options = *cached_options; + // return; + // } + // } + + let json_parser = &self.languages.json.parser; + + if let Some(allow_comments) = json_parser.allow_comments { + options.allow_comments = allow_comments.into(); + } + if let Some(allow_trailing_commas) = json_parser.allow_trailing_commas { + options.allow_trailing_commas = allow_trailing_commas.into(); + } + + // if let Ok(mut writeonly_cache) = self.cached_json_parse_options.write() { + // let options = *options; + // let _ = writeonly_cache.insert(options); + // } + } + fn apply_overrides_to_json_format_options(&self, options: &mut JsonFormatOptions) { if let Ok(readonly_cache) = self.cached_json_format_options.read() { if let Some(cached_options) = readonly_cache.as_ref() { @@ -1085,6 +1646,8 @@ impl OverrideSettingPattern { let json_formatter = &self.languages.json.formatter; let formatter = &self.formatter; + // Formatter settings which are also in top-level + if let Some(indent_style) = json_formatter.indent_style.or(formatter.indent_style) { options.set_indent_style(indent_style); } @@ -1097,6 +1660,9 @@ impl OverrideSettingPattern { if let Some(line_width) = json_formatter.line_width.or(formatter.line_width) { options.set_line_width(line_width); } + + // Formatter settings which are language-specific + if let Some(trailing_commas) = json_formatter.trailing_commas { options.set_trailing_commas(trailing_commas); } @@ -1107,6 +1673,33 @@ impl OverrideSettingPattern { } } + // endregion + + // region: CSS + + fn apply_overrides_to_css_parse_options(&self, options: &mut CssParseOptions) { + if let Ok(readonly_cache) = self.cached_css_parse_options.read() { + if let Some(cached_options) = readonly_cache.as_ref() { + *options = *cached_options; + return; + } + } + + let css_parser = &self.languages.css.parser; + + if let Some(allow_wrong_line_comments) = css_parser.allow_wrong_line_comments { + options.allow_wrong_line_comments = allow_wrong_line_comments.into(); + } + if let Some(css_modules) = css_parser.css_modules { + options.css_modules = css_modules.into(); + } + + if let Ok(mut writeonly_cache) = self.cached_css_parse_options.write() { + let options = *options; + let _ = writeonly_cache.insert(options); + } + } + fn apply_overrides_to_css_format_options(&self, options: &mut CssFormatOptions) { if let Ok(readonly_cache) = self.cached_css_format_options.read() { if let Some(cached_options) = readonly_cache.as_ref() { @@ -1118,6 +1711,8 @@ impl OverrideSettingPattern { let css_formatter = &self.languages.css.formatter; let formatter = &self.formatter; + // Formatter settings which are also in top-level + if let Some(indent_style) = css_formatter.indent_style.or(formatter.indent_style) { options.set_indent_style(indent_style); } @@ -1130,6 +1725,9 @@ impl OverrideSettingPattern { if let Some(line_width) = css_formatter.line_width.or(formatter.line_width) { options.set_line_width(line_width); } + + // Formatter settings which are language-specific + if let Some(quote_style) = css_formatter.quote_style { options.set_quote_style(quote_style); } @@ -1140,6 +1738,10 @@ impl OverrideSettingPattern { } } + // endregion + + // region: GraphQL + fn apply_overrides_to_graphql_format_options(&self, options: &mut GraphqlFormatOptions) { if let Ok(readonly_cache) = self.cached_graphql_format_options.read() { if let Some(cached_options) = readonly_cache.as_ref() { @@ -1151,6 +1753,8 @@ impl OverrideSettingPattern { let graphql_formatter = &self.languages.graphql.formatter; let formatter = &self.formatter; + // Formatter settings which are also in top-level + if let Some(indent_style) = graphql_formatter.indent_style.or(formatter.indent_style) { options.set_indent_style(indent_style); } @@ -1169,6 +1773,9 @@ impl OverrideSettingPattern { { options.set_bracket_spacing(bracket_spacing); } + + // Formatter settings which are language-specific + if let Some(quote_style) = graphql_formatter.quote_style { options.set_quote_style(quote_style); } @@ -1179,58 +1786,7 @@ impl OverrideSettingPattern { } } - fn apply_overrides_to_js_parser_options(&self, options: &mut JsParserOptions) { - if let Ok(readonly_cache) = self.cached_js_parser_options.read() { - if let Some(cached_options) = readonly_cache.as_ref() { - *options = cached_options.clone(); - return; - } - } - - let js_parser = &self.languages.javascript.parser; - - options.parse_class_parameter_decorators = js_parser.parse_class_parameter_decorators; - - if let Ok(mut writeonly_cache) = self.cached_js_parser_options.write() { - let options = options.clone(); - let _ = writeonly_cache.insert(options); - } - } - - fn apply_overrides_to_json_parser_options(&self, options: &mut JsonParserOptions) { - // these options are no longer cached because it was causing incorrect override behavior, see #3260 - let json_parser = &self.languages.json.parser; - - if let Some(allow_comments) = json_parser.allow_comments { - options.allow_comments = allow_comments; - } - if let Some(allow_trailing_commas) = json_parser.allow_trailing_commas { - options.allow_trailing_commas = allow_trailing_commas; - } - } - - fn apply_overrides_to_css_parser_options(&self, options: &mut CssParserOptions) { - if let Ok(readonly_cache) = self.cached_css_parser_options.read() { - if let Some(cached_options) = readonly_cache.as_ref() { - *options = *cached_options; - return; - } - } - - let css_parser = &self.languages.css.parser; - - if let Some(allow_wrong_line_comments) = css_parser.allow_wrong_line_comments { - options.allow_wrong_line_comments = allow_wrong_line_comments; - } - if let Some(css_modules) = css_parser.css_modules { - options.css_modules = css_modules; - } - - if let Ok(mut writeonly_cache) = self.cached_css_parser_options.write() { - let options = *options; - let _ = writeonly_cache.insert(options); - } - } + // endregion #[allow(dead_code)] // NOTE: Currently not used because the rule options are typed using TypeId and Any, which isn't thread safe. @@ -1238,332 +1794,38 @@ impl OverrideSettingPattern { fn analyzer_rules_mut(&self, _analyzer_rules: &mut AnalyzerRules) {} } -/// Creates a [Matcher] from a [StringSet] +// endregion + +/// Checks the feature activity according to language-specific +/// and top level feature activities. /// -/// ## Errors +/// ```markdown +/// | Top \ Lang | Some(T) | Some(F) | N | +/// | :--------: | :-----: | :-----: | :-----: | +/// | Some(T) | Some(T) | Some(F) | N | <-- notice: not Some(T) +/// | Some(F) | Some(T) | Some(F) | Some(F) | +/// | N | Some(T) | Some(F) | N | +/// ``` /// -/// It can raise an error if the patterns aren't valid -pub fn to_matcher( - working_directory: Option, - string_set: Option<&StringSet>, -) -> Result { - let mut matcher = Matcher::empty(); - if let Some(working_directory) = working_directory { - matcher.set_root(working_directory) - } - if let Some(string_set) = string_set { - for pattern in string_set.iter() { - matcher.add_pattern(pattern).map_err(|err| { - BiomeDiagnostic::new_invalid_ignore_pattern( - pattern.to_string(), - err.msg.to_string(), - ) - })?; - } - } - Ok(matcher) -} - -fn to_git_ignore(path: PathBuf, matches: &[String]) -> Result { - let mut gitignore_builder = GitignoreBuilder::new(path.clone()); - - for the_match in matches { - gitignore_builder - .add_line(Some(path.clone()), the_match) - .map_err(|err| { - BiomeDiagnostic::InvalidIgnorePattern(InvalidIgnorePattern { - message: err.to_string(), - file_path: path.to_str().map(|s| s.to_string()), - }) - })?; - } - let gitignore = gitignore_builder.build().map_err(|err| { - BiomeDiagnostic::InvalidIgnorePattern(InvalidIgnorePattern { - message: err.to_string(), - file_path: path.to_str().map(|s| s.to_string()), - }) - })?; - Ok(gitignore) -} - -pub fn to_organize_imports_settings( - working_directory: Option, - organize_imports: OrganizeImports, -) -> Result { - Ok(OrganizeImportsSettings { - enabled: organize_imports.enabled, - ignored_files: to_matcher(working_directory.clone(), Some(&organize_imports.ignore))?, - included_files: to_matcher(working_directory, Some(&organize_imports.include))?, - }) -} - -impl TryFrom for OrganizeImportsSettings { - type Error = WorkspaceError; - - fn try_from( - organize_imports: OverrideOrganizeImportsConfiguration, - ) -> Result { - Ok(Self { - enabled: organize_imports.enabled.unwrap_or_default(), - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - }) - } -} - -pub fn to_override_settings( - working_directory: Option, - overrides: Overrides, - current_settings: &Settings, -) -> Result { - let mut override_settings = OverrideSettings::default(); - for mut pattern in overrides.0 { - let formatter = pattern - .formatter - .map(|formatter| OverrideFormatSettings { - enabled: formatter.enabled, - format_with_errors: formatter - .format_with_errors - .unwrap_or(current_settings.formatter.format_with_errors), - indent_style: formatter - .indent_style - .map(|indent_style| indent_style.into()), - indent_width: formatter.indent_width, - line_ending: formatter.line_ending, - line_width: formatter.line_width, - bracket_spacing: formatter.bracket_spacing, - attribute_position: formatter.attribute_position, - }) - .unwrap_or_default(); - let linter = pattern - .linter - .map(|linter| OverrideLinterSettings { - enabled: linter.enabled, - rules: linter.rules, - }) - .unwrap_or_default(); - let organize_imports = OverrideOrganizeImportsSettings { - enabled: pattern - .organize_imports - .and_then(|organize_imports| organize_imports.enabled), - }; - - let mut languages = LanguageListSettings::default(); - let javascript = pattern.javascript.take().unwrap_or_default(); - let json = pattern.json.take().unwrap_or_default(); - let css = pattern.css.take().unwrap_or_default(); - let graphql = pattern.graphql.take().unwrap_or_default(); - languages.javascript = - to_javascript_language_settings(javascript, ¤t_settings.languages.javascript); - - languages.json = to_json_language_settings(json, ¤t_settings.languages.json); - languages.css = to_css_language_settings(css, ¤t_settings.languages.css); - languages.graphql = - to_graphql_language_settings(graphql, ¤t_settings.languages.graphql); - - let pattern_setting = OverrideSettingPattern { - include: to_matcher(working_directory.clone(), pattern.include.as_ref())?, - exclude: to_matcher(working_directory.clone(), pattern.ignore.as_ref())?, - formatter, - linter, - organize_imports, - languages, - ..OverrideSettingPattern::default() - }; - - override_settings.patterns.push(pattern_setting); - } - - Ok(override_settings) -} - -fn to_javascript_language_settings( - mut conf: PartialJavascriptConfiguration, - parent_settings: &LanguageSettings, -) -> LanguageSettings { - let mut language_setting: LanguageSettings = LanguageSettings::default(); - let formatter = conf.formatter.take().unwrap_or_default(); - language_setting.formatter.quote_style = formatter.quote_style; - language_setting.formatter.jsx_quote_style = formatter.jsx_quote_style; - language_setting.formatter.quote_properties = formatter.quote_properties; - language_setting.formatter.trailing_commas = - formatter.trailing_commas.or(formatter.trailing_comma); - language_setting.formatter.semicolons = formatter.semicolons; - language_setting.formatter.arrow_parentheses = formatter.arrow_parentheses; - language_setting.formatter.bracket_spacing = formatter.bracket_spacing; - language_setting.formatter.bracket_same_line = formatter.bracket_same_line.map(Into::into); - language_setting.formatter.enabled = formatter.enabled; - language_setting.formatter.line_width = formatter.line_width; - language_setting.formatter.line_ending = formatter.line_ending; - language_setting.formatter.indent_width = formatter - .indent_width - .map(Into::into) - .or(formatter.indent_size.map(Into::into)); - language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); - - let parser = conf.parser.take().unwrap_or_default(); - let parent_parser = &parent_settings.parser; - language_setting.parser.parse_class_parameter_decorators = parser - .unsafe_parameter_decorators_enabled - .unwrap_or(parent_parser.parse_class_parameter_decorators); - - let organize_imports = conf.organize_imports; - if let Some(_organize_imports) = organize_imports {} - - language_setting.globals = conf.globals.map(StringSet::into_index_set); - - language_setting.environment.jsx_runtime = conf - .jsx_runtime - .unwrap_or(parent_settings.environment.jsx_runtime); - - language_setting -} - -fn to_json_language_settings( - mut conf: PartialJsonConfiguration, - parent_settings: &LanguageSettings, -) -> LanguageSettings { - let mut language_setting: LanguageSettings = LanguageSettings::default(); - let formatter = conf.formatter.take().unwrap_or_default(); - - language_setting.formatter.enabled = formatter.enabled; - language_setting.formatter.line_width = formatter.line_width; - language_setting.formatter.line_ending = formatter.line_ending; - language_setting.formatter.indent_width = formatter - .indent_width - .map(Into::into) - .or(formatter.indent_size.map(Into::into)); - language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); - language_setting.formatter.trailing_commas = formatter.trailing_commas; - - let parser = conf.parser.take().unwrap_or_default(); - let parent_parser = &parent_settings.parser; - language_setting.parser.allow_comments = parser.allow_comments.or(parent_parser.allow_comments); - - language_setting.parser.allow_trailing_commas = parser - .allow_trailing_commas - .or(parent_parser.allow_trailing_commas); - - language_setting -} - -fn to_css_language_settings( - mut conf: PartialCssConfiguration, - parent_settings: &LanguageSettings, -) -> LanguageSettings { - let mut language_setting: LanguageSettings = LanguageSettings::default(); - let formatter = conf.formatter.take().unwrap_or_default(); - - language_setting.formatter.enabled = formatter.enabled; - language_setting.formatter.line_width = formatter.line_width; - language_setting.formatter.line_ending = formatter.line_ending; - language_setting.formatter.indent_width = formatter.indent_width.map(Into::into); - language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); - language_setting.formatter.quote_style = formatter.quote_style; - - let parser = conf.parser.take().unwrap_or_default(); - let parent_parser = &parent_settings.parser; - language_setting.parser.allow_wrong_line_comments = parser - .allow_wrong_line_comments - .or(parent_parser.allow_wrong_line_comments); - language_setting.parser.css_modules = parser.css_modules.or(parent_parser.css_modules); - - language_setting -} - -fn to_graphql_language_settings( - mut conf: PartialGraphqlConfiguration, - _parent_settings: &LanguageSettings, -) -> LanguageSettings { - let mut language_setting: LanguageSettings = LanguageSettings::default(); - let formatter = conf.formatter.take().unwrap_or_default(); - - language_setting.formatter.enabled = formatter.enabled; - language_setting.formatter.line_width = formatter.line_width; - language_setting.formatter.line_ending = formatter.line_ending; - language_setting.formatter.indent_width = formatter.indent_width.map(Into::into); - language_setting.formatter.indent_style = formatter.indent_style.map(Into::into); - language_setting.formatter.quote_style = formatter.quote_style; - language_setting.formatter.bracket_spacing = formatter.bracket_spacing; - - language_setting -} - -pub fn to_format_settings( - working_directory: Option, - conf: FormatterConfiguration, -) -> Result { - let indent_style = match conf.indent_style { - PlainIndentStyle::Tab => IndentStyle::Tab, - PlainIndentStyle::Space => IndentStyle::Space, - }; - let indent_width = conf.indent_width; - - Ok(FormatSettings { - enabled: conf.enabled, - indent_style: Some(indent_style), - indent_width: Some(indent_width), - line_ending: Some(conf.line_ending), - line_width: Some(conf.line_width), - format_with_errors: conf.format_with_errors, - attribute_position: Some(conf.attribute_position), - bracket_spacing: Some(conf.bracket_spacing), - ignored_files: to_matcher(working_directory.clone(), Some(&conf.ignore))?, - included_files: to_matcher(working_directory, Some(&conf.include))?, - }) -} - -impl TryFrom for FormatSettings { - type Error = WorkspaceError; - - fn try_from(conf: OverrideFormatterConfiguration) -> Result { - let indent_style = match conf.indent_style { - Some(PlainIndentStyle::Tab) => IndentStyle::Tab, - Some(PlainIndentStyle::Space) => IndentStyle::Space, - None => IndentStyle::default(), - }; - let indent_width = conf - .indent_width - .map(Into::into) - .or(conf.indent_size.map(Into::into)) - .unwrap_or_default(); - - Ok(Self { - enabled: conf.enabled.unwrap_or_default(), - indent_style: Some(indent_style), - indent_width: Some(indent_width), - line_ending: conf.line_ending, - line_width: conf.line_width, - attribute_position: Some(AttributePosition::default()), - bracket_spacing: Some(BracketSpacing::default()), - format_with_errors: conf.format_with_errors.unwrap_or_default(), - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - }) - } -} - -pub fn to_linter_settings( - working_directory: Option, - conf: LinterConfiguration, -) -> Result { - Ok(LinterSettings { - enabled: conf.enabled, - rules: Some(conf.rules), - ignored_files: to_matcher(working_directory.clone(), Some(&conf.ignore))?, - included_files: to_matcher(working_directory.clone(), Some(&conf.include))?, - }) -} - -impl TryFrom for LinterSettings { - type Error = WorkspaceError; - - fn try_from(conf: OverrideLinterConfiguration) -> Result { - Ok(Self { - enabled: conf.enabled.unwrap_or_default(), - rules: conf.rules, - ignored_files: Matcher::empty(), - included_files: Matcher::empty(), - }) - } +/// The reason for the notice is that we don't want a top level +/// feature to override the language-specific feature whose default +/// value is false but in an "unset" state (`None`). So that we can +/// still use `.unwrap_or_default()` to retrieve the correct +/// fallback value. This happens when we want to mark the features +/// of some languages as opt-in. +/// +fn check_feature_activity( + language_specific_feature_activity: Option>, + top_level_feature_activity: Option>, +) -> Option> { + // Check the language-specific feature first + language_specific_feature_activity + // Then check the top level feature + .or(top_level_feature_activity.and_then(|v| { + if v.into() { + None + } else { + Some(v.value().into()) + } + })) } diff --git a/crates/biome_service/src/workspace.rs b/crates/biome_service/src/workspace.rs index ee323bd49cf1..86e9fee42290 100644 --- a/crates/biome_service/src/workspace.rs +++ b/crates/biome_service/src/workspace.rs @@ -59,7 +59,7 @@ use crate::{Deserialize, Serialize, WorkspaceError}; use biome_analyze::ActionCategory; pub use biome_analyze::RuleCategories; use biome_configuration::linter::RuleSelector; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::{markup, Markup, MarkupBuf}; use biome_diagnostics::CodeSuggestion; use biome_formatter::Printed; @@ -160,49 +160,47 @@ impl FileFeaturesResult { file_source: &DocumentFileSource, path: &Path, ) -> Self { - let formatter_disabled = - if let Some(disabled) = settings.override_settings.formatter_disabled(path) { - disabled - } else if file_source.is_javascript_like() { - !settings.formatter().enabled || settings.javascript_formatter_disabled() - } else if file_source.is_json_like() { - !settings.formatter().enabled || settings.json_formatter_disabled() - } else if file_source.is_css_like() { - !settings.formatter().enabled || settings.css_formatter_disabled() - } else { - !settings.formatter().enabled - }; - if formatter_disabled { + // formatter + let formatter_enabled = if file_source.is_javascript_like() { + settings.formatter_enabled_for_this_js_file_path(path) + } else if file_source.is_json_like() { + settings.formatter_enabled_for_this_json_file_path(path) + } else if file_source.is_css_like() { + settings.formatter_enabled_for_this_css_file_path(path) + } else { + settings.formatter_enabled_for_this_file_path(path) + }; + if !formatter_enabled { self.features_supported .insert(FeatureKind::Format, SupportKind::FeatureNotEnabled); } + // linter - let linter_disabled = { - if let Some(disabled) = settings.override_settings.linter_disabled(path) { - disabled - } else if file_source.is_javascript_like() { - !settings.linter().enabled || settings.javascript_linter_disabled() - } else if file_source.is_json_like() { - !settings.linter().enabled || settings.json_linter_disabled() - } else if file_source.is_css_like() { - !settings.linter().enabled || settings.css_linter_disabled() - } else { - !settings.linter().enabled - } + let linter_enabled = if file_source.is_javascript_like() { + settings.linter_enabled_for_this_js_file_path(path) + } else if file_source.is_json_like() { + settings.linter_enabled_for_this_json_file_path(path) + } else if file_source.is_css_like() { + settings.linter_enabled_for_this_css_file_path(path) + } else { + settings.linter_enabled_for_this_file_path(path) }; - - if linter_disabled { + if !linter_enabled { self.features_supported .insert(FeatureKind::Lint, SupportKind::FeatureNotEnabled); } // organize imports - if let Some(disabled) = settings.override_settings.organize_imports_disabled(path) { - if disabled { - self.features_supported - .insert(FeatureKind::OrganizeImports, SupportKind::FeatureNotEnabled); - } - } else if !settings.organize_imports().enabled { + let organize_imports_enabled = if file_source.is_javascript_like() { + settings.organize_imports_enabled_for_this_js_file_path(path) + } else if file_source.is_json_like() { + settings.organize_imports_enabled_for_this_json_file_path(path) + } else if file_source.is_css_like() { + settings.organize_imports_enabled_for_this_css_file_path(path) + } else { + settings.organize_imports_enabled_for_this_file_path(path) + }; + if !organize_imports_enabled { self.features_supported .insert(FeatureKind::OrganizeImports, SupportKind::FeatureNotEnabled); } @@ -447,7 +445,7 @@ impl FeaturesBuilder { #[derive(Debug, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct UpdateSettingsParams { - pub configuration: PartialConfiguration, + pub configuration: Configuration, // @ematipico TODO: have a better data structure for this pub vcs_base_path: Option, // @ematipico TODO: have a better data structure for this diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index 9fab2264ca61..f6e5921670b7 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -19,7 +19,6 @@ use crate::workspace::{ use crate::{ file_handlers::Features, settings::WorkspaceSettingsHandle, Workspace, WorkspaceError, }; -use biome_configuration::DEFAULT_FILE_SIZE_LIMIT; use biome_diagnostics::{ serde::Diagnostic as SerdeDiagnostic, Diagnostic, DiagnosticExt, Severity, }; @@ -27,7 +26,7 @@ use biome_formatter::Printed; use biome_fs::{BiomePath, ConfigName}; use biome_grit_patterns::GritQuery; use biome_js_syntax::ModuleKind; -use biome_json_parser::{parse_json_with_cache, JsonParserOptions}; +use biome_json_parser::{parse_json_with_cache, JsonParseOptions}; use biome_json_syntax::JsonFileSource; use biome_parser::AnyParse; use biome_project::{NodeJsProject, PackageType}; @@ -164,7 +163,7 @@ impl WorkspaceServer { let parsed = parse_json_with_cache( document.content.as_str(), &mut document.node_cache, - JsonParserOptions::default(), + JsonParseOptions::default(), ); let mut node_js_project = NodeJsProject::default(); @@ -226,9 +225,7 @@ impl WorkspaceServer { let size_limit = { let workspace = self.workspace(); let settings = workspace.settings(); - let limit = - settings.map_or(DEFAULT_FILE_SIZE_LIMIT.get(), |s| s.files.max_size.get()); - usize::try_from(limit).unwrap_or(usize::MAX) + usize::from(settings.and_then(|s| s.files.max_size).unwrap_or_default()) }; let document = &mut *document; @@ -371,7 +368,7 @@ impl Workspace for WorkspaceServer { }; file_features = file_features.with_settings_and_language(settings, &language, path); - if settings.files.ignore_unknown + if settings.ignore_unknown_enabled() && language == DocumentFileSource::Unknown && self.get_file_source(¶ms.path) == DocumentFileSource::Unknown { @@ -540,7 +537,9 @@ impl Workspace for WorkspaceServer { let parse = self.get_parse(params.path.clone())?; if let Some(settings) = settings { - if !settings.formatter().format_with_errors && parse.has_errors() { + if !settings.format_with_errors_enabled_for_this_file_path(¶ms.path) + && parse.has_errors() + { return Err(WorkspaceError::format_with_errors_disabled()); } } @@ -679,7 +678,9 @@ impl Workspace for WorkspaceServer { let parse = self.get_parse(params.path.clone())?; if let Some(settings) = settings { - if !settings.formatter().format_with_errors && parse.has_errors() { + if !settings.format_with_errors_enabled_for_this_file_path(¶ms.path) + && parse.has_errors() + { return Err(WorkspaceError::format_with_errors_disabled()); } } @@ -698,7 +699,9 @@ impl Workspace for WorkspaceServer { let parse = self.get_parse(params.path.clone())?; if let Some(settings) = settings { - if !settings.formatter().format_with_errors && parse.has_errors() { + if !settings.format_with_errors_enabled_for_this_file_path(¶ms.path) + && parse.has_errors() + { return Err(WorkspaceError::format_with_errors_disabled()); } } @@ -723,7 +726,9 @@ impl Workspace for WorkspaceServer { let settings = workspace.settings(); let parse = self.get_parse(params.path.clone())?; if let Some(settings) = settings { - if !settings.formatter().format_with_errors && parse.has_errors() { + if !settings.format_with_errors_enabled_for_this_file_path(¶ms.path) + && parse.has_errors() + { return Err(WorkspaceError::format_with_errors_disabled()); } } diff --git a/crates/biome_service/tests/spec_tests.rs b/crates/biome_service/tests/spec_tests.rs index ce1176709932..d4284c4e62c2 100644 --- a/crates/biome_service/tests/spec_tests.rs +++ b/crates/biome_service/tests/spec_tests.rs @@ -1,7 +1,7 @@ -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_deserialize::json::deserialize_from_json_str; use biome_diagnostics::{print_diagnostic_to_string, DiagnosticExt}; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use std::ffi::OsStr; use std::fs::read_to_string; use std::path::Path; @@ -17,14 +17,14 @@ fn run_invalid_configurations(input: &'static str, _: &str, _: &str, _: &str) { .unwrap_or_else(|err| panic!("failed to read {input_file:?}: {err:?}")); let result = match extension { - "json" => deserialize_from_json_str::( + "json" => deserialize_from_json_str::( input_code.as_str(), - JsonParserOptions::default(), + JsonParseOptions::default(), "", ), - "jsonc" => deserialize_from_json_str::( + "jsonc" => deserialize_from_json_str::( input_code.as_str(), - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), "", @@ -68,14 +68,14 @@ fn run_valid_configurations(input: &'static str, _: &str, _: &str, _: &str) { .unwrap_or_else(|err| panic!("failed to read {input_file:?}: {err:?}")); let result = match extension { - "json" => deserialize_from_json_str::( + "json" => deserialize_from_json_str::( input_code.as_str(), - JsonParserOptions::default(), + JsonParseOptions::default(), "", ), - "jsonc" => deserialize_from_json_str::( + "jsonc" => deserialize_from_json_str::( input_code.as_str(), - JsonParserOptions::default() + JsonParseOptions::default() .with_allow_comments() .with_allow_trailing_commas(), "", @@ -122,7 +122,7 @@ fn quick_test() { } }"#; let result = - deserialize_from_json_str::(source, JsonParserOptions::default(), ""); + deserialize_from_json_str::(source, JsonParseOptions::default(), ""); dbg!(result.diagnostics()); assert!(!result.has_errors()); diff --git a/crates/biome_test_utils/src/lib.rs b/crates/biome_test_utils/src/lib.rs index 608b8949f114..4ea3d2489705 100644 --- a/crates/biome_test_utils/src/lib.rs +++ b/crates/biome_test_utils/src/lib.rs @@ -1,11 +1,11 @@ use biome_analyze::options::{JsxRuntime, PreferredQuote}; use biome_analyze::{AnalyzerAction, AnalyzerConfiguration, AnalyzerOptions, AnalyzerRules}; -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_console::fmt::{Formatter, Termcolor}; use biome_console::markup; use biome_diagnostics::termcolor::Buffer; use biome_diagnostics::{DiagnosticExt, Error, PrintDiagnostic}; -use biome_json_parser::{JsonParserOptions, ParseDiagnostic}; +use biome_json_parser::{JsonParseOptions, ParseDiagnostic}; use biome_project::PackageJson; use biome_rowan::{SyntaxKind, SyntaxNode, SyntaxSlot}; use biome_service::configuration::to_analyzer_rules; @@ -46,9 +46,9 @@ pub fn create_analyzer_options( }; let options_file = input_file.with_extension("options.json"); if let Ok(json) = std::fs::read_to_string(options_file.clone()) { - let deserialized = biome_deserialize::json::deserialize_from_json_str::( + let deserialized = biome_deserialize::json::deserialize_from_json_str::( json.as_str(), - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); if deserialized.has_errors() { @@ -112,7 +112,7 @@ pub fn load_manifest(input_file: &Path, diagnostics: &mut Vec) -> Option if let Ok(json) = std::fs::read_to_string(options_file.clone()) { let deserialized = biome_deserialize::json::deserialize_from_json_str::( json.as_str(), - JsonParserOptions::default(), + JsonParseOptions::default(), "", ); if deserialized.has_errors() { diff --git a/xtask/bench/src/language.rs b/xtask/bench/src/language.rs index 568a3c7e4d85..27168181ff67 100644 --- a/xtask/bench/src/language.rs +++ b/xtask/bench/src/language.rs @@ -2,16 +2,16 @@ use crate::test_case::TestCase; use biome_analyze::options::JsxRuntime; use biome_analyze::{AnalysisFilter, AnalyzerOptions, ControlFlow, Never, RuleCategoriesBuilder}; use biome_css_formatter::context::{CssFormatContext, CssFormatOptions}; -use biome_css_parser::CssParserOptions; +use biome_css_parser::CssParseOptions; use biome_css_syntax::{CssRoot, CssSyntaxNode}; use biome_formatter::{FormatResult, Formatted, PrintResult, Printed}; use biome_graphql_formatter::context::{GraphqlFormatContext, GraphqlFormatOptions}; use biome_graphql_syntax::GraphqlSyntaxNode; use biome_js_formatter::context::{JsFormatContext, JsFormatOptions}; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{AnyJsRoot, JsFileSource, JsSyntaxNode}; use biome_json_formatter::context::{JsonFormatContext, JsonFormatOptions}; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_json_syntax::JsonSyntaxNode; use biome_parser::prelude::ParseDiagnostic; use biome_rowan::NodeCache; @@ -40,16 +40,16 @@ impl<'a> Parse<'a> { pub fn parse(&self) -> Parsed { match self { Parse::JavaScript(source_type, code) => Parsed::JavaScript( - biome_js_parser::parse(code, *source_type, JsParserOptions::default()), + biome_js_parser::parse(code, *source_type, JsParseOptions::default()), *source_type, ), Parse::Json(code) => Parsed::Json(biome_json_parser::parse_json( code, - JsonParserOptions::default(), + JsonParseOptions::default(), )), Parse::Css(code) => Parsed::Css(biome_css_parser::parse_css( code, - CssParserOptions::default() + CssParseOptions::default() .allow_wrong_line_comments() .allow_css_modules(), )), @@ -63,7 +63,7 @@ impl<'a> Parse<'a> { biome_js_parser::parse_js_with_cache( code, *source_type, - JsParserOptions::default(), + JsParseOptions::default(), cache, ), *source_type, @@ -71,12 +71,12 @@ impl<'a> Parse<'a> { Parse::Json(code) => Parsed::Json(biome_json_parser::parse_json_with_cache( code, cache, - JsonParserOptions::default(), + JsonParseOptions::default(), )), Parse::Css(code) => Parsed::Css(biome_css_parser::parse_css_with_cache( code, cache, - CssParserOptions::default() + CssParseOptions::default() .allow_wrong_line_comments() .allow_css_modules(), )), diff --git a/xtask/codegen/src/generate_bindings.rs b/xtask/codegen/src/generate_bindings.rs index f50d73798acd..15f938a6acff 100644 --- a/xtask/codegen/src/generate_bindings.rs +++ b/xtask/codegen/src/generate_bindings.rs @@ -309,7 +309,7 @@ pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { .build(), )); - // Export `PartialConfiguration` as `Configuration` for backwards compatibility. + // Export `Configuration` as `Configuration` for backwards compatibility. items.push(AnyJsModuleItem::JsExport(make::js_export( make::js_decorator_list([]), make::token(T![export]), @@ -320,7 +320,7 @@ pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { make::token(T![=]), AnyTsType::TsReferenceType( make::ts_reference_type(AnyTsName::JsReferenceIdentifier( - make::js_reference_identifier(make::ident("PartialConfiguration")), + make::js_reference_identifier(make::ident("Configuration")), )) .build(), ), diff --git a/xtask/codegen/src/generate_schema.rs b/xtask/codegen/src/generate_schema.rs index 0c3eb8c985e2..7e119fa5f10e 100644 --- a/xtask/codegen/src/generate_schema.rs +++ b/xtask/codegen/src/generate_schema.rs @@ -1,6 +1,6 @@ -use biome_configuration::PartialConfiguration; +use biome_configuration::Configuration; use biome_json_formatter::context::JsonFormatOptions; -use biome_json_parser::{parse_json, JsonParserOptions}; +use biome_json_parser::{parse_json, JsonParseOptions}; use schemars::schema::{RootSchema, Schema, SchemaObject}; use schemars::schema_for; use serde_json::to_string; @@ -10,10 +10,10 @@ use xtask_codegen::update; pub(crate) fn generate_configuration_schema(mode: Mode) -> Result<()> { let schema_path_npm = project_root().join("packages/@biomejs/biome/configuration_schema.json"); - let schema = rename_partial_references_in_schema(schema_for!(PartialConfiguration)); + let schema = rename_partial_references_in_schema(schema_for!(Configuration)); let json_schema = to_string(&schema)?; - let parsed = parse_json(&json_schema, JsonParserOptions::default()); + let parsed = parse_json(&json_schema, JsonParseOptions::default()); let formatted = biome_json_formatter::format_node(JsonFormatOptions::default(), &parsed.syntax()) .unwrap() diff --git a/xtask/coverage/src/js/test262.rs b/xtask/coverage/src/js/test262.rs index 7ed8593e8286..ce87cbceb21e 100644 --- a/xtask/coverage/src/js/test262.rs +++ b/xtask/coverage/src/js/test262.rs @@ -1,7 +1,7 @@ use crate::runner::{ create_bogus_node_in_tree_diagnostic, TestCase, TestCaseFiles, TestRunOutcome, TestSuite, }; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::JsFileSource; use biome_rowan::syntax::SyntaxKind; use biome_rowan::AstNode; @@ -99,7 +99,7 @@ impl Test262TestCase { .filter(|neg| neg.phase == Phase::Parse) .is_some(); - let options = JsParserOptions::default().with_parse_class_parameter_decorators(); + let options = JsParseOptions::default().with_parse_class_parameter_decorators(); let files = TestCaseFiles::single( self.name.clone(), self.code.clone(), diff --git a/xtask/coverage/src/jsx/jsx_babel.rs b/xtask/coverage/src/jsx/jsx_babel.rs index 5d78e313abc7..9fd848b098d6 100644 --- a/xtask/coverage/src/jsx/jsx_babel.rs +++ b/xtask/coverage/src/jsx/jsx_babel.rs @@ -3,7 +3,7 @@ use crate::{ check_file_encoding, runner::{TestCase, TestCaseFiles, TestRunOutcome, TestSuite}, }; -use biome_js_parser::{parse, JsParserOptions}; +use biome_js_parser::{parse, JsParseOptions}; use biome_js_syntax::{JsFileSource, ModuleKind}; use biome_rowan::SyntaxKind; use std::io; @@ -39,7 +39,7 @@ impl TestCase for BabelJsxTestCase { fn run(&self) -> TestRunOutcome { let source_type = JsFileSource::jsx().with_module_kind(ModuleKind::Script); - let options = JsParserOptions::default().with_parse_class_parameter_decorators(); + let options = JsParseOptions::default().with_parse_class_parameter_decorators(); let files = TestCaseFiles::single( self.name().to_string(), diff --git a/xtask/coverage/src/runner.rs b/xtask/coverage/src/runner.rs index 1fac5cb7679a..b42d3fdf5b13 100644 --- a/xtask/coverage/src/runner.rs +++ b/xtask/coverage/src/runner.rs @@ -5,7 +5,7 @@ use biome_diagnostics::console::markup; use biome_diagnostics::termcolor::Buffer; use biome_diagnostics::Error; use biome_diagnostics::PrintDiagnostic; -use biome_js_parser::{parse, JsParserOptions, Parse}; +use biome_js_parser::{parse, JsParseOptions, Parse}; use biome_js_syntax::{AnyJsRoot, JsFileSource, JsSyntaxNode}; use biome_rowan::SyntaxKind; use std::fmt::Debug; @@ -80,7 +80,7 @@ pub(crate) struct TestCaseFile { /// The source type used to parse the file source_type: JsFileSource, - options: JsParserOptions, + options: JsParseOptions, } impl TestCaseFile { @@ -116,7 +116,7 @@ impl TestCaseFiles { name: String, code: String, source_type: JsFileSource, - options: JsParserOptions, + options: JsParseOptions, ) -> Self { Self { files: vec![TestCaseFile { @@ -137,7 +137,7 @@ impl TestCaseFiles { name: String, code: String, source_type: JsFileSource, - options: JsParserOptions, + options: JsParseOptions, ) { self.files.push(TestCaseFile { name, diff --git a/xtask/coverage/src/symbols/msts.rs b/xtask/coverage/src/symbols/msts.rs index cf6aac2b76f8..6babc936ea91 100644 --- a/xtask/coverage/src/symbols/msts.rs +++ b/xtask/coverage/src/symbols/msts.rs @@ -5,7 +5,7 @@ use biome_rowan::TextSize; use super::utils::{parse_separated_list, parse_str, parse_until_chr, parse_whitespace0}; use crate::check_file_encoding; use crate::runner::{TestCase, TestCaseFiles, TestRunOutcome, TestSuite}; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use std::collections::HashSet; use std::fmt::Write; use std::io; @@ -38,7 +38,7 @@ impl TestCase for SymbolsMicrosoftTestCase { } fn run(&self) -> TestRunOutcome { - let options = JsParserOptions::default().with_parse_class_parameter_decorators(); + let options = JsParseOptions::default().with_parse_class_parameter_decorators(); let symbols = check_file_encoding(&self.path).unwrap(); let expected = load_symbols_file(&symbols); diff --git a/xtask/coverage/src/ts/ts_babel.rs b/xtask/coverage/src/ts/ts_babel.rs index 001c0f19d38d..b80fa50b5e16 100644 --- a/xtask/coverage/src/ts/ts_babel.rs +++ b/xtask/coverage/src/ts/ts_babel.rs @@ -3,7 +3,7 @@ use crate::{ check_file_encoding, runner::{TestCase, TestCaseFiles, TestRunOutcome, TestSuite}, }; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsFileSource, LanguageVariant}; use biome_rowan::SyntaxKind; use std::io; @@ -46,7 +46,7 @@ impl TestCase for BabelTypescriptTestCase { fn run(&self) -> TestRunOutcome { let source_type = JsFileSource::ts().with_variant(self.variant); - let options = JsParserOptions::default().with_parse_class_parameter_decorators(); + let options = JsParseOptions::default().with_parse_class_parameter_decorators(); let files = TestCaseFiles::single( self.name().to_string(), self.code.clone(), diff --git a/xtask/coverage/src/ts/ts_microsoft.rs b/xtask/coverage/src/ts/ts_microsoft.rs index 09a3e46bc319..c06c1551f802 100644 --- a/xtask/coverage/src/ts/ts_microsoft.rs +++ b/xtask/coverage/src/ts/ts_microsoft.rs @@ -2,7 +2,7 @@ use crate::check_file_encoding; use crate::runner::{ create_bogus_node_in_tree_diagnostic, TestCase, TestCaseFiles, TestRunOutcome, TestSuite, }; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{JsFileSource, ModuleKind}; use biome_rowan::{AstNode, SyntaxKind}; use regex::Regex; @@ -211,7 +211,7 @@ fn add_file_if_supported(files: &mut TestCaseFiles, name: String, content: Strin name, content, source_type, - JsParserOptions::default().with_parse_class_parameter_decorators(), + JsParseOptions::default().with_parse_class_parameter_decorators(), ) } } diff --git a/xtask/rules_check/src/lib.rs b/xtask/rules_check/src/lib.rs index b16ffc171387..834860f99a2f 100644 --- a/xtask/rules_check/src/lib.rs +++ b/xtask/rules_check/src/lib.rs @@ -8,12 +8,12 @@ use biome_analyze::{ RegistryVisitor, Rule, RuleCategory, RuleFilter, RuleGroup, RuleMetadata, }; use biome_console::{markup, Console}; -use biome_css_parser::CssParserOptions; +use biome_css_parser::CssParseOptions; use biome_css_syntax::CssLanguage; use biome_diagnostics::{Diagnostic, DiagnosticExt, PrintDiagnostic}; -use biome_js_parser::JsParserOptions; +use biome_js_parser::JsParseOptions; use biome_js_syntax::{EmbeddingKind, JsFileSource, JsLanguage}; -use biome_json_parser::JsonParserOptions; +use biome_json_parser::JsonParseOptions; use biome_json_syntax::JsonLanguage; use biome_service::settings::WorkspaceSettings; use biome_service::workspace::DocumentFileSource; @@ -224,7 +224,7 @@ fn assert_lint( _ => (code, file_source), }; - let parse = biome_js_parser::parse(code, file_source, JsParserOptions::default()); + let parse = biome_js_parser::parse(code, file_source, JsParseOptions::default()); if parse.has_errors() { for diag in parse.into_diagnostics() { @@ -278,7 +278,7 @@ fn assert_lint( } } DocumentFileSource::Json(file_source) => { - let parse = biome_json_parser::parse_json(code, JsonParserOptions::from(&file_source)); + let parse = biome_json_parser::parse_json(code, JsonParseOptions::from(&file_source)); if parse.has_errors() { for diag in parse.into_diagnostics() { @@ -329,7 +329,7 @@ fn assert_lint( } } DocumentFileSource::Css(..) => { - let parse = biome_css_parser::parse_css(code, CssParserOptions::default()); + let parse = biome_css_parser::parse_css(code, CssParseOptions::default()); if parse.has_errors() { for diag in parse.into_diagnostics() {