From dbbb0beb3ec9f11a635f43e60f3b3a42ba61338a Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Thu, 25 Jul 2019 20:22:41 +0300 Subject: Make Analysis api cancellable --- crates/ra_ide_api/src/lib.rs | 86 ++++++++++++++++++++---------------- crates/ra_ide_api/src/references.rs | 3 +- crates/ra_ide_api/src/syntax_tree.rs | 14 +++--- crates/ra_ide_api/src/typing.rs | 4 +- 4 files changed, 58 insertions(+), 49 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index 16ffb03ce..edb646c11 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -317,24 +317,24 @@ impl Analysis { } /// Debug info about the current state of the analysis - pub fn status(&self) -> String { - status::status(&*self.db) + pub fn status(&self) -> Cancelable { + self.with_db(|db| status::status(&*db)) } /// Gets the text of the source file. - pub fn file_text(&self, file_id: FileId) -> Arc { - self.db.file_text(file_id) + pub fn file_text(&self, file_id: FileId) -> Cancelable> { + self.with_db(|db| db.file_text(file_id)) } /// Gets the syntax tree of the file. - pub fn parse(&self, file_id: FileId) -> SourceFile { - self.db.parse(file_id).tree() + pub fn parse(&self, file_id: FileId) -> Cancelable { + self.with_db(|db| db.parse(file_id).tree()) } /// Gets the file's `LineIndex`: data structure to convert between absolute /// offsets and line/column representation. - pub fn file_line_index(&self, file_id: FileId) -> Arc { - self.db.line_index(file_id) + pub fn file_line_index(&self, file_id: FileId) -> Cancelable> { + self.with_db(|db| db.line_index(file_id)) } /// 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 /// supported). - pub fn matching_brace(&self, position: FilePosition) -> Option { - let parse = self.db.parse(position.file_id); - let file = parse.tree(); - matching_brace::matching_brace(&file, position.offset) + pub fn matching_brace(&self, position: FilePosition) -> Cancelable> { + self.with_db(|db| { + let parse = db.parse(position.file_id); + let file = parse.tree(); + matching_brace::matching_brace(&file, position.offset) + }) } /// Returns a syntax tree represented as `String`, for debug purposes. // FIXME: use a better name here. - pub fn syntax_tree(&self, file_id: FileId, text_range: Option) -> String { - syntax_tree::syntax_tree(&self.db, file_id, text_range) + pub fn syntax_tree( + &self, + file_id: FileId, + text_range: Option, + ) -> Cancelable { + 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 /// stuff like trailing commas. - pub fn join_lines(&self, frange: FileRange) -> SourceChange { - let parse = self.db.parse(frange.file_id); - let file_edit = SourceFileEdit { - file_id: frange.file_id, - edit: join_lines::join_lines(&parse.tree(), frange.range), - }; - SourceChange::source_file_edit("join lines", file_edit) + pub fn join_lines(&self, frange: FileRange) -> Cancelable { + self.with_db(|db| { + let parse = db.parse(frange.file_id); + let file_edit = SourceFileEdit { + file_id: frange.file_id, + edit: join_lines::join_lines(&parse.tree(), frange.range), + }; + SourceChange::source_file_edit("join lines", file_edit) + }) } /// Returns an edit which should be applied when opening a new line, fixing /// up minor stuff like continuing the comment. - pub fn on_enter(&self, position: FilePosition) -> Option { - typing::on_enter(&self.db, position) + pub fn on_enter(&self, position: FilePosition) -> Cancelable> { + self.with_db(|db| typing::on_enter(&db, position)) } /// Returns an edit which should be applied after `=` was typed. Primarily, /// this works when adding `let =`. // FIXME: use a snippet completion instead of this hack here. - pub fn on_eq_typed(&self, position: FilePosition) -> Option { - let parse = self.db.parse(position.file_id); - let file = parse.tree(); - let edit = typing::on_eq_typed(&file, position.offset)?; - Some(SourceChange::source_file_edit( - "add semicolon", - SourceFileEdit { edit, file_id: position.file_id }, - )) + pub fn on_eq_typed(&self, position: FilePosition) -> Cancelable> { + self.with_db(|db| { + let parse = db.parse(position.file_id); + let file = parse.tree(); + let edit = typing::on_eq_typed(&file, position.offset)?; + Some(SourceChange::source_file_edit( + "add semicolon", + 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. - pub fn on_dot_typed(&self, position: FilePosition) -> Option { - typing::on_dot_typed(&self.db, position) + pub fn on_dot_typed(&self, position: FilePosition) -> Cancelable> { + self.with_db(|db| typing::on_dot_typed(&db, position)) } /// Returns a tree representation of symbols in the file. Useful to draw a /// file outline. - pub fn file_structure(&self, file_id: FileId) -> Vec { - let parse = self.db.parse(file_id); - file_structure(&parse.tree()) + pub fn file_structure(&self, file_id: FileId) -> Cancelable> { + self.with_db(|db| file_structure(&db.parse(file_id).tree())) } /// 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. - pub fn folding_ranges(&self, file_id: FileId) -> Vec { - let parse = self.db.parse(file_id); - folding_ranges::folding_ranges(&parse.tree()) + pub fn folding_ranges(&self, file_id: FileId) -> Cancelable> { + self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree())) } /// Fuzzy searches for a symbol. diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index 5c74d3e36..89984e642 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs @@ -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); } } diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs index a07e670fa..dd31b9093 100644 --- a/crates/ra_ide_api/src/syntax_tree.rs +++ b/crates/ra_ide_api/src/syntax_tree.rs @@ -101,7 +101,7 @@ mod tests { fn test_syntax_tree_without_range() { // Basic syntax 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!( syn.trim(), @@ -133,7 +133,7 @@ fn test() { }"# .trim(), ); - let syn = analysis.syntax_tree(file_id, None); + let syn = analysis.syntax_tree(file_id, None).unwrap(); assert_eq_text!( syn.trim(), @@ -176,7 +176,7 @@ SOURCE_FILE@[0; 60) #[test] fn test_syntax_tree_with_range() { 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!( syn.trim(), @@ -206,7 +206,7 @@ FN_DEF@[0; 11) }"# .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!( syn.trim(), @@ -244,7 +244,7 @@ fn bar() { }"# .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!( syn.trim(), r#" @@ -278,7 +278,7 @@ fn bar() { }"### .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!( syn.trim(), r#" @@ -311,7 +311,7 @@ fn bar() { }"### .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!( syn.trim(), r#" diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index 6b3fd5904..2d4491442 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs @@ -195,7 +195,7 @@ fn foo() { edit.insert(offset, ".".to_string()); let before = edit.finish().apply(&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); let actual = result.source_file_edits[0].edit.apply(&before); assert_eq_text!(after, &actual); @@ -377,7 +377,7 @@ fn foo() { fn apply_on_enter(before: &str) -> Option { let (offset, before) = extract_offset(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); let actual = result.source_file_edits[0].edit.apply(&before); -- cgit v1.2.3