From bf3db9c921f64e02883e7fede45740e70c6e7919 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 12:49:27 +0000 Subject: [PATCH 1/3] Initial plan From e5d7ee20282b994fc2e8e3c0e12b855a9ee8e4fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 13:09:47 +0000 Subject: [PATCH 2/3] Fix memory leak in oxc_linter resolver by clearing cache after run_source Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com> --- crates/oxc_linter/src/service/runtime.rs | 9 ++++++++ crates/oxc_linter/tests/integration_test.rs | 24 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/crates/oxc_linter/src/service/runtime.rs b/crates/oxc_linter/src/service/runtime.rs index a0c17efaca7c0..27e1b80ac44a9 100644 --- a/crates/oxc_linter/src/service/runtime.rs +++ b/crates/oxc_linter/src/service/runtime.rs @@ -733,6 +733,15 @@ impl Runtime { // } // } + // Clear resolver cache to prevent memory leaks in language server usage. + // The resolver caches filesystem metadata globally, which can accumulate + // indefinitely when processing files repeatedly in a language server context. + // Clearing after each run prevents unbounded memory growth while still + // allowing caching within a single linting session. + if let Some(resolver) = &self.resolver { + resolver.clear_cache(); + } + messages.into_inner().unwrap() } diff --git a/crates/oxc_linter/tests/integration_test.rs b/crates/oxc_linter/tests/integration_test.rs index 56bc2e1f7b0c1..901773312b023 100644 --- a/crates/oxc_linter/tests/integration_test.rs +++ b/crates/oxc_linter/tests/integration_test.rs @@ -39,3 +39,27 @@ fn test_declare_oxc_lint() { // plugin name is passed to const assert_eq!(TestRule::PLUGIN, "eslint"); } + +/// Test to ensure resolver cache clearing doesn't panic when called +#[test] +fn test_resolver_cache_clearing_integration() { + // This test verifies that the resolver cache clearing functionality + // compiles and can be called without panicking. + // The actual memory leak fix is in Runtime::run_source() method. + + use oxc_resolver::{ResolveOptions, Resolver}; + + // Create a resolver similar to how it's done in Runtime::get_resolver + let resolver = Resolver::new(ResolveOptions { + extensions: vec![".js".into(), ".ts".into(), ".jsx".into(), ".tsx".into()], + main_fields: vec!["module".into(), "main".into()], + condition_names: vec!["module".into(), "import".into()], + ..ResolveOptions::default() + }); + + // Test that clear_cache can be called without panicking + resolver.clear_cache(); + + // If we reach here, the clear_cache method works correctly + println!("Resolver cache clearing integration test passed"); +} From e97c00537f43540e62d2f498b0f73393a085f797 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 22:34:49 +0000 Subject: [PATCH 3/3] [autofix.ci] apply automated fixes --- crates/oxc_linter/tests/integration_test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/oxc_linter/tests/integration_test.rs b/crates/oxc_linter/tests/integration_test.rs index 901773312b023..883460af20f49 100644 --- a/crates/oxc_linter/tests/integration_test.rs +++ b/crates/oxc_linter/tests/integration_test.rs @@ -46,9 +46,9 @@ fn test_resolver_cache_clearing_integration() { // This test verifies that the resolver cache clearing functionality // compiles and can be called without panicking. // The actual memory leak fix is in Runtime::run_source() method. - + use oxc_resolver::{ResolveOptions, Resolver}; - + // Create a resolver similar to how it's done in Runtime::get_resolver let resolver = Resolver::new(ResolveOptions { extensions: vec![".js".into(), ".ts".into(), ".jsx".into(), ".tsx".into()], @@ -56,10 +56,10 @@ fn test_resolver_cache_clearing_integration() { condition_names: vec!["module".into(), "import".into()], ..ResolveOptions::default() }); - + // Test that clear_cache can be called without panicking resolver.clear_cache(); - + // If we reach here, the clear_cache method works correctly println!("Resolver cache clearing integration test passed"); }