Skip to content

Commit

Permalink
Make configuration a property of individual documents instead of per-…
Browse files Browse the repository at this point in the history
…workspace
  • Loading branch information
snowsignal committed Apr 14, 2024
1 parent 2d30be2 commit f7c073d
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 41 deletions.
4 changes: 1 addition & 3 deletions crates/ruff_server/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ pub(crate) struct Session {
/// An immutable snapshot of `Session` that references
/// a specific document.
pub(crate) struct DocumentSnapshot {
configuration: Arc<workspace::RuffConfiguration>,
resolved_client_capabilities: Arc<ResolvedClientCapabilities>,
client_settings: settings::ResolvedClientSettings,
document_ref: workspace::DocumentRef,
Expand All @@ -57,7 +56,6 @@ impl Session {

pub(crate) fn take_snapshot(&self, url: &Url) -> Option<DocumentSnapshot> {
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)?,
Expand Down Expand Up @@ -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 {
Expand Down
62 changes: 39 additions & 23 deletions crates/ruff_server/src/session/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,28 @@ pub(crate) struct Workspaces(BTreeMap<PathBuf, Workspace>);

pub(crate) struct Workspace {
open_documents: OpenDocuments,
configuration: Arc<RuffConfiguration>,
settings: ClientSettings,
}

#[derive(Default)]
pub(crate) struct OpenDocuments {
documents: FxHashMap<Url, DocumentController>,
configuration_index: configuration::ConfigurationIndex,
}

/// A mutable handler to an underlying document.
/// Handles copy-on-write mutation automatically when
/// calling `deref_mut`.
pub(crate) struct DocumentController {
document: Arc<Document>,
configuration: Arc<RuffConfiguration>,
}

/// A read-only reference to a document.
#[derive(Clone)]
pub(crate) struct DocumentRef {
document: Arc<Document>,
configuration: Arc<RuffConfiguration>,
}

impl Workspaces {
Expand Down Expand Up @@ -82,15 +84,11 @@ impl Workspaces {
.controller(document_url)
}

pub(super) fn configuration(&self, document_url: &Url) -> Option<&Arc<RuffConfiguration>> {
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(())
}

Expand Down Expand Up @@ -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();
}
}

Expand All @@ -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!");
Expand All @@ -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<RuffConfiguration>,
) -> Self {
Self {
document: Arc::new(Document::new(contents, version)),
configuration,
}
}

pub(crate) fn update_configuration(&mut self, new_configuration: Arc<RuffConfiguration>) {
self.configuration = new_configuration;
}

pub(crate) fn make_ref(&self) -> DocumentRef {
DocumentRef {
document: self.document.clone(),
configuration: self.configuration.clone(),
}
}

Expand All @@ -244,3 +254,9 @@ impl Deref for DocumentRef {
&self.document
}
}

impl DocumentRef {
pub(crate) fn configuration(&self) -> &RuffConfiguration {
&self.configuration
}
}
31 changes: 16 additions & 15 deletions crates/ruff_server/src/session/workspace/configuration.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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<RuffConfiguration> {
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<PathBuf, Arc<RuffConfiguration>>,
}

impl ConfigurationIndex {
pub(super) fn get_or_insert(&mut self, path: &Url) -> Arc<RuffConfiguration> {
todo!("impl");
}

pub(super) fn clear(&mut self) {
self.index.clear();
}
}

struct LSPConfigTransformer;
Expand Down

0 comments on commit f7c073d

Please sign in to comment.