mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-19 19:17:31 +00:00
Merge #1591
1591: Make Analysis api cancellable r=matklad a=SomeoneToIgnore Based on the discussion from here: https://github.com/rust-analyzer/rust-analyzer/pull/1549#discussion_r305593236 Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
commit
ceb16591de
@ -55,7 +55,7 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
|
|||||||
Op::Complete { line, column, .. } => {
|
Op::Complete { line, column, .. } => {
|
||||||
let offset = host
|
let offset = host
|
||||||
.analysis()
|
.analysis()
|
||||||
.file_line_index(file_id)
|
.file_line_index(file_id)?
|
||||||
.offset(LineCol { line, col_utf16: column });
|
.offset(LineCol { line, col_utf16: column });
|
||||||
let file_postion = FilePosition { file_id, offset };
|
let file_postion = FilePosition { file_id, offset };
|
||||||
|
|
||||||
|
@ -317,24 +317,24 @@ impl Analysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Debug info about the current state of the analysis
|
/// Debug info about the current state of the analysis
|
||||||
pub fn status(&self) -> String {
|
pub fn status(&self) -> Cancelable<String> {
|
||||||
status::status(&*self.db)
|
self.with_db(|db| status::status(&*db))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the text of the source file.
|
/// Gets the text of the source file.
|
||||||
pub fn file_text(&self, file_id: FileId) -> Arc<String> {
|
pub fn file_text(&self, file_id: FileId) -> Cancelable<Arc<String>> {
|
||||||
self.db.file_text(file_id)
|
self.with_db(|db| db.file_text(file_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the syntax tree of the file.
|
/// Gets the syntax tree of the file.
|
||||||
pub fn parse(&self, file_id: FileId) -> SourceFile {
|
pub fn parse(&self, file_id: FileId) -> Cancelable<SourceFile> {
|
||||||
self.db.parse(file_id).tree()
|
self.with_db(|db| db.parse(file_id).tree())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the file's `LineIndex`: data structure to convert between absolute
|
/// Gets the file's `LineIndex`: data structure to convert between absolute
|
||||||
/// offsets and line/column representation.
|
/// offsets and line/column representation.
|
||||||
pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> {
|
pub fn file_line_index(&self, file_id: FileId) -> Cancelable<Arc<LineIndex>> {
|
||||||
self.db.line_index(file_id)
|
self.with_db(|db| db.line_index(file_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects the next syntactic nodes encompassing the range.
|
/// Selects the next syntactic nodes encompassing the range.
|
||||||
@ -344,58 +344,67 @@ impl Analysis {
|
|||||||
|
|
||||||
/// Returns position of the matching brace (all types of braces are
|
/// Returns position of the matching brace (all types of braces are
|
||||||
/// supported).
|
/// supported).
|
||||||
pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
|
pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextUnit>> {
|
||||||
let parse = self.db.parse(position.file_id);
|
self.with_db(|db| {
|
||||||
|
let parse = db.parse(position.file_id);
|
||||||
let file = parse.tree();
|
let file = parse.tree();
|
||||||
matching_brace::matching_brace(&file, position.offset)
|
matching_brace::matching_brace(&file, position.offset)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a syntax tree represented as `String`, for debug purposes.
|
/// Returns a syntax tree represented as `String`, for debug purposes.
|
||||||
// FIXME: use a better name here.
|
// FIXME: use a better name here.
|
||||||
pub fn syntax_tree(&self, file_id: FileId, text_range: Option<TextRange>) -> String {
|
pub fn syntax_tree(
|
||||||
syntax_tree::syntax_tree(&self.db, file_id, text_range)
|
&self,
|
||||||
|
file_id: FileId,
|
||||||
|
text_range: Option<TextRange>,
|
||||||
|
) -> Cancelable<String> {
|
||||||
|
self.with_db(|db| syntax_tree::syntax_tree(&db, file_id, text_range))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an edit to remove all newlines in the range, cleaning up minor
|
/// Returns an edit to remove all newlines in the range, cleaning up minor
|
||||||
/// stuff like trailing commas.
|
/// stuff like trailing commas.
|
||||||
pub fn join_lines(&self, frange: FileRange) -> SourceChange {
|
pub fn join_lines(&self, frange: FileRange) -> Cancelable<SourceChange> {
|
||||||
let parse = self.db.parse(frange.file_id);
|
self.with_db(|db| {
|
||||||
|
let parse = db.parse(frange.file_id);
|
||||||
let file_edit = SourceFileEdit {
|
let file_edit = SourceFileEdit {
|
||||||
file_id: frange.file_id,
|
file_id: frange.file_id,
|
||||||
edit: join_lines::join_lines(&parse.tree(), frange.range),
|
edit: join_lines::join_lines(&parse.tree(), frange.range),
|
||||||
};
|
};
|
||||||
SourceChange::source_file_edit("join lines", file_edit)
|
SourceChange::source_file_edit("join lines", file_edit)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
/// up minor stuff like continuing the comment.
|
/// up minor stuff like continuing the comment.
|
||||||
pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> {
|
pub fn on_enter(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
|
||||||
typing::on_enter(&self.db, position)
|
self.with_db(|db| typing::on_enter(&db, position))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an edit which should be applied after `=` was typed. Primarily,
|
/// Returns an edit which should be applied after `=` was typed. Primarily,
|
||||||
/// this works when adding `let =`.
|
/// this works when adding `let =`.
|
||||||
// FIXME: use a snippet completion instead of this hack here.
|
// FIXME: use a snippet completion instead of this hack here.
|
||||||
pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
|
pub fn on_eq_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
|
||||||
let parse = self.db.parse(position.file_id);
|
self.with_db(|db| {
|
||||||
|
let parse = db.parse(position.file_id);
|
||||||
let file = parse.tree();
|
let file = parse.tree();
|
||||||
let edit = typing::on_eq_typed(&file, position.offset)?;
|
let edit = typing::on_eq_typed(&file, position.offset)?;
|
||||||
Some(SourceChange::source_file_edit(
|
Some(SourceChange::source_file_edit(
|
||||||
"add semicolon",
|
"add semicolon",
|
||||||
SourceFileEdit { edit, file_id: position.file_id },
|
SourceFileEdit { edit, file_id: position.file_id },
|
||||||
))
|
))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> {
|
pub fn on_dot_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
|
||||||
typing::on_dot_typed(&self.db, position)
|
self.with_db(|db| typing::on_dot_typed(&db, position))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a tree representation of symbols in the file. Useful to draw a
|
/// Returns a tree representation of symbols in the file. Useful to draw a
|
||||||
/// file outline.
|
/// file outline.
|
||||||
pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
|
pub fn file_structure(&self, file_id: FileId) -> Cancelable<Vec<StructureNode>> {
|
||||||
let parse = self.db.parse(file_id);
|
self.with_db(|db| file_structure(&db.parse(file_id).tree()))
|
||||||
file_structure(&parse.tree())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of the places in the file where type hints can be displayed.
|
/// Returns a list of the places in the file where type hints can be displayed.
|
||||||
@ -404,9 +413,8 @@ impl Analysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of folding ranges.
|
/// Returns the set of folding ranges.
|
||||||
pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
|
pub fn folding_ranges(&self, file_id: FileId) -> Cancelable<Vec<Fold>> {
|
||||||
let parse = self.db.parse(file_id);
|
self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree()))
|
||||||
folding_ranges::folding_ranges(&parse.tree())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fuzzy searches for a symbol.
|
/// Fuzzy searches for a symbol.
|
||||||
|
@ -372,7 +372,8 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()));
|
let result =
|
||||||
|
text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()).unwrap());
|
||||||
assert_eq_text!(expected, &*result);
|
assert_eq_text!(expected, &*result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ mod tests {
|
|||||||
fn test_syntax_tree_without_range() {
|
fn test_syntax_tree_without_range() {
|
||||||
// Basic syntax
|
// Basic syntax
|
||||||
let (analysis, file_id) = single_file(r#"fn foo() {}"#);
|
let (analysis, file_id) = single_file(r#"fn foo() {}"#);
|
||||||
let syn = analysis.syntax_tree(file_id, None);
|
let syn = analysis.syntax_tree(file_id, None).unwrap();
|
||||||
|
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
@ -133,7 +133,7 @@ fn test() {
|
|||||||
}"#
|
}"#
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let syn = analysis.syntax_tree(file_id, None);
|
let syn = analysis.syntax_tree(file_id, None).unwrap();
|
||||||
|
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
@ -176,7 +176,7 @@ SOURCE_FILE@[0; 60)
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_syntax_tree_with_range() {
|
fn test_syntax_tree_with_range() {
|
||||||
let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
|
let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
|
||||||
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
|
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
|
||||||
|
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
@ -206,7 +206,7 @@ FN_DEF@[0; 11)
|
|||||||
}"#
|
}"#
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
|
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
|
||||||
|
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
@ -244,7 +244,7 @@ fn bar() {
|
|||||||
}"#
|
}"#
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
|
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
r#"
|
r#"
|
||||||
@ -278,7 +278,7 @@ fn bar() {
|
|||||||
}"###
|
}"###
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
|
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
r#"
|
r#"
|
||||||
@ -311,7 +311,7 @@ fn bar() {
|
|||||||
}"###
|
}"###
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
|
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
|
||||||
assert_eq_text!(
|
assert_eq_text!(
|
||||||
syn.trim(),
|
syn.trim(),
|
||||||
r#"
|
r#"
|
||||||
|
@ -195,7 +195,7 @@ fn foo() {
|
|||||||
edit.insert(offset, ".".to_string());
|
edit.insert(offset, ".".to_string());
|
||||||
let before = edit.finish().apply(&before);
|
let before = edit.finish().apply(&before);
|
||||||
let (analysis, file_id) = single_file(&before);
|
let (analysis, file_id) = single_file(&before);
|
||||||
if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }) {
|
if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }).unwrap() {
|
||||||
assert_eq!(result.source_file_edits.len(), 1);
|
assert_eq!(result.source_file_edits.len(), 1);
|
||||||
let actual = result.source_file_edits[0].edit.apply(&before);
|
let actual = result.source_file_edits[0].edit.apply(&before);
|
||||||
assert_eq_text!(after, &actual);
|
assert_eq_text!(after, &actual);
|
||||||
@ -377,7 +377,7 @@ fn foo() {
|
|||||||
fn apply_on_enter(before: &str) -> Option<String> {
|
fn apply_on_enter(before: &str) -> Option<String> {
|
||||||
let (offset, before) = extract_offset(before);
|
let (offset, before) = extract_offset(before);
|
||||||
let (analysis, file_id) = single_file(&before);
|
let (analysis, file_id) = single_file(&before);
|
||||||
let result = analysis.on_enter(FilePosition { offset, file_id })?;
|
let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?;
|
||||||
|
|
||||||
assert_eq!(result.source_file_edits.len(), 1);
|
assert_eq!(result.source_file_edits.len(), 1);
|
||||||
let actual = result.source_file_edits[0].edit.apply(&before);
|
let actual = result.source_file_edits[0].edit.apply(&before);
|
||||||
|
@ -272,7 +272,7 @@ impl<'a> TryConvWith for &'a TextDocumentPositionParams {
|
|||||||
type Output = FilePosition;
|
type Output = FilePosition;
|
||||||
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> {
|
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> {
|
||||||
let file_id = self.text_document.try_conv_with(world)?;
|
let file_id = self.text_document.try_conv_with(world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let offset = self.position.conv_with(&line_index);
|
let offset = self.position.conv_with(&line_index);
|
||||||
Ok(FilePosition { file_id, offset })
|
Ok(FilePosition { file_id, offset })
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) {
|
|||||||
type Output = FileRange;
|
type Output = FileRange;
|
||||||
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> {
|
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> {
|
||||||
let file_id = self.0.try_conv_with(world)?;
|
let file_id = self.0.try_conv_with(world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let range = self.1.conv_with(&line_index);
|
let range = self.1.conv_with(&line_index);
|
||||||
Ok(FileRange { file_id, range })
|
Ok(FileRange { file_id, range })
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ impl TryConvWith for SourceChange {
|
|||||||
let cursor_position = match self.cursor_position {
|
let cursor_position = match self.cursor_position {
|
||||||
None => None,
|
None => None,
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
let line_index = world.analysis().file_line_index(pos.file_id);
|
let line_index = world.analysis().file_line_index(pos.file_id)?;
|
||||||
let edit = self
|
let edit = self
|
||||||
.source_file_edits
|
.source_file_edits
|
||||||
.iter()
|
.iter()
|
||||||
@ -349,7 +349,7 @@ impl TryConvWith for SourceFileEdit {
|
|||||||
uri: self.file_id.try_conv_with(world)?,
|
uri: self.file_id.try_conv_with(world)?,
|
||||||
version: None,
|
version: None,
|
||||||
};
|
};
|
||||||
let line_index = world.analysis().file_line_index(self.file_id);
|
let line_index = world.analysis().file_line_index(self.file_id)?;
|
||||||
let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect();
|
let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect();
|
||||||
Ok(TextDocumentEdit { text_document, edits })
|
Ok(TextDocumentEdit { text_document, edits })
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ impl TryConvWith for &NavigationTarget {
|
|||||||
type Ctx = WorldSnapshot;
|
type Ctx = WorldSnapshot;
|
||||||
type Output = Location;
|
type Output = Location;
|
||||||
fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> {
|
fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> {
|
||||||
let line_index = world.analysis().file_line_index(self.file_id());
|
let line_index = world.analysis().file_line_index(self.file_id())?;
|
||||||
let range = self.range();
|
let range = self.range();
|
||||||
to_location(self.file_id(), range, &world, &line_index)
|
to_location(self.file_id(), range, &world, &line_index)
|
||||||
}
|
}
|
||||||
@ -391,8 +391,8 @@ impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) {
|
|||||||
let (src_file_id, target) = self;
|
let (src_file_id, target) = self;
|
||||||
|
|
||||||
let target_uri = target.info.file_id().try_conv_with(world)?;
|
let target_uri = target.info.file_id().try_conv_with(world)?;
|
||||||
let src_line_index = world.analysis().file_line_index(src_file_id);
|
let src_line_index = world.analysis().file_line_index(src_file_id)?;
|
||||||
let tgt_line_index = world.analysis().file_line_index(target.info.file_id());
|
let tgt_line_index = world.analysis().file_line_index(target.info.file_id())?;
|
||||||
|
|
||||||
let target_range = target.info.full_range().conv_with(&tgt_line_index);
|
let target_range = target.info.full_range().conv_with(&tgt_line_index);
|
||||||
|
|
||||||
|
@ -39,9 +39,9 @@ pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> {
|
|||||||
|
|
||||||
pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> {
|
pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> {
|
||||||
let id = params.text_document.try_conv_with(&world)?;
|
let id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(id);
|
let line_index = world.analysis().file_line_index(id)?;
|
||||||
let text_range = params.range.map(|p| p.conv_with(&line_index));
|
let text_range = params.range.map(|p| p.conv_with(&line_index));
|
||||||
let res = world.analysis().syntax_tree(id, text_range);
|
let res = world.analysis().syntax_tree(id, text_range)?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ pub fn handle_extend_selection(
|
|||||||
use the new selection range API in LSP",
|
use the new selection range API in LSP",
|
||||||
);
|
);
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let selections = params
|
let selections = params
|
||||||
.selections
|
.selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -72,7 +72,7 @@ pub fn handle_selection_range(
|
|||||||
) -> Result<Vec<req::SelectionRange>> {
|
) -> Result<Vec<req::SelectionRange>> {
|
||||||
let _p = profile("handle_selection_range");
|
let _p = profile("handle_selection_range");
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
params
|
params
|
||||||
.positions
|
.positions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -113,13 +113,19 @@ pub fn handle_find_matching_brace(
|
|||||||
) -> Result<Vec<Position>> {
|
) -> Result<Vec<Position>> {
|
||||||
let _p = profile("handle_find_matching_brace");
|
let _p = profile("handle_find_matching_brace");
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let res = params
|
let res = params
|
||||||
.offsets
|
.offsets
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map_conv_with(&line_index)
|
.map_conv_with(&line_index)
|
||||||
.map(|offset| {
|
.map(|offset| {
|
||||||
world.analysis().matching_brace(FilePosition { file_id, offset }).unwrap_or(offset)
|
if let Ok(Some(matching_brace_offset)) =
|
||||||
|
world.analysis().matching_brace(FilePosition { file_id, offset })
|
||||||
|
{
|
||||||
|
matching_brace_offset
|
||||||
|
} else {
|
||||||
|
offset
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map_conv_with(&line_index)
|
.map_conv_with(&line_index)
|
||||||
.collect();
|
.collect();
|
||||||
@ -132,7 +138,7 @@ pub fn handle_join_lines(
|
|||||||
) -> Result<req::SourceChange> {
|
) -> Result<req::SourceChange> {
|
||||||
let _p = profile("handle_join_lines");
|
let _p = profile("handle_join_lines");
|
||||||
let frange = (¶ms.text_document, params.range).try_conv_with(&world)?;
|
let frange = (¶ms.text_document, params.range).try_conv_with(&world)?;
|
||||||
world.analysis().join_lines(frange).try_conv_with(&world)
|
world.analysis().join_lines(frange)?.try_conv_with(&world)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_on_enter(
|
pub fn handle_on_enter(
|
||||||
@ -141,7 +147,7 @@ pub fn handle_on_enter(
|
|||||||
) -> Result<Option<req::SourceChange>> {
|
) -> Result<Option<req::SourceChange>> {
|
||||||
let _p = profile("handle_on_enter");
|
let _p = profile("handle_on_enter");
|
||||||
let position = params.try_conv_with(&world)?;
|
let position = params.try_conv_with(&world)?;
|
||||||
match world.analysis().on_enter(position) {
|
match world.analysis().on_enter(position)? {
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
Some(edit) => Ok(Some(edit.try_conv_with(&world)?)),
|
Some(edit) => Ok(Some(edit.try_conv_with(&world)?)),
|
||||||
}
|
}
|
||||||
@ -153,7 +159,7 @@ pub fn handle_on_type_formatting(
|
|||||||
) -> Result<Option<Vec<TextEdit>>> {
|
) -> Result<Option<Vec<TextEdit>>> {
|
||||||
let _p = profile("handle_on_type_formatting");
|
let _p = profile("handle_on_type_formatting");
|
||||||
let mut position = params.text_document_position.try_conv_with(&world)?;
|
let mut position = params.text_document_position.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(position.file_id);
|
let line_index = world.analysis().file_line_index(position.file_id)?;
|
||||||
|
|
||||||
// in `ra_ide_api`, the `on_type` invariant is that
|
// in `ra_ide_api`, the `on_type` invariant is that
|
||||||
// `text.char_at(position) == typed_char`.
|
// `text.char_at(position) == typed_char`.
|
||||||
@ -163,7 +169,7 @@ pub fn handle_on_type_formatting(
|
|||||||
"=" => world.analysis().on_eq_typed(position),
|
"=" => world.analysis().on_eq_typed(position),
|
||||||
"." => world.analysis().on_dot_typed(position),
|
"." => world.analysis().on_dot_typed(position),
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
}?;
|
||||||
let mut edit = match edit {
|
let mut edit = match edit {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
@ -181,11 +187,11 @@ pub fn handle_document_symbol(
|
|||||||
params: req::DocumentSymbolParams,
|
params: req::DocumentSymbolParams,
|
||||||
) -> Result<Option<req::DocumentSymbolResponse>> {
|
) -> Result<Option<req::DocumentSymbolResponse>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
|
|
||||||
let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new();
|
let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new();
|
||||||
|
|
||||||
for symbol in world.analysis().file_structure(file_id) {
|
for symbol in world.analysis().file_structure(file_id)? {
|
||||||
let doc_symbol = DocumentSymbol {
|
let doc_symbol = DocumentSymbol {
|
||||||
name: symbol.label,
|
name: symbol.label,
|
||||||
detail: symbol.detail,
|
detail: symbol.detail,
|
||||||
@ -309,7 +315,7 @@ pub fn handle_runnables(
|
|||||||
params: req::RunnablesParams,
|
params: req::RunnablesParams,
|
||||||
) -> Result<Vec<req::Runnable>> {
|
) -> Result<Vec<req::Runnable>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let offset = params.position.map(|it| it.conv_with(&line_index));
|
let offset = params.position.map(|it| it.conv_with(&line_index));
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
let workspace_root = world.workspace_root_for(file_id);
|
let workspace_root = world.workspace_root_for(file_id);
|
||||||
@ -383,7 +389,7 @@ pub fn handle_completion(
|
|||||||
let mut res = false;
|
let mut res = false;
|
||||||
if let Some(ctx) = params.context {
|
if let Some(ctx) = params.context {
|
||||||
if ctx.trigger_character.unwrap_or_default() == ":" {
|
if ctx.trigger_character.unwrap_or_default() == ":" {
|
||||||
let source_file = world.analysis().parse(position.file_id);
|
let source_file = world.analysis().parse(position.file_id)?;
|
||||||
let syntax = source_file.syntax();
|
let syntax = source_file.syntax();
|
||||||
let text = syntax.text();
|
let text = syntax.text();
|
||||||
if let Some(next_char) = text.char_at(position.offset) {
|
if let Some(next_char) = text.char_at(position.offset) {
|
||||||
@ -405,7 +411,7 @@ pub fn handle_completion(
|
|||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(items) => items,
|
Some(items) => items,
|
||||||
};
|
};
|
||||||
let line_index = world.analysis().file_line_index(position.file_id);
|
let line_index = world.analysis().file_line_index(position.file_id)?;
|
||||||
let items: Vec<CompletionItem> =
|
let items: Vec<CompletionItem> =
|
||||||
items.into_iter().map(|item| item.conv_with(&line_index)).collect();
|
items.into_iter().map(|item| item.conv_with(&line_index)).collect();
|
||||||
|
|
||||||
@ -417,12 +423,12 @@ pub fn handle_folding_range(
|
|||||||
params: FoldingRangeParams,
|
params: FoldingRangeParams,
|
||||||
) -> Result<Option<Vec<FoldingRange>>> {
|
) -> Result<Option<Vec<FoldingRange>>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
|
|
||||||
let res = Some(
|
let res = Some(
|
||||||
world
|
world
|
||||||
.analysis()
|
.analysis()
|
||||||
.folding_ranges(file_id)
|
.folding_ranges(file_id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|fold| {
|
.map(|fold| {
|
||||||
let kind = match fold.kind {
|
let kind = match fold.kind {
|
||||||
@ -474,7 +480,7 @@ pub fn handle_hover(
|
|||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
};
|
};
|
||||||
let line_index = world.analysis.file_line_index(position.file_id);
|
let line_index = world.analysis.file_line_index(position.file_id)?;
|
||||||
let range = info.range.conv_with(&line_index);
|
let range = info.range.conv_with(&line_index);
|
||||||
let res = Hover {
|
let res = Hover {
|
||||||
contents: HoverContents::Markup(MarkupContent {
|
contents: HoverContents::Markup(MarkupContent {
|
||||||
@ -503,7 +509,7 @@ pub fn handle_prepare_rename(
|
|||||||
// Refs should always have a declaration
|
// Refs should always have a declaration
|
||||||
let r = refs.declaration();
|
let r = refs.declaration();
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let loc = to_location(r.file_id(), r.range(), &world, &line_index)?;
|
let loc = to_location(r.file_id(), r.range(), &world, &line_index)?;
|
||||||
|
|
||||||
Ok(Some(PrepareRenameResponse::Range(loc.range)))
|
Ok(Some(PrepareRenameResponse::Range(loc.range)))
|
||||||
@ -536,7 +542,7 @@ pub fn handle_references(
|
|||||||
params: req::ReferenceParams,
|
params: req::ReferenceParams,
|
||||||
) -> Result<Option<Vec<Location>>> {
|
) -> Result<Option<Vec<Location>>> {
|
||||||
let position = params.text_document_position.try_conv_with(&world)?;
|
let position = params.text_document_position.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(position.file_id);
|
let line_index = world.analysis().file_line_index(position.file_id)?;
|
||||||
|
|
||||||
let refs = match world.analysis().find_all_refs(position)? {
|
let refs = match world.analysis().find_all_refs(position)? {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
@ -563,9 +569,9 @@ pub fn handle_formatting(
|
|||||||
params: DocumentFormattingParams,
|
params: DocumentFormattingParams,
|
||||||
) -> Result<Option<Vec<TextEdit>>> {
|
) -> Result<Option<Vec<TextEdit>>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let file = world.analysis().file_text(file_id);
|
let file = world.analysis().file_text(file_id)?;
|
||||||
|
|
||||||
let file_line_index = world.analysis().file_line_index(file_id);
|
let file_line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let end_position = TextUnit::of_str(&file).conv_with(&file_line_index);
|
let end_position = TextUnit::of_str(&file).conv_with(&file_line_index);
|
||||||
|
|
||||||
use std::process;
|
use std::process;
|
||||||
@ -623,7 +629,7 @@ pub fn handle_code_action(
|
|||||||
) -> Result<Option<CodeActionResponse>> {
|
) -> Result<Option<CodeActionResponse>> {
|
||||||
let _p = profile("handle_code_action");
|
let _p = profile("handle_code_action");
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let range = params.range.conv_with(&line_index);
|
let range = params.range.conv_with(&line_index);
|
||||||
|
|
||||||
let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter();
|
let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter();
|
||||||
@ -685,7 +691,7 @@ pub fn handle_code_lens(
|
|||||||
params: req::CodeLensParams,
|
params: req::CodeLensParams,
|
||||||
) -> Result<Option<Vec<CodeLens>>> {
|
) -> Result<Option<Vec<CodeLens>>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
|
|
||||||
let mut lenses: Vec<CodeLens> = Default::default();
|
let mut lenses: Vec<CodeLens> = Default::default();
|
||||||
let workspace_root = world.workspace_root_for(file_id);
|
let workspace_root = world.workspace_root_for(file_id);
|
||||||
@ -730,7 +736,7 @@ pub fn handle_code_lens(
|
|||||||
lenses.extend(
|
lenses.extend(
|
||||||
world
|
world
|
||||||
.analysis()
|
.analysis()
|
||||||
.file_structure(file_id)
|
.file_structure(file_id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|it| match it.kind {
|
.filter(|it| match it.kind {
|
||||||
SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true,
|
SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true,
|
||||||
@ -807,7 +813,7 @@ pub fn handle_document_highlight(
|
|||||||
params: req::TextDocumentPositionParams,
|
params: req::TextDocumentPositionParams,
|
||||||
) -> Result<Option<Vec<DocumentHighlight>>> {
|
) -> Result<Option<Vec<DocumentHighlight>>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
|
|
||||||
let refs = match world.analysis().find_all_refs(params.try_conv_with(&world)?)? {
|
let refs = match world.analysis().find_all_refs(params.try_conv_with(&world)?)? {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
@ -826,7 +832,7 @@ pub fn publish_diagnostics(
|
|||||||
file_id: FileId,
|
file_id: FileId,
|
||||||
) -> Result<req::PublishDiagnosticsParams> {
|
) -> Result<req::PublishDiagnosticsParams> {
|
||||||
let uri = world.file_id_to_uri(file_id)?;
|
let uri = world.file_id_to_uri(file_id)?;
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let diagnostics = world
|
let diagnostics = world
|
||||||
.analysis()
|
.analysis()
|
||||||
.diagnostics(file_id)?
|
.diagnostics(file_id)?
|
||||||
@ -852,7 +858,7 @@ pub fn publish_decorations(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> {
|
fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> {
|
||||||
let line_index = world.analysis().file_line_index(file_id);
|
let line_index = world.analysis().file_line_index(file_id)?;
|
||||||
let res = world
|
let res = world
|
||||||
.analysis()
|
.analysis()
|
||||||
.highlight(file_id)?
|
.highlight(file_id)?
|
||||||
@ -881,7 +887,7 @@ pub fn handle_inlay_hints(
|
|||||||
) -> Result<Vec<InlayHint>> {
|
) -> Result<Vec<InlayHint>> {
|
||||||
let file_id = params.text_document.try_conv_with(&world)?;
|
let file_id = params.text_document.try_conv_with(&world)?;
|
||||||
let analysis = world.analysis();
|
let analysis = world.analysis();
|
||||||
let line_index = analysis.file_line_index(file_id);
|
let line_index = analysis.file_line_index(file_id)?;
|
||||||
Ok(analysis
|
Ok(analysis
|
||||||
.inlay_hints(file_id)?
|
.inlay_hints(file_id)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -215,7 +215,12 @@ impl WorldSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.push_str("\nanalysis:\n");
|
res.push_str("\nanalysis:\n");
|
||||||
res.push_str(&self.analysis.status());
|
res.push_str(
|
||||||
|
&self
|
||||||
|
.analysis
|
||||||
|
.status()
|
||||||
|
.unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
|
||||||
|
);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user