Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-ssr/src/lib.rs')
-rw-r--r--crates/ide-ssr/src/lib.rs41
1 files changed, 25 insertions, 16 deletions
diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs
index 407433ed19..e62ef60433 100644
--- a/crates/ide-ssr/src/lib.rs
+++ b/crates/ide-ssr/src/lib.rs
@@ -83,9 +83,8 @@ mod tests;
pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Match};
use crate::{errors::bail, matching::MatchFailureReason};
-use hir::Semantics;
-use ide_db::base_db::{FileId, FilePosition, FileRange};
-use nohash_hasher::IntMap;
+use hir::{FileRange, Semantics};
+use ide_db::{EditionedFileId, FileId, FxHashMap, RootDatabase};
use resolving::ResolvedRule;
use syntax::{ast, AstNode, SyntaxNode, TextRange};
use text_edit::TextEdit;
@@ -116,21 +115,27 @@ pub struct MatchFinder<'db> {
sema: Semantics<'db, ide_db::RootDatabase>,
rules: Vec<ResolvedRule>,
resolution_scope: resolving::ResolutionScope<'db>,
- restrict_ranges: Vec<FileRange>,
+ restrict_ranges: Vec<ide_db::FileRange>,
}
impl<'db> MatchFinder<'db> {
/// Constructs a new instance where names will be looked up as if they appeared at
/// `lookup_context`.
pub fn in_context(
- db: &'db ide_db::RootDatabase,
- lookup_context: FilePosition,
- mut restrict_ranges: Vec<FileRange>,
+ db: &'db RootDatabase,
+ lookup_context: ide_db::FilePosition,
+ mut restrict_ranges: Vec<ide_db::FileRange>,
) -> Result<MatchFinder<'db>, SsrError> {
restrict_ranges.retain(|range| !range.range.is_empty());
let sema = Semantics::new(db);
- let resolution_scope = resolving::ResolutionScope::new(&sema, lookup_context)
- .ok_or_else(|| SsrError("no resolution scope for file".into()))?;
+ let file_id = sema
+ .attach_first_edition(lookup_context.file_id)
+ .unwrap_or_else(|| EditionedFileId::current_edition(lookup_context.file_id));
+ let resolution_scope = resolving::ResolutionScope::new(
+ &sema,
+ hir::FilePosition { file_id, offset: lookup_context.offset },
+ )
+ .ok_or_else(|| SsrError("no resolution scope for file".into()))?;
Ok(MatchFinder { sema, rules: Vec::new(), resolution_scope, restrict_ranges })
}
@@ -143,7 +148,7 @@ impl<'db> MatchFinder<'db> {
{
MatchFinder::in_context(
db,
- FilePosition { file_id: first_file_id, offset: 0.into() },
+ ide_db::FilePosition { file_id: first_file_id, offset: 0.into() },
vec![],
)
} else {
@@ -166,12 +171,12 @@ impl<'db> MatchFinder<'db> {
}
/// Finds matches for all added rules and returns edits for all found matches.
- pub fn edits(&self) -> IntMap<FileId, TextEdit> {
+ pub fn edits(&self) -> FxHashMap<FileId, TextEdit> {
use ide_db::base_db::SourceDatabaseExt;
- let mut matches_by_file = IntMap::default();
+ let mut matches_by_file = FxHashMap::default();
for m in self.matches().matches {
matches_by_file
- .entry(m.range.file_id)
+ .entry(m.range.file_id.file_id())
.or_insert_with(SsrMatches::default)
.matches
.push(m);
@@ -218,11 +223,15 @@ impl<'db> MatchFinder<'db> {
/// Finds all nodes in `file_id` whose text is exactly equal to `snippet` and attempts to match
/// them, while recording reasons why they don't match. This API is useful for command
/// line-based debugging where providing a range is difficult.
- pub fn debug_where_text_equal(&self, file_id: FileId, snippet: &str) -> Vec<MatchDebugInfo> {
+ pub fn debug_where_text_equal(
+ &self,
+ file_id: EditionedFileId,
+ snippet: &str,
+ ) -> Vec<MatchDebugInfo> {
use ide_db::base_db::SourceDatabaseExt;
let file = self.sema.parse(file_id);
let mut res = Vec::new();
- let file_text = self.sema.db.file_text(file_id);
+ let file_text = self.sema.db.file_text(file_id.into());
let mut remaining_text = &*file_text;
let mut base = 0;
let len = snippet.len() as u32;
@@ -349,7 +358,7 @@ impl std::error::Error for SsrError {}
#[cfg(test)]
impl MatchDebugInfo {
- pub(crate) fn match_failure_reason(&self) -> Option<&str> {
+ pub fn match_failure_reason(&self) -> Option<&str> {
self.matched.as_ref().err().map(|r| r.reason.as_str())
}
}