Add convenience functions to SourceChange for creating single edits

This commit is contained in:
Ville Penttinen 2019-03-24 22:53:41 +02:00
parent 449eea1161
commit 22e1c7a112
4 changed files with 63 additions and 44 deletions

View File

@ -17,14 +17,9 @@ pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<Assist> {
let file_id = frange.file_id; let file_id = frange.file_id;
let file_edit = SourceFileEdit { file_id, edit: action.edit }; let file_edit = SourceFileEdit { file_id, edit: action.edit };
let id = label.id; let id = label.id;
let change = SourceChange { let change = SourceChange::source_edit(label.label, file_edit).with_cursor_opt(
label: label.label, action.cursor_position.map(|offset| FilePosition { offset, file_id }),
source_file_edits: vec![file_edit], );
file_system_edits: vec![],
cursor_position: action
.cursor_position
.map(|offset| FilePosition { offset, file_id }),
};
Assist { id, change } Assist { id, change }
}) })
.collect() .collect()

View File

@ -71,12 +71,10 @@ fn check_unnecessary_braces_in_use_statement(
range, range,
message: format!("Unnecessary braces in use statement"), message: format!("Unnecessary braces in use statement"),
severity: Severity::WeakWarning, severity: Severity::WeakWarning,
fix: Some(SourceChange { fix: Some(SourceChange::source_edit(
label: "Remove unnecessary braces".to_string(), "Remove unnecessary braces",
source_file_edits: vec![SourceFileEdit { file_id, edit }], SourceFileEdit { file_id, edit },
file_system_edits: Vec::new(), )),
cursor_position: None,
}),
}); });
} }
@ -119,12 +117,10 @@ fn check_struct_shorthand_initialization(
range: named_field.syntax().range(), range: named_field.syntax().range(),
message: format!("Shorthand struct initialization"), message: format!("Shorthand struct initialization"),
severity: Severity::WeakWarning, severity: Severity::WeakWarning,
fix: Some(SourceChange { fix: Some(SourceChange::source_edit(
label: "use struct shorthand initialization".to_string(), "use struct shorthand initialization",
source_file_edits: vec![SourceFileEdit { file_id, edit }], SourceFileEdit { file_id, edit },
file_system_edits: Vec::new(), )),
cursor_position: None,
}),
}); });
} }
} }
@ -144,12 +140,7 @@ fn check_module(
Problem::UnresolvedModule { candidate } => { Problem::UnresolvedModule { candidate } => {
let create_file = let create_file =
FileSystemEdit::CreateFile { source_root, path: candidate.clone() }; FileSystemEdit::CreateFile { source_root, path: candidate.clone() };
let fix = SourceChange { let fix = SourceChange::system_edit("create module", create_file);
label: "create module".to_string(),
source_file_edits: Vec::new(),
file_system_edits: vec![create_file],
cursor_position: None,
};
Diagnostic { Diagnostic {
range: name_node.range(), range: name_node.range(),
message: "unresolved module".to_string(), message: "unresolved module".to_string(),

View File

@ -97,6 +97,44 @@ pub struct SourceChange {
pub cursor_position: Option<FilePosition>, pub cursor_position: Option<FilePosition>,
} }
impl SourceChange {
pub fn source_edits<L: Into<String>>(label: L, edits: Vec<SourceFileEdit>) -> Self {
SourceChange {
label: label.into(),
source_file_edits: edits,
file_system_edits: vec![],
cursor_position: None,
}
}
pub fn system_edits<L: Into<String>>(label: L, edits: Vec<FileSystemEdit>) -> Self {
SourceChange {
label: label.into(),
source_file_edits: vec![],
file_system_edits: edits,
cursor_position: None,
}
}
pub fn source_edit<L: Into<String>>(label: L, edit: SourceFileEdit) -> Self {
SourceChange::source_edits(label, vec![edit])
}
pub fn system_edit<L: Into<String>>(label: L, edit: FileSystemEdit) -> Self {
SourceChange::system_edits(label, vec![edit])
}
pub fn with_cursor(mut self, cursor_position: FilePosition) -> Self {
self.cursor_position = Some(cursor_position);
self
}
pub fn with_cursor_opt(mut self, cursor_position: Option<FilePosition>) -> Self {
self.cursor_position = cursor_position;
self
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct SourceFileEdit { pub struct SourceFileEdit {
pub file_id: FileId, pub file_id: FileId,
@ -285,12 +323,7 @@ impl Analysis {
file_id: frange.file_id, file_id: frange.file_id,
edit: join_lines::join_lines(&file, frange.range), edit: join_lines::join_lines(&file, frange.range),
}; };
SourceChange { SourceChange::source_edit("join lines", file_edit)
label: "join lines".to_string(),
source_file_edits: vec![file_edit],
file_system_edits: vec![],
cursor_position: None,
}
} }
/// Returns an edit which should be applied when opening a new line, fixing /// Returns an edit which should be applied when opening a new line, fixing
@ -305,12 +338,10 @@ impl Analysis {
pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
let file = self.db.parse(position.file_id); let file = self.db.parse(position.file_id);
let edit = typing::on_eq_typed(&file, position.offset)?; let edit = typing::on_eq_typed(&file, position.offset)?;
Some(SourceChange { Some(SourceChange::source_edit(
label: "add semicolon".to_string(), "add semicolon",
source_file_edits: vec![SourceFileEdit { edit, file_id: position.file_id }], SourceFileEdit { edit, file_id: position.file_id },
file_system_edits: vec![], ))
cursor_position: None,
})
} }
/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.

View File

@ -31,12 +31,14 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour
let cursor_position = position.offset + TextUnit::of_str(&inserted); let cursor_position = position.offset + TextUnit::of_str(&inserted);
let mut edit = TextEditBuilder::default(); let mut edit = TextEditBuilder::default();
edit.insert(position.offset, inserted); edit.insert(position.offset, inserted);
Some(SourceChange {
label: "on enter".to_string(), Some(
source_file_edits: vec![SourceFileEdit { edit: edit.finish(), file_id: position.file_id }], SourceChange::source_edit(
file_system_edits: vec![], "on enter",
cursor_position: Some(FilePosition { offset: cursor_position, file_id: position.file_id }), SourceFileEdit { edit: edit.finish(), file_id: position.file_id },
}) )
.with_cursor(FilePosition { offset: cursor_position, file_id: position.file_id }),
)
} }
fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> { fn node_indent<'a>(file: &'a SourceFile, node: &SyntaxNode) -> Option<&'a str> {