diff --git a/crates/biome_js_formatter/tests/language.rs b/crates/biome_js_formatter/tests/language.rs index 0ee6b64829a5..e8fd67ca178f 100644 --- a/crates/biome_js_formatter/tests/language.rs +++ b/crates/biome_js_formatter/tests/language.rs @@ -1,5 +1,6 @@ use biome_css_formatter::context::CssFormatOptions; use biome_css_parser::{parse_css, CssParserOptions}; +use biome_formatter::FormatError; use biome_formatter_test::TestFormatLanguage; use biome_fs::BiomePath; use biome_js_formatter::{context::JsFormatContext, JsForeignLanguageFormatter}; @@ -24,6 +25,7 @@ impl JsTestFormatLanguage { #[derive(Debug, Clone)] struct MultiLanguageFormatter { + format_with_errors: bool, css_parse_options: CssParserOptions, css_format_options: CssFormatOptions, } @@ -37,6 +39,9 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { match language { JsForeignLanguage::Css => { let parse = parse_css(source, self.css_parse_options); + if !self.format_with_errors && parse.has_errors() { + return Err(FormatError::SyntaxError); + } biome_css_formatter::format_node(self.css_format_options.clone(), &parse.syntax()) .map(|formatted| formatted.into_document()) } @@ -91,9 +96,11 @@ impl TestFormatLanguage for JsTestFormatLanguage { .quote_style .unwrap_or_default(), ); + let format_with_error = settings.formatter.format_with_errors; let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors: format_with_error, }; JsFormatLanguage::new(js_formatter_options, multi_language_formatter) } diff --git a/crates/biome_js_formatter/tests/prettier_tests.rs b/crates/biome_js_formatter/tests/prettier_tests.rs index a303f0b255d8..4a0e4019ca49 100644 --- a/crates/biome_js_formatter/tests/prettier_tests.rs +++ b/crates/biome_js_formatter/tests/prettier_tests.rs @@ -2,7 +2,7 @@ use std::{env, path::Path}; use biome_css_formatter::context::CssFormatOptions; use biome_css_parser::CssParserOptions; -use biome_formatter::{prelude::Document, FormatResult, IndentStyle, IndentWidth}; +use biome_formatter::{prelude::Document, FormatError, FormatResult, IndentStyle, IndentWidth}; use biome_formatter_test::test_prettier_snapshot::{PrettierSnapshot, PrettierTestFile}; use biome_js_formatter::{ context::JsFormatOptions, JsForeignLanguage, JsForeignLanguageFormatter, JsFormatLanguage, @@ -23,6 +23,9 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { let parse_options = CssParserOptions::default().allow_grit_metavariables(); let format_options = CssFormatOptions::default(); let parse = biome_css_parser::parse_css(source, parse_options); + if parse.has_errors() { + return Err(FormatError::SyntaxError); + } biome_css_formatter::format_node(format_options, &parse.syntax()) .map(|formatted| formatted.into_document()) } diff --git a/crates/biome_js_formatter/tests/quick_test.rs b/crates/biome_js_formatter/tests/quick_test.rs index ee6edf324607..c60498ddce44 100644 --- a/crates/biome_js_formatter/tests/quick_test.rs +++ b/crates/biome_js_formatter/tests/quick_test.rs @@ -1,7 +1,9 @@ use biome_css_formatter::context::CssFormatOptions; use biome_css_parser::{parse_css, CssParserOptions}; use biome_formatter::prelude::Document; -use biome_formatter::{AttributePosition, FormatResult, IndentStyle, LineWidth, QuoteStyle}; +use biome_formatter::{ + AttributePosition, FormatError, FormatResult, IndentStyle, LineWidth, QuoteStyle, +}; use biome_formatter_test::check_reformat::CheckReformat; use biome_js_formatter::context::{ArrowParentheses, JsFormatOptions, Semicolons}; use biome_js_formatter::{ @@ -16,6 +18,7 @@ mod language { #[derive(Debug, Clone)] struct MultiLanguageFormatter { + format_with_errors: bool, css_parse_options: CssParserOptions, css_format_options: CssFormatOptions, } @@ -25,6 +28,9 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { match language { JsForeignLanguage::Css => { let parse = parse_css(source, self.css_parse_options); + if parse.has_errors() && !self.format_with_errors { + return Err(FormatError::SyntaxError); + } biome_css_formatter::format_node(self.css_format_options.clone(), &parse.syntax()) .map(|formatted| formatted.into_document()) } @@ -68,6 +74,7 @@ function outerFunctionToForceIndent() { let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors: false, }; let doc = format_node( diff --git a/crates/biome_js_formatter/tests/spec_test.rs b/crates/biome_js_formatter/tests/spec_test.rs index 25c06f7a3600..306c92941607 100644 --- a/crates/biome_js_formatter/tests/spec_test.rs +++ b/crates/biome_js_formatter/tests/spec_test.rs @@ -1,5 +1,6 @@ use biome_css_formatter::context::CssFormatOptions; use biome_css_parser::{parse_css, CssParserOptions}; +use biome_formatter::FormatError; use biome_formatter_test::spec::{SpecSnapshot, SpecTestFile}; use biome_js_formatter::{ context::JsFormatOptions, JsForeignLanguage, JsForeignLanguageFormatter, JsFormatLanguage, @@ -12,10 +13,7 @@ mod language { } #[derive(Debug, Clone)] -struct MultiLanguageFormatter { - css_parse_options: CssParserOptions, - css_format_options: CssFormatOptions, -} +struct MultiLanguageFormatter; impl JsForeignLanguageFormatter for MultiLanguageFormatter { fn format( @@ -23,10 +21,15 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { language: biome_js_formatter::JsForeignLanguage, source: &str, ) -> biome_formatter::FormatResult { + let css_parse_options = CssParserOptions::default().allow_grit_metavariables(); + let css_format_options = CssFormatOptions::default(); match language { JsForeignLanguage::Css => { - let parse = parse_css(source, self.css_parse_options); - biome_css_formatter::format_node(self.css_format_options.clone(), &parse.syntax()) + let parse = parse_css(source, css_parse_options); + if parse.has_errors() { + return Err(FormatError::SyntaxError); + } + biome_css_formatter::format_node(css_format_options, &parse.syntax()) .map(|formatted| formatted.into_document()) } } @@ -63,19 +66,13 @@ pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, fi } let options = JsFormatOptions::new(source_type); - let css_parse_options = CssParserOptions::default().allow_grit_metavariables(); - let css_format_options = CssFormatOptions::default(); - let multi_language_formatter = MultiLanguageFormatter { - css_parse_options, - css_format_options, - }; let language = language::JsTestFormatLanguage::new(source_type); let snapshot = SpecSnapshot::new( test_file, test_directory, language, - JsFormatLanguage::new(options, multi_language_formatter), + JsFormatLanguage::new(options, MultiLanguageFormatter), ); snapshot.test() diff --git a/crates/biome_service/src/file_handlers/javascript.rs b/crates/biome_service/src/file_handlers/javascript.rs index f91180037c1d..49e3febbf204 100644 --- a/crates/biome_service/src/file_handlers/javascript.rs +++ b/crates/biome_service/src/file_handlers/javascript.rs @@ -306,6 +306,7 @@ impl ExtensionHandler for JsFileHandler { #[derive(Clone, Debug)] struct MultiLanguageFormatter { + format_with_errors: bool, css_parse_options: CssParserOptions, css_format_options: CssFormatOptions, } @@ -319,6 +320,9 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { match language { JsForeignLanguage::Css => { let parse = parse_css(content, self.css_parse_options); + if parse.has_errors() && !self.format_with_errors { + return Err(FormatError::SyntaxError); + } biome_css_formatter::format_node(self.css_format_options.clone(), &parse.syntax()) .map(|formatted| formatted.into_document()) } @@ -428,9 +432,14 @@ fn debug_formatter_ir( }) .unwrap_or_default(); let css_format_options = settings.format_options::(path, document_file_source); + let format_with_errors = settings + .settings() + .map(|settings| settings.formatter.format_with_errors) + .unwrap_or_default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; let tree = parse.syntax(); @@ -833,9 +842,14 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result(biome_path, &document_file_source); + let format_with_errors = workspace + .settings() + .map(|settings| settings.formatter.format_with_errors) + .unwrap_or_default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; let code = if should_format { format_node( @@ -883,9 +897,14 @@ pub(crate) fn format( .unwrap_or_default(); let css_format_options = settings.format_options::(biome_path, document_file_source); + let format_with_errors = settings + .settings() + .map(|settings| settings.formatter.format_with_errors) + .unwrap_or_default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; let formatted = format_node(options, multi_language_formatter, &tree)?; match formatted.print() { @@ -919,9 +938,14 @@ pub(crate) fn format_range( .unwrap_or_default(); let css_format_options = settings.format_options::(biome_path, document_file_source); + let format_with_errors = settings + .settings() + .map(|settings| settings.formatter.format_with_errors) + .unwrap_or_default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; let printed = biome_js_formatter::format_range(options, multi_language_formatter, &tree, range)?; @@ -972,9 +996,14 @@ pub(crate) fn format_on_type( }) .unwrap_or_default(); let css_format_options = settings.format_options::(path, document_file_source); + let format_with_errors = settings + .settings() + .map(|settings| settings.formatter.format_with_errors) + .unwrap_or_default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; let printed = diff --git a/xtask/bench/src/language.rs b/xtask/bench/src/language.rs index 7be5fc3de4e1..70cec3034973 100644 --- a/xtask/bench/src/language.rs +++ b/xtask/bench/src/language.rs @@ -2,9 +2,10 @@ 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::{parse_css, CssParserOptions}; use biome_css_syntax::{CssRoot, CssSyntaxNode}; -use biome_formatter::{FormatResult, Formatted, PrintResult, Printed}; +use biome_formatter::prelude::Document; +use biome_formatter::{FormatError, FormatResult, Formatted, PrintResult, Printed}; use biome_graphql_formatter::context::{GraphqlFormatContext, GraphqlFormatOptions}; use biome_graphql_syntax::GraphqlSyntaxNode; use biome_js_formatter::context::{JsFormatContext, JsFormatOptions}; @@ -130,17 +131,16 @@ impl Parsed { struct MultiLanguageFormatter; impl JsForeignLanguageFormatter for MultiLanguageFormatter { - fn format( - &self, - language: biome_js_formatter::JsForeignLanguage, - source: &str, - ) -> FormatResult { + fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult { match language { JsForeignLanguage::Css => { - let parse = biome_css_parser::parse_css( + let parse = parse_css( source, CssParserOptions::default().allow_grit_metavariables(), ); + if parse.has_errors() { + return Err(FormatError::SyntaxError); + } biome_css_formatter::format_node(CssFormatOptions::default(), &parse.syntax()) .map(|formatted| formatted.into_document()) }