diff --git a/Cargo.lock b/Cargo.lock index 1b435b13facac..4776f93baa9a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2022,14 +2022,11 @@ dependencies = [ "futures", "ignore", "insta", - "json-strip-comments", "log", "oxc_allocator", "oxc_data_structures", "oxc_diagnostics", - "oxc_formatter", "oxc_linter", - "oxc_parser", "papaya", "rustc-hash", "serde", @@ -2557,7 +2554,9 @@ dependencies = [ "cow-utils", "editorconfig-parser", "ignore", + "insta", "json-strip-comments", + "log", "mimalloc-safe", "napi", "napi-build", @@ -2565,6 +2564,7 @@ dependencies = [ "oxc-miette", "oxc-toml", "oxc_allocator", + "oxc_data_structures", "oxc_diagnostics", "oxc_formatter", "oxc_language_server", @@ -2573,10 +2573,12 @@ dependencies = [ "oxc_span", "phf", "rayon", + "serde", "serde_json", "simdutf8", "sort-package-json", "tokio", + "tower-lsp-server", "tracing", "tracing-subscriber", ] diff --git a/apps/oxfmt/Cargo.toml b/apps/oxfmt/Cargo.toml index ad070ae72d889..40966f00386a2 100644 --- a/apps/oxfmt/Cargo.toml +++ b/apps/oxfmt/Cargo.toml @@ -28,9 +28,10 @@ doctest = false [dependencies] oxc_allocator = { workspace = true, features = ["pool"] } +oxc_data_structures = { workspace = true, features = ["rope"] } oxc_diagnostics = { workspace = true } oxc_formatter = { workspace = true } -oxc_language_server = { workspace = true, default-features = false, features = ["formatter"] } +oxc_language_server = { workspace = true, default-features = false } oxc_napi = { workspace = true } oxc_parser = { workspace = true } oxc_span = { workspace = true } @@ -40,9 +41,11 @@ cow-utils = { workspace = true } editorconfig-parser = { workspace = true } ignore = { workspace = true, features = ["simd-accel"] } json-strip-comments = { workspace = true } +log = { workspace = true } miette = { workspace = true } phf = { workspace = true, features = ["macros"] } rayon = { workspace = true } +serde = { workspace = true } serde_json = { workspace = true } simdutf8 = { workspace = true } sort-package-json = { workspace = true } @@ -50,6 +53,7 @@ oxc-toml = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = [] } # Omit the `regex` feature +tower-lsp-server = { workspace = true, features = ["proposed"] } # NAPI dependencies (conditional on napi feature) napi = { workspace = true, features = ["async", "serde-json"], optional = true } @@ -58,6 +62,9 @@ napi-derive = { workspace = true, optional = true } [build-dependencies] napi-build = { workspace = true } +[dev-dependencies] +insta = { workspace = true } + [target.'cfg(not(any(target_os = "linux", target_os = "freebsd", target_arch = "arm", target_family = "wasm")))'.dependencies] mimalloc-safe = { workspace = true, optional = true, features = ["skip_collect_on_exit"] } diff --git a/apps/oxfmt/src/lsp/mod.rs b/apps/oxfmt/src/lsp/mod.rs index 2059b23a0e027..ee874bd33be6c 100644 --- a/apps/oxfmt/src/lsp/mod.rs +++ b/apps/oxfmt/src/lsp/mod.rs @@ -1,11 +1,17 @@ -use oxc_language_server::{ServerFormatterBuilder, run_server}; +use oxc_language_server::run_server; + +mod options; +mod server_formatter; +#[cfg(test)] +mod tester; +const FORMAT_CONFIG_FILES: &[&str; 2] = &[".oxfmtrc.json", ".oxfmtrc.jsonc"]; /// Run the language server pub async fn run_lsp() { run_server( "oxfmt".to_string(), env!("CARGO_PKG_VERSION").to_string(), - vec![Box::new(ServerFormatterBuilder)], + vec![Box::new(server_formatter::ServerFormatterBuilder)], ) .await; } diff --git a/crates/oxc_language_server/src/formatter/options.rs b/apps/oxfmt/src/lsp/options.rs similarity index 100% rename from crates/oxc_language_server/src/formatter/options.rs rename to apps/oxfmt/src/lsp/options.rs diff --git a/crates/oxc_language_server/src/formatter/server_formatter.rs b/apps/oxfmt/src/lsp/server_formatter.rs similarity index 96% rename from crates/oxc_language_server/src/formatter/server_formatter.rs rename to apps/oxfmt/src/lsp/server_formatter.rs index ddb1e992ff66c..3aeb83ebefde3 100644 --- a/crates/oxc_language_server/src/formatter/server_formatter.rs +++ b/apps/oxfmt/src/lsp/server_formatter.rs @@ -11,11 +11,12 @@ use oxc_formatter::{ use oxc_parser::Parser; use tower_lsp_server::ls_types::{Pattern, Position, Range, ServerCapabilities, TextEdit, Uri}; -use crate::{ - capabilities::Capabilities, - formatter::{FORMAT_CONFIG_FILES, options::FormatOptions as LSPFormatOptions}, - tool::{Tool, ToolBuilder, ToolRestartChanges}, +use crate::lsp::{FORMAT_CONFIG_FILES, options::FormatOptions as LSPFormatOptions}; + +use oxc_language_server::{ + Capabilities, utils::normalize_path, + {Tool, ToolBuilder, ToolRestartChanges}, }; pub struct ServerFormatterBuilder; @@ -370,7 +371,8 @@ fn load_ignore_paths(cwd: &Path) -> Vec { #[cfg(test)] mod tests_builder { - use crate::{ServerFormatterBuilder, ToolBuilder, capabilities::Capabilities}; + use crate::lsp::server_formatter::ServerFormatterBuilder; + use oxc_language_server::{Capabilities, ToolBuilder}; #[test] fn test_server_capabilities() { @@ -392,7 +394,7 @@ mod test_watchers { const FAKE_DIR: &str = "fixtures/formatter/watchers"; mod init_watchers { - use crate::formatter::{server_formatter::test_watchers::FAKE_DIR, tester::Tester}; + use crate::lsp::{server_formatter::test_watchers::FAKE_DIR, tester::Tester}; use serde_json::json; #[test] @@ -432,10 +434,8 @@ mod test_watchers { } mod handle_configuration_change { - use crate::{ - ToolRestartChanges, - formatter::{server_formatter::test_watchers::FAKE_DIR, tester::Tester}, - }; + use crate::lsp::{server_formatter::test_watchers::FAKE_DIR, tester::Tester}; + use oxc_language_server::ToolRestartChanges; use serde_json::json; #[test] @@ -465,7 +465,7 @@ mod tests { use serde_json::json; use super::compute_minimal_text_edit; - use crate::formatter::tester::Tester; + use crate::lsp::tester::Tester; #[test] #[should_panic(expected = "assertion failed")] @@ -551,7 +551,7 @@ mod tests { #[test] fn test_formatter() { Tester::new( - "fixtures/formatter/basic", + "test/fixtures/lsp/basic", json!({ "fmt.experimental": true }), @@ -562,7 +562,7 @@ mod tests { #[test] fn test_root_config_detection() { Tester::new( - "fixtures/formatter/root_config", + "test/fixtures/lsp/root_config", json!({ "fmt.experimental": true }), @@ -573,7 +573,7 @@ mod tests { #[test] fn test_custom_config_path() { Tester::new( - "fixtures/formatter/custom_config_path", + "test/fixtures/lsp/custom_config_path", json!({ "fmt.experimental": true, "fmt.configPath": "./format.json", @@ -585,7 +585,7 @@ mod tests { #[test] fn test_ignore_files() { Tester::new( - "fixtures/formatter/ignore-file", + "test/fixtures/lsp/ignore-file", json!({ "fmt.experimental": true }), @@ -596,7 +596,7 @@ mod tests { #[test] fn test_ignore_pattern() { Tester::new( - "fixtures/formatter/ignore-pattern", + "test/fixtures/lsp/ignore-pattern", json!({ "fmt.experimental": true }), diff --git a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_basic@basic.ts.snap b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_basic@basic.ts.snap similarity index 85% rename from crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_basic@basic.ts.snap rename to apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_basic@basic.ts.snap index 1f9451fe82cda..a60a760deb6d2 100644 --- a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_basic@basic.ts.snap +++ b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_basic@basic.ts.snap @@ -1,8 +1,8 @@ --- -source: crates/oxc_language_server/src/formatter/tester.rs +source: apps/oxfmt/src/lsp/tester.rs --- ======================================== -File: fixtures/formatter/basic/basic.ts +File: test/fixtures/lsp/basic/basic.ts ======================================== Range: Range { start: Position { diff --git a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_root_config@semicolons-as-needed.ts.snap b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_custom_config_path@semicolons-as-needed.ts.snap similarity index 66% rename from crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_root_config@semicolons-as-needed.ts.snap rename to apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_custom_config_path@semicolons-as-needed.ts.snap index 54e0658b19b4b..1535f64def1d3 100644 --- a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_root_config@semicolons-as-needed.ts.snap +++ b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_custom_config_path@semicolons-as-needed.ts.snap @@ -1,8 +1,8 @@ --- -source: crates/oxc_language_server/src/formatter/tester.rs +source: apps/oxfmt/src/lsp/tester.rs --- ======================================== -File: fixtures/formatter/root_config/semicolons-as-needed.ts +File: test/fixtures/lsp/custom_config_path/semicolons-as-needed.ts ======================================== Range: Range { start: Position { diff --git a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-file@ignored.ts_not-ignored.js.snap b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-file@ignored.ts_not-ignored.js.snap similarity index 68% rename from crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-file@ignored.ts_not-ignored.js.snap rename to apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-file@ignored.ts_not-ignored.js.snap index 2efdf397ea62d..8cb66235394b2 100644 --- a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-file@ignored.ts_not-ignored.js.snap +++ b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-file@ignored.ts_not-ignored.js.snap @@ -1,12 +1,12 @@ --- -source: crates/oxc_language_server/src/formatter/tester.rs +source: apps/oxfmt/src/lsp/tester.rs --- ======================================== -File: fixtures/formatter/ignore-file/ignored.ts +File: test/fixtures/lsp/ignore-file/ignored.ts ======================================== File is ignored ======================================== -File: fixtures/formatter/ignore-file/not-ignored.js +File: test/fixtures/lsp/ignore-file/not-ignored.js ======================================== Range: Range { start: Position { diff --git a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-pattern@ignored.ts_not-ignored.js.snap b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-pattern@ignored.ts_not-ignored.js.snap similarity index 67% rename from crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-pattern@ignored.ts_not-ignored.js.snap rename to apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-pattern@ignored.ts_not-ignored.js.snap index 1f8e1625ff94c..4a7a68fa679d4 100644 --- a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_ignore-pattern@ignored.ts_not-ignored.js.snap +++ b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_ignore-pattern@ignored.ts_not-ignored.js.snap @@ -1,12 +1,12 @@ --- -source: crates/oxc_language_server/src/formatter/tester.rs +source: apps/oxfmt/src/lsp/tester.rs --- ======================================== -File: fixtures/formatter/ignore-pattern/ignored.ts +File: test/fixtures/lsp/ignore-pattern/ignored.ts ======================================== File is ignored ======================================== -File: fixtures/formatter/ignore-pattern/not-ignored.js +File: test/fixtures/lsp/ignore-pattern/not-ignored.js ======================================== Range: Range { start: Position { diff --git a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_custom_config_path@semicolons-as-needed.ts.snap b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_root_config@semicolons-as-needed.ts.snap similarity index 65% rename from crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_custom_config_path@semicolons-as-needed.ts.snap rename to apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_root_config@semicolons-as-needed.ts.snap index cc8326ab9f066..18f2222da980e 100644 --- a/crates/oxc_language_server/src/formatter/snapshots/fixtures_formatter_custom_config_path@semicolons-as-needed.ts.snap +++ b/apps/oxfmt/src/lsp/snapshots/test_fixtures_lsp_root_config@semicolons-as-needed.ts.snap @@ -1,8 +1,8 @@ --- -source: crates/oxc_language_server/src/formatter/tester.rs +source: apps/oxfmt/src/lsp/tester.rs --- ======================================== -File: fixtures/formatter/custom_config_path/semicolons-as-needed.ts +File: test/fixtures/lsp/root_config/semicolons-as-needed.ts ======================================== Range: Range { start: Position { diff --git a/crates/oxc_language_server/src/formatter/tester.rs b/apps/oxfmt/src/lsp/tester.rs similarity index 97% rename from crates/oxc_language_server/src/formatter/tester.rs rename to apps/oxfmt/src/lsp/tester.rs index b07c476c9cd5d..74e7206a9254d 100644 --- a/crates/oxc_language_server/src/formatter/tester.rs +++ b/apps/oxfmt/src/lsp/tester.rs @@ -2,11 +2,8 @@ use std::{fmt::Write, path::PathBuf}; use tower_lsp_server::ls_types::{TextEdit, Uri}; -use crate::{ - ToolRestartChanges, - formatter::server_formatter::{ServerFormatter, ServerFormatterBuilder}, - tool::Tool, -}; +use crate::lsp::server_formatter::{ServerFormatter, ServerFormatterBuilder}; +use oxc_language_server::{Tool, ToolRestartChanges}; /// Given a file path relative to the crate root directory, return the absolute path of the file. pub fn get_file_path(relative_file_path: &str) -> PathBuf { diff --git a/crates/oxc_language_server/fixtures/formatter/basic/basic.ts b/apps/oxfmt/test/fixtures/lsp/basic/basic.ts similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/basic/basic.ts rename to apps/oxfmt/test/fixtures/lsp/basic/basic.ts diff --git a/crates/oxc_language_server/fixtures/formatter/custom_config_path/format.json b/apps/oxfmt/test/fixtures/lsp/custom_config_path/format.json similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/custom_config_path/format.json rename to apps/oxfmt/test/fixtures/lsp/custom_config_path/format.json diff --git a/crates/oxc_language_server/fixtures/formatter/custom_config_path/semicolons-as-needed.ts b/apps/oxfmt/test/fixtures/lsp/custom_config_path/semicolons-as-needed.ts similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/custom_config_path/semicolons-as-needed.ts rename to apps/oxfmt/test/fixtures/lsp/custom_config_path/semicolons-as-needed.ts diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-file/.oxfmtrc.json b/apps/oxfmt/test/fixtures/lsp/ignore-file/.oxfmtrc.json similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-file/.oxfmtrc.json rename to apps/oxfmt/test/fixtures/lsp/ignore-file/.oxfmtrc.json diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-file/.prettierignore b/apps/oxfmt/test/fixtures/lsp/ignore-file/.prettierignore similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-file/.prettierignore rename to apps/oxfmt/test/fixtures/lsp/ignore-file/.prettierignore diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-file/ignored.ts b/apps/oxfmt/test/fixtures/lsp/ignore-file/ignored.ts similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-file/ignored.ts rename to apps/oxfmt/test/fixtures/lsp/ignore-file/ignored.ts diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-file/not-ignored.js b/apps/oxfmt/test/fixtures/lsp/ignore-file/not-ignored.js similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-file/not-ignored.js rename to apps/oxfmt/test/fixtures/lsp/ignore-file/not-ignored.js diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-pattern/.oxfmtrc.json b/apps/oxfmt/test/fixtures/lsp/ignore-pattern/.oxfmtrc.json similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-pattern/.oxfmtrc.json rename to apps/oxfmt/test/fixtures/lsp/ignore-pattern/.oxfmtrc.json diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-pattern/ignored.ts b/apps/oxfmt/test/fixtures/lsp/ignore-pattern/ignored.ts similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-pattern/ignored.ts rename to apps/oxfmt/test/fixtures/lsp/ignore-pattern/ignored.ts diff --git a/crates/oxc_language_server/fixtures/formatter/ignore-pattern/not-ignored.js b/apps/oxfmt/test/fixtures/lsp/ignore-pattern/not-ignored.js similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/ignore-pattern/not-ignored.js rename to apps/oxfmt/test/fixtures/lsp/ignore-pattern/not-ignored.js diff --git a/crates/oxc_language_server/fixtures/formatter/root_config/.oxfmtrc.json b/apps/oxfmt/test/fixtures/lsp/root_config/.oxfmtrc.json similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/root_config/.oxfmtrc.json rename to apps/oxfmt/test/fixtures/lsp/root_config/.oxfmtrc.json diff --git a/crates/oxc_language_server/fixtures/formatter/root_config/semicolons-as-needed.ts b/apps/oxfmt/test/fixtures/lsp/root_config/semicolons-as-needed.ts similarity index 100% rename from crates/oxc_language_server/fixtures/formatter/root_config/semicolons-as-needed.ts rename to apps/oxfmt/test/fixtures/lsp/root_config/semicolons-as-needed.ts diff --git a/crates/oxc_language_server/Cargo.toml b/crates/oxc_language_server/Cargo.toml index 65f7cadef09cd..d2fb9e6c52eed 100644 --- a/crates/oxc_language_server/Cargo.toml +++ b/crates/oxc_language_server/Cargo.toml @@ -28,15 +28,12 @@ doctest = false oxc_allocator = { workspace = true, optional = true } oxc_data_structures = { workspace = true, features = ["rope"], optional = true } oxc_diagnostics = { workspace = true, optional = true } -oxc_formatter = { workspace = true, optional = true } oxc_linter = { workspace = true, optional = true } -oxc_parser = { workspace = true, optional = true } # env_logger = { workspace = true, features = ["humantime"] } futures = { workspace = true } ignore = { workspace = true, features = ["simd-accel"], optional = true } -json-strip-comments = { workspace = true } log = { workspace = true } papaya = { workspace = true } rustc-hash = { workspace = true } @@ -50,7 +47,7 @@ insta = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "io-util", "macros"] } [features] -default = ["linter", "formatter"] +default = ["linter"] linter = [ "dep:oxc_allocator", "dep:oxc_data_structures", @@ -59,11 +56,3 @@ linter = [ # "dep:ignore", ] -formatter = [ - "dep:oxc_allocator", - "dep:oxc_data_structures", - "dep:oxc_formatter", - "dep:oxc_parser", - # - "dep:ignore", -] diff --git a/crates/oxc_language_server/src/formatter/mod.rs b/crates/oxc_language_server/src/formatter/mod.rs deleted file mode 100644 index 4fac84212e425..0000000000000 --- a/crates/oxc_language_server/src/formatter/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod options; -mod server_formatter; -#[cfg(test)] -mod tester; - -pub use server_formatter::ServerFormatterBuilder; - -const FORMAT_CONFIG_FILES: &[&str; 2] = &[".oxfmtrc.json", ".oxfmtrc.jsonc"]; diff --git a/crates/oxc_language_server/src/lib.rs b/crates/oxc_language_server/src/lib.rs index 88075d437f8e2..9afa5c2af5d3a 100644 --- a/crates/oxc_language_server/src/lib.rs +++ b/crates/oxc_language_server/src/lib.rs @@ -4,20 +4,16 @@ use tower_lsp_server::{LspService, Server, ls_types::ServerInfo}; mod backend; mod capabilities; mod file_system; -#[cfg(feature = "formatter")] -mod formatter; #[cfg(feature = "linter")] mod linter; mod options; #[cfg(test)] mod tests; mod tool; -mod utils; +pub mod utils; mod worker; -use crate::backend::Backend; -#[cfg(feature = "formatter")] -pub use crate::formatter::ServerFormatterBuilder; +pub use crate::capabilities::Capabilities; #[cfg(feature = "linter")] pub use crate::linter::ServerLinterBuilder; pub use crate::tool::{Tool, ToolBuilder, ToolRestartChanges}; @@ -36,7 +32,11 @@ pub async fn run_server( let stdout = tokio::io::stdout(); let (service, socket) = LspService::build(|client| { - Backend::new(client, ServerInfo { name: server_name, version: Some(server_version) }, tools) + crate::backend::Backend::new( + client, + ServerInfo { name: server_name, version: Some(server_version) }, + tools, + ) }) .finish(); diff --git a/crates/oxc_language_server/src/main.rs b/crates/oxc_language_server/src/main.rs index 29452b86828cf..2f109deed2edd 100644 --- a/crates/oxc_language_server/src/main.rs +++ b/crates/oxc_language_server/src/main.rs @@ -3,8 +3,6 @@ async fn main() { #[expect(clippy::vec_init_then_push)] let tools: Vec> = { let mut v: Vec> = Vec::new(); - #[cfg(feature = "formatter")] - v.push(Box::new(oxc_language_server::ServerFormatterBuilder)); #[cfg(feature = "linter")] v.push(Box::new(oxc_language_server::ServerLinterBuilder)); v