diff --git a/.github/workflows/repository_dispatch.yml b/.github/workflows/repository_dispatch.yml index d6144d383974..1048579c7127 100644 --- a/.github/workflows/repository_dispatch.yml +++ b/.github/workflows/repository_dispatch.yml @@ -39,7 +39,7 @@ jobs: run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - name: Build WASM module for the web - run: wasm-pack build --out-dir ../../packages/@biomejs/wasm-web --target web --profiling --scope biomejs crates/biome_wasm --features experimental-html + run: wasm-pack build --out-dir ../../packages/@biomejs/wasm-web --target web --profiling --scope biomejs crates/biome_wasm --features experimental-html,experimental-grit # https://github.com/actions/cache/issues/342 - name: Clear old wasm-pack cache diff --git a/Cargo.lock b/Cargo.lock index 912a060987fd..13d4608a3b2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,11 +593,19 @@ dependencies = [ name = "biome_grit_formatter" version = "0.0.0" dependencies = [ + "biome_configuration", "biome_formatter", + "biome_formatter_test", + "biome_grit_factory", + "biome_grit_parser", "biome_grit_syntax", + "biome_parser", "biome_rowan", + "biome_service", + "countme", "serde", "serde_json", + "tests_macros", ] [[package]] @@ -1088,7 +1096,10 @@ dependencies = [ "biome_graphql_formatter", "biome_graphql_parser", "biome_graphql_syntax", + "biome_grit_formatter", + "biome_grit_parser", "biome_grit_patterns", + "biome_grit_syntax", "biome_html_formatter", "biome_html_parser", "biome_html_syntax", diff --git a/crates/biome_cli/Cargo.toml b/crates/biome_cli/Cargo.toml index 06ad44b835e3..01001244ac15 100644 --- a/crates/biome_cli/Cargo.toml +++ b/crates/biome_cli/Cargo.toml @@ -78,6 +78,7 @@ tokio = { workspace = true, features = ["io-util"] } [features] docgen = ["bpaf/docgen"] +experimental-grit = ["biome_service/experimental-grit"] experimental-html = ["biome_service/experimental-html"] [lints] diff --git a/crates/biome_formatter/CONTRIBUTING.md b/crates/biome_formatter/CONTRIBUTING.md index 0d36e8f2bf9a..1a9072c20323 100644 --- a/crates/biome_formatter/CONTRIBUTING.md +++ b/crates/biome_formatter/CONTRIBUTING.md @@ -424,9 +424,15 @@ pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, _f return; }; + let options = HtmlFormatOptions::default(); let language = language::HtmlTestFormatLanguage::default(); - let snapshot = SpecSnapshot::new(test_file, test_directory, language, ()); + let snapshot = SpecSnapshot::new( + test_file, + test_directory, + language, + HtmlFormatLanguage::new(options), + ); snapshot.test() } diff --git a/crates/biome_grit_formatter/Cargo.toml b/crates/biome_grit_formatter/Cargo.toml index 6d79810951d0..399c4eda2216 100644 --- a/crates/biome_grit_formatter/Cargo.toml +++ b/crates/biome_grit_formatter/Cargo.toml @@ -18,9 +18,16 @@ biome_grit_syntax = { workspace = true } biome_rowan = { workspace = true } [dev-dependencies] -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } - +biome_configuration = { path = "../biome_configuration" } +biome_formatter_test = { path = "../biome_formatter_test" } +biome_grit_factory = { path = "../biome_grit_factory" } +biome_grit_parser = { path = "../biome_grit_parser" } +biome_parser = { path = "../biome_parser" } +biome_service = { path = "../biome_service", features = ["experimental-grit"] } +countme = { workspace = true, features = ["enable"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +tests_macros = { path = "../tests_macros" } # cargo-workspaces metadata [package.metadata.workspaces] independent = true diff --git a/crates/biome_grit_formatter/src/context.rs b/crates/biome_grit_formatter/src/context.rs index b4a8e093459a..43812f0b78e5 100644 --- a/crates/biome_grit_formatter/src/context.rs +++ b/crates/biome_grit_formatter/src/context.rs @@ -1,21 +1,25 @@ use crate::comments::{FormatGritLeadingComment, GritCommentStyle, GritComments}; +use biome_formatter::printer::PrinterOptions; use biome_formatter::{ - CstFormatContext, FormatContext, FormatOptions, IndentStyle, IndentWidth, LineEnding, - LineWidth, QuoteStyle, TransformSourceMap, + AttributePosition, BracketSpacing, CstFormatContext, FormatContext, FormatOptions, IndentStyle, + IndentWidth, LineEnding, LineWidth, QuoteStyle, TransformSourceMap, }; use biome_grit_syntax::GritLanguage; +use std::fmt::Display; use std::rc::Rc; #[allow(dead_code)] #[derive(Debug, Clone)] pub struct GritFormatContext { + options: GritFormatOptions, comments: Rc, source_map: Option, } impl GritFormatContext { - pub fn new(comments: GritComments) -> Self { + pub fn new(options: GritFormatOptions, comments: GritComments) -> Self { Self { + options, comments: Rc::new(comments), source_map: None, } @@ -31,11 +35,11 @@ impl FormatContext for GritFormatContext { type Options = GritFormatOptions; fn options(&self) -> &Self::Options { - todo!() + &self.options } fn source_map(&self) -> Option<&TransformSourceMap> { - todo!() + self.source_map.as_ref() } } impl CstFormatContext for GritFormatContext { @@ -46,18 +50,18 @@ impl CstFormatContext for GritFormatContext { type CommentRule = FormatGritLeadingComment; fn comments(&self) -> &biome_formatter::comments::Comments { - todo!() + &self.comments } } -#[derive(Debug, Default, Clone, PartialEq)] - +#[derive(Debug, Default, Clone)] pub struct GritFormatOptions { indent_style: IndentStyle, indent_width: IndentWidth, line_ending: LineEnding, line_width: LineWidth, quote_style: QuoteStyle, + attribute_position: AttributePosition, } impl GritFormatOptions { @@ -68,6 +72,7 @@ impl GritFormatOptions { line_ending: LineEnding::default(), line_width: LineWidth::default(), quote_style: QuoteStyle::default(), + attribute_position: AttributePosition::default(), } } pub fn with_indent_style(mut self, indent_style: IndentStyle) -> Self { @@ -118,34 +123,48 @@ impl GritFormatOptions { pub fn quote_style(&self) -> QuoteStyle { self.quote_style } + + pub fn attribute_position(&self) -> AttributePosition { + self.attribute_position + } +} + +impl Display for GritFormatOptions { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Indent style: {}", self.indent_style)?; + writeln!(f, "Indent width: {}", self.indent_width.value())?; + writeln!(f, "Line ending: {}", self.line_ending)?; + writeln!(f, "Line width: {}", self.line_width.value())?; + writeln!(f, "Attribute Position: {}", self.attribute_position) + } } impl FormatOptions for GritFormatOptions { fn indent_style(&self) -> IndentStyle { - todo!() + self.indent_style } fn indent_width(&self) -> IndentWidth { - todo!() + self.indent_width } fn line_width(&self) -> LineWidth { - todo!() + self.line_width } fn line_ending(&self) -> LineEnding { - todo!() + self.line_ending } fn attribute_position(&self) -> biome_formatter::AttributePosition { - todo!() + self.attribute_position } fn bracket_spacing(&self) -> biome_formatter::BracketSpacing { - todo!() + BracketSpacing::default() } fn as_print_options(&self) -> biome_formatter::prelude::PrinterOptions { - todo!() + PrinterOptions::from(self) } } diff --git a/crates/biome_grit_formatter/src/lib.rs b/crates/biome_grit_formatter/src/lib.rs index c935554e575c..4e04079ee536 100644 --- a/crates/biome_grit_formatter/src/lib.rs +++ b/crates/biome_grit_formatter/src/lib.rs @@ -6,11 +6,13 @@ mod grit; mod prelude; use biome_formatter::{ + comments::Comments, prelude::*, trivia::{format_dangling_comments, format_leading_comments, format_trailing_comments}, write, CstFormatContext, Format, FormatLanguage, FormatResult, Formatted, }; use biome_grit_syntax::{GritLanguage, GritSyntaxNode}; +use comments::GritCommentStyle; pub(crate) use crate::context::GritFormatContext; @@ -120,15 +122,18 @@ impl FormatLanguage for GritFormatLanguage { } fn options(&self) -> &::Options { - todo!() + &self.options } fn create_context( self, - _root: &biome_rowan::SyntaxNode, - _source_map: Option, + root: &biome_rowan::SyntaxNode, + source_map: Option, ) -> Self::Context { - todo!() + let comments: Comments = + Comments::from_node(root, &GritCommentStyle, source_map.as_ref()); + + GritFormatContext::new(self.options, comments).with_source_map(source_map) } } diff --git a/crates/biome_grit_formatter/tests/language.rs b/crates/biome_grit_formatter/tests/language.rs new file mode 100644 index 000000000000..24edd18515ba --- /dev/null +++ b/crates/biome_grit_formatter/tests/language.rs @@ -0,0 +1,25 @@ +use biome_formatter_test::TestFormatLanguage; +use biome_grit_formatter::{context::GritFormatContext, GritFormatLanguage}; +use biome_grit_parser::parse_grit; +use biome_grit_syntax::GritLanguage; + +#[derive(Default)] +pub struct GritTestFormatLanguage; + +impl TestFormatLanguage for GritTestFormatLanguage { + type ServiceLanguage = GritLanguage; + type Context = GritFormatContext; + type FormatLanguage = GritFormatLanguage; + + fn parse(&self, text: &str) -> biome_parser::AnyParse { + parse_grit(text).into() + } + + fn to_format_language( + &self, + _settings: &biome_service::settings::Settings, + _file_source: &biome_service::workspace::DocumentFileSource, + ) -> Self::FormatLanguage { + todo!() + } +} diff --git a/crates/biome_grit_formatter/tests/spec_test.rs b/crates/biome_grit_formatter/tests/spec_test.rs new file mode 100644 index 000000000000..0da896dfc841 --- /dev/null +++ b/crates/biome_grit_formatter/tests/spec_test.rs @@ -0,0 +1,27 @@ +use biome_formatter_test::spec::{SpecSnapshot, SpecTestFile}; +use biome_grit_formatter::{context::GritFormatOptions, GritFormatLanguage}; +use std::path::Path; + +mod language { + include!("language.rs"); +} + +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 Some(test_file) = SpecTestFile::try_from_file(spec_input_file, root_path, None) else { + panic!("Failed to set up snapshot test"); + }; + + let options = GritFormatOptions::default(); + let language = language::GritTestFormatLanguage; + + let snapshot = SpecSnapshot::new( + test_file, + test_directory, + language, + GritFormatLanguage::new(options), + ); + + snapshot.test() +} diff --git a/crates/biome_grit_formatter/tests/spec_tests.rs b/crates/biome_grit_formatter/tests/spec_tests.rs new file mode 100644 index 000000000000..f68ad1f252f7 --- /dev/null +++ b/crates/biome_grit_formatter/tests/spec_tests.rs @@ -0,0 +1,8 @@ +mod spec_test; + +mod formatter { + + mod grit_module { + tests_macros::gen_tests! {"tests/specs/grit/**/*.grit", crate::spec_test::run, ""} + } +} diff --git a/crates/biome_grit_formatter/tests/specs/grit/file_node.grit b/crates/biome_grit_formatter/tests/specs/grit/file_node.grit new file mode 100644 index 000000000000..4273ffb1159b --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/file_node.grit @@ -0,0 +1 @@ +file(body = contains `console.$method` => `println`) \ No newline at end of file diff --git a/crates/biome_grit_formatter/tests/specs/grit/file_node.grit.snap b/crates/biome_grit_formatter/tests/specs/grit/file_node.grit.snap new file mode 100644 index 000000000000..6af8139fa4cf --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/file_node.grit.snap @@ -0,0 +1,33 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: grit/file_node.grit +--- +# Input + +```grit +file(body = contains `console.$method` => `println`) +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```grit +file(body = contains `console.$method` => `println`)``` + + + +## Unimplemented nodes/tokens + +"file(body = contains `console.$method` => `println`)" => 0..52 diff --git a/crates/biome_grit_parser/src/lib.rs b/crates/biome_grit_parser/src/lib.rs index 69e9c671b466..1aa0cf697e8d 100644 --- a/crates/biome_grit_parser/src/lib.rs +++ b/crates/biome_grit_parser/src/lib.rs @@ -5,8 +5,8 @@ mod token_source; use biome_grit_factory::GritSyntaxFactory; use biome_grit_syntax::{GritLanguage, GritRoot, GritSyntaxNode}; -use biome_parser::diagnostic::ParseDiagnostic; use biome_parser::tree_sink::LosslessTreeSink; +use biome_parser::{diagnostic::ParseDiagnostic, AnyParse}; use biome_rowan::{AstNode, NodeCache}; use parser::{parse_root, GritParser}; @@ -100,3 +100,11 @@ impl GritParse { GritRoot::unwrap_cast(self.syntax()) } } + +impl From for AnyParse { + fn from(parse: GritParse) -> Self { + let root = parse.syntax(); + let diagnostics = parse.into_diagnostics(); + Self::new(root.as_send().unwrap(), diagnostics) + } +} diff --git a/crates/biome_grit_syntax/src/file_source.rs b/crates/biome_grit_syntax/src/file_source.rs new file mode 100644 index 000000000000..44d61148a248 --- /dev/null +++ b/crates/biome_grit_syntax/src/file_source.rs @@ -0,0 +1,65 @@ +use biome_rowan::FileSourceError; +use std::{ffi::OsStr, path::Path}; +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive( + Debug, Clone, Default, Copy, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, +)] +pub struct GritFileSource { + #[allow(unused)] + variant: GritVariant, +} + +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive( + Debug, Clone, Default, Copy, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, +)] +enum GritVariant { + #[default] + Standard, +} + +impl GritFileSource { + pub fn grit() -> Self { + Self { + variant: GritVariant::Standard, + } + } + + /// Try to return the HTML file source corresponding to this file name from well-known files + pub fn try_from_well_known(_: &Path) -> Result { + // TODO: to be implemented + Err(FileSourceError::UnknownFileName) + } + + pub fn try_from_extension(extension: &OsStr) -> Result { + match extension.as_encoded_bytes() { + b"grit" => Ok(Self::grit()), + _ => Err(FileSourceError::UnknownExtension), + } + } + + pub fn try_from_language_id(language_id: &str) -> Result { + match language_id { + "grit" => Ok(Self::grit()), + _ => Err(FileSourceError::UnknownLanguageId), + } + } +} + +impl TryFrom<&Path> for GritFileSource { + type Error = FileSourceError; + + fn try_from(path: &Path) -> Result { + if let Ok(file_source) = Self::try_from_well_known(path) { + return Ok(file_source); + } + + let Some(extension) = path.extension() else { + return Err(FileSourceError::MissingFileExtension); + }; + // We assume the file extensions are case-insensitive + // and we use the lowercase form of them for pattern matching + #[allow(clippy::disallowed_methods)] + Self::try_from_extension(&extension.to_ascii_lowercase()) + } +} diff --git a/crates/biome_grit_syntax/src/lib.rs b/crates/biome_grit_syntax/src/lib.rs index 76a7309d1b92..364af38a5cb3 100644 --- a/crates/biome_grit_syntax/src/lib.rs +++ b/crates/biome_grit_syntax/src/lib.rs @@ -4,6 +4,7 @@ #[macro_use] mod generated; +pub mod file_source; mod syntax_ext; mod syntax_node; diff --git a/crates/biome_service/Cargo.toml b/crates/biome_service/Cargo.toml index ce7435dfcd3a..9ca9261aab40 100644 --- a/crates/biome_service/Cargo.toml +++ b/crates/biome_service/Cargo.toml @@ -31,7 +31,10 @@ biome_graphql_analyze = { workspace = true } biome_graphql_formatter = { workspace = true } biome_graphql_parser = { workspace = true } biome_graphql_syntax = { workspace = true } +biome_grit_formatter = { workspace = true } +biome_grit_parser = { workspace = true } biome_grit_patterns = { workspace = true } +biome_grit_syntax = { workspace = true } biome_html_formatter = { workspace = true } biome_html_parser = { workspace = true } biome_html_syntax = { workspace = true } @@ -67,7 +70,9 @@ smallvec = { workspace = true, features = ["serde"] } tracing = { workspace = true, features = ["attributes", "log"] } [features] +experimental-grit = [] experimental-html = [] + schema = [ "dep:schemars", "biome_js_analyze/schema", @@ -77,6 +82,8 @@ schema = [ "biome_json_syntax/schema", "biome_css_syntax/schema", "biome_graphql_syntax/schema", + "biome_grit_syntax/schema", + ] [dev-dependencies] diff --git a/crates/biome_service/src/file_handlers/grit.rs b/crates/biome_service/src/file_handlers/grit.rs new file mode 100644 index 000000000000..afb9529d2fe2 --- /dev/null +++ b/crates/biome_service/src/file_handlers/grit.rs @@ -0,0 +1,119 @@ +use crate::{ + settings::{ServiceLanguage, Settings, WorkspaceSettingsHandle}, + WorkspaceError, +}; +use biome_analyze::{AnalyzerConfiguration, AnalyzerOptions}; +use biome_formatter::Printed; +use biome_fs::BiomePath; +use biome_grit_formatter::{context::GritFormatOptions, format_node}; +use biome_grit_parser::parse_grit_with_cache; +use biome_grit_syntax::GritLanguage; +use biome_parser::AnyParse; +use biome_rowan::NodeCache; + +use super::{ + AnalyzerCapabilities, Capabilities, DebugCapabilities, DocumentFileSource, ExtensionHandler, + FormatterCapabilities, ParseResult, ParserCapabilities, SearchCapabilities, +}; + +impl ServiceLanguage for GritLanguage { + type FormatterSettings = (); + type LinterSettings = (); + type OrganizeImportsSettings = (); + type FormatOptions = GritFormatOptions; + type ParserSettings = (); + type EnvironmentSettings = (); + fn lookup_settings( + languages: &crate::settings::LanguageListSettings, + ) -> &crate::settings::LanguageSettings { + &languages.grit + } + + fn resolve_format_options( + _global: Option<&crate::settings::FormatSettings>, + _overrides: Option<&crate::settings::OverrideSettings>, + _language: Option<&Self::FormatterSettings>, + _path: &biome_fs::BiomePath, + _file_source: &super::DocumentFileSource, + ) -> Self::FormatOptions { + GritFormatOptions::default() + } + + fn resolve_analyzer_options( + _global: Option<&crate::settings::Settings>, + _linter: Option<&crate::settings::LinterSettings>, + _overrides: Option<&crate::settings::OverrideSettings>, + _language: Option<&Self::LinterSettings>, + path: &biome_fs::BiomePath, + _file_source: &super::DocumentFileSource, + ) -> biome_analyze::AnalyzerOptions { + AnalyzerOptions { + configuration: AnalyzerConfiguration::default(), + file_path: path.to_path_buf(), + } + } +} + +#[derive(Debug, Default, PartialEq, Eq)] +pub(crate) struct GritFileHandler; + +impl ExtensionHandler for GritFileHandler { + fn capabilities(&self) -> Capabilities { + Capabilities { + parser: ParserCapabilities { parse: Some(parse) }, + debug: DebugCapabilities { + debug_syntax_tree: None, + debug_control_flow: None, + debug_formatter_ir: None, + }, + analyzer: AnalyzerCapabilities { + lint: None, + code_actions: None, + rename: None, + fix_all: None, + organize_imports: None, + }, + formatter: FormatterCapabilities { + format: Some(format), + format_range: None, + format_on_type: None, + }, + search: SearchCapabilities { search: None }, + } + } +} + +fn parse( + _biome_path: &BiomePath, + file_source: DocumentFileSource, + text: &str, + _settings: Option<&Settings>, + cache: &mut NodeCache, +) -> ParseResult { + let parse = parse_grit_with_cache(text, cache); + + ParseResult { + any_parse: parse.into(), + language: Some(file_source), + } +} + +#[tracing::instrument(level = "debug", skip(parse, settings))] +fn format( + biome_path: &BiomePath, + document_file_source: &DocumentFileSource, + parse: AnyParse, + settings: WorkspaceSettingsHandle, +) -> Result { + let options = settings.format_options::(biome_path, document_file_source); + + tracing::debug!("Format with the following options: \n{}", options); + + let tree = parse.syntax(); + let formatted = format_node(options, &tree)?; + + match formatted.print() { + Ok(printed) => Ok(printed), + Err(error) => Err(WorkspaceError::FormatError(error.into())), + } +} diff --git a/crates/biome_service/src/file_handlers/mod.rs b/crates/biome_service/src/file_handlers/mod.rs index 77238dafce73..600b33d9c1d6 100644 --- a/crates/biome_service/src/file_handlers/mod.rs +++ b/crates/biome_service/src/file_handlers/mod.rs @@ -28,6 +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_grit_syntax::file_source::GritFileSource; use biome_html_syntax::HtmlFileSource; use biome_js_parser::{parse, JsParserOptions}; use biome_js_syntax::{ @@ -38,6 +39,8 @@ use biome_parser::AnyParse; use biome_project::PackageJson; use biome_rowan::{FileSourceError, NodeCache}; use biome_string_case::StrExtension; + +use grit::GritFileHandler; use html::HtmlFileHandler; pub use javascript::JsFormatterSettings; use std::borrow::Cow; @@ -48,6 +51,7 @@ use tracing::instrument; mod astro; mod css; mod graphql; +mod grit; mod html; mod javascript; mod json; @@ -65,6 +69,7 @@ pub enum DocumentFileSource { Css(CssFileSource), Graphql(GraphqlFileSource), Html(HtmlFileSource), + Grit(GritFileSource), #[default] Unknown, } @@ -99,6 +104,12 @@ impl From for DocumentFileSource { } } +impl From for DocumentFileSource { + fn from(value: GritFileSource) -> Self { + Self::Grit(value) + } +} + impl From<&Path> for DocumentFileSource { fn from(path: &Path) -> Self { Self::from_path(path) @@ -148,6 +159,11 @@ impl DocumentFileSource { if let Ok(file_source) = HtmlFileSource::try_from_extension(extension) { return Ok(file_source.into()); } + + #[cfg(feature = "experimental-grit")] + if let Ok(file_source) = GritFileSource::try_from_extension(extension) { + return Ok(file_source.into()); + } Err(FileSourceError::UnknownExtension) } @@ -175,6 +191,10 @@ impl DocumentFileSource { if let Ok(file_source) = HtmlFileSource::try_from_language_id(language_id) { return Ok(file_source.into()); } + #[cfg(feature = "experimental-grit")] + if let Ok(file_source) = GritFileSource::try_from_language_id(language_id) { + return Ok(file_source.into()); + } Err(FileSourceError::UnknownLanguageId) } @@ -324,6 +344,7 @@ impl DocumentFileSource { | DocumentFileSource::Graphql(_) | DocumentFileSource::Json(_) => true, DocumentFileSource::Html(_) => cfg!(feature = "experimental-html"), + DocumentFileSource::Grit(_) => cfg!(feature = "experimental-grit"), DocumentFileSource::Unknown => false, } } @@ -356,6 +377,7 @@ impl biome_console::fmt::Display for DocumentFileSource { DocumentFileSource::Css(_) => fmt.write_markup(markup! { "CSS" }), DocumentFileSource::Graphql(_) => fmt.write_markup(markup! { "GraphQL" }), DocumentFileSource::Html(_) => fmt.write_markup(markup! { "HTML" }), + DocumentFileSource::Grit(_) => fmt.write_markup(markup! { "Grit" }), DocumentFileSource::Unknown => fmt.write_markup(markup! { "Unknown" }), } } @@ -534,6 +556,7 @@ pub(crate) struct Features { unknown: UnknownFileHandler, graphql: GraphqlFileHandler, html: HtmlFileHandler, + grit: GritFileHandler, } impl Features { @@ -547,6 +570,7 @@ impl Features { svelte: SvelteFileHandler {}, graphql: GraphqlFileHandler {}, html: HtmlFileHandler {}, + grit: GritFileHandler {}, unknown: UnknownFileHandler::default(), } } @@ -568,6 +592,7 @@ impl Features { DocumentFileSource::Css(_) => self.css.capabilities(), DocumentFileSource::Graphql(_) => self.graphql.capabilities(), DocumentFileSource::Html(_) => self.html.capabilities(), + DocumentFileSource::Grit(_) => self.grit.capabilities(), DocumentFileSource::Unknown => self.unknown.capabilities(), } } diff --git a/crates/biome_service/src/settings.rs b/crates/biome_service/src/settings.rs index 11b13bb2d539..3f02d1f1a7b2 100644 --- a/crates/biome_service/src/settings.rs +++ b/crates/biome_service/src/settings.rs @@ -23,6 +23,7 @@ use biome_formatter::{ use biome_fs::BiomePath; use biome_graphql_formatter::context::GraphqlFormatOptions; use biome_graphql_syntax::GraphqlLanguage; +use biome_grit_syntax::GritLanguage; use biome_html_formatter::HtmlFormatOptions; use biome_html_syntax::HtmlLanguage; use biome_js_formatter::context::JsFormatOptions; @@ -563,6 +564,7 @@ pub struct LanguageListSettings { pub css: LanguageSettings, pub graphql: LanguageSettings, pub html: LanguageSettings, + pub grit: LanguageSettings, } impl From for LanguageSettings { diff --git a/crates/biome_wasm/Cargo.toml b/crates/biome_wasm/Cargo.toml index 462dbbb6500a..2058da5a419b 100644 --- a/crates/biome_wasm/Cargo.toml +++ b/crates/biome_wasm/Cargo.toml @@ -17,6 +17,7 @@ crate-type = ["cdylib", "rlib"] [features] default = ["console_error_panic_hook"] +experimental-grit = ["biome_service/experimental-grit"] experimental-html = ["biome_service/experimental-html"] [dependencies] diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 88cad0f8c634..5f6212d128fa 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -2579,7 +2579,8 @@ export type DocumentFileSource = | { Json: JsonFileSource } | { Css: CssFileSource } | { Graphql: GraphqlFileSource } - | { Html: HtmlFileSource }; + | { Html: HtmlFileSource } + | { Grit: GritFileSource }; export interface JsFileSource { /** * Used to mark if the source is being used for an Astro, Svelte or Vue file @@ -2603,6 +2604,9 @@ export interface GraphqlFileSource { export interface HtmlFileSource { variant: HtmlVariant; } +export interface GritFileSource { + variant: GritVariant; +} export type EmbeddingKind = "Astro" | "Vue" | "Svelte" | "None"; export type Language = | "JavaScript" @@ -2629,6 +2633,7 @@ export type CssVariant = "Standard"; */ export type GraphqlVariant = "Standard"; export type HtmlVariant = "Standard" | "Astro"; +export type GritVariant = "Standard"; export interface ChangeFileParams { content: string; path: BiomePath; diff --git a/xtask/rules_check/src/lib.rs b/xtask/rules_check/src/lib.rs index 23cf017ce3b8..b33f9359c76d 100644 --- a/xtask/rules_check/src/lib.rs +++ b/xtask/rules_check/src/lib.rs @@ -449,6 +449,8 @@ fn assert_lint( } } DocumentFileSource::Html(..) => todo!("HTML analysis is not yet supported"), + DocumentFileSource::Grit(..) => todo!("Grit analysis is not yet supported"), + // Unknown code blocks should be ignored by tests DocumentFileSource::Unknown => {} }