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.rs140
1 files changed, 88 insertions, 52 deletions
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 8ac1a96cc6..a13be6c492 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -20,6 +20,7 @@ mod navigation_target;
mod annotations;
mod call_hierarchy;
+mod child_modules;
mod doc_links;
mod expand_macro;
mod extend_selection;
@@ -57,23 +58,22 @@ mod view_memory_layout;
mod view_mir;
mod view_syntax_tree;
-use std::{iter, panic::UnwindSafe};
+use std::panic::{AssertUnwindSafe, UnwindSafe};
use cfg::CfgOptions;
use fetch_crates::CrateInfo;
-use hir::{sym, ChangeWithProcMacros};
+use hir::{ChangeWithProcMacros, EditionedFileId, sym};
use ide_db::{
+ FxHashMap, FxIndexSet, LineIndexDatabase,
base_db::{
- ra_salsa::{self, ParallelDatabase},
- CrateOrigin, CrateWorkspaceData, Env, FileLoader, FileSet, SourceDatabase,
- SourceRootDatabase, VfsPath,
+ CrateOrigin, CrateWorkspaceData, Env, FileSet, RootQueryDb, SourceDatabase, VfsPath,
+ salsa::Cancelled,
},
- prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase,
+ prime_caches, symbol_index,
};
-use span::EditionedFileId;
use syntax::SourceFile;
use triomphe::Arc;
-use view_memory_layout::{view_memory_layout, RecursiveMemoryLayout};
+use view_memory_layout::{RecursiveMemoryLayout, view_memory_layout};
use crate::navigation_target::ToNav;
@@ -110,8 +110,8 @@ pub use crate::{
StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig,
},
syntax_highlighting::{
- tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
HighlightConfig, HlRange,
+ tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
},
test_explorer::{TestItem, TestItemKind},
};
@@ -125,7 +125,8 @@ pub use ide_completion::{
};
pub use ide_db::text_edit::{Indel, TextEdit};
pub use ide_db::{
- base_db::{Cancelled, CrateGraph, CrateId, FileChange, SourceRoot, SourceRootId},
+ FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind,
+ base_db::{Crate, CrateGraphBuilder, FileChange, SourceRoot, SourceRootId},
documentation::Documentation,
label::Label,
line_index::{LineCol, LineIndex},
@@ -133,7 +134,6 @@ pub use ide_db::{
search::{ReferenceCategory, SearchScope},
source_change::{FileSystemEdit, SnippetEdit, SourceChange},
symbol_index::Query,
- FileId, FilePosition, FileRange, RootDatabase, Severity, SymbolKind,
};
pub use ide_diagnostics::{Diagnostic, DiagnosticCode, DiagnosticsConfig, ExprFillDefaultMode};
pub use ide_ssr::SsrError;
@@ -217,7 +217,7 @@ impl Default for AnalysisHost {
/// `Analysis` are canceled (most method return `Err(Canceled)`).
#[derive(Debug)]
pub struct Analysis {
- db: ra_salsa::Snapshot<RootDatabase>,
+ db: RootDatabase,
}
// As a general design guideline, `Analysis` API are intended to be independent
@@ -237,34 +237,37 @@ impl Analysis {
file_set.insert(file_id, VfsPath::new_virtual_path("/main.rs".to_owned()));
let source_root = SourceRoot::new_local(file_set);
- let mut change = ChangeWithProcMacros::new();
+ let mut change = ChangeWithProcMacros::default();
change.set_roots(vec![source_root]);
- let mut crate_graph = CrateGraph::default();
+ let mut crate_graph = CrateGraphBuilder::default();
// FIXME: cfg options
// Default to enable test for single file.
let mut cfg_options = CfgOptions::default();
- cfg_options.insert_atom(sym::test.clone());
+
+ // FIXME: This is less than ideal
+ let proc_macro_cwd = Arc::new(
+ TryFrom::try_from(&*std::env::current_dir().unwrap().as_path().to_string_lossy())
+ .unwrap(),
+ );
+ cfg_options.insert_atom(sym::test);
crate_graph.add_crate_root(
file_id,
Edition::CURRENT,
None,
None,
- Arc::new(cfg_options),
+ cfg_options,
None,
Env::default(),
CrateOrigin::Local { repo: None, name: None },
false,
- None,
- );
- change.change_file(file_id, Some(text));
- let ws_data = crate_graph
- .iter()
- .zip(iter::repeat(Arc::new(CrateWorkspaceData {
+ proc_macro_cwd,
+ Arc::new(CrateWorkspaceData {
data_layout: Err("fixture has no layout".into()),
toolchain: None,
- })))
- .collect();
- change.set_crate_graph(crate_graph, ws_data);
+ }),
+ );
+ change.change_file(file_id, Some(text));
+ change.set_crate_graph(crate_graph);
host.apply_change(change);
(host.analysis(), file_id)
@@ -276,12 +279,12 @@ impl Analysis {
}
pub fn source_root_id(&self, file_id: FileId) -> Cancellable<SourceRootId> {
- self.with_db(|db| db.file_source_root(file_id))
+ self.with_db(|db| db.file_source_root(file_id).source_root_id(db))
}
pub fn is_local_source_root(&self, source_root_id: SourceRootId) -> Cancellable<bool> {
self.with_db(|db| {
- let sr = db.source_root(source_root_id);
+ let sr = db.source_root(source_root_id).source_root(db);
!sr.is_library
})
}
@@ -295,18 +298,25 @@ 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))
+ self.with_db(|db| SourceDatabase::file_text(db, file_id).text(db))
}
/// Gets the syntax tree of the file.
pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> {
// FIXME edition
- self.with_db(|db| db.parse(EditionedFileId::current_edition(file_id)).tree())
+ self.with_db(|db| {
+ let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
+
+ db.parse(editioned_file_id_wrapper).tree()
+ })
}
/// Returns true if this file belongs to an immutable library.
pub fn is_library_file(&self, file_id: FileId) -> Cancellable<bool> {
- self.with_db(|db| db.source_root(db.file_source_root(file_id)).is_library)
+ self.with_db(|db| {
+ let source_root = db.file_source_root(file_id).source_root_id(db);
+ db.source_root(source_root).source_root(db).is_library
+ })
}
/// Gets the file's `LineIndex`: data structure to convert between absolute
@@ -324,7 +334,8 @@ impl Analysis {
/// supported).
pub fn matching_brace(&self, position: FilePosition) -> Cancellable<Option<TextSize>> {
self.with_db(|db| {
- let parse = db.parse(EditionedFileId::current_edition(position.file_id));
+ let file_id = EditionedFileId::current_edition(&self.db, position.file_id);
+ let parse = db.parse(file_id);
let file = parse.tree();
matching_brace::matching_brace(&file, position.offset)
})
@@ -358,7 +369,7 @@ impl Analysis {
self.with_db(|db| test_explorer::discover_tests_in_crate_by_test_id(db, crate_id))
}
- pub fn discover_tests_in_crate(&self, crate_id: CrateId) -> Cancellable<Vec<TestItem>> {
+ pub fn discover_tests_in_crate(&self, crate_id: Crate) -> Cancellable<Vec<TestItem>> {
self.with_db(|db| test_explorer::discover_tests_in_crate(db, crate_id))
}
@@ -383,7 +394,9 @@ impl Analysis {
/// stuff like trailing commas.
pub fn join_lines(&self, config: &JoinLinesConfig, frange: FileRange) -> Cancellable<TextEdit> {
self.with_db(|db| {
- let parse = db.parse(EditionedFileId::current_edition(frange.file_id));
+ let editioned_file_id_wrapper =
+ EditionedFileId::current_edition(&self.db, frange.file_id);
+ let parse = db.parse(editioned_file_id_wrapper);
join_lines::join_lines(config, &parse.tree(), frange.range)
})
}
@@ -419,9 +432,9 @@ impl Analysis {
pub fn file_structure(&self, file_id: FileId) -> Cancellable<Vec<StructureNode>> {
// FIXME: Edition
self.with_db(|db| {
- file_structure::file_structure(
- &db.parse(EditionedFileId::current_edition(file_id)).tree(),
- )
+ let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
+
+ file_structure::file_structure(&db.parse(editioned_file_id_wrapper).tree())
})
}
@@ -450,9 +463,9 @@ impl Analysis {
/// Returns the set of folding ranges.
pub fn folding_ranges(&self, file_id: FileId) -> Cancellable<Vec<Fold>> {
self.with_db(|db| {
- folding_ranges::folding_ranges(
- &db.parse(EditionedFileId::current_edition(file_id)).tree(),
- )
+ let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
+
+ folding_ranges::folding_ranges(&db.parse(editioned_file_id_wrapper).tree())
})
}
@@ -506,7 +519,11 @@ impl Analysis {
position: FilePosition,
search_scope: Option<SearchScope>,
) -> Cancellable<Option<Vec<ReferenceSearchResult>>> {
- self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, search_scope))
+ let search_scope = AssertUnwindSafe(search_scope);
+ self.with_db(|db| {
+ let _ = &search_scope;
+ references::find_all_refs(&Semantics::new(db), position, search_scope.0)
+ })
}
/// Returns a short text describing element at position.
@@ -577,34 +594,44 @@ impl Analysis {
self.with_db(|db| parent_module::parent_module(db, position))
}
+ /// Returns vec of `mod name;` declaration which are created by the current module.
+ pub fn child_modules(&self, position: FilePosition) -> Cancellable<Vec<NavigationTarget>> {
+ self.with_db(|db| child_modules::child_modules(db, position))
+ }
+
/// Returns crates that this file belongs to.
- pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
+ pub fn crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
self.with_db(|db| parent_module::crates_for(db, file_id))
}
/// Returns crates that this file belongs to.
- pub fn transitive_rev_deps(&self, crate_id: CrateId) -> Cancellable<Vec<CrateId>> {
- self.with_db(|db| db.crate_graph().transitive_rev_deps(crate_id).collect())
+ 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)))
}
/// Returns crates that this file *might* belong to.
- pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> {
+ pub fn relevant_crates_for(&self, file_id: FileId) -> Cancellable<Vec<Crate>> {
self.with_db(|db| db.relevant_crates(file_id).iter().copied().collect())
}
/// Returns the edition of the given crate.
- pub fn crate_edition(&self, crate_id: CrateId) -> Cancellable<Edition> {
- self.with_db(|db| db.crate_graph()[crate_id].edition)
+ pub fn crate_edition(&self, crate_id: Crate) -> Cancellable<Edition> {
+ self.with_db(|db| crate_id.data(db).edition)
+ }
+
+ /// Returns whether the given crate is a proc macro.
+ pub fn is_proc_macro_crate(&self, crate_id: Crate) -> Cancellable<bool> {
+ self.with_db(|db| crate_id.data(db).is_proc_macro)
}
/// Returns true if this crate has `no_std` or `no_core` specified.
- pub fn is_crate_no_std(&self, crate_id: CrateId) -> Cancellable<bool> {
+ pub fn is_crate_no_std(&self, crate_id: Crate) -> Cancellable<bool> {
self.with_db(|db| hir::db::DefDatabase::crate_def_map(db, crate_id).is_no_std())
}
/// Returns the root file of the given crate.
- pub fn crate_root(&self, crate_id: CrateId) -> Cancellable<FileId> {
- self.with_db(|db| db.crate_graph()[crate_id].root_file_id)
+ pub fn crate_root(&self, crate_id: Crate) -> Cancellable<FileId> {
+ self.with_db(|db| crate_id.data(db).root_file_id)
}
/// Returns the set of possible targets to run for the current file.
@@ -618,7 +645,11 @@ impl Analysis {
position: FilePosition,
search_scope: Option<SearchScope>,
) -> Cancellable<Vec<Runnable>> {
- self.with_db(|db| runnables::related_tests(db, position, search_scope))
+ let search_scope = AssertUnwindSafe(search_scope);
+ self.with_db(|db| {
+ let _ = &search_scope;
+ runnables::related_tests(db, position, search_scope.0)
+ })
}
/// Computes syntax highlighting for the given file
@@ -717,7 +748,7 @@ impl Analysis {
frange: FileRange,
) -> Cancellable<Vec<Assist>> {
let include_fixes = match &assist_config.allowed {
- Some(it) => it.iter().any(|&it| it == AssistKind::None || it == AssistKind::QuickFix),
+ Some(it) => it.contains(&AssistKind::QuickFix),
None => true,
};
@@ -811,6 +842,10 @@ impl Analysis {
self.with_db(|db| view_memory_layout(db, position))
}
+ pub fn editioned_file_id_to_vfs(&self, file_id: hir::EditionedFileId) -> FileId {
+ file_id.file_id(&self.db)
+ }
+
/// Performs an operation on the database that may be canceled.
///
/// rust-analyzer needs to be able to answer semantic questions about the
@@ -828,7 +863,8 @@ impl Analysis {
where
F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe,
{
- Cancelled::catch(|| f(&self.db))
+ let snap = self.db.snapshot();
+ Cancelled::catch(|| f(&snap))
}
}