Skip to content

Commit ceb1659

Browse files
Merge #1591
1591: Make Analysis api cancellable r=matklad a=SomeoneToIgnore Based on the discussion from here: #1549 (comment) Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2 parents a8e37dd + dbbb0be commit ceb1659

File tree

8 files changed

+107
-87
lines changed

8 files changed

+107
-87
lines changed

crates/ra_cli/src/analysis_bench.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> {
5555
Op::Complete { line, column, .. } => {
5656
let offset = host
5757
.analysis()
58-
.file_line_index(file_id)
58+
.file_line_index(file_id)?
5959
.offset(LineCol { line, col_utf16: column });
6060
let file_postion = FilePosition { file_id, offset };
6161

crates/ra_ide_api/src/lib.rs

+47-39
Original file line numberDiff line numberDiff line change
@@ -317,24 +317,24 @@ impl Analysis {
317317
}
318318

319319
/// Debug info about the current state of the analysis
320-
pub fn status(&self) -> String {
321-
status::status(&*self.db)
320+
pub fn status(&self) -> Cancelable<String> {
321+
self.with_db(|db| status::status(&*db))
322322
}
323323

324324
/// Gets the text of the source file.
325-
pub fn file_text(&self, file_id: FileId) -> Arc<String> {
326-
self.db.file_text(file_id)
325+
pub fn file_text(&self, file_id: FileId) -> Cancelable<Arc<String>> {
326+
self.with_db(|db| db.file_text(file_id))
327327
}
328328

329329
/// Gets the syntax tree of the file.
330-
pub fn parse(&self, file_id: FileId) -> SourceFile {
331-
self.db.parse(file_id).tree()
330+
pub fn parse(&self, file_id: FileId) -> Cancelable<SourceFile> {
331+
self.with_db(|db| db.parse(file_id).tree())
332332
}
333333

334334
/// Gets the file's `LineIndex`: data structure to convert between absolute
335335
/// offsets and line/column representation.
336-
pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> {
337-
self.db.line_index(file_id)
336+
pub fn file_line_index(&self, file_id: FileId) -> Cancelable<Arc<LineIndex>> {
337+
self.with_db(|db| db.line_index(file_id))
338338
}
339339

340340
/// Selects the next syntactic nodes encompassing the range.
@@ -344,58 +344,67 @@ impl Analysis {
344344

345345
/// Returns position of the matching brace (all types of braces are
346346
/// supported).
347-
pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
348-
let parse = self.db.parse(position.file_id);
349-
let file = parse.tree();
350-
matching_brace::matching_brace(&file, position.offset)
347+
pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextUnit>> {
348+
self.with_db(|db| {
349+
let parse = db.parse(position.file_id);
350+
let file = parse.tree();
351+
matching_brace::matching_brace(&file, position.offset)
352+
})
351353
}
352354

353355
/// Returns a syntax tree represented as `String`, for debug purposes.
354356
// FIXME: use a better name here.
355-
pub fn syntax_tree(&self, file_id: FileId, text_range: Option<TextRange>) -> String {
356-
syntax_tree::syntax_tree(&self.db, file_id, text_range)
357+
pub fn syntax_tree(
358+
&self,
359+
file_id: FileId,
360+
text_range: Option<TextRange>,
361+
) -> Cancelable<String> {
362+
self.with_db(|db| syntax_tree::syntax_tree(&db, file_id, text_range))
357363
}
358364

359365
/// Returns an edit to remove all newlines in the range, cleaning up minor
360366
/// stuff like trailing commas.
361-
pub fn join_lines(&self, frange: FileRange) -> SourceChange {
362-
let parse = self.db.parse(frange.file_id);
363-
let file_edit = SourceFileEdit {
364-
file_id: frange.file_id,
365-
edit: join_lines::join_lines(&parse.tree(), frange.range),
366-
};
367-
SourceChange::source_file_edit("join lines", file_edit)
367+
pub fn join_lines(&self, frange: FileRange) -> Cancelable<SourceChange> {
368+
self.with_db(|db| {
369+
let parse = db.parse(frange.file_id);
370+
let file_edit = SourceFileEdit {
371+
file_id: frange.file_id,
372+
edit: join_lines::join_lines(&parse.tree(), frange.range),
373+
};
374+
SourceChange::source_file_edit("join lines", file_edit)
375+
})
368376
}
369377

370378
/// Returns an edit which should be applied when opening a new line, fixing
371379
/// up minor stuff like continuing the comment.
372-
pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> {
373-
typing::on_enter(&self.db, position)
380+
pub fn on_enter(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
381+
self.with_db(|db| typing::on_enter(&db, position))
374382
}
375383

376384
/// Returns an edit which should be applied after `=` was typed. Primarily,
377385
/// this works when adding `let =`.
378386
// FIXME: use a snippet completion instead of this hack here.
379-
pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
380-
let parse = self.db.parse(position.file_id);
381-
let file = parse.tree();
382-
let edit = typing::on_eq_typed(&file, position.offset)?;
383-
Some(SourceChange::source_file_edit(
384-
"add semicolon",
385-
SourceFileEdit { edit, file_id: position.file_id },
386-
))
387+
pub fn on_eq_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
388+
self.with_db(|db| {
389+
let parse = db.parse(position.file_id);
390+
let file = parse.tree();
391+
let edit = typing::on_eq_typed(&file, position.offset)?;
392+
Some(SourceChange::source_file_edit(
393+
"add semicolon",
394+
SourceFileEdit { edit, file_id: position.file_id },
395+
))
396+
})
387397
}
388398

389399
/// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately.
390-
pub fn on_dot_typed(&self, position: FilePosition) -> Option<SourceChange> {
391-
typing::on_dot_typed(&self.db, position)
400+
pub fn on_dot_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> {
401+
self.with_db(|db| typing::on_dot_typed(&db, position))
392402
}
393403

394404
/// Returns a tree representation of symbols in the file. Useful to draw a
395405
/// file outline.
396-
pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
397-
let parse = self.db.parse(file_id);
398-
file_structure(&parse.tree())
406+
pub fn file_structure(&self, file_id: FileId) -> Cancelable<Vec<StructureNode>> {
407+
self.with_db(|db| file_structure(&db.parse(file_id).tree()))
399408
}
400409

401410
/// Returns a list of the places in the file where type hints can be displayed.
@@ -404,9 +413,8 @@ impl Analysis {
404413
}
405414

406415
/// Returns the set of folding ranges.
407-
pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
408-
let parse = self.db.parse(file_id);
409-
folding_ranges::folding_ranges(&parse.tree())
416+
pub fn folding_ranges(&self, file_id: FileId) -> Cancelable<Vec<Fold>> {
417+
self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree()))
410418
}
411419

412420
/// Fuzzy searches for a symbol.

crates/ra_ide_api/src/references.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ mod tests {
372372
}
373373
}
374374
}
375-
let result = text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()));
375+
let result =
376+
text_edit_builder.finish().apply(&*analysis.file_text(file_id.unwrap()).unwrap());
376377
assert_eq_text!(expected, &*result);
377378
}
378379
}

crates/ra_ide_api/src/syntax_tree.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ mod tests {
101101
fn test_syntax_tree_without_range() {
102102
// Basic syntax
103103
let (analysis, file_id) = single_file(r#"fn foo() {}"#);
104-
let syn = analysis.syntax_tree(file_id, None);
104+
let syn = analysis.syntax_tree(file_id, None).unwrap();
105105

106106
assert_eq_text!(
107107
syn.trim(),
@@ -133,7 +133,7 @@ fn test() {
133133
}"#
134134
.trim(),
135135
);
136-
let syn = analysis.syntax_tree(file_id, None);
136+
let syn = analysis.syntax_tree(file_id, None).unwrap();
137137

138138
assert_eq_text!(
139139
syn.trim(),
@@ -176,7 +176,7 @@ SOURCE_FILE@[0; 60)
176176
#[test]
177177
fn test_syntax_tree_with_range() {
178178
let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim());
179-
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
179+
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
180180

181181
assert_eq_text!(
182182
syn.trim(),
@@ -206,7 +206,7 @@ FN_DEF@[0; 11)
206206
}"#
207207
.trim(),
208208
);
209-
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
209+
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
210210

211211
assert_eq_text!(
212212
syn.trim(),
@@ -244,7 +244,7 @@ fn bar() {
244244
}"#
245245
.trim(),
246246
);
247-
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
247+
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
248248
assert_eq_text!(
249249
syn.trim(),
250250
r#"
@@ -278,7 +278,7 @@ fn bar() {
278278
}"###
279279
.trim(),
280280
);
281-
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
281+
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
282282
assert_eq_text!(
283283
syn.trim(),
284284
r#"
@@ -311,7 +311,7 @@ fn bar() {
311311
}"###
312312
.trim(),
313313
);
314-
let syn = analysis.syntax_tree(range.file_id, Some(range.range));
314+
let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap();
315315
assert_eq_text!(
316316
syn.trim(),
317317
r#"

crates/ra_ide_api/src/typing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ fn foo() {
195195
edit.insert(offset, ".".to_string());
196196
let before = edit.finish().apply(&before);
197197
let (analysis, file_id) = single_file(&before);
198-
if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }) {
198+
if let Some(result) = analysis.on_dot_typed(FilePosition { offset, file_id }).unwrap() {
199199
assert_eq!(result.source_file_edits.len(), 1);
200200
let actual = result.source_file_edits[0].edit.apply(&before);
201201
assert_eq_text!(after, &actual);
@@ -377,7 +377,7 @@ fn foo() {
377377
fn apply_on_enter(before: &str) -> Option<String> {
378378
let (offset, before) = extract_offset(before);
379379
let (analysis, file_id) = single_file(&before);
380-
let result = analysis.on_enter(FilePosition { offset, file_id })?;
380+
let result = analysis.on_enter(FilePosition { offset, file_id }).unwrap()?;
381381

382382
assert_eq!(result.source_file_edits.len(), 1);
383383
let actual = result.source_file_edits[0].edit.apply(&before);

crates/ra_lsp_server/src/conv.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ impl<'a> TryConvWith for &'a TextDocumentPositionParams {
272272
type Output = FilePosition;
273273
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> {
274274
let file_id = self.text_document.try_conv_with(world)?;
275-
let line_index = world.analysis().file_line_index(file_id);
275+
let line_index = world.analysis().file_line_index(file_id)?;
276276
let offset = self.position.conv_with(&line_index);
277277
Ok(FilePosition { file_id, offset })
278278
}
@@ -283,7 +283,7 @@ impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) {
283283
type Output = FileRange;
284284
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> {
285285
let file_id = self.0.try_conv_with(world)?;
286-
let line_index = world.analysis().file_line_index(file_id);
286+
let line_index = world.analysis().file_line_index(file_id)?;
287287
let range = self.1.conv_with(&line_index);
288288
Ok(FileRange { file_id, range })
289289
}
@@ -308,7 +308,7 @@ impl TryConvWith for SourceChange {
308308
let cursor_position = match self.cursor_position {
309309
None => None,
310310
Some(pos) => {
311-
let line_index = world.analysis().file_line_index(pos.file_id);
311+
let line_index = world.analysis().file_line_index(pos.file_id)?;
312312
let edit = self
313313
.source_file_edits
314314
.iter()
@@ -349,7 +349,7 @@ impl TryConvWith for SourceFileEdit {
349349
uri: self.file_id.try_conv_with(world)?,
350350
version: None,
351351
};
352-
let line_index = world.analysis().file_line_index(self.file_id);
352+
let line_index = world.analysis().file_line_index(self.file_id)?;
353353
let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect();
354354
Ok(TextDocumentEdit { text_document, edits })
355355
}
@@ -378,7 +378,7 @@ impl TryConvWith for &NavigationTarget {
378378
type Ctx = WorldSnapshot;
379379
type Output = Location;
380380
fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> {
381-
let line_index = world.analysis().file_line_index(self.file_id());
381+
let line_index = world.analysis().file_line_index(self.file_id())?;
382382
let range = self.range();
383383
to_location(self.file_id(), range, &world, &line_index)
384384
}
@@ -391,8 +391,8 @@ impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) {
391391
let (src_file_id, target) = self;
392392

393393
let target_uri = target.info.file_id().try_conv_with(world)?;
394-
let src_line_index = world.analysis().file_line_index(src_file_id);
395-
let tgt_line_index = world.analysis().file_line_index(target.info.file_id());
394+
let src_line_index = world.analysis().file_line_index(src_file_id)?;
395+
let tgt_line_index = world.analysis().file_line_index(target.info.file_id())?;
396396

397397
let target_range = target.info.full_range().conv_with(&tgt_line_index);
398398

0 commit comments

Comments
 (0)