Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/lib.rs')
| -rw-r--r-- | crates/ide/src/lib.rs | 147 |
1 files changed, 101 insertions, 46 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index b3b8deb61f..857252832f 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -71,7 +71,9 @@ use ide_db::{ }, prime_caches, symbol_index, }; -use syntax::SourceFile; +use ide_db::{MiniCore, ra_fixture::RaFixtureAnalysis}; +use macros::UpmapFromRaFixture; +use syntax::{SourceFile, ast}; use triomphe::Arc; use view_memory_layout::{RecursiveMemoryLayout, view_memory_layout}; @@ -81,8 +83,9 @@ pub use crate::{ annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation}, call_hierarchy::{CallHierarchyConfig, CallItem}, expand_macro::ExpandedMacro, - file_structure::{StructureNode, StructureNodeKind}, + file_structure::{FileStructureConfig, StructureNode, StructureNodeKind}, folding_ranges::{Fold, FoldKind}, + goto_definition::GotoDefinitionConfig, highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{ HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult, @@ -102,7 +105,7 @@ pub use crate::{ }, move_item::Direction, navigation_target::{NavigationTarget, TryToNav, UpmappingResult}, - references::ReferenceSearchResult, + references::{FindAllRefsConfig, ReferenceSearchResult}, rename::RenameError, runnables::{Runnable, RunnableKind, TestId, UpdateTest}, signature_help::SignatureHelp, @@ -144,7 +147,7 @@ pub use syntax::{TextRange, TextSize}; pub type Cancellable<T> = Result<T, Cancelled>; /// Info associated with a text range. -#[derive(Debug)] +#[derive(Debug, UpmapFromRaFixture)] pub struct RangeInfo<T> { pub range: TextRange, pub info: T, @@ -263,7 +266,7 @@ impl Analysis { false, proc_macro_cwd, Arc::new(CrateWorkspaceData { - data_layout: Err("fixture has no layout".into()), + target: Err("fixture has no layout".into()), toolchain: None, }), ); @@ -274,6 +277,28 @@ impl Analysis { (host.analysis(), file_id) } + pub(crate) fn from_ra_fixture( + sema: &Semantics<'_, RootDatabase>, + literal: ast::String, + expanded: &ast::String, + minicore: MiniCore<'_>, + ) -> Option<(Analysis, RaFixtureAnalysis)> { + Self::from_ra_fixture_with_on_cursor(sema, literal, expanded, minicore, &mut |_| {}) + } + + /// Like [`Analysis::from_ra_fixture()`], but also calls `on_cursor` with the cursor position. + pub(crate) fn from_ra_fixture_with_on_cursor( + sema: &Semantics<'_, RootDatabase>, + literal: ast::String, + expanded: &ast::String, + minicore: MiniCore<'_>, + on_cursor: &mut dyn FnMut(TextRange), + ) -> Option<(Analysis, RaFixtureAnalysis)> { + let analysis = + RaFixtureAnalysis::analyze_ra_fixture(sema, literal, expanded, minicore, on_cursor)?; + Some((Analysis { db: analysis.db.clone() }, analysis)) + } + /// Debug info about the current state of the analysis. pub fn status(&self, file_id: Option<FileId>) -> Cancellable<String> { self.with_db(|db| status::status(db, file_id)) @@ -299,7 +324,7 @@ impl Analysis { /// Gets the text of the source file. pub fn file_text(&self, file_id: FileId) -> Cancellable<Arc<str>> { - self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db)) + self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db).clone()) } /// Gets the syntax tree of the file. @@ -430,19 +455,23 @@ impl Analysis { /// Returns a tree representation of symbols in the file. Useful to draw a /// file outline. - pub fn file_structure(&self, file_id: FileId) -> Cancellable<Vec<StructureNode>> { + pub fn file_structure( + &self, + config: &FileStructureConfig, + file_id: FileId, + ) -> Cancellable<Vec<StructureNode>> { // FIXME: Edition self.with_db(|db| { let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id); - - file_structure::file_structure(&db.parse(editioned_file_id_wrapper).tree()) + let source_file = db.parse(editioned_file_id_wrapper).tree(); + file_structure::file_structure(&source_file, config) }) } /// Returns a list of the places in the file where type hints can be displayed. pub fn inlay_hints( &self, - config: &InlayHintsConfig, + config: &InlayHintsConfig<'_>, file_id: FileId, range: Option<TextRange>, ) -> Cancellable<Vec<InlayHint>> { @@ -450,7 +479,7 @@ impl Analysis { } pub fn inlay_hints_resolve( &self, - config: &InlayHintsConfig, + config: &InlayHintsConfig<'_>, file_id: FileId, resolve_range: TextRange, hash: u64, @@ -472,13 +501,18 @@ impl Analysis { /// Fuzzy searches for a symbol. pub fn symbol_search(&self, query: Query, limit: usize) -> Cancellable<Vec<NavigationTarget>> { - self.with_db(|db| { - symbol_index::world_symbols(db, query) - .into_iter() // xx: should we make this a par iter? - .filter_map(|s| s.try_to_nav(db)) - .take(limit) - .map(UpmappingResult::call_site) - .collect::<Vec<_>>() + // `world_symbols` currently clones the database to run stuff in parallel, which will make any query panic + // if we were to attach it here. + Cancelled::catch(|| { + let symbols = symbol_index::world_symbols(&self.db, query); + hir::attach_db(&self.db, || { + symbols + .into_iter() + .filter_map(|s| s.try_to_nav(&Semantics::new(&self.db))) + .take(limit) + .map(UpmappingResult::call_site) + .collect::<Vec<_>>() + }) }) } @@ -486,16 +520,18 @@ impl Analysis { pub fn goto_definition( &self, position: FilePosition, + config: &GotoDefinitionConfig<'_>, ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { - self.with_db(|db| goto_definition::goto_definition(db, position)) + self.with_db(|db| goto_definition::goto_definition(db, position, config)) } /// Returns the declaration from the symbol at `position`. pub fn goto_declaration( &self, position: FilePosition, + config: &GotoDefinitionConfig<'_>, ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { - self.with_db(|db| goto_declaration::goto_declaration(db, position)) + self.with_db(|db| goto_declaration::goto_declaration(db, position, config)) } /// Returns the impls from the symbol at `position`. @@ -517,19 +553,16 @@ impl Analysis { pub fn find_all_refs( &self, position: FilePosition, - search_scope: Option<SearchScope>, + config: &FindAllRefsConfig<'_>, ) -> Cancellable<Option<Vec<ReferenceSearchResult>>> { - let search_scope = AssertUnwindSafe(search_scope); - self.with_db(|db| { - let _ = &search_scope; - references::find_all_refs(&Semantics::new(db), position, search_scope.0) - }) + let config = AssertUnwindSafe(config); + self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, &config)) } /// Returns a short text describing element at position. pub fn hover( &self, - config: &HoverConfig, + config: &HoverConfig<'_>, range: FileRange, ) -> Cancellable<Option<RangeInfo<HoverResult>>> { self.with_db(|db| hover::hover(db, range, config)) @@ -567,14 +600,15 @@ impl Analysis { pub fn call_hierarchy( &self, position: FilePosition, + config: &CallHierarchyConfig<'_>, ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { - self.with_db(|db| call_hierarchy::call_hierarchy(db, position)) + self.with_db(|db| call_hierarchy::call_hierarchy(db, position, config)) } /// Computes incoming calls for the given file position. pub fn incoming_calls( &self, - config: CallHierarchyConfig, + config: &CallHierarchyConfig<'_>, position: FilePosition, ) -> Cancellable<Option<Vec<CallItem>>> { self.with_db(|db| call_hierarchy::incoming_calls(db, config, position)) @@ -583,7 +617,7 @@ impl Analysis { /// Computes outgoing calls for the given file position. pub fn outgoing_calls( &self, - config: CallHierarchyConfig, + config: &CallHierarchyConfig<'_>, position: FilePosition, ) -> Cancellable<Option<Vec<CallItem>>> { self.with_db(|db| call_hierarchy::outgoing_calls(db, config, position)) @@ -652,15 +686,6 @@ impl Analysis { }) } - /// Computes syntax highlighting for the given file - pub fn highlight( - &self, - highlight_config: HighlightConfig, - file_id: FileId, - ) -> Cancellable<Vec<HlRange>> { - self.with_db(|db| syntax_highlighting::highlight(db, highlight_config, file_id, None)) - } - /// Computes all ranges to highlight for a given item in a file. pub fn highlight_related( &self, @@ -672,14 +697,40 @@ impl Analysis { }) } + /// Computes syntax highlighting for the given file + pub fn highlight( + &self, + highlight_config: HighlightConfig<'_>, + file_id: FileId, + ) -> Cancellable<Vec<HlRange>> { + self.with_db(|db| syntax_highlighting::highlight(db, &highlight_config, file_id, None)) + } + /// Computes syntax highlighting for the given file range. pub fn highlight_range( &self, - highlight_config: HighlightConfig, + highlight_config: HighlightConfig<'_>, frange: FileRange, ) -> Cancellable<Vec<HlRange>> { self.with_db(|db| { - syntax_highlighting::highlight(db, highlight_config, frange.file_id, Some(frange.range)) + syntax_highlighting::highlight( + db, + &highlight_config, + frange.file_id, + Some(frange.range), + ) + }) + } + + /// Computes syntax highlighting for the given file. + pub fn highlight_as_html_with_config( + &self, + config: HighlightConfig<'_>, + file_id: FileId, + rainbow: bool, + ) -> Cancellable<String> { + self.with_db(|db| { + syntax_highlighting::highlight_as_html_with_config(db, &config, file_id, rainbow) }) } @@ -817,14 +868,18 @@ impl Analysis { pub fn annotations( &self, - config: &AnnotationConfig, + config: &AnnotationConfig<'_>, file_id: FileId, ) -> Cancellable<Vec<Annotation>> { self.with_db(|db| annotations::annotations(db, config, file_id)) } - pub fn resolve_annotation(&self, annotation: Annotation) -> Cancellable<Annotation> { - self.with_db(|db| annotations::resolve_annotation(db, annotation)) + pub fn resolve_annotation( + &self, + config: &AnnotationConfig<'_>, + annotation: Annotation, + ) -> Cancellable<Annotation> { + self.with_db(|db| annotations::resolve_annotation(db, config, annotation)) } pub fn move_item( @@ -863,8 +918,8 @@ impl Analysis { where F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, { - let snap = self.db.clone(); - Cancelled::catch(|| f(&snap)) + // We use `attach_db_allow_change()` and not `attach_db()` because fixture injection can change the database. + hir::attach_db_allow_change(&self.db, || Cancelled::catch(|| f(&self.db))) } } |