js_source_scopes/
name_resolver.rs1use sourcemap::DecodedMap;
2
3use crate::{NameComponent, ScopeName, SourceContext};
4
5pub struct NameResolver<'a, T> {
8 ctx: &'a SourceContext<T>,
9 sourcemap: &'a DecodedMap,
10}
11
12impl<'a, T: AsRef<str>> NameResolver<'a, T> {
13 pub fn new(ctx: &'a SourceContext<T>, sourcemap: &'a DecodedMap) -> Self {
15 Self { ctx, sourcemap }
16 }
17
18 pub fn resolve_name(&self, name: &ScopeName) -> String {
24 name.components()
25 .map(|c| self.try_map_token(c).unwrap_or_else(|| c.text()))
26 .collect::<String>()
27 }
28
29 fn try_map_token(&self, c: &NameComponent) -> Option<&str> {
30 let range = c.range()?;
31 let source_position = self.ctx.offset_to_position(range.start)?;
32 let token = self
33 .sourcemap
34 .lookup_token(source_position.line, source_position.column)?;
35
36 let is_exactish_match = token.get_dst_line() == source_position.line
37 && token.get_dst_col() >= source_position.column.saturating_sub(1);
38
39 if is_exactish_match {
40 token.get_name()
41 } else {
42 None
43 }
44 }
45}