about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ssr/src/lib.rs26
-rw-r--r--crates/ra_ssr/src/resolving.rs39
2 files changed, 38 insertions, 27 deletions
diff --git a/crates/ra_ssr/src/lib.rs b/crates/ra_ssr/src/lib.rs
index 2fb326b45f4..7014a6ac66e 100644
--- a/crates/ra_ssr/src/lib.rs
+++ b/crates/ra_ssr/src/lib.rs
@@ -51,8 +51,7 @@ pub struct MatchFinder<'db> {
     /// Our source of information about the user's code.
     sema: Semantics<'db, ra_ide_db::RootDatabase>,
     rules: Vec<ResolvedRule>,
-    scope: hir::SemanticsScope<'db>,
-    hygiene: hir::Hygiene,
+    resolution_scope: resolving::ResolutionScope<'db>,
 }
 
 impl<'db> MatchFinder<'db> {
@@ -63,21 +62,8 @@ impl<'db> MatchFinder<'db> {
         lookup_context: FilePosition,
     ) -> MatchFinder<'db> {
         let sema = Semantics::new(db);
-        let file = sema.parse(lookup_context.file_id);
-        // Find a node at the requested position, falling back to the whole file.
-        let node = file
-            .syntax()
-            .token_at_offset(lookup_context.offset)
-            .left_biased()
-            .map(|token| token.parent())
-            .unwrap_or_else(|| file.syntax().clone());
-        let scope = sema.scope(&node);
-        MatchFinder {
-            sema: Semantics::new(db),
-            rules: Vec::new(),
-            scope,
-            hygiene: hir::Hygiene::new(db, lookup_context.file_id.into()),
-        }
+        let resolution_scope = resolving::ResolutionScope::new(&sema, lookup_context);
+        MatchFinder { sema: Semantics::new(db), rules: Vec::new(), resolution_scope }
     }
 
     /// Constructs an instance using the start of the first file in `db` as the lookup context.
@@ -106,8 +92,7 @@ impl<'db> MatchFinder<'db> {
         for parsed_rule in rule.parsed_rules {
             self.rules.push(ResolvedRule::new(
                 parsed_rule,
-                &self.scope,
-                &self.hygiene,
+                &self.resolution_scope,
                 self.rules.len(),
             )?);
         }
@@ -140,8 +125,7 @@ impl<'db> MatchFinder<'db> {
         for parsed_rule in pattern.parsed_rules {
             self.rules.push(ResolvedRule::new(
                 parsed_rule,
-                &self.scope,
-                &self.hygiene,
+                &self.resolution_scope,
                 self.rules.len(),
             )?);
         }
diff --git a/crates/ra_ssr/src/resolving.rs b/crates/ra_ssr/src/resolving.rs
index 75f5567856f..d53981737a8 100644
--- a/crates/ra_ssr/src/resolving.rs
+++ b/crates/ra_ssr/src/resolving.rs
@@ -3,10 +3,16 @@
 use crate::errors::error;
 use crate::{parsing, SsrError};
 use parsing::Placeholder;
+use ra_db::FilePosition;
 use ra_syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken};
 use rustc_hash::{FxHashMap, FxHashSet};
 use test_utils::mark;
 
+pub(crate) struct ResolutionScope<'db> {
+    scope: hir::SemanticsScope<'db>,
+    hygiene: hir::Hygiene,
+}
+
 pub(crate) struct ResolvedRule {
     pub(crate) pattern: ResolvedPattern,
     pub(crate) template: Option<ResolvedPattern>,
@@ -30,12 +36,11 @@ pub(crate) struct ResolvedPath {
 impl ResolvedRule {
     pub(crate) fn new(
         rule: parsing::ParsedRule,
-        scope: &hir::SemanticsScope,
-        hygiene: &hir::Hygiene,
+        resolution_scope: &ResolutionScope,
         index: usize,
     ) -> Result<ResolvedRule, SsrError> {
         let resolver =
-            Resolver { scope, hygiene, placeholders_by_stand_in: rule.placeholders_by_stand_in };
+            Resolver { resolution_scope, placeholders_by_stand_in: rule.placeholders_by_stand_in };
         let resolved_template = if let Some(template) = rule.template {
             Some(resolver.resolve_pattern_tree(template)?)
         } else {
@@ -57,8 +62,7 @@ impl ResolvedRule {
 }
 
 struct Resolver<'a, 'db> {
-    scope: &'a hir::SemanticsScope<'db>,
-    hygiene: &'a hir::Hygiene,
+    resolution_scope: &'a ResolutionScope<'db>,
     placeholders_by_stand_in: FxHashMap<SmolStr, parsing::Placeholder>,
 }
 
@@ -104,6 +108,7 @@ impl Resolver<'_, '_> {
                 && !self.path_contains_placeholder(&path)
             {
                 let resolution = self
+                    .resolution_scope
                     .resolve_path(&path)
                     .ok_or_else(|| error!("Failed to resolve path `{}`", node.text()))?;
                 resolved_paths.insert(node, ResolvedPath { resolution, depth });
@@ -131,9 +136,31 @@ impl Resolver<'_, '_> {
         }
         false
     }
+}
+
+impl<'db> ResolutionScope<'db> {
+    pub(crate) fn new(
+        sema: &hir::Semantics<'db, ra_ide_db::RootDatabase>,
+        lookup_context: FilePosition,
+    ) -> ResolutionScope<'db> {
+        use ra_syntax::ast::AstNode;
+        let file = sema.parse(lookup_context.file_id);
+        // Find a node at the requested position, falling back to the whole file.
+        let node = file
+            .syntax()
+            .token_at_offset(lookup_context.offset)
+            .left_biased()
+            .map(|token| token.parent())
+            .unwrap_or_else(|| file.syntax().clone());
+        let scope = sema.scope(&node);
+        ResolutionScope {
+            scope,
+            hygiene: hir::Hygiene::new(sema.db, lookup_context.file_id.into()),
+        }
+    }
 
     fn resolve_path(&self, path: &ast::Path) -> Option<hir::PathResolution> {
-        let hir_path = hir::Path::from_src(path.clone(), self.hygiene)?;
+        let hir_path = hir::Path::from_src(path.clone(), &self.hygiene)?;
         // First try resolving the whole path. This will work for things like
         // `std::collections::HashMap`, but will fail for things like
         // `std::collections::HashMap::new`.