From a69d57f49fead74c408860ca0f3c3bac2c5b79eb Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Sun, 1 Nov 2026 12:49:04 +0900 Subject: [PATCH 1/2] test --- .../test/lsp/lsp_interaction/definition.rs | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/pyrefly/lib/test/lsp/lsp_interaction/definition.rs b/pyrefly/lib/test/lsp/lsp_interaction/definition.rs index ef70043632..c6c00c9d64 100644 --- a/pyrefly/lib/test/lsp/lsp_interaction/definition.rs +++ b/pyrefly/lib/test/lsp/lsp_interaction/definition.rs @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +use std::fs; use std::path::PathBuf; use std::sync::Arc; @@ -145,6 +146,172 @@ fn test_go_to_def_basic(root: &TempDir, workspace_folders: Option Date: Mon, 6 Apr 2026 17:57:13 +0900 Subject: [PATCH 2/2] fix --- pyrefly/lib/lsp/non_wasm/server.rs | 31 +++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/pyrefly/lib/lsp/non_wasm/server.rs b/pyrefly/lib/lsp/non_wasm/server.rs index 3ca2aae429..32fa1f9f97 100644 --- a/pyrefly/lib/lsp/non_wasm/server.rs +++ b/pyrefly/lib/lsp/non_wasm/server.rs @@ -235,9 +235,11 @@ use pyrefly_python::module::TextRangeWithModule; use pyrefly_python::module_name::ModuleName; use pyrefly_python::module_name::ModuleNameWithKind; use pyrefly_python::module_path::ModulePath; +use pyrefly_python::module_path::ModulePathDetails; use pyrefly_util::absolutize::Absolutize as _; use pyrefly_util::arc_id::ArcId; use pyrefly_util::events::CategorizedEvents; +use pyrefly_util::fs_anyhow; use pyrefly_util::globs::FilteredGlobs; use pyrefly_util::globs::HiddenDirFilter; use pyrefly_util::includes::Includes as _; @@ -2463,7 +2465,7 @@ impl Server { params, &x.id, ) { - let response = match self.goto_definition(&transaction, params) { + let response = match self.goto_definition(&mut transaction, params) { Ok(response) => response, Err(reason) => { telemetry_event.set_empty_response_reason(reason); @@ -5034,7 +5036,7 @@ impl Server { fn goto_definition( &self, - transaction: &Transaction<'_>, + transaction: &mut Transaction<'_>, params: DefinitionParams, ) -> Result, EmptyResponseReason> { let uri = ¶ms.text_document_position_params.text_document.uri; @@ -5044,7 +5046,30 @@ impl Server { .ok_or(EmptyResponseReason::ModuleInfoNotFound)?; let range = self.from_lsp_position(uri, &info, params.text_document_position_params.position); - let targets = transaction.goto_definition(&handle, range)?; + let mut targets = transaction.goto_definition(&handle, range)?; + + // Client positions refer to open buffers. Only closed destinations can be + // refreshed from disk without changing the meaning of those positions. + let mut changed = SmallSet::new(); + for target in &targets { + if let ModulePathDetails::FileSystem(path) = target.module.path().details() + && !self.open_files.read().contains_key(path.as_path()) + && !target.module.is_notebook() + && let Ok(contents) = fs_anyhow::read_to_string(path) + && contents.as_str() != target.module.contents().as_str() + { + changed.insert(path.to_path_buf()); + } + } + if !changed.is_empty() { + transaction.invalidate_disk(&changed.into_iter().collect::>()); + transaction.run( + std::slice::from_ref(&handle), + Require::Everything, + Some(&self.lsp_thread_pool), + ); + targets = transaction.goto_definition(&handle, range)?; + } let mut lsp_targets = targets .iter() .filter_map(|x| self.to_lsp_location(x))