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 | 137 |
1 files changed, 79 insertions, 58 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 5febe4ee20..9436264904 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -62,16 +62,18 @@ use std::panic::{AssertUnwindSafe, UnwindSafe}; use cfg::CfgOptions; use fetch_crates::CrateInfo; -use hir::{ChangeWithProcMacros, EditionedFileId, crate_def_map, db::HirDatabase, sym}; +use hir::{ChangeWithProcMacros, EditionedFileId, crate_def_map, sym}; use ide_db::{ FxHashMap, FxIndexSet, LineIndexDatabase, base_db::{ CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, VfsPath, - salsa::{self, Cancelled}, + salsa::Cancelled, }, 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}; @@ -83,6 +85,8 @@ pub use crate::{ expand_macro::ExpandedMacro, file_structure::{FileStructureConfig, StructureNode, StructureNodeKind}, folding_ranges::{Fold, FoldKind}, + goto_definition::GotoDefinitionConfig, + goto_implementation::GotoImplementationConfig, highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{ HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult, @@ -102,8 +106,8 @@ pub use crate::{ }, move_item::Direction, navigation_target::{NavigationTarget, TryToNav, UpmappingResult}, - references::ReferenceSearchResult, - rename::RenameError, + references::{FindAllRefsConfig, ReferenceSearchResult}, + rename::{RenameConfig, RenameError}, runnables::{Runnable, RunnableKind, TestId, UpdateTest}, signature_help::SignatureHelp, static_index::{ @@ -144,7 +148,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, @@ -274,6 +278,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)) @@ -306,7 +332,8 @@ impl Analysis { pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> { // FIXME edition self.with_db(|db| { - let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id); + let editioned_file_id_wrapper = + EditionedFileId::current_edition_guess_origin(&self.db, file_id); db.parse(editioned_file_id_wrapper).tree() }) @@ -335,7 +362,7 @@ impl Analysis { /// supported). pub fn matching_brace(&self, position: FilePosition) -> Cancellable<Option<TextSize>> { self.with_db(|db| { - let file_id = EditionedFileId::current_edition(&self.db, position.file_id); + let file_id = EditionedFileId::current_edition_guess_origin(&self.db, position.file_id); let parse = db.parse(file_id); let file = parse.tree(); matching_brace::matching_brace(&file, position.offset) @@ -396,7 +423,7 @@ impl Analysis { pub fn join_lines(&self, config: &JoinLinesConfig, frange: FileRange) -> Cancellable<TextEdit> { self.with_db(|db| { let editioned_file_id_wrapper = - EditionedFileId::current_edition(&self.db, frange.file_id); + EditionedFileId::current_edition_guess_origin(&self.db, frange.file_id); let parse = db.parse(editioned_file_id_wrapper); join_lines::join_lines(config, &parse.tree(), frange.range) }) @@ -437,7 +464,8 @@ impl Analysis { ) -> Cancellable<Vec<StructureNode>> { // FIXME: Edition self.with_db(|db| { - let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id); + let editioned_file_id_wrapper = + EditionedFileId::current_edition_guess_origin(&self.db, file_id); let source_file = db.parse(editioned_file_id_wrapper).tree(); file_structure::file_structure(&source_file, config) }) @@ -446,7 +474,7 @@ impl Analysis { /// 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>> { @@ -454,7 +482,7 @@ impl Analysis { } pub fn inlay_hints_resolve( &self, - config: &InlayHintsConfig, + config: &InlayHintsConfig<'_>, file_id: FileId, resolve_range: TextRange, hash: u64, @@ -468,7 +496,8 @@ impl Analysis { /// Returns the set of folding ranges. pub fn folding_ranges(&self, file_id: FileId) -> Cancellable<Vec<Fold>> { self.with_db(|db| { - let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id); + let editioned_file_id_wrapper = + EditionedFileId::current_edition_guess_origin(&self.db, file_id); folding_ranges::folding_ranges(&db.parse(editioned_file_id_wrapper).tree()) }) @@ -480,7 +509,7 @@ impl Analysis { // if we were to attach it here. Cancelled::catch(|| { let symbols = symbol_index::world_symbols(&self.db, query); - salsa::attach(&self.db, || { + hir::attach_db(&self.db, || { symbols .into_iter() .filter_map(|s| s.try_to_nav(&Semantics::new(&self.db))) @@ -495,24 +524,27 @@ 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`. pub fn goto_implementation( &self, + config: &GotoImplementationConfig, position: FilePosition, ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { - self.with_db(|db| goto_implementation::goto_implementation(db, position)) + self.with_db(|db| goto_implementation::goto_implementation(db, config, position)) } /// Returns the type definitions for the symbol at `position`. @@ -526,19 +558,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)) @@ -576,14 +605,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)) @@ -592,7 +622,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)) @@ -615,7 +645,7 @@ impl Analysis { /// Returns crates that this file belongs to. pub fn transitive_rev_deps(&self, crate_id: Crate) -> Cancellable<Vec<Crate>> { - self.with_db(|db| Vec::from_iter(db.transitive_rev_deps(crate_id))) + self.with_db(|db| Vec::from_iter(crate_id.transitive_rev_deps(db))) } /// Returns crates that this file *might* belong to. @@ -675,28 +705,22 @@ impl Analysis { /// Computes syntax highlighting for the given file pub fn highlight( &self, - highlight_config: HighlightConfig, + highlight_config: HighlightConfig<'_>, file_id: FileId, ) -> Cancellable<Vec<HlRange>> { - // highlighting may construct a new database for "speculative" execution, so we can't currently attach the database - // highlighting instead sets up the attach hook where neceesary for the trait solver - Cancelled::catch(|| { - syntax_highlighting::highlight(&self.db, highlight_config, file_id, None) - }) + 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>> { - // highlighting may construct a new database for "speculative" execution, so we can't currently attach the database - // highlighting instead sets up the attach hook where neceesary for the trait solver - Cancelled::catch(|| { + self.with_db(|db| { syntax_highlighting::highlight( - &self.db, - highlight_config, + db, + &highlight_config, frange.file_id, Some(frange.range), ) @@ -706,22 +730,18 @@ impl Analysis { /// Computes syntax highlighting for the given file. pub fn highlight_as_html_with_config( &self, - config: HighlightConfig, + config: HighlightConfig<'_>, file_id: FileId, rainbow: bool, ) -> Cancellable<String> { - // highlighting may construct a new database for "speculative" execution, so we can't currently attach the database - // highlighting instead sets up the attach hook where neceesary for the trait solver - Cancelled::catch(|| { - syntax_highlighting::highlight_as_html_with_config(&self.db, config, file_id, rainbow) + self.with_db(|db| { + syntax_highlighting::highlight_as_html_with_config(db, &config, file_id, rainbow) }) } /// Computes syntax highlighting for the given file. pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancellable<String> { - // highlighting may construct a new database for "speculative" execution, so we can't currently attach the database - // highlighting instead sets up the attach hook where neceesary for the trait solver - Cancelled::catch(|| syntax_highlighting::highlight_as_html(&self.db, file_id, rainbow)) + self.with_db(|db| syntax_highlighting::highlight_as_html(db, file_id, rainbow)) } /// Computes completions at the given position. @@ -815,8 +835,9 @@ impl Analysis { &self, position: FilePosition, new_name: &str, + config: &RenameConfig, ) -> Cancellable<Result<SourceChange, RenameError>> { - self.with_db(|db| rename::rename(db, position, new_name)) + self.with_db(|db| rename::rename(db, position, new_name, config)) } pub fn prepare_rename( @@ -853,14 +874,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( @@ -899,12 +924,8 @@ impl Analysis { where F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, { - salsa::attach(&self.db, || { - // the trait solver code may invoke `as_view<HirDatabase>` outside of queries, - // so technically we might run into a panic in salsa if the downcaster has not yet been registered. - HirDatabase::zalsa_register_downcaster(&self.db); - Cancelled::catch(|| f(&self.db)) - }) + // 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))) } } |