From a27e7f6e4f69df0645ed540ee845e0c97b7be7f7 Mon Sep 17 00:00:00 2001 From: Zheyu Zhang Date: Wed, 10 Jul 2024 13:15:44 +0800 Subject: [PATCH 1/4] ability to format other languages --- Cargo.lock | 4 + crates/biome_js_formatter/Cargo.toml | 2 + crates/biome_js_formatter/src/context.rs | 14 ++- crates/biome_js_formatter/src/lib.rs | 71 +++++++++-- .../biome_js_formatter/src/syntax_rewriter.rs | 25 +++- crates/biome_js_formatter/tests/language.rs | 59 ++++++++- .../tests/prettier_tests.rs | 31 ++++- crates/biome_js_formatter/tests/quick_test.rs | 43 ++++++- crates/biome_js_formatter/tests/spec_test.rs | 36 +++++- crates/biome_js_transform/Cargo.toml | 1 + crates/biome_js_transform/tests/spec_tests.rs | 20 ++- .../src/file_handlers/javascript.rs | 114 +++++++++++++++++- crates/biome_wasm/Cargo.toml | 1 + crates/biome_wasm/build.rs | 23 +++- xtask/bench/src/language.rs | 32 ++++- 15 files changed, 437 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef2708145843..209e5e7379f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -773,6 +773,8 @@ dependencies = [ name = "biome_js_formatter" version = "0.5.7" dependencies = [ + "biome_css_formatter", + "biome_css_parser", "biome_deserialize", "biome_deserialize_macros", "biome_diagnostics_categories", @@ -858,6 +860,7 @@ version = "0.5.7" dependencies = [ "biome_analyze", "biome_diagnostics", + "biome_formatter", "biome_js_factory", "biome_js_formatter", "biome_js_parser", @@ -1212,6 +1215,7 @@ version = "1.7.3" dependencies = [ "biome_console", "biome_diagnostics", + "biome_formatter", "biome_js_factory", "biome_js_formatter", "biome_rowan", diff --git a/crates/biome_js_formatter/Cargo.toml b/crates/biome_js_formatter/Cargo.toml index 42016f709665..ee3c1bf9a204 100644 --- a/crates/biome_js_formatter/Cargo.toml +++ b/crates/biome_js_formatter/Cargo.toml @@ -30,6 +30,8 @@ smallvec = { workspace = true } unicode-width = { workspace = true } [dev-dependencies] +biome_css_formatter = { path = "../biome_css_formatter" } +biome_css_parser = { path = "../biome_css_parser" } biome_formatter_test = { path = "../biome_formatter_test" } biome_fs = { path = "../biome_fs" } biome_js_factory = { path = "../biome_js_factory" } diff --git a/crates/biome_js_formatter/src/context.rs b/crates/biome_js_formatter/src/context.rs index 4bbcb83f2aa9..6856047457e2 100644 --- a/crates/biome_js_formatter/src/context.rs +++ b/crates/biome_js_formatter/src/context.rs @@ -1,6 +1,7 @@ pub mod trailing_commas; use crate::comments::{FormatJsLeadingComment, JsCommentStyle, JsComments}; +use crate::JsForeignLanguageFormatter; use biome_deserialize_macros::{Deserializable, Merge}; use biome_formatter::printer::PrinterOptions; use biome_formatter::{ @@ -44,12 +45,19 @@ pub struct JsFormatContext { cached_function_body: Option<(AnyJsFunctionBody, FormatElement)>, source_map: Option, + + foreign_language_formatter: Rc, } impl JsFormatContext { - pub fn new(options: JsFormatOptions, comments: JsComments) -> Self { + pub fn new( + options: JsFormatOptions, + foreign_language_formatter: Rc, + comments: JsComments, + ) -> Self { Self { options, + foreign_language_formatter, comments: Rc::new(comments), cached_function_body: None, source_map: None, @@ -90,6 +98,10 @@ impl JsFormatContext { self.source_map = source_map; self } + + pub fn get_foreign_language_formatter(&self) -> &dyn JsForeignLanguageFormatter { + self.foreign_language_formatter.as_ref() + } } #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] diff --git a/crates/biome_js_formatter/src/lib.rs b/crates/biome_js_formatter/src/lib.rs index aa3398c25178..4f2cd493b398 100644 --- a/crates/biome_js_formatter/src/lib.rs +++ b/crates/biome_js_formatter/src/lib.rs @@ -178,6 +178,8 @@ mod parentheses; pub(crate) mod separated; mod syntax_rewriter; +use std::rc::Rc; + use biome_formatter::format_element::tag::Label; use biome_formatter::prelude::*; use biome_formatter::{ @@ -442,13 +444,28 @@ impl IntoFormat for JsSyntaxToken { } } +pub enum JsForeignLanguage { + Css, +} + +pub trait JsForeignLanguageFormatter: std::fmt::Debug + 'static { + fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult; +} + #[derive(Debug, Clone)] pub struct JsFormatLanguage { options: JsFormatOptions, + foreign_language_formatter: Rc, } impl JsFormatLanguage { - pub fn new(options: JsFormatOptions) -> Self { - Self { options } + pub fn new( + options: JsFormatOptions, + foreign_language_formatter: impl JsForeignLanguageFormatter, + ) -> Self { + Self { + options, + foreign_language_formatter: Rc::new(foreign_language_formatter), + } } } @@ -490,7 +507,8 @@ impl FormatLanguage for JsFormatLanguage { source_map: Option, ) -> Self::Context { let comments = Comments::from_node(root, &JsCommentStyle, source_map.as_ref()); - JsFormatContext::new(self.options, comments).with_source_map(source_map) + JsFormatContext::new(self.options, self.foreign_language_formatter, comments) + .with_source_map(source_map) } } @@ -507,10 +525,15 @@ impl FormatLanguage for JsFormatLanguage { /// range of the input that was effectively overwritten by the formatter pub fn format_range( options: JsFormatOptions, + foreign_language_formatter: impl JsForeignLanguageFormatter, root: &JsSyntaxNode, range: TextRange, ) -> FormatResult { - biome_formatter::format_range(root, range, JsFormatLanguage::new(options)) + biome_formatter::format_range( + root, + range, + JsFormatLanguage::new(options, foreign_language_formatter), + ) } /// Formats a JavaScript (and its super languages) file based on its features. @@ -518,9 +541,13 @@ pub fn format_range( /// It returns a [Formatted] result, which the user can use to override a file. pub fn format_node( options: JsFormatOptions, + foreign_language_formatter: impl JsForeignLanguageFormatter, root: &JsSyntaxNode, ) -> FormatResult> { - biome_formatter::format_node(root, JsFormatLanguage::new(options)) + biome_formatter::format_node( + root, + JsFormatLanguage::new(options, foreign_language_formatter), + ) } /// Formats a single node within a file, supported by Biome. @@ -533,8 +560,15 @@ pub fn format_node( /// even if it's a mismatch from the rest of the block the selection is in /// /// It returns a [Formatted] result -pub fn format_sub_tree(options: JsFormatOptions, root: &JsSyntaxNode) -> FormatResult { - biome_formatter::format_sub_tree(root, JsFormatLanguage::new(options)) +pub fn format_sub_tree( + options: JsFormatOptions, + foreign_language_formatter: impl JsForeignLanguageFormatter, + root: &JsSyntaxNode, +) -> FormatResult { + biome_formatter::format_sub_tree( + root, + JsFormatLanguage::new(options, foreign_language_formatter), + ) } #[derive(Copy, Clone, Debug)] @@ -559,12 +593,25 @@ mod tests { use super::format_range; - use crate::context::JsFormatOptions; - use biome_formatter::IndentStyle; + use crate::{context::JsFormatOptions, JsForeignLanguageFormatter}; + use biome_formatter::{prelude::Document, FormatError, IndentStyle}; use biome_js_parser::{parse, parse_script, JsParserOptions}; use biome_js_syntax::JsFileSource; use biome_rowan::{TextRange, TextSize}; + #[derive(Debug, Clone)] + struct FakeFormatter; + + impl JsForeignLanguageFormatter for FakeFormatter { + fn format( + &self, + _language: super::JsForeignLanguage, + _source: &str, + ) -> biome_formatter::FormatResult { + Err(FormatError::SyntaxError) + } + } + #[test] fn test_range_formatting() { let input = " @@ -600,6 +647,7 @@ while( JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) .with_indent_width(4.try_into().unwrap()), + FakeFormatter, &tree.syntax(), TextRange::new(range_start, range_end), ); @@ -634,6 +682,7 @@ function() { JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) .with_indent_width(4.try_into().unwrap()), + FakeFormatter, &tree.syntax(), TextRange::new(range_start, range_end), ); @@ -663,6 +712,7 @@ function() { JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) .with_indent_width(4.try_into().unwrap()), + FakeFormatter, &tree.syntax(), TextRange::new(range_start, range_end), ); @@ -693,6 +743,7 @@ function() { JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) .with_indent_width(4.try_into().unwrap()), + FakeFormatter, &tree.syntax(), range, ) @@ -726,6 +777,7 @@ function() { JsFormatOptions::new(JsFileSource::js_script()) .with_indent_style(IndentStyle::Space) .with_indent_width(4.try_into().unwrap()), + FakeFormatter, &tree.syntax(), range, ) @@ -747,6 +799,7 @@ function() { let result = format_range( JsFormatOptions::new(syntax), + FakeFormatter, &tree.syntax(), TextRange::new(TextSize::from(0), TextSize::of(src) + TextSize::from(5)), ); diff --git a/crates/biome_js_formatter/src/syntax_rewriter.rs b/crates/biome_js_formatter/src/syntax_rewriter.rs index ff39bd173032..f89e4703b4c5 100644 --- a/crates/biome_js_formatter/src/syntax_rewriter.rs +++ b/crates/biome_js_formatter/src/syntax_rewriter.rs @@ -464,8 +464,8 @@ fn has_type_cast_comment_or_skipped(trivia: &JsSyntaxTrivia) -> bool { #[cfg(test)] mod tests { use super::JsFormatSyntaxRewriter; - use crate::{format_node, JsFormatOptions, TextRange}; - use biome_formatter::{SourceMarker, TransformSourceMap}; + use crate::{format_node, JsForeignLanguageFormatter, JsFormatOptions, TextRange}; + use biome_formatter::{FormatError, SourceMarker, TransformSourceMap}; use biome_js_parser::{parse, parse_module, JsParserOptions}; use biome_js_syntax::{ JsArrayExpression, JsBinaryExpression, JsExpressionStatement, JsFileSource, @@ -838,12 +838,29 @@ mod tests { (transformed, source_map) } + #[derive(Debug, Clone)] + struct FakeFormatter; + + impl JsForeignLanguageFormatter for FakeFormatter { + fn format( + &self, + _language: crate::JsForeignLanguage, + _source: &str, + ) -> biome_formatter::FormatResult { + Err(FormatError::SyntaxError) + } + } + #[test] fn mappings() { let (transformed, source_map) = source_map_test("(((a * b) * c)) / 3"); - let formatted = - format_node(JsFormatOptions::new(JsFileSource::default()), &transformed).unwrap(); + let formatted = format_node( + JsFormatOptions::new(JsFileSource::default()), + FakeFormatter, + &transformed, + ) + .unwrap(); let printed = formatted.print().unwrap(); assert_eq!(printed.as_code(), "(a * b * c) / 3;\n"); diff --git a/crates/biome_js_formatter/tests/language.rs b/crates/biome_js_formatter/tests/language.rs index a94792bea95b..0ee6b64829a5 100644 --- a/crates/biome_js_formatter/tests/language.rs +++ b/crates/biome_js_formatter/tests/language.rs @@ -1,7 +1,9 @@ +use biome_css_formatter::context::CssFormatOptions; +use biome_css_parser::{parse_css, CssParserOptions}; use biome_formatter_test::TestFormatLanguage; use biome_fs::BiomePath; -use biome_js_formatter::context::JsFormatContext; -use biome_js_formatter::JsFormatLanguage; +use biome_js_formatter::{context::JsFormatContext, JsForeignLanguageFormatter}; +use biome_js_formatter::{JsForeignLanguage, JsFormatLanguage}; use biome_js_parser::{parse, JsParserOptions}; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_parser::AnyParse; @@ -20,6 +22,28 @@ impl JsTestFormatLanguage { } } +#[derive(Debug, Clone)] +struct MultiLanguageFormatter { + css_parse_options: CssParserOptions, + css_format_options: CssFormatOptions, +} + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format( + &self, + language: biome_js_formatter::JsForeignLanguage, + source: &str, + ) -> biome_formatter::FormatResult { + 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()) + .map(|formatted| formatted.into_document()) + } + } + } +} + impl TestFormatLanguage for JsTestFormatLanguage { type ServiceLanguage = JsLanguage; type Context = JsFormatContext; @@ -37,13 +61,40 @@ impl TestFormatLanguage for JsTestFormatLanguage { file_source: &DocumentFileSource, ) -> Self::FormatLanguage { let language_settings = &settings.languages.javascript.formatter; - let options = Self::ServiceLanguage::resolve_format_options( + let js_formatter_options = Self::ServiceLanguage::resolve_format_options( Some(&settings.formatter), Some(&settings.override_settings), Some(language_settings), &BiomePath::new(""), file_source, ); - JsFormatLanguage::new(options) + let css_parse_options = CssParserOptions { + css_modules: settings + .languages + .css + .parser + .css_modules + .unwrap_or_default(), + allow_wrong_line_comments: settings + .languages + .css + .parser + .allow_wrong_line_comments + .unwrap_or_default(), + grit_metavariable: true, + }; + let css_format_options = CssFormatOptions::default().with_quote_style( + settings + .languages + .css + .formatter + .quote_style + .unwrap_or_default(), + ); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; + 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 59175a3ecea2..a303f0b255d8 100644 --- a/crates/biome_js_formatter/tests/prettier_tests.rs +++ b/crates/biome_js_formatter/tests/prettier_tests.rs @@ -1,14 +1,35 @@ use std::{env, path::Path}; -use biome_formatter::{IndentStyle, IndentWidth}; +use biome_css_formatter::context::CssFormatOptions; +use biome_css_parser::CssParserOptions; +use biome_formatter::{prelude::Document, FormatResult, IndentStyle, IndentWidth}; use biome_formatter_test::test_prettier_snapshot::{PrettierSnapshot, PrettierTestFile}; -use biome_js_formatter::{context::JsFormatOptions, JsFormatLanguage}; +use biome_js_formatter::{ + context::JsFormatOptions, JsForeignLanguage, JsForeignLanguageFormatter, JsFormatLanguage, +}; use biome_js_syntax::{JsFileSource, LanguageVariant, ModuleKind}; mod language; tests_macros::gen_tests! {"tests/specs/prettier/{js,typescript,jsx}/**/*.{js,ts,jsx,tsx}", crate::test_snapshot, "script"} +#[derive(Debug, Clone)] +struct MultiLanguageFormatter; + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult { + match language { + JsForeignLanguage::Css => { + let parse_options = CssParserOptions::default().allow_grit_metavariables(); + let format_options = CssFormatOptions::default(); + let parse = biome_css_parser::parse_css(source, parse_options); + biome_css_formatter::format_node(format_options, &parse.syntax()) + .map(|formatted| formatted.into_document()) + } + } + } +} + fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) { countme::enable(true); @@ -45,7 +66,11 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) { let language = language::JsTestFormatLanguage::new(source_type); - let snapshot = PrettierSnapshot::new(test_file, language, JsFormatLanguage::new(options)); + let snapshot = PrettierSnapshot::new( + test_file, + language, + JsFormatLanguage::new(options, MultiLanguageFormatter), + ); snapshot.test() } diff --git a/crates/biome_js_formatter/tests/quick_test.rs b/crates/biome_js_formatter/tests/quick_test.rs index e2b38d871768..ee6edf324607 100644 --- a/crates/biome_js_formatter/tests/quick_test.rs +++ b/crates/biome_js_formatter/tests/quick_test.rs @@ -1,7 +1,12 @@ -use biome_formatter::{AttributePosition, IndentStyle, LineWidth, QuoteStyle}; +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_test::check_reformat::CheckReformat; use biome_js_formatter::context::{ArrowParentheses, JsFormatOptions, Semicolons}; -use biome_js_formatter::{format_node, JsFormatLanguage}; +use biome_js_formatter::{ + format_node, JsForeignLanguage, JsForeignLanguageFormatter, JsFormatLanguage, +}; use biome_js_parser::{parse, JsParserOptions}; use biome_js_syntax::JsFileSource; @@ -9,6 +14,24 @@ mod language { include!("language.rs"); } +#[derive(Debug, Clone)] +struct MultiLanguageFormatter { + css_parse_options: CssParserOptions, + css_format_options: CssFormatOptions, +} + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult { + 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()) + .map(|formatted| formatted.into_document()) + } + } + } +} + #[ignore] #[test] // use this test check if your snippet prints as you wish, without using a snapshot @@ -40,7 +63,19 @@ function outerFunctionToForceIndent() { .with_arrow_parentheses(ArrowParentheses::AsNeeded) .with_attribute_position(AttributePosition::Multiline); - let doc = format_node(options.clone(), &tree.syntax()).unwrap(); + 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 doc = format_node( + options.clone(), + multi_language_formatter.clone(), + &tree.syntax(), + ) + .unwrap(); let result = doc.print().unwrap(); println!("{}", doc.into_document()); @@ -51,7 +86,7 @@ function outerFunctionToForceIndent() { result.as_code(), "testing", &language::JsTestFormatLanguage::new(source_type), - JsFormatLanguage::new(options), + JsFormatLanguage::new(options, multi_language_formatter), ) .check_reformat(); } diff --git a/crates/biome_js_formatter/tests/spec_test.rs b/crates/biome_js_formatter/tests/spec_test.rs index c21eff69f01c..25c06f7a3600 100644 --- a/crates/biome_js_formatter/tests/spec_test.rs +++ b/crates/biome_js_formatter/tests/spec_test.rs @@ -1,5 +1,9 @@ +use biome_css_formatter::context::CssFormatOptions; +use biome_css_parser::{parse_css, CssParserOptions}; use biome_formatter_test::spec::{SpecSnapshot, SpecTestFile}; -use biome_js_formatter::{context::JsFormatOptions, JsFormatLanguage}; +use biome_js_formatter::{ + context::JsFormatOptions, JsForeignLanguage, JsForeignLanguageFormatter, JsFormatLanguage, +}; use biome_js_syntax::{JsFileSource, ModuleKind}; use std::path::Path; @@ -7,6 +11,28 @@ mod language { include!("language.rs"); } +#[derive(Debug, Clone)] +struct MultiLanguageFormatter { + css_parse_options: CssParserOptions, + css_format_options: CssFormatOptions, +} + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format( + &self, + language: biome_js_formatter::JsForeignLanguage, + source: &str, + ) -> biome_formatter::FormatResult { + 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()) + .map(|formatted| formatted.into_document()) + } + } + } +} + /// [insta.rs](https://insta.rs/docs) snapshot testing /// /// For better development workflow, run @@ -37,13 +63,19 @@ 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), + JsFormatLanguage::new(options, multi_language_formatter), ); snapshot.test() diff --git a/crates/biome_js_transform/Cargo.toml b/crates/biome_js_transform/Cargo.toml index cab161c52342..be9ebf6a8562 100644 --- a/crates/biome_js_transform/Cargo.toml +++ b/crates/biome_js_transform/Cargo.toml @@ -22,6 +22,7 @@ biome_rowan = { workspace = true } [dev-dependencies] biome_analyze = { path = "../biome_analyze" } +biome_formatter = { path = "../biome_formatter" } biome_js_formatter = { path = "../biome_js_formatter" } biome_js_parser = { path = "../biome_js_parser" } biome_test_utils = { path = "../biome_test_utils" } diff --git a/crates/biome_js_transform/tests/spec_tests.rs b/crates/biome_js_transform/tests/spec_tests.rs index ca9769a2fe64..b8fb0ea15ec4 100644 --- a/crates/biome_js_transform/tests/spec_tests.rs +++ b/crates/biome_js_transform/tests/spec_tests.rs @@ -1,6 +1,8 @@ use biome_analyze::{AnalysisFilter, AnalyzerTransformation, ControlFlow, Never, RuleFilter}; -use biome_js_formatter::context::JsFormatOptions; +use biome_formatter::prelude::Document; +use biome_formatter::{FormatError, FormatResult}; use biome_js_formatter::format_node; +use biome_js_formatter::{context::JsFormatOptions, JsForeignLanguageFormatter}; use biome_js_parser::{parse, JsParserOptions}; use biome_js_syntax::{JsFileSource, JsLanguage}; use biome_rowan::AstNode; @@ -87,6 +89,19 @@ fn run_test(input: &'static str, _: &str, _: &str, _: &str) { } } +#[derive(Debug, Clone)] +struct FakeFormatter; + +impl JsForeignLanguageFormatter for FakeFormatter { + fn format( + &self, + _language: biome_js_formatter::JsForeignLanguage, + _content: &str, + ) -> FormatResult { + Err(FormatError::SyntaxError) + } +} + #[allow(clippy::too_many_arguments)] pub(crate) fn analyze_and_snap( snapshot: &mut String, @@ -116,7 +131,8 @@ pub(crate) fn analyze_and_snap( ); let node = transformation.mutation.commit(); - let formatted = format_node(JsFormatOptions::new(source_type), &node).unwrap(); + let formatted = + format_node(JsFormatOptions::new(source_type), FakeFormatter, &node).unwrap(); transformations.push(formatted.print().unwrap().as_code().to_string()); } diff --git a/crates/biome_service/src/file_handlers/javascript.rs b/crates/biome_service/src/file_handlers/javascript.rs index b5d694b3194c..14b1597a6f85 100644 --- a/crates/biome_service/src/file_handlers/javascript.rs +++ b/crates/biome_service/src/file_handlers/javascript.rs @@ -25,6 +25,9 @@ use biome_analyze::{ RuleCategoriesBuilder, RuleCategory, RuleError, RuleFilter, }; use biome_configuration::javascript::JsxRuntime; +use biome_css_formatter::context::CssFormatOptions; +use biome_css_parser::{parse_css, CssParserOptions}; +use biome_css_syntax::CssLanguage; use biome_diagnostics::{category, Applicability, Diagnostic, DiagnosticExt, Severity}; use biome_formatter::{ AttributePosition, BracketSpacing, FormatError, IndentStyle, IndentWidth, LineEnding, @@ -37,7 +40,7 @@ use biome_js_formatter::context::trailing_commas::TrailingCommas; use biome_js_formatter::context::{ ArrowParentheses, BracketSameLine, JsFormatOptions, QuoteProperties, Semicolons, }; -use biome_js_formatter::format_node; +use biome_js_formatter::{format_node, JsForeignLanguage, JsForeignLanguageFormatter}; use biome_js_parser::JsParserOptions; use biome_js_semantic::{semantic_model, SemanticModelOptions}; use biome_js_syntax::{ @@ -314,6 +317,28 @@ impl ExtensionHandler for JsFileHandler { } } +#[derive(Clone, Debug)] +struct MultiLanguageFormatter { + css_parse_options: CssParserOptions, + css_format_options: CssFormatOptions, +} + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format( + &self, + language: biome_js_formatter::JsForeignLanguage, + content: &str, + ) -> biome_formatter::FormatResult { + match language { + JsForeignLanguage::Css => { + let parse = parse_css(content, self.css_parse_options); + biome_css_formatter::format_node(self.css_format_options.clone(), &parse.syntax()) + .map(|formatted| formatted.into_document()) + } + } + } +} + fn parse( biome_path: &BiomePath, file_source: DocumentFileSource, @@ -405,9 +430,23 @@ fn debug_formatter_ir( settings: WorkspaceSettingsHandle, ) -> Result { let options = settings.format_options::(path, document_file_source); + let css_parse_options = settings + .settings() + .map(|settings| settings.languages.css.parser.clone()) + .map(|settings| CssParserOptions { + css_modules: settings.css_modules.unwrap_or_default(), + allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), + grit_metavariable: true, + }) + .unwrap_or_default(); + let css_format_options = settings.format_options::(path, document_file_source); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; let tree = parse.syntax(); - let formatted = format_node(options, &tree)?; + let formatted = format_node(options, multi_language_formatter, &tree)?; let root_element = formatted.into_document(); Ok(root_element.to_string()) @@ -716,12 +755,30 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result { + let css_parse_options = workspace + .settings() + .map(|settings| settings.languages.css.parser.clone()) + .map(|settings| CssParserOptions { + css_modules: settings.css_modules.unwrap_or_default(), + allow_wrong_line_comments: settings + .allow_wrong_line_comments + .unwrap_or_default(), + grit_metavariable: true, + }) + .unwrap_or_default(); + let css_format_options = + workspace.format_options::(biome_path, &document_file_source); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; let code = if params.should_format { format_node( params.workspace.format_options::( params.biome_path, ¶ms.document_file_source, ), + multi_language_formatter, tree.syntax(), )? .print()? @@ -753,7 +810,22 @@ pub(crate) fn format( let tree = parse.syntax(); info!("Format file {}", biome_path.display()); - let formatted = format_node(options, &tree)?; + let css_parse_options = settings + .settings() + .map(|settings| settings.languages.css.parser.clone()) + .map(|settings| CssParserOptions { + css_modules: settings.css_modules.unwrap_or_default(), + allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), + grit_metavariable: true, + }) + .unwrap_or_default(); + let css_format_options = + settings.format_options::(biome_path, document_file_source); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; + let formatted = format_node(options, multi_language_formatter, &tree)?; match formatted.print() { Ok(printed) => Ok(printed), Err(error) => { @@ -774,7 +846,23 @@ pub(crate) fn format_range( let options = settings.format_options::(biome_path, document_file_source); let tree = parse.syntax(); - let printed = biome_js_formatter::format_range(options, &tree, range)?; + let css_parse_options = settings + .settings() + .map(|settings| settings.languages.css.parser.clone()) + .map(|settings| CssParserOptions { + css_modules: settings.css_modules.unwrap_or_default(), + allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), + grit_metavariable: true, + }) + .unwrap_or_default(); + let css_format_options = + settings.format_options::(biome_path, document_file_source); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; + let printed = + biome_js_formatter::format_range(options, multi_language_formatter, &tree, range)?; Ok(printed) } @@ -812,7 +900,23 @@ pub(crate) fn format_on_type( None => panic!("found a token with no parent"), }; - let printed = biome_js_formatter::format_sub_tree(options, &root_node)?; + let css_parse_options = settings + .settings() + .map(|settings| settings.languages.css.parser.clone()) + .map(|settings| CssParserOptions { + css_modules: settings.css_modules.unwrap_or_default(), + allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), + grit_metavariable: true, + }) + .unwrap_or_default(); + let css_format_options = settings.format_options::(path, document_file_source); + let multi_language_formatter = MultiLanguageFormatter { + css_parse_options, + css_format_options, + }; + + let printed = + biome_js_formatter::format_sub_tree(options, multi_language_formatter, &root_node)?; Ok(printed) } diff --git a/crates/biome_wasm/Cargo.toml b/crates/biome_wasm/Cargo.toml index 2058da5a419b..f4aa2fb8002e 100644 --- a/crates/biome_wasm/Cargo.toml +++ b/crates/biome_wasm/Cargo.toml @@ -37,6 +37,7 @@ console_error_panic_hook = { version = "0.1.7", optional = true } [build-dependencies] +biome_formatter = { workspace = true } biome_js_factory = { workspace = true } biome_js_formatter = { workspace = true } biome_rowan = { workspace = true } diff --git a/crates/biome_wasm/build.rs b/crates/biome_wasm/build.rs index d72a0dfc75c6..0cf277b5d91d 100644 --- a/crates/biome_wasm/build.rs +++ b/crates/biome_wasm/build.rs @@ -1,5 +1,8 @@ use std::{env, fs, io, path::PathBuf}; +use biome_formatter::prelude::Document; +use biome_formatter::{FormatError, FormatResult}; +use biome_js_formatter::JsForeignLanguageFormatter; use quote::{format_ident, quote}; use biome_js_factory::syntax::JsFileSource; @@ -11,6 +14,19 @@ use biome_js_formatter::{context::JsFormatOptions, format_node}; use biome_rowan::AstNode; use biome_service::workspace_types::{generate_type, methods, ModuleQueue}; +#[derive(Debug, Clone)] +struct FakeFormatter; + +impl JsForeignLanguageFormatter for FakeFormatter { + fn format( + &self, + _language: biome_js_formatter::JsForeignLanguage, + _source: &str, + ) -> FormatResult { + Err(FormatError::SyntaxError) + } +} + fn main() -> io::Result<()> { let methods = methods(); @@ -67,7 +83,12 @@ fn main() -> io::Result<()> { // Wasm-bindgen will paste the generated TS code as-is into the final .d.ts file, // ensure it looks good by running it through the formatter - let formatted = format_node(JsFormatOptions::new(JsFileSource::ts()), module.syntax()).unwrap(); + let formatted = format_node( + JsFormatOptions::new(JsFileSource::ts()), + FakeFormatter, + module.syntax(), + ) + .unwrap(); let printed = formatted.print().unwrap(); let definitions = printed.into_code(); diff --git a/xtask/bench/src/language.rs b/xtask/bench/src/language.rs index 568a3c7e4d85..7be5fc3de4e1 100644 --- a/xtask/bench/src/language.rs +++ b/xtask/bench/src/language.rs @@ -8,6 +8,7 @@ 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_formatter::{JsForeignLanguage, JsForeignLanguageFormatter}; use biome_js_parser::JsParserOptions; use biome_js_syntax::{AnyJsRoot, JsFileSource, JsSyntaxNode}; use biome_json_formatter::context::{JsonFormatContext, JsonFormatOptions}; @@ -125,6 +126,27 @@ impl Parsed { } } +#[derive(Debug, Clone)] +struct MultiLanguageFormatter; + +impl JsForeignLanguageFormatter for MultiLanguageFormatter { + fn format( + &self, + language: biome_js_formatter::JsForeignLanguage, + source: &str, + ) -> FormatResult { + match language { + JsForeignLanguage::Css => { + let parse = biome_css_parser::parse_css( + source, + CssParserOptions::default().allow_grit_metavariables(), + ); + biome_css_formatter::format_node(CssFormatOptions::default(), &parse.syntax()) + .map(|formatted| formatted.into_document()) + } + } + } +} pub enum FormatNode { JavaScript(JsSyntaxNode, JsFileSource), Json(JsonSyntaxNode), @@ -135,10 +157,12 @@ pub enum FormatNode { impl FormatNode { pub fn format_node(&self) -> FormatResult { match self { - Self::JavaScript(root, source_type) => { - biome_js_formatter::format_node(JsFormatOptions::new(*source_type), root) - .map(FormattedNode::JavaScript) - } + Self::JavaScript(root, source_type) => biome_js_formatter::format_node( + JsFormatOptions::new(*source_type), + MultiLanguageFormatter, + root, + ) + .map(FormattedNode::JavaScript), Self::Json(root) => { biome_json_formatter::format_node(JsonFormatOptions::default(), root) .map(FormattedNode::Json) From 56a07f0173a232847bcf61de004b186e042f1970 Mon Sep 17 00:00:00 2001 From: Zheyu Zhang Date: Wed, 10 Jul 2024 13:43:05 +0800 Subject: [PATCH 2/4] format with errors --- crates/biome_js_formatter/tests/language.rs | 7 +++++ .../tests/prettier_tests.rs | 5 +++- crates/biome_js_formatter/tests/quick_test.rs | 9 +++++- crates/biome_js_formatter/tests/spec_test.rs | 23 +++++++-------- .../src/file_handlers/javascript.rs | 29 +++++++++++++++++++ xtask/bench/src/language.rs | 16 +++++----- 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/crates/biome_js_formatter/tests/language.rs b/crates/biome_js_formatter/tests/language.rs index 0ee6b64829a5..a896e952cb68 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_errors = settings.formatter.format_with_errors; let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, + format_with_errors, }; 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 14b1597a6f85..8210f9674f3c 100644 --- a/crates/biome_service/src/file_handlers/javascript.rs +++ b/crates/biome_service/src/file_handlers/javascript.rs @@ -319,6 +319,7 @@ impl ExtensionHandler for JsFileHandler { #[derive(Clone, Debug)] struct MultiLanguageFormatter { + format_with_errors: bool, css_parse_options: CssParserOptions, css_format_options: CssFormatOptions, } @@ -332,6 +333,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()) } @@ -440,9 +444,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(); @@ -768,9 +777,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 params.should_format { format_node( @@ -821,9 +835,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() { @@ -857,9 +876,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)?; @@ -910,9 +934,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()) } From 0a5a492f17ffd08a638e779317638bff84e6af95 Mon Sep 17 00:00:00 2001 From: Zheyu Zhang Date: Wed, 10 Jul 2024 14:27:37 +0800 Subject: [PATCH 3/4] more --- Cargo.lock | 1 + xtask/codegen/Cargo.toml | 2 ++ xtask/codegen/src/generate_bindings.rs | 24 ++++++++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 209e5e7379f4..e4e43bc17220 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4490,6 +4490,7 @@ dependencies = [ "biome_css_analyze", "biome_css_syntax", "biome_diagnostics", + "biome_formatter", "biome_graphql_analyze", "biome_graphql_parser", "biome_graphql_syntax", diff --git a/xtask/codegen/Cargo.toml b/xtask/codegen/Cargo.toml index e6d96dcbbba0..32308812b0c7 100644 --- a/xtask/codegen/Cargo.toml +++ b/xtask/codegen/Cargo.toml @@ -22,6 +22,7 @@ biome_configuration = { workspace = true, optional = true } biome_css_analyze = { workspace = true, optional = true } biome_css_syntax = { workspace = true, optional = true } biome_diagnostics = { workspace = true, optional = true } +biome_formatter = { workspace = true, optional = true } biome_graphql_analyze = { workspace = true, optional = true } biome_graphql_parser = { workspace = true, optional = true } biome_graphql_syntax = { workspace = true, optional = true } @@ -68,6 +69,7 @@ schema = [ "biome_json_parser", "biome_diagnostics", "biome_configuration", + "biome_formatter", ] [lints] diff --git a/xtask/codegen/src/generate_bindings.rs b/xtask/codegen/src/generate_bindings.rs index 950492336884..fdcb4b45f7b1 100644 --- a/xtask/codegen/src/generate_bindings.rs +++ b/xtask/codegen/src/generate_bindings.rs @@ -1,5 +1,7 @@ use biome_js_factory::make; -use biome_js_formatter::{context::JsFormatOptions, format_node}; +use biome_js_formatter::{ + context::JsFormatOptions, format_node, JsForeignLanguage, JsForeignLanguageFormatter, +}; use biome_js_syntax::{ AnyJsBinding, AnyJsBindingPattern, AnyJsCallArgument, AnyJsDeclaration, AnyJsDeclarationClause, AnyJsExportClause, AnyJsExpression, AnyJsFormalParameter, AnyJsImportClause, @@ -13,6 +15,19 @@ use biome_string_case::Case; use xtask::{project_root, Mode, Result}; use xtask_codegen::update; +#[derive(Debug, Clone)] +struct FakeFormater; + +impl JsForeignLanguageFormatter for FakeFormater { + fn format( + &self, + _language: JsForeignLanguage, + _content: &str, + ) -> biome_formatter::FormatResult { + Err(biome_formatter::FormatError::SyntaxError) + } +} + pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { let bindings_path = project_root().join("packages/@biomejs/backend-jsonrpc/src/workspace.ts"); let methods = methods(); @@ -424,7 +439,12 @@ pub(crate) fn generate_workspace_bindings(mode: Mode) -> Result<()> { ) .build(); - let formatted = format_node(JsFormatOptions::new(JsFileSource::ts()), module.syntax()).unwrap(); + let formatted = format_node( + JsFormatOptions::new(JsFileSource::ts()), + FakeFormater, + module.syntax(), + ) + .unwrap(); let printed = formatted.print().unwrap(); let code = printed.into_code(); From 94bd39b43397c90990572c90119caa64fd54e7f6 Mon Sep 17 00:00:00 2001 From: Zheyu Zhang Date: Mon, 14 Oct 2024 16:01:33 +0800 Subject: [PATCH 4/4] tweak --- crates/biome_js_formatter/tests/language.rs | 2 +- .../tests/prettier_tests.rs | 2 +- crates/biome_js_formatter/tests/quick_test.rs | 2 +- crates/biome_js_formatter/tests/spec_test.rs | 2 +- .../src/file_handlers/javascript.rs | 36 +++++++++---------- xtask/bench/src/language.rs | 5 +-- 6 files changed, 22 insertions(+), 27 deletions(-) diff --git a/crates/biome_js_formatter/tests/language.rs b/crates/biome_js_formatter/tests/language.rs index a896e952cb68..4eb55fffe75b 100644 --- a/crates/biome_js_formatter/tests/language.rs +++ b/crates/biome_js_formatter/tests/language.rs @@ -86,7 +86,7 @@ impl TestFormatLanguage for JsTestFormatLanguage { .parser .allow_wrong_line_comments .unwrap_or_default(), - grit_metavariable: true, + grit_metavariables: true, }; let css_format_options = CssFormatOptions::default().with_quote_style( settings diff --git a/crates/biome_js_formatter/tests/prettier_tests.rs b/crates/biome_js_formatter/tests/prettier_tests.rs index 4a0e4019ca49..3dc3ad7070be 100644 --- a/crates/biome_js_formatter/tests/prettier_tests.rs +++ b/crates/biome_js_formatter/tests/prettier_tests.rs @@ -20,7 +20,7 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult { match language { JsForeignLanguage::Css => { - let parse_options = CssParserOptions::default().allow_grit_metavariables(); + let parse_options = CssParserOptions::default().allow_metavariables(); let format_options = CssFormatOptions::default(); let parse = biome_css_parser::parse_css(source, parse_options); if parse.has_errors() { diff --git a/crates/biome_js_formatter/tests/quick_test.rs b/crates/biome_js_formatter/tests/quick_test.rs index c60498ddce44..a3beaac6cbb2 100644 --- a/crates/biome_js_formatter/tests/quick_test.rs +++ b/crates/biome_js_formatter/tests/quick_test.rs @@ -69,7 +69,7 @@ function outerFunctionToForceIndent() { .with_arrow_parentheses(ArrowParentheses::AsNeeded) .with_attribute_position(AttributePosition::Multiline); - let css_parse_options = CssParserOptions::default().allow_grit_metavariables(); + let css_parse_options = CssParserOptions::default().allow_metavariables(); let css_format_options = CssFormatOptions::default(); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, diff --git a/crates/biome_js_formatter/tests/spec_test.rs b/crates/biome_js_formatter/tests/spec_test.rs index 306c92941607..0c51280d1e71 100644 --- a/crates/biome_js_formatter/tests/spec_test.rs +++ b/crates/biome_js_formatter/tests/spec_test.rs @@ -21,7 +21,7 @@ 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_parse_options = CssParserOptions::default().allow_metavariables(); let css_format_options = CssFormatOptions::default(); match language { JsForeignLanguage::Css => { diff --git a/crates/biome_service/src/file_handlers/javascript.rs b/crates/biome_service/src/file_handlers/javascript.rs index 8210f9674f3c..5453576c851b 100644 --- a/crates/biome_service/src/file_handlers/javascript.rs +++ b/crates/biome_service/src/file_handlers/javascript.rs @@ -440,14 +440,13 @@ fn debug_formatter_ir( .map(|settings| CssParserOptions { css_modules: settings.css_modules.unwrap_or_default(), allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), - grit_metavariable: true, + grit_metavariables: true, }) .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(); + .is_some_and(|settings| settings.formatter.format_with_errors); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, @@ -764,7 +763,8 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result { - let css_parse_options = workspace + let css_parse_options = params + .workspace .settings() .map(|settings| settings.languages.css.parser.clone()) .map(|settings| CssParserOptions { @@ -772,15 +772,16 @@ pub(crate) fn fix_all(params: FixAllParams) -> Result(biome_path, &document_file_source); - let format_with_errors = workspace + let css_format_options = params + .workspace + .format_options::(params.biome_path, ¶ms.document_file_source); + let format_with_errors = params + .workspace .settings() - .map(|settings| settings.formatter.format_with_errors) - .unwrap_or_default(); + .is_some_and(|settings| settings.formatter.format_with_errors); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, @@ -830,15 +831,14 @@ pub(crate) fn format( .map(|settings| CssParserOptions { css_modules: settings.css_modules.unwrap_or_default(), allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), - grit_metavariable: true, + grit_metavariables: true, }) .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(); + .is_some_and(|settings| settings.formatter.format_with_errors); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, @@ -871,15 +871,14 @@ pub(crate) fn format_range( .map(|settings| CssParserOptions { css_modules: settings.css_modules.unwrap_or_default(), allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), - grit_metavariable: true, + grit_metavariables: true, }) .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(); + .is_some_and(|settings| settings.formatter.format_with_errors); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, @@ -930,14 +929,13 @@ pub(crate) fn format_on_type( .map(|settings| CssParserOptions { css_modules: settings.css_modules.unwrap_or_default(), allow_wrong_line_comments: settings.allow_wrong_line_comments.unwrap_or_default(), - grit_metavariable: true, + grit_metavariables: true, }) .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(); + .is_some_and(|settings| settings.formatter.format_with_errors); let multi_language_formatter = MultiLanguageFormatter { css_parse_options, css_format_options, diff --git a/xtask/bench/src/language.rs b/xtask/bench/src/language.rs index 70cec3034973..7d4025ff18ef 100644 --- a/xtask/bench/src/language.rs +++ b/xtask/bench/src/language.rs @@ -134,10 +134,7 @@ impl JsForeignLanguageFormatter for MultiLanguageFormatter { fn format(&self, language: JsForeignLanguage, source: &str) -> FormatResult { match language { JsForeignLanguage::Css => { - let parse = parse_css( - source, - CssParserOptions::default().allow_grit_metavariables(), - ); + let parse = parse_css(source, CssParserOptions::default().allow_metavariables()); if parse.has_errors() { return Err(FormatError::SyntaxError); }