From 182e16d3b31b88e80c05b6fdce70eda21e7973ab Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Wed, 30 Jul 2025 17:13:36 -0400 Subject: [PATCH] ensure that builtin basedpyright will override the extension --- crates/language/src/language.rs | 9 ++ crates/language/src/language_registry.rs | 69 +++++++--------- .../src/extension_lsp_adapter.rs | 4 + crates/languages/src/lib.rs | 27 ++---- crates/project/src/lsp_store.rs | 82 ------------------- 5 files changed, 51 insertions(+), 140 deletions(-) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 549afc931c..870826d3ca 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -615,6 +615,11 @@ pub trait LspAdapter: 'static + Send + Sync { "Not implemented for this adapter. This method should only be called on the default JSON language server adapter" ); } + + /// True for the extension adapter and false otherwise. + fn is_extension(&self) -> bool { + false + } } async fn try_fetch_server_binary( @@ -2273,6 +2278,10 @@ impl LspAdapter for FakeLspAdapter { let label_for_completion = self.label_for_completion.as_ref()?; label_for_completion(item, language) } + + fn is_extension(&self) -> bool { + false + } } fn get_capture_indices(query: &Query, captures: &mut [(&str, &mut Option)]) { diff --git a/crates/language/src/language_registry.rs b/crates/language/src/language_registry.rs index ab3c0f9b37..608b12f352 100644 --- a/crates/language/src/language_registry.rs +++ b/crates/language/src/language_registry.rs @@ -370,14 +370,23 @@ impl LanguageRegistry { pub fn register_available_lsp_adapter( &self, name: LanguageServerName, - load: impl Fn() -> Arc + 'static + Send + Sync, + adapter: Arc, ) { - self.state.write().available_lsp_adapters.insert( + let mut state = self.state.write(); + + if adapter.is_extension() + && let Some(existing_adapter) = state.all_lsp_adapters.get(&name) + && !existing_adapter.adapter.is_extension() + { + log::warn!( + "not registering extension-provided language server {name:?}, since a builtin language server exists with that name", + ); + return; + } + + state.available_lsp_adapters.insert( name, - Arc::new(move || { - let lsp_adapter = load(); - CachedLspAdapter::new(lsp_adapter) - }), + Arc::new(move || CachedLspAdapter::new(adapter.clone())), ); } @@ -392,47 +401,29 @@ impl LanguageRegistry { Some(load_lsp_adapter()) } - pub fn register_lsp_adapter( - &self, - language_name: LanguageName, - adapter: Arc, - ) -> Arc { - let cached = CachedLspAdapter::new(adapter); + pub fn register_lsp_adapter(&self, language_name: LanguageName, adapter: Arc) { let mut state = self.state.write(); + + if adapter.is_extension() + && let Some(existing_adapter) = state.all_lsp_adapters.get(&adapter.name()) + && !existing_adapter.adapter.is_extension() + { + log::warn!( + "not registering extension-provided language server {:?} for language {language_name:?}, since a builtin language server exists with that name", + adapter.name(), + ); + return; + } + + let cached = CachedLspAdapter::new(adapter); state .lsp_adapters - .entry(language_name) + .entry(language_name.clone()) .or_default() .push(cached.clone()); state .all_lsp_adapters .insert(cached.name.clone(), cached.clone()); - - cached - } - - pub fn get_or_register_lsp_adapter( - &self, - language_name: LanguageName, - server_name: LanguageServerName, - build_adapter: impl FnOnce() -> Arc + 'static, - ) -> Arc { - let registered = self - .state - .write() - .lsp_adapters - .entry(language_name.clone()) - .or_default() - .iter() - .find(|cached_adapter| cached_adapter.name == server_name) - .cloned(); - - if let Some(found) = registered { - found - } else { - let adapter = build_adapter(); - self.register_lsp_adapter(language_name, adapter) - } } /// Register a fake language server and adapter diff --git a/crates/language_extension/src/extension_lsp_adapter.rs b/crates/language_extension/src/extension_lsp_adapter.rs index 58fbe6cda2..8d6dd6eba5 100644 --- a/crates/language_extension/src/extension_lsp_adapter.rs +++ b/crates/language_extension/src/extension_lsp_adapter.rs @@ -397,6 +397,10 @@ impl LspAdapter for ExtensionLspAdapter { Ok(labels_from_extension(labels, language)) } + + fn is_extension(&self) -> bool { + true + } } fn labels_from_extension( diff --git a/crates/languages/src/lib.rs b/crates/languages/src/lib.rs index 06f285fccc..9fb792fc6c 100644 --- a/crates/languages/src/lib.rs +++ b/crates/languages/src/lib.rs @@ -265,29 +265,18 @@ pub fn init(languages: Arc, node: NodeRuntime, cx: &mut App) { // ``` languages.register_available_lsp_adapter( LanguageServerName("tailwindcss-language-server".into()), - { - let adapter = tailwind_adapter.clone(); - move || adapter.clone() - }, + tailwind_adapter.clone(), ); - languages.register_available_lsp_adapter(LanguageServerName("eslint".into()), { - let adapter = eslint_adapter.clone(); - move || adapter.clone() - }); - languages.register_available_lsp_adapter(LanguageServerName("vtsls".into()), { - let adapter = vtsls_adapter.clone(); - move || adapter.clone() - }); + languages.register_available_lsp_adapter( + LanguageServerName("eslint".into()), + eslint_adapter.clone(), + ); + languages.register_available_lsp_adapter(LanguageServerName("vtsls".into()), vtsls_adapter); languages.register_available_lsp_adapter( LanguageServerName("typescript-language-server".into()), - { - let adapter = typescript_lsp_adapter.clone(); - move || adapter.clone() - }, + typescript_lsp_adapter, ); - languages.register_available_lsp_adapter(python_lsp_adapter.name(), move || { - python_lsp_adapter.clone() - }); + languages.register_available_lsp_adapter(python_lsp_adapter.name(), python_lsp_adapter); // Register Tailwind for the existing languages that should have it by default. // diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index dd4d0a7f40..9dab6f5527 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -81,7 +81,6 @@ use sha2::{Digest, Sha256}; use smol::channel::Sender; use snippet::Snippet; use std::{ - any::Any, borrow::Cow, cell::RefCell, cmp::{Ordering, Reverse}, @@ -12227,87 +12226,6 @@ fn glob_literal_prefix(glob: &Path) -> PathBuf { .collect() } -pub struct SshLspAdapter { - name: LanguageServerName, - binary: LanguageServerBinary, - initialization_options: Option, - code_action_kinds: Option>, -} - -impl SshLspAdapter { - pub fn new( - name: LanguageServerName, - binary: LanguageServerBinary, - initialization_options: Option, - code_action_kinds: Option, - ) -> Self { - Self { - name, - binary, - initialization_options, - code_action_kinds: code_action_kinds - .as_ref() - .and_then(|c| serde_json::from_str(c).ok()), - } - } -} - -#[async_trait(?Send)] -impl LspAdapter for SshLspAdapter { - fn name(&self) -> LanguageServerName { - self.name.clone() - } - - async fn initialization_options( - self: Arc, - _: &dyn Fs, - _: &Arc, - ) -> Result> { - let Some(options) = &self.initialization_options else { - return Ok(None); - }; - let result = serde_json::from_str(options)?; - Ok(result) - } - - fn code_action_kinds(&self) -> Option> { - self.code_action_kinds.clone() - } - - async fn check_if_user_installed( - &self, - _: &dyn LspAdapterDelegate, - _: Arc, - _: &AsyncApp, - ) -> Option { - Some(self.binary.clone()) - } - - async fn cached_server_binary( - &self, - _: PathBuf, - _: &dyn LspAdapterDelegate, - ) -> Option { - None - } - - async fn fetch_latest_server_version( - &self, - _: &dyn LspAdapterDelegate, - ) -> Result> { - anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version") - } - - async fn fetch_server_binary( - &self, - _: Box, - _: PathBuf, - _: &dyn LspAdapterDelegate, - ) -> Result { - anyhow::bail!("SshLspAdapter does not support fetch_server_binary") - } -} - pub fn language_server_settings<'a>( delegate: &'a dyn LspAdapterDelegate, language: &LanguageServerName,