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.rs | 41 |
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()) } } |