Skip to content

Commit d358d45

Browse files
committedJul 18, 2024··
fix: use fix in data for fix all command
1 parent 1390726 commit d358d45

File tree

2 files changed

+23
-60
lines changed

2 files changed

+23
-60
lines changed
 

‎crates/lsp/src/lib.rs

+20-57
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use ast_grep_core::{language::Language, AstGrep, Doc, StrDoc};
1212
use std::collections::HashMap;
1313
use std::path::{Path, PathBuf};
1414

15-
use utils::{convert_match_to_diagnostic, convert_node_to_range, diagnostic_to_code_action};
15+
use utils::{convert_match_to_diagnostic, diagnostic_to_code_action, RewriteData};
1616

1717
pub use tower_lsp::{LspService, Server};
1818

@@ -165,19 +165,6 @@ impl<L: LSPLang> LanguageServer for Backend<L> {
165165
}
166166
}
167167

168-
fn build_error_id_to_ranges(diagnostics: Vec<Diagnostic>) -> HashMap<String, Vec<Range>> {
169-
let mut error_id_to_ranges = HashMap::new();
170-
for diagnostic in diagnostics {
171-
let rule_id = match diagnostic.code {
172-
Some(NumberOrString::String(rule)) => rule,
173-
_ => continue,
174-
};
175-
let ranges = error_id_to_ranges.entry(rule_id).or_insert_with(Vec::new);
176-
ranges.push(diagnostic.range);
177-
}
178-
error_id_to_ranges
179-
}
180-
181168
impl<L: LSPLang> Backend<L> {
182169
pub fn new(
183170
client: Client,
@@ -287,45 +274,32 @@ impl<L: LSPLang> Backend<L> {
287274
fn compute_all_fixes(
288275
&self,
289276
text_document: TextDocumentIdentifier,
290-
error_id_to_ranges: HashMap<String, Vec<Range>>,
291-
path: PathBuf,
277+
mut diagnostics: Vec<Diagnostic>,
292278
) -> Option<HashMap<Url, Vec<TextEdit>>>
293279
where
294280
L: ast_grep_core::Language + std::cmp::Eq,
295281
{
296-
let uri = text_document.uri.as_str();
297-
let versioned = self.map.get(uri)?;
298-
let mut edits = vec![];
299-
let rules = self.rules.as_ref().ok()?;
300-
for config in rules.for_path(&path) {
301-
let ranges = match error_id_to_ranges.get(&config.id) {
302-
Some(ranges) => ranges,
303-
None => continue,
304-
};
305-
let matcher = &config.matcher;
306-
307-
for matched_node in versioned.root.root().find_all(&matcher) {
308-
let range = convert_node_to_range(&matched_node);
309-
if !ranges.contains(&range) {
310-
continue;
282+
diagnostics.sort_by_key(|d| (d.range.start, d.range.end));
283+
let mut last = Position {
284+
line: 0,
285+
character: 0,
286+
};
287+
let edits: Vec<_> = diagnostics
288+
.into_iter()
289+
.filter_map(|d| {
290+
if d.range.start < last {
291+
return None;
311292
}
312-
let fixer = match &config.matcher.fixer {
313-
Some(fixer) => fixer,
314-
None => continue,
315-
};
316-
let edit = matched_node.replace_by(fixer);
317-
let edit = TextEdit {
318-
range,
319-
new_text: String::from_utf8(edit.inserted_text).unwrap(),
320-
};
321-
322-
edits.push(edit);
323-
}
324-
}
293+
let rewrite_data = RewriteData::from_value(d.data?)?;
294+
let edit = TextEdit::new(d.range, rewrite_data.fixed);
295+
last = d.range.end;
296+
Some(edit)
297+
})
298+
.collect();
325299
if edits.is_empty() {
326300
return None;
327301
}
328-
let mut changes: HashMap<Url, Vec<TextEdit>> = HashMap::new();
302+
let mut changes = HashMap::new();
329303
changes.insert(text_document.uri, edits);
330304
Some(changes)
331305
}
@@ -380,7 +354,6 @@ impl<L: LSPLang> Backend<L> {
380354
let text_doc: TextDocumentItem =
381355
serde_json::from_value(first).map_err(LspError::JSONDecodeError)?;
382356
let uri = text_doc.uri;
383-
let path = uri.to_file_path().map_err(|_| LspError::InvalidFileURI)?;
384357
let Some(lang) = Self::infer_lang_from_uri(&uri) else {
385358
return Err(LspError::UnsupportedFileType);
386359
};
@@ -392,10 +365,7 @@ impl<L: LSPLang> Backend<L> {
392365
let Some(diagnostics) = self.get_diagnostics(&uri, &versioned) else {
393366
return Err(LspError::NoActionableFix);
394367
};
395-
let error_id_to_ranges = build_error_id_to_ranges(diagnostics);
396-
397-
let changes =
398-
self.compute_all_fixes(TextDocumentIdentifier::new(uri), error_id_to_ranges, path);
368+
let changes = self.compute_all_fixes(TextDocumentIdentifier::new(uri), diagnostics);
399369
let workspace_edit = WorkspaceEdit {
400370
changes,
401371
document_changes: None,
@@ -435,12 +405,6 @@ impl<L: LSPLang> Backend<L> {
435405
)
436406
.await;
437407
}
438-
LspError::InvalidFileURI => {
439-
self
440-
.client
441-
.log_message(MessageType::ERROR, "Invalid URI format")
442-
.await;
443-
}
444408
LspError::UnsupportedFileType => {
445409
self
446410
.client
@@ -459,7 +423,6 @@ impl<L: LSPLang> Backend<L> {
459423

460424
enum LspError {
461425
JSONDecodeError(serde_json::Error),
462-
InvalidFileURI,
463426
UnsupportedFileType,
464427
NoActionableFix,
465428
}

‎crates/lsp/src/utils.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ use std::collections::HashMap;
1010

1111
#[derive(Serialize, Deserialize)]
1212
pub struct RewriteData {
13-
fixed: String,
13+
pub fixed: String,
1414
// maybe we should have fixed range
1515
}
1616

1717
impl RewriteData {
18-
fn from_value(data: serde_json::Value) -> Option<Self> {
18+
pub fn from_value(data: serde_json::Value) -> Option<Self> {
1919
serde_json::from_value(data).ok()
2020
}
2121

@@ -56,7 +56,7 @@ pub fn diagnostic_to_code_action(
5656
Some(action)
5757
}
5858

59-
pub fn convert_node_to_range<D: Doc>(node_match: &Node<D>) -> Range {
59+
fn convert_node_to_range<D: Doc>(node_match: &Node<D>) -> Range {
6060
let (start_row, start_col) = node_match.start_pos();
6161
let (end_row, end_col) = node_match.end_pos();
6262
Range {

0 commit comments

Comments
 (0)
Please sign in to comment.