js_source_scopes/
scope_name.rs

1use std::borrow::Cow;
2use std::collections::VecDeque;
3use std::fmt::Display;
4use std::ops::Range;
5
6use swc_ecma_visit::swc_ecma_ast as ast;
7
8use crate::swc::convert_span;
9
10/// An abstract scope name which can consist of multiple [`NameComponent`]s.
11#[derive(Debug)]
12pub struct ScopeName {
13    pub(crate) components: VecDeque<NameComponent>,
14}
15
16impl ScopeName {
17    pub(crate) fn new() -> Self {
18        Self {
19            components: Default::default(),
20        }
21    }
22
23    /// An Iterator over the individual components of this scope name.
24    pub fn components(&self) -> impl Iterator<Item = &NameComponent> + '_ {
25        self.components.iter()
26    }
27}
28
29impl Display for ScopeName {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        for c in self.components() {
32            f.write_str(c.text())?;
33        }
34        Ok(())
35    }
36}
37
38/// An individual component of a [`ScopeName`].
39#[derive(Debug)]
40pub struct NameComponent {
41    pub(crate) inner: NameComponentInner,
42}
43
44impl NameComponent {
45    /// The source text of this component.
46    pub fn text(&self) -> &str {
47        match &self.inner {
48            NameComponentInner::Interpolation(s) => s,
49            NameComponentInner::SourceIdentifierToken(t) => &t.sym,
50        }
51    }
52
53    /// The range of this component inside of the source text.
54    ///
55    /// This will return `None` for synthetic components that do not correspond
56    /// to a specific token inside the source text.
57    pub fn range(&self) -> Option<Range<u32>> {
58        match &self.inner {
59            NameComponentInner::SourceIdentifierToken(t) => Some(convert_span(t.span)),
60            _ => None,
61        }
62    }
63
64    pub(crate) fn interp(s: impl Into<Cow<'static, str>>) -> Self {
65        Self {
66            inner: NameComponentInner::Interpolation(s.into()),
67        }
68    }
69    pub(crate) fn ident(ident: ast::Ident) -> Self {
70        Self {
71            inner: NameComponentInner::SourceIdentifierToken(ident),
72        }
73    }
74}
75
76#[derive(Debug)]
77pub(crate) enum NameComponentInner {
78    Interpolation(Cow<'static, str>),
79    SourceIdentifierToken(ast::Ident),
80}