From f7c073d4412242dfe09fd620371432735ffa0c18 Mon Sep 17 00:00:00 2001 From: Jane Lewis Date: Sun, 14 Apr 2024 15:47:22 -0700 Subject: [PATCH] Make configuration a property of individual documents instead of per-workspace --- crates/ruff_server/src/session.rs | 4 +- crates/ruff_server/src/session/workspace.rs | 62 ++++++++++++------- .../src/session/workspace/configuration.rs | 31 +++++----- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/crates/ruff_server/src/session.rs b/crates/ruff_server/src/session.rs index c23a199d85e08..9ee0dbd5c3e79 100644 --- a/crates/ruff_server/src/session.rs +++ b/crates/ruff_server/src/session.rs @@ -30,7 +30,6 @@ pub(crate) struct Session { /// An immutable snapshot of `Session` that references /// a specific document. pub(crate) struct DocumentSnapshot { - configuration: Arc, resolved_client_capabilities: Arc, client_settings: settings::ResolvedClientSettings, document_ref: workspace::DocumentRef, @@ -57,7 +56,6 @@ impl Session { pub(crate) fn take_snapshot(&self, url: &Url) -> Option { Some(DocumentSnapshot { - configuration: self.workspaces.configuration(url)?.clone(), resolved_client_capabilities: self.resolved_client_capabilities.clone(), client_settings: self.workspaces.client_settings(url, &self.global_settings), document_ref: self.workspaces.snapshot(url)?, @@ -109,7 +107,7 @@ impl Session { impl DocumentSnapshot { pub(crate) fn configuration(&self) -> &workspace::RuffConfiguration { - &self.configuration + self.document().configuration() } pub(crate) fn resolved_client_capabilities(&self) -> &ResolvedClientCapabilities { diff --git a/crates/ruff_server/src/session/workspace.rs b/crates/ruff_server/src/session/workspace.rs index ee15dfaf22e93..92219e06ae560 100644 --- a/crates/ruff_server/src/session/workspace.rs +++ b/crates/ruff_server/src/session/workspace.rs @@ -21,13 +21,13 @@ pub(crate) struct Workspaces(BTreeMap); pub(crate) struct Workspace { open_documents: OpenDocuments, - configuration: Arc, settings: ClientSettings, } #[derive(Default)] pub(crate) struct OpenDocuments { documents: FxHashMap, + configuration_index: configuration::ConfigurationIndex, } /// A mutable handler to an underlying document. @@ -35,12 +35,14 @@ pub(crate) struct OpenDocuments { /// calling `deref_mut`. pub(crate) struct DocumentController { document: Arc, + configuration: Arc, } /// A read-only reference to a document. #[derive(Clone)] pub(crate) struct DocumentRef { document: Arc, + configuration: Arc, } impl Workspaces { @@ -82,15 +84,11 @@ impl Workspaces { .controller(document_url) } - pub(super) fn configuration(&self, document_url: &Url) -> Option<&Arc> { - Some(&self.workspace_for_url(document_url)?.configuration) - } - pub(super) fn reload_configuration(&mut self, changed_url: &Url) -> crate::Result<()> { - let (path, workspace) = self - .entry_for_url_mut(changed_url) + let workspace = self + .workspace_for_url_mut(changed_url) .ok_or_else(|| anyhow!("Workspace not found for {changed_url}"))?; - workspace.reload_configuration(path); + workspace.reload_configuration(); Ok(()) } @@ -158,29 +156,18 @@ impl Workspace { let path = root .to_file_path() .map_err(|()| anyhow!("workspace URL was not a file path!"))?; - // Fall-back to default configuration - let configuration = Self::find_configuration_or_fallback(&path); Ok(( path, Self { open_documents: OpenDocuments::default(), - configuration: Arc::new(configuration), settings, }, )) } - fn reload_configuration(&mut self, path: &Path) { - self.configuration = Arc::new(Self::find_configuration_or_fallback(path)); - } - - fn find_configuration_or_fallback(root: &Path) -> RuffConfiguration { - configuration::find_configuration_from_root(root).unwrap_or_else(|err| { - tracing::error!("The following error occurred when trying to find a configuration file at `{}`:\n{err}", root.display()); - tracing::error!("Falling back to default configuration for `{}`", root.display()); - RuffConfiguration::default() - }) + fn reload_configuration(&mut self) { + self.open_documents.reload_configuration(); } } @@ -194,9 +181,13 @@ impl OpenDocuments { } fn open(&mut self, url: &Url, contents: String, version: DocumentVersion) { + let configuration = self.configuration_index.get_or_insert(url); if self .documents - .insert(url.clone(), DocumentController::new(contents, version)) + .insert( + url.clone(), + DocumentController::new(contents, version, configuration), + ) .is_some() { tracing::warn!("Opening document `{url}` that is already open!"); @@ -211,18 +202,37 @@ impl OpenDocuments { }; Ok(()) } + + fn reload_configuration(&mut self) { + self.configuration_index.clear(); + + for (path, document) in &mut self.documents { + let new_configuration = self.configuration_index.get_or_insert(path); + document.update_configuration(new_configuration); + } + } } impl DocumentController { - fn new(contents: String, version: DocumentVersion) -> Self { + fn new( + contents: String, + version: DocumentVersion, + configuration: Arc, + ) -> Self { Self { document: Arc::new(Document::new(contents, version)), + configuration, } } + pub(crate) fn update_configuration(&mut self, new_configuration: Arc) { + self.configuration = new_configuration; + } + pub(crate) fn make_ref(&self) -> DocumentRef { DocumentRef { document: self.document.clone(), + configuration: self.configuration.clone(), } } @@ -244,3 +254,9 @@ impl Deref for DocumentRef { &self.document } } + +impl DocumentRef { + pub(crate) fn configuration(&self) -> &RuffConfiguration { + &self.configuration + } +} diff --git a/crates/ruff_server/src/session/workspace/configuration.rs b/crates/ruff_server/src/session/workspace/configuration.rs index b8ba39275723c..8818a1e61559d 100644 --- a/crates/ruff_server/src/session/workspace/configuration.rs +++ b/crates/ruff_server/src/session/workspace/configuration.rs @@ -1,6 +1,6 @@ -use anyhow::anyhow; -use ruff_workspace::resolver::{ConfigurationTransformer, Relativity}; -use std::path::Path; +use lsp_types::Url; +use ruff_workspace::resolver::ConfigurationTransformer; +use std::{collections::BTreeMap, path::PathBuf, sync::Arc}; #[derive(Default)] pub(crate) struct RuffConfiguration { @@ -10,18 +10,19 @@ pub(crate) struct RuffConfiguration { pub(crate) formatter: ruff_workspace::FormatterSettings, } -pub(crate) fn find_configuration_from_root(root: &Path) -> crate::Result { - let pyproject = ruff_workspace::pyproject::find_settings_toml(root)? - .ok_or_else(|| anyhow!("No pyproject.toml/ruff.toml/.ruff.toml file was found"))?; - let settings = ruff_workspace::resolver::resolve_root_settings( - &pyproject, - Relativity::Parent, - &LSPConfigTransformer, - )?; - Ok(RuffConfiguration { - linter: settings.linter, - formatter: settings.formatter, - }) +#[derive(Default)] +pub(super) struct ConfigurationIndex { + index: BTreeMap>, +} + +impl ConfigurationIndex { + pub(super) fn get_or_insert(&mut self, path: &Url) -> Arc { + todo!("impl"); + } + + pub(super) fn clear(&mut self) { + self.index.clear(); + } } struct LSPConfigTransformer;