Skip to content

Commit 8cb7d55

Browse files
committed
Address additional suggestions
1 parent 884dba1 commit 8cb7d55

File tree

7 files changed

+87
-88
lines changed

7 files changed

+87
-88
lines changed

crates/ruff_server/src/fix.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,22 @@ pub(crate) fn fix_all(
7070
if let (Some(source_notebook), Some(modified_notebook)) =
7171
(source_kind.as_ipy_notebook(), transformed.as_ipy_notebook())
7272
{
73+
fn cell_source(cell: &ruff_notebook::Cell) -> String {
74+
match cell.source() {
75+
SourceValue::String(string) => string.clone(),
76+
SourceValue::StringArray(array) => array.join(""),
77+
}
78+
}
79+
7380
let Some(notebook) = query.as_notebook() else {
7481
anyhow::bail!("Notebook document expected from notebook source kind");
7582
};
7683
let mut fixes = Fixes::default();
7784
for ((source, modified), url) in source_notebook
7885
.cells()
7986
.iter()
80-
.map(|cell| match cell.source() {
81-
SourceValue::String(string) => string.clone(),
82-
SourceValue::StringArray(array) => array.join(""),
83-
})
84-
.zip(
85-
modified_notebook
86-
.cells()
87-
.iter()
88-
.map(|cell| match cell.source() {
89-
SourceValue::String(string) => string.clone(),
90-
SourceValue::StringArray(array) => array.join(""),
91-
}),
92-
)
87+
.map(cell_source)
88+
.zip(modified_notebook.cells().iter().map(cell_source))
9389
.zip(notebook.urls())
9490
{
9591
let source_index = LineIndex::from_source_text(&source);

crates/ruff_server/src/lint.rs

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ruff_python_codegen::Stylist;
1515
use ruff_python_index::Indexer;
1616
use ruff_python_parser::AsMode;
1717
use ruff_source_file::{LineIndex, Locator};
18-
use ruff_text_size::Ranged;
18+
use ruff_text_size::{Ranged, TextRange};
1919
use rustc_hash::FxHashMap;
2020
use serde::{Deserialize, Serialize};
2121

@@ -127,20 +127,23 @@ pub(crate) fn check(
127127
}
128128
}
129129

130-
for (index, diagnostic) in data
130+
let lsp_diagnostics = data
131131
.into_iter()
132132
.zip(noqa_edits)
133133
.map(|(diagnostic, noqa_edit)| {
134134
to_lsp_diagnostic(diagnostic, &noqa_edit, &source_kind, &index, encoding)
135-
})
136-
{
137-
if let Some(notebook) = query.as_notebook() {
135+
});
136+
137+
if let Some(notebook) = query.as_notebook() {
138+
for (index, diagnostic) in lsp_diagnostics {
138139
let Some(uri) = notebook.cell_uri_by_index(index) else {
139140
tracing::warn!("Unable to find notebook cell at index {index}.");
140141
continue;
141142
};
142143
diagnostics.entry(uri.clone()).or_default().push(diagnostic);
143-
} else {
144+
}
145+
} else {
146+
for (_, diagnostic) in lsp_diagnostics {
144147
diagnostics
145148
.entry(query.make_key().into_url())
146149
.or_default()
@@ -208,42 +211,12 @@ fn to_lsp_diagnostic(
208211
.into_iter()
209212
.flat_map(Fix::edits)
210213
.map(|edit| lsp_types::TextEdit {
211-
range: if let Some(notebook_index) =
212-
source_kind.as_ipy_notebook().map(Notebook::index)
213-
{
214-
edit.range()
215-
.to_notebook_range(
216-
source_kind.source_code(),
217-
index,
218-
notebook_index,
219-
encoding,
220-
)
221-
.range
222-
} else {
223-
edit.range()
224-
.to_range(source_kind.source_code(), index, encoding)
225-
},
214+
range: diagnostic_edit_range(edit.range(), source_kind, index, encoding),
226215
new_text: edit.content().unwrap_or_default().to_string(),
227216
})
228217
.collect();
229218
let noqa_edit = noqa_edit.as_ref().map(|noqa_edit| lsp_types::TextEdit {
230-
range: if let Some(notebook_index) =
231-
source_kind.as_ipy_notebook().map(Notebook::index)
232-
{
233-
noqa_edit
234-
.range()
235-
.to_notebook_range(
236-
source_kind.source_code(),
237-
index,
238-
notebook_index,
239-
encoding,
240-
)
241-
.range
242-
} else {
243-
noqa_edit
244-
.range()
245-
.to_range(source_kind.source_code(), index, encoding)
246-
},
219+
range: diagnostic_edit_range(noqa_edit.range(), source_kind, index, encoding),
247220
new_text: noqa_edit.content().unwrap_or_default().to_string(),
248221
});
249222
serde_json::to_value(AssociatedDiagnosticData {
@@ -293,6 +266,21 @@ fn to_lsp_diagnostic(
293266
)
294267
}
295268

269+
fn diagnostic_edit_range(
270+
range: TextRange,
271+
source_kind: &SourceKind,
272+
index: &LineIndex,
273+
encoding: PositionEncoding,
274+
) -> lsp_types::Range {
275+
if let Some(notebook_index) = source_kind.as_ipy_notebook().map(Notebook::index) {
276+
range
277+
.to_notebook_range(source_kind.source_code(), index, notebook_index, encoding)
278+
.range
279+
} else {
280+
range.to_range(source_kind.source_code(), index, encoding)
281+
}
282+
}
283+
296284
fn severity(code: &str) -> lsp_types::DiagnosticSeverity {
297285
match code {
298286
// F821: undefined name <name>

crates/ruff_server/src/server/api/notifications/did_change.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::server::api::LSPResult;
33
use crate::server::client::{Notifier, Requester};
44
use crate::server::Result;
55
use crate::session::Session;
6+
use lsp_server::ErrorCode;
67
use lsp_types as types;
78
use lsp_types::notification as notif;
89

@@ -26,11 +27,13 @@ impl super::SyncNotificationHandler for DidChange {
2627
content_changes,
2728
}: types::DidChangeTextDocumentParams,
2829
) -> Result<()> {
29-
let key = session.key_from_url(&uri);
30+
let key = session
31+
.key_from_url(&uri)
32+
.with_failure_code(ErrorCode::InternalError)?;
3033

3134
session
3235
.update_text_document(&key, content_changes, new_version)
33-
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
36+
.with_failure_code(ErrorCode::InternalError)?;
3437

3538
// Publish diagnostics if the client doesnt support pull diagnostics
3639
if !session.resolved_client_capabilities().pull_diagnostics {

crates/ruff_server/src/server/api/notifications/did_change_notebook.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ impl super::SyncNotificationHandler for DidChangeNotebook {
2323
change: types::NotebookDocumentChangeEvent { cells, metadata },
2424
}: types::DidChangeNotebookDocumentParams,
2525
) -> Result<()> {
26-
let key = session.key_from_url(&uri);
26+
let key = session
27+
.key_from_url(&uri)
28+
.with_failure_code(ErrorCode::InternalError)?;
2729
session
2830
.update_notebook_document(&key, cells, metadata, version)
2931
.with_failure_code(ErrorCode::InternalError)?;

crates/ruff_server/src/server/api/notifications/did_close_notebook.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ impl super::SyncNotificationHandler for DidCloseNotebook {
2222
..
2323
}: types::DidCloseNotebookDocumentParams,
2424
) -> Result<()> {
25-
let key = session.key_from_url(&uri);
25+
let key = session
26+
.key_from_url(&uri)
27+
.with_failure_code(ErrorCode::InternalError)?;
2628

2729
session
2830
.close_document(&key)

crates/ruff_server/src/session.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod settings;
77
use std::path::PathBuf;
88
use std::sync::Arc;
99

10+
use anyhow::anyhow;
1011
use lsp_types::{ClientCapabilities, NotebookDocumentCellChange, Url};
1112

1213
use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument};
@@ -54,13 +55,15 @@ impl Session {
5455
}
5556
}
5657

57-
pub(crate) fn key_from_url(&self, url: &lsp_types::Url) -> DocumentKey {
58-
self.index.key_from_url(url)
58+
pub(crate) fn key_from_url(&self, url: &lsp_types::Url) -> crate::Result<DocumentKey> {
59+
self.index
60+
.key_from_url(url)
61+
.ok_or_else(|| anyhow!("No document found for {url}"))
5962
}
6063

6164
/// Creates a document snapshot with the URL referencing the document to snapshot.
6265
pub(crate) fn take_snapshot(&self, url: &Url) -> Option<DocumentSnapshot> {
63-
let key = self.key_from_url(url);
66+
let key = self.key_from_url(url).ok()?;
6467
Some(DocumentSnapshot {
6568
resolved_client_capabilities: self.resolved_client_capabilities.clone(),
6669
client_settings: self.index.client_settings(&key, &self.global_settings),

crates/ruff_server/src/session/index.rs

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ enum DocumentController {
4848
}
4949

5050
/// A read-only query to an open document.
51-
/// This query can 'select' a text document, full notebook, or notebook cell.
51+
/// This query can 'select' a text document, full notebook, or a specific notebook cell.
5252
/// It also includes document settings.
5353
#[derive(Clone)]
5454
pub(crate) enum DocumentQuery {
@@ -58,8 +58,7 @@ pub(crate) enum DocumentQuery {
5858
settings: Arc<RuffSettings>,
5959
},
6060
Notebook {
61-
/// The selected notebook cell.
62-
/// If this is `None`, the entire notebook file is selected.
61+
/// The selected notebook cell, if it exists.
6362
cell_uri: Option<lsp_types::Url>,
6463
file_path: PathBuf,
6564
notebook: Arc<NotebookDocument>,
@@ -96,12 +95,7 @@ impl Index {
9695
new_version: DocumentVersion,
9796
encoding: PositionEncoding,
9897
) -> crate::Result<()> {
99-
let Some(path) = self.path_for_key(key).cloned() else {
100-
anyhow::bail!("Tried to open unavailable document `{key}`");
101-
};
102-
let Some(controller) = self.documents.get_mut(&path) else {
103-
anyhow::bail!("Document controller not available at `{}`", path.display());
104-
};
98+
let controller = self.document_controller_for_key(key)?;
10599
let Some(document) = controller.as_text_mut() else {
106100
anyhow::bail!("Text document URI does not point to a text document");
107101
};
@@ -116,22 +110,22 @@ impl Index {
116110
Ok(())
117111
}
118112

119-
pub(super) fn key_from_url(&self, url: &lsp_types::Url) -> DocumentKey {
113+
pub(super) fn key_from_url(&self, url: &lsp_types::Url) -> Option<DocumentKey> {
120114
if self.notebook_cells.contains_key(url) {
121-
return DocumentKey::NotebookCell(url.clone());
122-
}
123-
let path = url
124-
.to_file_path()
125-
.expect("non-notebook cell URL should be a valid path");
126-
match path
127-
.extension()
128-
.unwrap_or_default()
129-
.to_str()
130-
.unwrap_or_default()
131-
{
132-
"ipynb" => DocumentKey::Notebook(path),
133-
_ => DocumentKey::Text(path),
115+
return Some(DocumentKey::NotebookCell(url.clone()));
134116
}
117+
let path = url.to_file_path().ok()?;
118+
Some(
119+
match path
120+
.extension()
121+
.unwrap_or_default()
122+
.to_str()
123+
.unwrap_or_default()
124+
{
125+
"ipynb" => DocumentKey::Notebook(path),
126+
_ => DocumentKey::Text(path),
127+
},
128+
)
135129
}
136130

137131
pub(super) fn update_notebook_document(
@@ -142,17 +136,17 @@ impl Index {
142136
new_version: DocumentVersion,
143137
encoding: PositionEncoding,
144138
) -> crate::Result<()> {
145-
let Some(path) = self.path_for_key(key).cloned() else {
146-
anyhow::bail!("Tried to open unavailable document `{key}`");
147-
};
148-
149139
// update notebook cell index
150140
if let Some(lsp_types::NotebookDocumentCellChangeStructure {
151141
did_open,
152142
did_close,
153143
..
154144
}) = cells.as_ref().and_then(|cells| cells.structure.as_ref())
155145
{
146+
let Some(path) = self.path_for_key(key).cloned() else {
147+
anyhow::bail!("Tried to open unavailable document `{key}`");
148+
};
149+
156150
for opened_cell in did_open.iter().flatten() {
157151
self.notebook_cells
158152
.insert(opened_cell.uri.clone(), path.clone());
@@ -167,9 +161,7 @@ impl Index {
167161
}
168162
}
169163

170-
let Some(controller) = self.documents.get_mut(&path) else {
171-
anyhow::bail!("Document controller not available at `{}`", path.display());
172-
};
164+
let controller = self.document_controller_for_key(key)?;
173165
let Some(notebook) = controller.as_notebook_mut() else {
174166
anyhow::bail!("Notebook document URI does not point to a notebook document");
175167
};
@@ -306,6 +298,19 @@ impl Index {
306298
client_settings.clone()
307299
}
308300

301+
fn document_controller_for_key(
302+
&mut self,
303+
key: &DocumentKey,
304+
) -> crate::Result<&mut DocumentController> {
305+
let Some(path) = self.path_for_key(key).cloned() else {
306+
anyhow::bail!("Tried to open unavailable document `{key}`");
307+
};
308+
let Some(controller) = self.documents.get_mut(&path) else {
309+
anyhow::bail!("Document controller not available at `{}`", path.display());
310+
};
311+
Ok(controller)
312+
}
313+
309314
fn path_for_key<'a>(&'a self, key: &'a DocumentKey) -> Option<&'a PathBuf> {
310315
match key {
311316
DocumentKey::Notebook(path) | DocumentKey::Text(path) => Some(path),

0 commit comments

Comments
 (0)