aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/resolve.rs
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-02-21 21:57:07 +0000
committerVille Penttinen <[email protected]>2019-02-21 21:57:07 +0000
commit2e7bc905be156a007a4ee8f1a1bd1d73a1d19ade (patch)
tree2159410676f8fcddfd8e23b0fbc0fcb759c6ce7a /crates/ra_hir/src/resolve.rs
parent816971ebc9207c5fb5779d448613dd171c27f398 (diff)
Remove Const inference for now, refactor PathResult
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r--crates/ra_hir/src/resolve.rs78
1 files changed, 59 insertions, 19 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 00b55eae9..9f4d4ab42 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -33,27 +33,68 @@ pub(crate) struct ExprScope {
33} 33}
34 34
35#[derive(Debug, Clone)] 35#[derive(Debug, Clone)]
36pub enum PathResult { 36pub struct PathResult {
37 /// Path was fully resolved 37 /// The actual path resolution
38 FullyResolved(PerNs<Resolution>), 38 resolution: PerNs<Resolution>,
39 /// Path was partially resolved, first element contains the resolution 39 /// The first index in the path that we
40 /// second contains the index in the Path.segments which we were unable to resolve 40 /// were unable to resolve.
41 PartiallyResolved(PerNs<Resolution>, usize), 41 /// When path is fully resolved, this is 0.
42 remaining_index: usize,
42} 43}
43 44
44impl PathResult { 45impl PathResult {
45 pub fn segment_index(&self) -> Option<usize> { 46 /// Returns the remaining index in the result
46 match self { 47 /// returns None if the path was fully resolved
47 PathResult::FullyResolved(_) => None, 48 pub fn remaining_index(&self) -> Option<usize> {
48 PathResult::PartiallyResolved(_, ref i) => Some(*i), 49 if self.remaining_index > 0 {
50 Some(self.remaining_index)
51 } else {
52 None
49 } 53 }
50 } 54 }
51 55
52 /// Consumes `PathResult` and returns the contained `PerNs<Resolution>` 56 /// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
57 /// if the path was fully resolved, meaning we have no remaining items
53 pub fn into_per_ns(self) -> PerNs<Resolution> { 58 pub fn into_per_ns(self) -> PerNs<Resolution> {
54 match self { 59 if self.remaining_index().is_none() {
55 PathResult::FullyResolved(def) => def, 60 self.resolution
56 PathResult::PartiallyResolved(def, _) => def, 61 } else {
62 PerNs::none()
63 }
64 }
65
66 /// Consumes `PathResult` and returns the resolution and the
67 /// remaining_index as a tuple.
68 pub fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) {
69 let index = self.remaining_index();
70 (self.resolution, index)
71 }
72
73 /// Path is fully resolved when `remaining_index` is none
74 /// and the resolution contains anything
75 pub fn is_fully_resolved(&self) -> bool {
76 !self.resolution.is_none() && self.remaining_index().is_none()
77 }
78
79 /// Empty path result is where the resolution is `none`
80 /// and the remaining index is 0
81 pub fn is_empty(&self) -> bool {
82 self.resolution.is_none() && self.remaining_index().is_none()
83 }
84
85 fn empty() -> PathResult {
86 PathResult { resolution: PerNs::none(), remaining_index: 0 }
87 }
88
89 fn from_resolution(res: PerNs<Resolution>) -> PathResult {
90 PathResult::from_resolution_with_index(res, 0)
91 }
92
93 fn from_resolution_with_index(res: PerNs<Resolution>, remaining_index: usize) -> PathResult {
94 if res.is_none() {
95 PathResult::empty()
96 } else {
97 PathResult { resolution: res, remaining_index }
57 } 98 }
58 } 99 }
59} 100}
@@ -94,24 +135,23 @@ impl Resolver {
94 } 135 }
95 136
96 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult { 137 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
97 use self::PathResult::*;
98 if let Some(name) = path.as_ident() { 138 if let Some(name) = path.as_ident() {
99 FullyResolved(self.resolve_name(db, name)) 139 PathResult::from_resolution(self.resolve_name(db, name))
100 } else if path.is_self() { 140 } else if path.is_self() {
101 FullyResolved(self.resolve_name(db, &Name::self_param())) 141 PathResult::from_resolution(self.resolve_name(db, &Name::self_param()))
102 } else { 142 } else {
103 let (item_map, module) = match self.module() { 143 let (item_map, module) = match self.module() {
104 Some(m) => m, 144 Some(m) => m,
105 _ => return FullyResolved(PerNs::none()), 145 _ => return PathResult::empty(),
106 }; 146 };
107 let (module_res, segment_index) = item_map.resolve_path(db, module, path); 147 let (module_res, segment_index) = item_map.resolve_path(db, module, path);
108 148
109 let def = module_res.map(Resolution::Def); 149 let def = module_res.map(Resolution::Def);
110 150
111 if let Some(index) = segment_index { 151 if let Some(index) = segment_index {
112 PartiallyResolved(def, index) 152 PathResult::from_resolution_with_index(def, index)
113 } else { 153 } else {
114 FullyResolved(def) 154 PathResult::from_resolution(def)
115 } 155 }
116 } 156 }
117 } 157 }