aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/lib.rs90
1 files changed, 62 insertions, 28 deletions
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index efb483103..b4669dfff 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -148,27 +148,6 @@ impl AnalysisChange {
148 } 148 }
149} 149}
150 150
151/// `AnalysisHost` stores the current state of the world.
152#[derive(Debug, Default)]
153pub struct AnalysisHost {
154 db: db::RootDatabase,
155}
156
157impl AnalysisHost {
158 /// Returns a snapshot of the current state, which you can query for
159 /// semantic information.
160 pub fn analysis(&self) -> Analysis {
161 Analysis {
162 db: self.db.snapshot(),
163 }
164 }
165 /// Applies changes to the current state of the world. If there are
166 /// outstanding snapshots, they will be canceled.
167 pub fn apply_change(&mut self, change: AnalysisChange) {
168 self.db.apply_change(change)
169 }
170}
171
172#[derive(Debug)] 151#[derive(Debug)]
173pub struct SourceChange { 152pub struct SourceChange {
174 pub label: String, 153 pub label: String,
@@ -285,6 +264,27 @@ impl ReferenceResolution {
285 } 264 }
286} 265}
287 266
267/// `AnalysisHost` stores the current state of the world.
268#[derive(Debug, Default)]
269pub struct AnalysisHost {
270 db: db::RootDatabase,
271}
272
273impl AnalysisHost {
274 /// Returns a snapshot of the current state, which you can query for
275 /// semantic information.
276 pub fn analysis(&self) -> Analysis {
277 Analysis {
278 db: self.db.snapshot(),
279 }
280 }
281 /// Applies changes to the current state of the world. If there are
282 /// outstanding snapshots, they will be canceled.
283 pub fn apply_change(&mut self, change: AnalysisChange) {
284 self.db.apply_change(change)
285 }
286}
287
288/// Analysis is a snapshot of a world state at a moment in time. It is the main 288/// Analysis is a snapshot of a world state at a moment in time. It is the main
289/// entry point for asking semantic information about the world. When the world 289/// entry point for asking semantic information about the world. When the world
290/// state is advanced using `AnalysisHost::apply_change` method, all existing 290/// state is advanced using `AnalysisHost::apply_change` method, all existing
@@ -295,107 +295,141 @@ pub struct Analysis {
295} 295}
296 296
297impl Analysis { 297impl Analysis {
298 /// Gets the text of the source file.
298 pub fn file_text(&self, file_id: FileId) -> Arc<String> { 299 pub fn file_text(&self, file_id: FileId) -> Arc<String> {
299 self.db.file_text(file_id) 300 self.db.file_text(file_id)
300 } 301 }
302 /// Gets the syntax tree of the file.
301 pub fn file_syntax(&self, file_id: FileId) -> SourceFileNode { 303 pub fn file_syntax(&self, file_id: FileId) -> SourceFileNode {
302 self.db.source_file(file_id).clone() 304 self.db.source_file(file_id).clone()
303 } 305 }
306 /// Gets the file's `LineIndex`: data structure to convert between absolute
307 /// offsets and line/column representation.
304 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { 308 pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> {
305 self.db.file_lines(file_id) 309 self.db.file_lines(file_id)
306 } 310 }
311 /// Selects the next syntactic nodes encopasing the range.
307 pub fn extend_selection(&self, frange: FileRange) -> TextRange { 312 pub fn extend_selection(&self, frange: FileRange) -> TextRange {
308 extend_selection::extend_selection(&self.db, frange) 313 extend_selection::extend_selection(&self.db, frange)
309 } 314 }
315 /// Returns position of the mathcing brace (all types of braces are
316 /// supported).
310 pub fn matching_brace(&self, file: &SourceFileNode, offset: TextUnit) -> Option<TextUnit> { 317 pub fn matching_brace(&self, file: &SourceFileNode, offset: TextUnit) -> Option<TextUnit> {
311 ra_editor::matching_brace(file, offset) 318 ra_editor::matching_brace(file, offset)
312 } 319 }
320 /// Returns a syntax tree represented as `String`, for debug purposes.
321 // FIXME: use a better name here.
313 pub fn syntax_tree(&self, file_id: FileId) -> String { 322 pub fn syntax_tree(&self, file_id: FileId) -> String {
314 let file = self.db.source_file(file_id); 323 let file = self.db.source_file(file_id);
315 ra_editor::syntax_tree(&file) 324 ra_editor::syntax_tree(&file)
316 } 325 }
326 /// Returns an edit to remove all newlines in the range, cleaning up minor
327 /// stuff like trailing commas.
317 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 328 pub fn join_lines(&self, frange: FileRange) -> SourceChange {
318 let file = self.db.source_file(frange.file_id); 329 let file = self.db.source_file(frange.file_id);
319 SourceChange::from_local_edit(frange.file_id, ra_editor::join_lines(&file, frange.range)) 330 SourceChange::from_local_edit(frange.file_id, ra_editor::join_lines(&file, frange.range))
320 } 331 }
332 /// Returns an edit which should be applied when opening a new line, fixing
333 /// up minor stuff like continuing the comment.
321 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> { 334 pub fn on_enter(&self, position: FilePosition) -> Option<SourceChange> {
322 let file = self.db.source_file(position.file_id); 335 let file = self.db.source_file(position.file_id);
323 let edit = ra_editor::on_enter(&file, position.offset)?; 336 let edit = ra_editor::on_enter(&file, position.offset)?;
324 let res = SourceChange::from_local_edit(position.file_id, edit); 337 Some(SourceChange::from_local_edit(position.file_id, edit))
325 Some(res)
326 } 338 }
339 /// Returns an edit which should be applied after `=` was typed. Primaraly,
340 /// this works when adding `let =`.
341 // FIXME: use a snippet completion instead of this hack here.
327 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { 342 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
328 let file = self.db.source_file(position.file_id); 343 let file = self.db.source_file(position.file_id);
329 Some(SourceChange::from_local_edit( 344 let edit = ra_editor::on_eq_typed(&file, position.offset)?;
330 position.file_id, 345 Some(SourceChange::from_local_edit(position.file_id, edit))
331 ra_editor::on_eq_typed(&file, position.offset)?,
332 ))
333 } 346 }
347 /// Returns a tree representation of symbols in the file. Useful to draw a
348 /// file outline.
334 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { 349 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
335 let file = self.db.source_file(file_id); 350 let file = self.db.source_file(file_id);
336 ra_editor::file_structure(&file) 351 ra_editor::file_structure(&file)
337 } 352 }
353 /// Returns the set of folding ranges.
338 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 354 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
339 let file = self.db.source_file(file_id); 355 let file = self.db.source_file(file_id);
340 ra_editor::folding_ranges(&file) 356 ra_editor::folding_ranges(&file)
341 } 357 }
358 /// Fuzzy searches for a symbol.
342 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { 359 pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> {
343 let res = symbol_index::world_symbols(&*self.db, query)? 360 let res = symbol_index::world_symbols(self.db, query)?
344 .into_iter() 361 .into_iter()
345 .map(|(file_id, symbol)| NavigationTarget { file_id, symbol }) 362 .map(|(file_id, symbol)| NavigationTarget { file_id, symbol })
346 .collect(); 363 .collect();
347 Ok(res) 364 Ok(res)
348 } 365 }
366 /// Resolves reference to definition, but does not gurantee correctness.
349 pub fn approximately_resolve_symbol( 367 pub fn approximately_resolve_symbol(
350 &self, 368 &self,
351 position: FilePosition, 369 position: FilePosition,
352 ) -> Cancelable<Option<ReferenceResolution>> { 370 ) -> Cancelable<Option<ReferenceResolution>> {
353 self.db.approximately_resolve_symbol(position) 371 self.db.approximately_resolve_symbol(position)
354 } 372 }
373 /// Finds all usages of the reference at point.
355 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 374 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
356 self.db.find_all_refs(position) 375 self.db.find_all_refs(position)
357 } 376 }
377 /// Returns documentation string for a given target.
358 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> { 378 pub fn doc_text_for(&self, nav: NavigationTarget) -> Cancelable<Option<String>> {
359 self.db.doc_text_for(nav) 379 self.db.doc_text_for(nav)
360 } 380 }
381 /// Returns a `mod name;` declaration whihc created the current module.
361 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 382 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
362 self.db.parent_module(position) 383 self.db.parent_module(position)
363 } 384 }
385 /// Returns `::` separated path to the current module from the crate root.
364 pub fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> { 386 pub fn module_path(&self, position: FilePosition) -> Cancelable<Option<String>> {
365 self.db.module_path(position) 387 self.db.module_path(position)
366 } 388 }
389 /// Returns crates this file belongs too.
367 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 390 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
368 self.db.crate_for(file_id) 391 self.db.crate_for(file_id)
369 } 392 }
393 /// Returns the root file of the given crate.
370 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { 394 pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> {
371 Ok(self.db.crate_root(crate_id)) 395 Ok(self.db.crate_root(crate_id))
372 } 396 }
397 /// Returns the set of possible targets to run for the current file.
373 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { 398 pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> {
374 let file = self.db.source_file(file_id); 399 let file = self.db.source_file(file_id);
375 Ok(runnables::runnables(self, &file, file_id)) 400 Ok(runnables::runnables(self, &file, file_id))
376 } 401 }
402 /// Computes syntax highlighting for the given file.
377 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { 403 pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> {
378 syntax_highlighting::highlight(&*self.db, file_id) 404 syntax_highlighting::highlight(&*self.db, file_id)
379 } 405 }
406 /// Computes completions at the given position.
380 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { 407 pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
381 let completions = completion::completions(&self.db, position)?; 408 let completions = completion::completions(&self.db, position)?;
382 Ok(completions.map(|it| it.into())) 409 Ok(completions.map(|it| it.into()))
383 } 410 }
411 /// Computes assists (aks code actons aka intentions) for the given
412 /// position.
384 pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<SourceChange>> { 413 pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<SourceChange>> {
385 Ok(self.db.assists(frange)) 414 Ok(self.db.assists(frange))
386 } 415 }
416 /// Computes the set of diagnostics for the given file.
387 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 417 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
388 self.db.diagnostics(file_id) 418 self.db.diagnostics(file_id)
389 } 419 }
420 /// Computes parameter information for the given call expression.
390 pub fn resolve_callable( 421 pub fn resolve_callable(
391 &self, 422 &self,
392 position: FilePosition, 423 position: FilePosition,
393 ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { 424 ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> {
394 self.db.resolve_callable(position) 425 self.db.resolve_callable(position)
395 } 426 }
427 /// Computes the type of the expression at the given position.
396 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { 428 pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> {
397 self.db.type_of(frange) 429 self.db.type_of(frange)
398 } 430 }
431 /// Returns the edit required to rename reference at the position to the new
432 /// name.
399 pub fn rename( 433 pub fn rename(
400 &self, 434 &self,
401 position: FilePosition, 435 position: FilePosition,