| 135 | } |
| 136 | |
| 137 | pub fn lookup(&self, ident: &Ident) -> HashSet<Ident> { |
| 138 | fn lookup_in(module: &Module, ident: Ident) -> HashSet<Ident> { |
| 139 | let (prefix, ident) = ident.pop_front(); |
| 140 | |
| 141 | if let Some(ident) = ident { |
| 142 | if let Some(entry) = module.names.get(&prefix) { |
| 143 | let redirected = match &entry.kind { |
| 144 | DeclKind::Module(ns) => ns.lookup(&ident), |
| 145 | DeclKind::LayeredModules(stack) => { |
| 146 | let mut r = HashSet::new(); |
| 147 | for ns in stack.iter().rev() { |
| 148 | r = ns.lookup(&ident); |
| 149 | |
| 150 | if !r.is_empty() { |
| 151 | break; |
| 152 | } |
| 153 | } |
| 154 | r |
| 155 | } |
| 156 | _ => HashSet::new(), |
| 157 | }; |
| 158 | |
| 159 | return redirected |
| 160 | .into_iter() |
| 161 | .map(|i| Ident::from_name(&prefix) + i) |
| 162 | .collect(); |
| 163 | } |
| 164 | } else if let Some(decl) = module.names.get(&prefix) { |
| 165 | if let DeclKind::Module(inner) = &decl.kind { |
| 166 | if inner.names.contains_key(NS_SELF) { |
| 167 | return HashSet::from([Ident::from_path(vec![ |
| 168 | prefix, |
| 169 | NS_SELF.to_string(), |
| 170 | ])]); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | return HashSet::from([Ident::from_name(prefix)]); |
| 175 | } |
| 176 | HashSet::new() |
| 177 | } |
| 178 | |
| 179 | log::trace!("lookup: {ident}"); |
| 180 | |
| 181 | let mut res = HashSet::new(); |
| 182 | |
| 183 | res.extend(lookup_in(self, ident.clone())); |
| 184 | |
| 185 | for redirect in &self.redirects { |
| 186 | log::trace!("... following redirect {redirect}"); |
| 187 | let r = lookup_in(self, redirect.clone() + ident.clone()); |
| 188 | log::trace!("... result of redirect {redirect}: {r:?}"); |
| 189 | if !r.is_empty() { |
| 190 | res.remove(ident); |
| 191 | res.extend(r); |
| 192 | } |
| 193 | } |
| 194 | res |