use sourcemap::DecodedMap;
use crate::{NameComponent, ScopeName, SourceContext};
pub struct NameResolver<'a, T> {
ctx: &'a SourceContext<T>,
sourcemap: &'a DecodedMap,
}
impl<'a, T: AsRef<str>> NameResolver<'a, T> {
pub fn new(ctx: &'a SourceContext<T>, sourcemap: &'a DecodedMap) -> Self {
Self { ctx, sourcemap }
}
pub fn resolve_name(&self, name: &ScopeName) -> String {
name.components()
.map(|c| self.try_map_token(c).unwrap_or_else(|| c.text()))
.collect::<String>()
}
fn try_map_token(&self, c: &NameComponent) -> Option<&str> {
let range = c.range()?;
let source_position = self.ctx.offset_to_position(range.start)?;
let token = self
.sourcemap
.lookup_token(source_position.line, source_position.column)?;
let is_exactish_match = token.get_dst_line() == source_position.line
&& token.get_dst_col() >= source_position.column.saturating_sub(1);
if is_exactish_match {
if let Some(name) = token.get_name() {
return Some(name);
}
if token.get_dst_col() > 0 {
if let Some(prev_token) = self
.sourcemap
.lookup_token(token.get_dst_line(), token.get_dst_col() - 1)
{
if prev_token.get_src_id() == token.get_src_id()
&& prev_token.get_src_line() == token.get_src_line()
&& prev_token.get_src_col() == token.get_src_col()
{
return prev_token.get_name();
}
}
}
}
None
}
}