diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-25 18:32:17 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-25 18:32:17 +0100 |
commit | ceb16591deef2190daaf5eb9a6480f20dc5d169c (patch) | |
tree | 47edb8102902df9e291d5d0c8274ef1388546d03 /crates | |
parent | a8e37ddbc8fa666105a5eca8e2dc9f261d8934e8 (diff) | |
parent | dbbb0beb3ec9f11a635f43e60f3b3a42ba61338a (diff) |
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 <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_cli/src/analysis_bench.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 86 | ||||
-rw-r--r-- | crates/ra_ide_api/src/references.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/syntax_tree.rs | 14 | ||||
-rw-r--r-- | crates/ra_ide_api/src/typing.rs | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 14 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 64 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 7 |
8 files changed, 107 insertions, 87 deletions
diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_cli/src/analysis_bench.rs index 639ac763e..5e9d0c16d 100644 --- a/crates/ra_cli/src/analysis_bench.rs +++ b/crates/ra_cli/src/analysis_bench.rs | |||
@@ -55,7 +55,7 @@ pub(crate) fn run(verbose: bool, path: &Path, op: Op) -> Result<()> { | |||
55 | Op::Complete { line, column, .. } => { | 55 | Op::Complete { line, column, .. } => { |
56 | let offset = host | 56 | let offset = host |
57 | .analysis() | 57 | .analysis() |
58 | .file_line_index(file_id) | 58 | .file_line_index(file_id)? |
59 | .offset(LineCol { line, col_utf16: column }); | 59 | .offset(LineCol { line, col_utf16: column }); |
60 | let file_postion = FilePosition { file_id, offset }; | 60 | let file_postion = FilePosition { file_id, offset }; |
61 | 61 | ||
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 { | |||
317 | } | 317 | } |
318 | 318 | ||
319 | /// Debug info about the current state of the analysis | 319 | /// Debug info about the current state of the analysis |
320 | pub fn status(&self) -> String { | 320 | pub fn status(&self) -> Cancelable<String> { |
321 | status::status(&*self.db) | 321 | self.with_db(|db| status::status(&*db)) |
322 | } | 322 | } |
323 | 323 | ||
324 | /// Gets the text of the source file. | 324 | /// Gets the text of the source file. |
325 | pub fn file_text(&self, file_id: FileId) -> Arc<String> { | 325 | pub fn file_text(&self, file_id: FileId) -> Cancelable<Arc<String>> { |
326 | self.db.file_text(file_id) | 326 | self.with_db(|db| db.file_text(file_id)) |
327 | } | 327 | } |
328 | 328 | ||
329 | /// Gets the syntax tree of the file. | 329 | /// Gets the syntax tree of the file. |
330 | pub fn parse(&self, file_id: FileId) -> SourceFile { | 330 | pub fn parse(&self, file_id: FileId) -> Cancelable<SourceFile> { |
331 | self.db.parse(file_id).tree() | 331 | self.with_db(|db| db.parse(file_id).tree()) |
332 | } | 332 | } |
333 | 333 | ||
334 | /// Gets the file's `LineIndex`: data structure to convert between absolute | 334 | /// Gets the file's `LineIndex`: data structure to convert between absolute |
335 | /// offsets and line/column representation. | 335 | /// offsets and line/column representation. |
336 | pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { | 336 | pub fn file_line_index(&self, file_id: FileId) -> Cancelable<Arc<LineIndex>> { |
337 | self.db.line_index(file_id) | 337 | self.with_db(|db| db.line_index(file_id)) |
338 | } | 338 | } |
339 | 339 | ||
340 | /// Selects the next syntactic nodes encompassing the range. | 340 | /// Selects the next syntactic nodes encompassing the range. |
@@ -344,58 +344,67 @@ impl Analysis { | |||
344 | 344 | ||
345 | /// Returns position of the matching brace (all types of braces are | 345 | /// Returns position of the matching brace (all types of braces are |
346 | /// supported). | 346 | /// supported). |
347 | pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { | 347 | pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextUnit>> { |
348 | let parse = self.db.parse(position.file_id); | 348 | self.with_db(|db| { |
349 | let file = parse.tree(); | 349 | let parse = db.parse(position.file_id); |
350 | matching_brace::matching_brace(&file, position.offset) | 350 | let file = parse.tree(); |
351 | matching_brace::matching_brace(&file, position.offset) | ||
352 | }) | ||
351 | } | 353 | } |
352 | 354 | ||
353 | /// Returns a syntax tree represented as `String`, for debug purposes. | 355 | /// Returns a syntax tree represented as `String`, for debug purposes. |
354 | // FIXME: use a better name here. | 356 | // FIXME: use a better name here. |
355 | pub fn syntax_tree(&self, file_id: FileId, text_range: Option<TextRange>) -> String { | 357 | pub fn syntax_tree( |
356 | syntax_tree::syntax_tree(&self.db, file_id, text_range) | 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)) | ||
357 | } | 363 | } |
358 | 364 | ||
359 | /// Returns an edit to remove all newlines in the range, cleaning up minor | 365 | /// Returns an edit to remove all newlines in the range, cleaning up minor |
360 | /// stuff like trailing commas. | 366 | /// stuff like trailing commas. |
361 | pub fn join_lines(&self, frange: FileRange) -> SourceChange { | 367 | pub fn join_lines(&self, frange: FileRange) -> Cancelable<SourceChange> { |
362 | let parse = self.db.parse(frange.file_id); | 368 | self.with_db(|db| { |
363 | let file_edit = SourceFileEdit { | 369 | let parse = db.parse(frange.file_id); |
364 | file_id: frange.file_id, | 370 | let file_edit = SourceFileEdit { |
365 | edit: join_lines::join_lines(&parse.tree(), frange.range), | 371 | file_id: frange.file_id, |
366 | }; | 372 | edit: join_lines::join_lines(&parse.tree(), frange.range), |
367 | SourceChange::source_file_edit("join lines", file_edit) | 373 | }; |
374 | SourceChange::source_file_edit("join lines", file_edit) | ||
375 | }) | ||
368 | } | 376 | } |
369 | 377 | ||
370 | /// Returns an edit which should be applied when opening a new line, fixing | 378 | /// Returns an edit which should be applied when opening a new line, fixing |
371 | /// up minor stuff like continuing the comment. | 379 | /// up minor stuff like continuing the comment. |
372 | pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { | 380 | pub fn on_enter(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> { |
373 | typing::on_enter(&self.db, position) | 381 | self.with_db(|db| typing::on_enter(&db, position)) |
374 | } | 382 | } |
375 | 383 | ||
376 | /// Returns an edit which should be applied after `=` was typed. Primarily, | 384 | /// Returns an edit which should be applied after `=` was typed. Primarily, |
377 | /// this works when adding `let =`. | 385 | /// this works when adding `let =`. |
378 | // FIXME: use a snippet completion instead of this hack here. | 386 | // FIXME: use a snippet completion instead of this hack here. |
379 | pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { | 387 | pub fn on_eq_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> { |
380 | let parse = self.db.parse(position.file_id); | 388 | self.with_db(|db| { |
381 | let file = parse.tree(); | 389 | let parse = db.parse(position.file_id); |
382 | let edit = typing::on_eq_typed(&file, position.offset)?; | 390 | let file = parse.tree(); |
383 | Some(SourceChange::source_file_edit( | 391 | let edit = typing::on_eq_typed(&file, position.offset)?; |
384 | "add semicolon", | 392 | Some(SourceChange::source_file_edit( |
385 | SourceFileEdit { edit, file_id: position.file_id }, | 393 | "add semicolon", |
386 | )) | 394 | SourceFileEdit { edit, file_id: position.file_id }, |
395 | )) | ||
396 | }) | ||
387 | } | 397 | } |
388 | 398 | ||
389 | /// Returns an edit which should be applied when a dot ('.') is typed on a blank line, indenting the line appropriately. | 399 | /// 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> { | 400 | pub fn on_dot_typed(&self, position: FilePosition) -> Cancelable<Option<SourceChange>> { |
391 | typing::on_dot_typed(&self.db, position) | 401 | self.with_db(|db| typing::on_dot_typed(&db, position)) |
392 | } | 402 | } |
393 | 403 | ||
394 | /// Returns a tree representation of symbols in the file. Useful to draw a | 404 | /// Returns a tree representation of symbols in the file. Useful to draw a |
395 | /// file outline. | 405 | /// file outline. |
396 | pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { | 406 | pub fn file_structure(&self, file_id: FileId) -> Cancelable<Vec<StructureNode>> { |
397 | let parse = self.db.parse(file_id); | 407 | self.with_db(|db| file_structure(&db.parse(file_id).tree())) |
398 | file_structure(&parse.tree()) | ||
399 | } | 408 | } |
400 | 409 | ||
401 | /// Returns a list of the places in the file where type hints can be displayed. | 410 | /// Returns a list of the places in the file where type hints can be displayed. |
@@ -404,9 +413,8 @@ impl Analysis { | |||
404 | } | 413 | } |
405 | 414 | ||
406 | /// Returns the set of folding ranges. | 415 | /// Returns the set of folding ranges. |
407 | pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { | 416 | pub fn folding_ranges(&self, file_id: FileId) -> Cancelable<Vec<Fold>> { |
408 | let parse = self.db.parse(file_id); | 417 | self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree())) |
409 | folding_ranges::folding_ranges(&parse.tree()) | ||
410 | } | 418 | } |
411 | 419 | ||
412 | /// Fuzzy searches for a symbol. | 420 | /// 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 { | |||
372 | } | 372 | } |
373 | } | 373 | } |
374 | } | 374 | } |
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()); | ||
376 | assert_eq_text!(expected, &*result); | 377 | assert_eq_text!(expected, &*result); |
377 | } | 378 | } |
378 | } | 379 | } |
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 { | |||
101 | fn test_syntax_tree_without_range() { | 101 | fn test_syntax_tree_without_range() { |
102 | // Basic syntax | 102 | // Basic syntax |
103 | let (analysis, file_id) = single_file(r#"fn foo() {}"#); | 103 | 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(); |
105 | 105 | ||
106 | assert_eq_text!( | 106 | assert_eq_text!( |
107 | syn.trim(), | 107 | syn.trim(), |
@@ -133,7 +133,7 @@ fn test() { | |||
133 | }"# | 133 | }"# |
134 | .trim(), | 134 | .trim(), |
135 | ); | 135 | ); |
136 | let syn = analysis.syntax_tree(file_id, None); | 136 | let syn = analysis.syntax_tree(file_id, None).unwrap(); |
137 | 137 | ||
138 | assert_eq_text!( | 138 | assert_eq_text!( |
139 | syn.trim(), | 139 | syn.trim(), |
@@ -176,7 +176,7 @@ SOURCE_FILE@[0; 60) | |||
176 | #[test] | 176 | #[test] |
177 | fn test_syntax_tree_with_range() { | 177 | fn test_syntax_tree_with_range() { |
178 | let (analysis, range) = single_file_with_range(r#"<|>fn foo() {}<|>"#.trim()); | 178 | 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(); |
180 | 180 | ||
181 | assert_eq_text!( | 181 | assert_eq_text!( |
182 | syn.trim(), | 182 | syn.trim(), |
@@ -206,7 +206,7 @@ FN_DEF@[0; 11) | |||
206 | }"# | 206 | }"# |
207 | .trim(), | 207 | .trim(), |
208 | ); | 208 | ); |
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(); |
210 | 210 | ||
211 | assert_eq_text!( | 211 | assert_eq_text!( |
212 | syn.trim(), | 212 | syn.trim(), |
@@ -244,7 +244,7 @@ fn bar() { | |||
244 | }"# | 244 | }"# |
245 | .trim(), | 245 | .trim(), |
246 | ); | 246 | ); |
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(); |
248 | assert_eq_text!( | 248 | assert_eq_text!( |
249 | syn.trim(), | 249 | syn.trim(), |
250 | r#" | 250 | r#" |
@@ -278,7 +278,7 @@ fn bar() { | |||
278 | }"### | 278 | }"### |
279 | .trim(), | 279 | .trim(), |
280 | ); | 280 | ); |
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(); |
282 | assert_eq_text!( | 282 | assert_eq_text!( |
283 | syn.trim(), | 283 | syn.trim(), |
284 | r#" | 284 | r#" |
@@ -311,7 +311,7 @@ fn bar() { | |||
311 | }"### | 311 | }"### |
312 | .trim(), | 312 | .trim(), |
313 | ); | 313 | ); |
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(); |
315 | assert_eq_text!( | 315 | assert_eq_text!( |
316 | syn.trim(), | 316 | syn.trim(), |
317 | r#" | 317 | 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() { | |||
195 | edit.insert(offset, ".".to_string()); | 195 | edit.insert(offset, ".".to_string()); |
196 | let before = edit.finish().apply(&before); | 196 | let before = edit.finish().apply(&before); |
197 | let (analysis, file_id) = single_file(&before); | 197 | 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() { |
199 | assert_eq!(result.source_file_edits.len(), 1); | 199 | assert_eq!(result.source_file_edits.len(), 1); |
200 | let actual = result.source_file_edits[0].edit.apply(&before); | 200 | let actual = result.source_file_edits[0].edit.apply(&before); |
201 | assert_eq_text!(after, &actual); | 201 | assert_eq_text!(after, &actual); |
@@ -377,7 +377,7 @@ fn foo() { | |||
377 | fn apply_on_enter(before: &str) -> Option<String> { | 377 | fn apply_on_enter(before: &str) -> Option<String> { |
378 | let (offset, before) = extract_offset(before); | 378 | let (offset, before) = extract_offset(before); |
379 | let (analysis, file_id) = single_file(&before); | 379 | 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()?; |
381 | 381 | ||
382 | assert_eq!(result.source_file_edits.len(), 1); | 382 | assert_eq!(result.source_file_edits.len(), 1); |
383 | let actual = result.source_file_edits[0].edit.apply(&before); | 383 | let actual = result.source_file_edits[0].edit.apply(&before); |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 82c7e757f..6b3be444f 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -272,7 +272,7 @@ impl<'a> TryConvWith for &'a TextDocumentPositionParams { | |||
272 | type Output = FilePosition; | 272 | type Output = FilePosition; |
273 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> { | 273 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> { |
274 | let file_id = self.text_document.try_conv_with(world)?; | 274 | 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)?; |
276 | let offset = self.position.conv_with(&line_index); | 276 | let offset = self.position.conv_with(&line_index); |
277 | Ok(FilePosition { file_id, offset }) | 277 | Ok(FilePosition { file_id, offset }) |
278 | } | 278 | } |
@@ -283,7 +283,7 @@ impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) { | |||
283 | type Output = FileRange; | 283 | type Output = FileRange; |
284 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> { | 284 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> { |
285 | let file_id = self.0.try_conv_with(world)?; | 285 | 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)?; |
287 | let range = self.1.conv_with(&line_index); | 287 | let range = self.1.conv_with(&line_index); |
288 | Ok(FileRange { file_id, range }) | 288 | Ok(FileRange { file_id, range }) |
289 | } | 289 | } |
@@ -308,7 +308,7 @@ impl TryConvWith for SourceChange { | |||
308 | let cursor_position = match self.cursor_position { | 308 | let cursor_position = match self.cursor_position { |
309 | None => None, | 309 | None => None, |
310 | Some(pos) => { | 310 | 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)?; |
312 | let edit = self | 312 | let edit = self |
313 | .source_file_edits | 313 | .source_file_edits |
314 | .iter() | 314 | .iter() |
@@ -349,7 +349,7 @@ impl TryConvWith for SourceFileEdit { | |||
349 | uri: self.file_id.try_conv_with(world)?, | 349 | uri: self.file_id.try_conv_with(world)?, |
350 | version: None, | 350 | version: None, |
351 | }; | 351 | }; |
352 | let line_index = world.analysis().file_line_index(self.file_id); | 352 | let line_index = world.analysis().file_line_index(self.file_id)?; |
353 | let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); | 353 | let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); |
354 | Ok(TextDocumentEdit { text_document, edits }) | 354 | Ok(TextDocumentEdit { text_document, edits }) |
355 | } | 355 | } |
@@ -378,7 +378,7 @@ impl TryConvWith for &NavigationTarget { | |||
378 | type Ctx = WorldSnapshot; | 378 | type Ctx = WorldSnapshot; |
379 | type Output = Location; | 379 | type Output = Location; |
380 | fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> { | 380 | 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())?; |
382 | let range = self.range(); | 382 | let range = self.range(); |
383 | to_location(self.file_id(), range, &world, &line_index) | 383 | to_location(self.file_id(), range, &world, &line_index) |
384 | } | 384 | } |
@@ -391,8 +391,8 @@ impl TryConvWith for (FileId, RangeInfo<NavigationTarget>) { | |||
391 | let (src_file_id, target) = self; | 391 | let (src_file_id, target) = self; |
392 | 392 | ||
393 | let target_uri = target.info.file_id().try_conv_with(world)?; | 393 | let target_uri = target.info.file_id().try_conv_with(world)?; |
394 | let src_line_index = world.analysis().file_line_index(src_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()); | 395 | let tgt_line_index = world.analysis().file_line_index(target.info.file_id())?; |
396 | 396 | ||
397 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | 397 | let target_range = target.info.full_range().conv_with(&tgt_line_index); |
398 | 398 | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5bf950a53..14619ede2 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -39,9 +39,9 @@ pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { | |||
39 | 39 | ||
40 | pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> { | 40 | pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> { |
41 | let id = params.text_document.try_conv_with(&world)?; | 41 | let id = params.text_document.try_conv_with(&world)?; |
42 | let line_index = world.analysis().file_line_index(id); | 42 | let line_index = world.analysis().file_line_index(id)?; |
43 | let text_range = params.range.map(|p| p.conv_with(&line_index)); | 43 | let text_range = params.range.map(|p| p.conv_with(&line_index)); |
44 | let res = world.analysis().syntax_tree(id, text_range); | 44 | let res = world.analysis().syntax_tree(id, text_range)?; |
45 | Ok(res) | 45 | Ok(res) |
46 | } | 46 | } |
47 | 47 | ||
@@ -55,7 +55,7 @@ pub fn handle_extend_selection( | |||
55 | use the new selection range API in LSP", | 55 | use the new selection range API in LSP", |
56 | ); | 56 | ); |
57 | let file_id = params.text_document.try_conv_with(&world)?; | 57 | let file_id = params.text_document.try_conv_with(&world)?; |
58 | let line_index = world.analysis().file_line_index(file_id); | 58 | let line_index = world.analysis().file_line_index(file_id)?; |
59 | let selections = params | 59 | let selections = params |
60 | .selections | 60 | .selections |
61 | .into_iter() | 61 | .into_iter() |
@@ -72,7 +72,7 @@ pub fn handle_selection_range( | |||
72 | ) -> Result<Vec<req::SelectionRange>> { | 72 | ) -> Result<Vec<req::SelectionRange>> { |
73 | let _p = profile("handle_selection_range"); | 73 | let _p = profile("handle_selection_range"); |
74 | let file_id = params.text_document.try_conv_with(&world)?; | 74 | let file_id = params.text_document.try_conv_with(&world)?; |
75 | let line_index = world.analysis().file_line_index(file_id); | 75 | let line_index = world.analysis().file_line_index(file_id)?; |
76 | params | 76 | params |
77 | .positions | 77 | .positions |
78 | .into_iter() | 78 | .into_iter() |
@@ -113,13 +113,19 @@ pub fn handle_find_matching_brace( | |||
113 | ) -> Result<Vec<Position>> { | 113 | ) -> Result<Vec<Position>> { |
114 | let _p = profile("handle_find_matching_brace"); | 114 | let _p = profile("handle_find_matching_brace"); |
115 | let file_id = params.text_document.try_conv_with(&world)?; | 115 | let file_id = params.text_document.try_conv_with(&world)?; |
116 | let line_index = world.analysis().file_line_index(file_id); | 116 | let line_index = world.analysis().file_line_index(file_id)?; |
117 | let res = params | 117 | let res = params |
118 | .offsets | 118 | .offsets |
119 | .into_iter() | 119 | .into_iter() |
120 | .map_conv_with(&line_index) | 120 | .map_conv_with(&line_index) |
121 | .map(|offset| { | 121 | .map(|offset| { |
122 | world.analysis().matching_brace(FilePosition { file_id, offset }).unwrap_or(offset) | 122 | if let Ok(Some(matching_brace_offset)) = |
123 | world.analysis().matching_brace(FilePosition { file_id, offset }) | ||
124 | { | ||
125 | matching_brace_offset | ||
126 | } else { | ||
127 | offset | ||
128 | } | ||
123 | }) | 129 | }) |
124 | .map_conv_with(&line_index) | 130 | .map_conv_with(&line_index) |
125 | .collect(); | 131 | .collect(); |
@@ -132,7 +138,7 @@ pub fn handle_join_lines( | |||
132 | ) -> Result<req::SourceChange> { | 138 | ) -> Result<req::SourceChange> { |
133 | let _p = profile("handle_join_lines"); | 139 | let _p = profile("handle_join_lines"); |
134 | let frange = (¶ms.text_document, params.range).try_conv_with(&world)?; | 140 | let frange = (¶ms.text_document, params.range).try_conv_with(&world)?; |
135 | world.analysis().join_lines(frange).try_conv_with(&world) | 141 | world.analysis().join_lines(frange)?.try_conv_with(&world) |
136 | } | 142 | } |
137 | 143 | ||
138 | pub fn handle_on_enter( | 144 | pub fn handle_on_enter( |
@@ -141,7 +147,7 @@ pub fn handle_on_enter( | |||
141 | ) -> Result<Option<req::SourceChange>> { | 147 | ) -> Result<Option<req::SourceChange>> { |
142 | let _p = profile("handle_on_enter"); | 148 | let _p = profile("handle_on_enter"); |
143 | let position = params.try_conv_with(&world)?; | 149 | let position = params.try_conv_with(&world)?; |
144 | match world.analysis().on_enter(position) { | 150 | match world.analysis().on_enter(position)? { |
145 | None => Ok(None), | 151 | None => Ok(None), |
146 | Some(edit) => Ok(Some(edit.try_conv_with(&world)?)), | 152 | Some(edit) => Ok(Some(edit.try_conv_with(&world)?)), |
147 | } | 153 | } |
@@ -153,7 +159,7 @@ pub fn handle_on_type_formatting( | |||
153 | ) -> Result<Option<Vec<TextEdit>>> { | 159 | ) -> Result<Option<Vec<TextEdit>>> { |
154 | let _p = profile("handle_on_type_formatting"); | 160 | let _p = profile("handle_on_type_formatting"); |
155 | let mut position = params.text_document_position.try_conv_with(&world)?; | 161 | let mut position = params.text_document_position.try_conv_with(&world)?; |
156 | let line_index = world.analysis().file_line_index(position.file_id); | 162 | let line_index = world.analysis().file_line_index(position.file_id)?; |
157 | 163 | ||
158 | // in `ra_ide_api`, the `on_type` invariant is that | 164 | // in `ra_ide_api`, the `on_type` invariant is that |
159 | // `text.char_at(position) == typed_char`. | 165 | // `text.char_at(position) == typed_char`. |
@@ -163,7 +169,7 @@ pub fn handle_on_type_formatting( | |||
163 | "=" => world.analysis().on_eq_typed(position), | 169 | "=" => world.analysis().on_eq_typed(position), |
164 | "." => world.analysis().on_dot_typed(position), | 170 | "." => world.analysis().on_dot_typed(position), |
165 | _ => return Ok(None), | 171 | _ => return Ok(None), |
166 | }; | 172 | }?; |
167 | let mut edit = match edit { | 173 | let mut edit = match edit { |
168 | Some(it) => it, | 174 | Some(it) => it, |
169 | None => return Ok(None), | 175 | None => return Ok(None), |
@@ -181,11 +187,11 @@ pub fn handle_document_symbol( | |||
181 | params: req::DocumentSymbolParams, | 187 | params: req::DocumentSymbolParams, |
182 | ) -> Result<Option<req::DocumentSymbolResponse>> { | 188 | ) -> Result<Option<req::DocumentSymbolResponse>> { |
183 | let file_id = params.text_document.try_conv_with(&world)?; | 189 | let file_id = params.text_document.try_conv_with(&world)?; |
184 | let line_index = world.analysis().file_line_index(file_id); | 190 | let line_index = world.analysis().file_line_index(file_id)?; |
185 | 191 | ||
186 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 192 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
187 | 193 | ||
188 | for symbol in world.analysis().file_structure(file_id) { | 194 | for symbol in world.analysis().file_structure(file_id)? { |
189 | let doc_symbol = DocumentSymbol { | 195 | let doc_symbol = DocumentSymbol { |
190 | name: symbol.label, | 196 | name: symbol.label, |
191 | detail: symbol.detail, | 197 | detail: symbol.detail, |
@@ -309,7 +315,7 @@ pub fn handle_runnables( | |||
309 | params: req::RunnablesParams, | 315 | params: req::RunnablesParams, |
310 | ) -> Result<Vec<req::Runnable>> { | 316 | ) -> Result<Vec<req::Runnable>> { |
311 | let file_id = params.text_document.try_conv_with(&world)?; | 317 | let file_id = params.text_document.try_conv_with(&world)?; |
312 | let line_index = world.analysis().file_line_index(file_id); | 318 | let line_index = world.analysis().file_line_index(file_id)?; |
313 | let offset = params.position.map(|it| it.conv_with(&line_index)); | 319 | let offset = params.position.map(|it| it.conv_with(&line_index)); |
314 | let mut res = Vec::new(); | 320 | let mut res = Vec::new(); |
315 | let workspace_root = world.workspace_root_for(file_id); | 321 | let workspace_root = world.workspace_root_for(file_id); |
@@ -383,7 +389,7 @@ pub fn handle_completion( | |||
383 | let mut res = false; | 389 | let mut res = false; |
384 | if let Some(ctx) = params.context { | 390 | if let Some(ctx) = params.context { |
385 | if ctx.trigger_character.unwrap_or_default() == ":" { | 391 | if ctx.trigger_character.unwrap_or_default() == ":" { |
386 | let source_file = world.analysis().parse(position.file_id); | 392 | let source_file = world.analysis().parse(position.file_id)?; |
387 | let syntax = source_file.syntax(); | 393 | let syntax = source_file.syntax(); |
388 | let text = syntax.text(); | 394 | let text = syntax.text(); |
389 | if let Some(next_char) = text.char_at(position.offset) { | 395 | if let Some(next_char) = text.char_at(position.offset) { |
@@ -405,7 +411,7 @@ pub fn handle_completion( | |||
405 | None => return Ok(None), | 411 | None => return Ok(None), |
406 | Some(items) => items, | 412 | Some(items) => items, |
407 | }; | 413 | }; |
408 | let line_index = world.analysis().file_line_index(position.file_id); | 414 | let line_index = world.analysis().file_line_index(position.file_id)?; |
409 | let items: Vec<CompletionItem> = | 415 | let items: Vec<CompletionItem> = |
410 | items.into_iter().map(|item| item.conv_with(&line_index)).collect(); | 416 | items.into_iter().map(|item| item.conv_with(&line_index)).collect(); |
411 | 417 | ||
@@ -417,12 +423,12 @@ pub fn handle_folding_range( | |||
417 | params: FoldingRangeParams, | 423 | params: FoldingRangeParams, |
418 | ) -> Result<Option<Vec<FoldingRange>>> { | 424 | ) -> Result<Option<Vec<FoldingRange>>> { |
419 | let file_id = params.text_document.try_conv_with(&world)?; | 425 | let file_id = params.text_document.try_conv_with(&world)?; |
420 | let line_index = world.analysis().file_line_index(file_id); | 426 | let line_index = world.analysis().file_line_index(file_id)?; |
421 | 427 | ||
422 | let res = Some( | 428 | let res = Some( |
423 | world | 429 | world |
424 | .analysis() | 430 | .analysis() |
425 | .folding_ranges(file_id) | 431 | .folding_ranges(file_id)? |
426 | .into_iter() | 432 | .into_iter() |
427 | .map(|fold| { | 433 | .map(|fold| { |
428 | let kind = match fold.kind { | 434 | let kind = match fold.kind { |
@@ -474,7 +480,7 @@ pub fn handle_hover( | |||
474 | None => return Ok(None), | 480 | None => return Ok(None), |
475 | Some(info) => info, | 481 | Some(info) => info, |
476 | }; | 482 | }; |
477 | let line_index = world.analysis.file_line_index(position.file_id); | 483 | let line_index = world.analysis.file_line_index(position.file_id)?; |
478 | let range = info.range.conv_with(&line_index); | 484 | let range = info.range.conv_with(&line_index); |
479 | let res = Hover { | 485 | let res = Hover { |
480 | contents: HoverContents::Markup(MarkupContent { | 486 | contents: HoverContents::Markup(MarkupContent { |
@@ -503,7 +509,7 @@ pub fn handle_prepare_rename( | |||
503 | // Refs should always have a declaration | 509 | // Refs should always have a declaration |
504 | let r = refs.declaration(); | 510 | let r = refs.declaration(); |
505 | let file_id = params.text_document.try_conv_with(&world)?; | 511 | let file_id = params.text_document.try_conv_with(&world)?; |
506 | let line_index = world.analysis().file_line_index(file_id); | 512 | let line_index = world.analysis().file_line_index(file_id)?; |
507 | let loc = to_location(r.file_id(), r.range(), &world, &line_index)?; | 513 | let loc = to_location(r.file_id(), r.range(), &world, &line_index)?; |
508 | 514 | ||
509 | Ok(Some(PrepareRenameResponse::Range(loc.range))) | 515 | Ok(Some(PrepareRenameResponse::Range(loc.range))) |
@@ -536,7 +542,7 @@ pub fn handle_references( | |||
536 | params: req::ReferenceParams, | 542 | params: req::ReferenceParams, |
537 | ) -> Result<Option<Vec<Location>>> { | 543 | ) -> Result<Option<Vec<Location>>> { |
538 | let position = params.text_document_position.try_conv_with(&world)?; | 544 | let position = params.text_document_position.try_conv_with(&world)?; |
539 | let line_index = world.analysis().file_line_index(position.file_id); | 545 | let line_index = world.analysis().file_line_index(position.file_id)?; |
540 | 546 | ||
541 | let refs = match world.analysis().find_all_refs(position)? { | 547 | let refs = match world.analysis().find_all_refs(position)? { |
542 | None => return Ok(None), | 548 | None => return Ok(None), |
@@ -563,9 +569,9 @@ pub fn handle_formatting( | |||
563 | params: DocumentFormattingParams, | 569 | params: DocumentFormattingParams, |
564 | ) -> Result<Option<Vec<TextEdit>>> { | 570 | ) -> Result<Option<Vec<TextEdit>>> { |
565 | let file_id = params.text_document.try_conv_with(&world)?; | 571 | let file_id = params.text_document.try_conv_with(&world)?; |
566 | let file = world.analysis().file_text(file_id); | 572 | let file = world.analysis().file_text(file_id)?; |
567 | 573 | ||
568 | let file_line_index = world.analysis().file_line_index(file_id); | 574 | let file_line_index = world.analysis().file_line_index(file_id)?; |
569 | let end_position = TextUnit::of_str(&file).conv_with(&file_line_index); | 575 | let end_position = TextUnit::of_str(&file).conv_with(&file_line_index); |
570 | 576 | ||
571 | use std::process; | 577 | use std::process; |
@@ -623,7 +629,7 @@ pub fn handle_code_action( | |||
623 | ) -> Result<Option<CodeActionResponse>> { | 629 | ) -> Result<Option<CodeActionResponse>> { |
624 | let _p = profile("handle_code_action"); | 630 | let _p = profile("handle_code_action"); |
625 | let file_id = params.text_document.try_conv_with(&world)?; | 631 | let file_id = params.text_document.try_conv_with(&world)?; |
626 | let line_index = world.analysis().file_line_index(file_id); | 632 | let line_index = world.analysis().file_line_index(file_id)?; |
627 | let range = params.range.conv_with(&line_index); | 633 | let range = params.range.conv_with(&line_index); |
628 | 634 | ||
629 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); | 635 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); |
@@ -685,7 +691,7 @@ pub fn handle_code_lens( | |||
685 | params: req::CodeLensParams, | 691 | params: req::CodeLensParams, |
686 | ) -> Result<Option<Vec<CodeLens>>> { | 692 | ) -> Result<Option<Vec<CodeLens>>> { |
687 | let file_id = params.text_document.try_conv_with(&world)?; | 693 | let file_id = params.text_document.try_conv_with(&world)?; |
688 | let line_index = world.analysis().file_line_index(file_id); | 694 | let line_index = world.analysis().file_line_index(file_id)?; |
689 | 695 | ||
690 | let mut lenses: Vec<CodeLens> = Default::default(); | 696 | let mut lenses: Vec<CodeLens> = Default::default(); |
691 | let workspace_root = world.workspace_root_for(file_id); | 697 | let workspace_root = world.workspace_root_for(file_id); |
@@ -730,7 +736,7 @@ pub fn handle_code_lens( | |||
730 | lenses.extend( | 736 | lenses.extend( |
731 | world | 737 | world |
732 | .analysis() | 738 | .analysis() |
733 | .file_structure(file_id) | 739 | .file_structure(file_id)? |
734 | .into_iter() | 740 | .into_iter() |
735 | .filter(|it| match it.kind { | 741 | .filter(|it| match it.kind { |
736 | SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, | 742 | SyntaxKind::TRAIT_DEF | SyntaxKind::STRUCT_DEF | SyntaxKind::ENUM_DEF => true, |
@@ -807,7 +813,7 @@ pub fn handle_document_highlight( | |||
807 | params: req::TextDocumentPositionParams, | 813 | params: req::TextDocumentPositionParams, |
808 | ) -> Result<Option<Vec<DocumentHighlight>>> { | 814 | ) -> Result<Option<Vec<DocumentHighlight>>> { |
809 | let file_id = params.text_document.try_conv_with(&world)?; | 815 | let file_id = params.text_document.try_conv_with(&world)?; |
810 | let line_index = world.analysis().file_line_index(file_id); | 816 | let line_index = world.analysis().file_line_index(file_id)?; |
811 | 817 | ||
812 | let refs = match world.analysis().find_all_refs(params.try_conv_with(&world)?)? { | 818 | let refs = match world.analysis().find_all_refs(params.try_conv_with(&world)?)? { |
813 | None => return Ok(None), | 819 | None => return Ok(None), |
@@ -826,7 +832,7 @@ pub fn publish_diagnostics( | |||
826 | file_id: FileId, | 832 | file_id: FileId, |
827 | ) -> Result<req::PublishDiagnosticsParams> { | 833 | ) -> Result<req::PublishDiagnosticsParams> { |
828 | let uri = world.file_id_to_uri(file_id)?; | 834 | let uri = world.file_id_to_uri(file_id)?; |
829 | let line_index = world.analysis().file_line_index(file_id); | 835 | let line_index = world.analysis().file_line_index(file_id)?; |
830 | let diagnostics = world | 836 | let diagnostics = world |
831 | .analysis() | 837 | .analysis() |
832 | .diagnostics(file_id)? | 838 | .diagnostics(file_id)? |
@@ -852,7 +858,7 @@ pub fn publish_decorations( | |||
852 | } | 858 | } |
853 | 859 | ||
854 | fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { | 860 | fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { |
855 | let line_index = world.analysis().file_line_index(file_id); | 861 | let line_index = world.analysis().file_line_index(file_id)?; |
856 | let res = world | 862 | let res = world |
857 | .analysis() | 863 | .analysis() |
858 | .highlight(file_id)? | 864 | .highlight(file_id)? |
@@ -881,7 +887,7 @@ pub fn handle_inlay_hints( | |||
881 | ) -> Result<Vec<InlayHint>> { | 887 | ) -> Result<Vec<InlayHint>> { |
882 | let file_id = params.text_document.try_conv_with(&world)?; | 888 | let file_id = params.text_document.try_conv_with(&world)?; |
883 | let analysis = world.analysis(); | 889 | let analysis = world.analysis(); |
884 | let line_index = analysis.file_line_index(file_id); | 890 | let line_index = analysis.file_line_index(file_id)?; |
885 | Ok(analysis | 891 | Ok(analysis |
886 | .inlay_hints(file_id)? | 892 | .inlay_hints(file_id)? |
887 | .into_iter() | 893 | .into_iter() |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 9fd654305..1d7755910 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -215,7 +215,12 @@ impl WorldSnapshot { | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | res.push_str("\nanalysis:\n"); | 217 | res.push_str("\nanalysis:\n"); |
218 | res.push_str(&self.analysis.status()); | 218 | res.push_str( |
219 | &self | ||
220 | .analysis | ||
221 | .status() | ||
222 | .unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()), | ||
223 | ); | ||
219 | res | 224 | res |
220 | } | 225 | } |
221 | 226 | ||