mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
perf(semantic): use Atom<'a> for References (#3972)
Relates to [this issue](https://github.com/oxc-project/backlog/issues/31) on the backlog.
This commit is contained in:
parent
0c81fbeac6
commit
1eac3d244d
12 changed files with 88 additions and 88 deletions
|
|
@ -66,7 +66,9 @@ impl Rule for NoGlobalAssign {
|
|||
let reference = symbol_table.get_reference(reference_id);
|
||||
if reference.is_write() {
|
||||
let name = reference.name();
|
||||
if !self.excludes.contains(name) && ctx.env_contains_var(name) {
|
||||
// Vec::contains isn't working here, but this has the same
|
||||
// effect and time complexity.
|
||||
if !self.excludes.iter().any(|e| e == name) && ctx.env_contains_var(name) {
|
||||
ctx.diagnostic(no_global_assign_diagnostic(name, reference.span()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ use oxc_span::CompactStr;
|
|||
type Slot = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mangler {
|
||||
symbol_table: SymbolTable,
|
||||
pub struct Mangler<'a> {
|
||||
symbol_table: SymbolTable<'a>,
|
||||
}
|
||||
|
||||
impl Mangler {
|
||||
impl<'a> Mangler<'a> {
|
||||
pub fn get_symbol_name(&self, symbol_id: SymbolId) -> &str {
|
||||
self.symbol_table.get_name(symbol_id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use oxc_cfg::{
|
|||
IterationInstructionKind, ReturnInstructionKind,
|
||||
};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_span::{CompactStr, SourceType, Span};
|
||||
use oxc_span::{Atom, CompactStr, SourceType, Span};
|
||||
use oxc_syntax::{module_record::ModuleRecord, operator::AssignmentOperator};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -63,8 +63,8 @@ pub struct SemanticBuilder<'a> {
|
|||
|
||||
// builders
|
||||
pub nodes: AstNodes<'a>,
|
||||
pub scope: ScopeTree,
|
||||
pub symbols: SymbolTable,
|
||||
pub scope: ScopeTree<'a>,
|
||||
pub symbols: SymbolTable<'a>,
|
||||
|
||||
pub(crate) module_record: Arc<ModuleRecord>,
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
|
||||
pub fn declare_reference(
|
||||
&mut self,
|
||||
reference: Reference,
|
||||
reference: Reference<'a>,
|
||||
add_unresolved_reference: bool,
|
||||
) -> ReferenceId {
|
||||
let reference_name = reference.name().clone();
|
||||
|
|
@ -327,7 +327,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
reference_id,
|
||||
);
|
||||
} else {
|
||||
self.resolve_reference_ids(reference_name.clone(), vec![reference_id]);
|
||||
self.resolve_reference_ids(reference_name, vec![reference_id]);
|
||||
}
|
||||
reference_id
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_reference_ids(&mut self, name: CompactStr, reference_ids: Vec<ReferenceId>) {
|
||||
fn resolve_reference_ids(&mut self, name: Atom<'a>, reference_ids: Vec<ReferenceId>) {
|
||||
let parent_scope_id =
|
||||
self.scope.get_parent_id(self.current_scope_id).unwrap_or(self.current_scope_id);
|
||||
|
||||
|
|
@ -1884,9 +1884,9 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn reference_identifier(&mut self, ident: &IdentifierReference) {
|
||||
fn reference_identifier(&mut self, ident: &IdentifierReference<'a>) {
|
||||
let flag = self.resolve_reference_usages();
|
||||
let name = ident.name.to_compact_str();
|
||||
let name = ident.name.clone();
|
||||
let reference = Reference::new(ident.span, name, self.current_node_id, flag);
|
||||
// `function foo({bar: identifier_reference}) {}`
|
||||
// ^^^^^^^^^^^^^^^^^^^^ Parameter initializer must be resolved immediately
|
||||
|
|
@ -1905,7 +1905,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn reference_jsx_identifier(&mut self, ident: &JSXIdentifier) {
|
||||
fn reference_jsx_identifier(&mut self, ident: &JSXIdentifier<'a>) {
|
||||
match self.nodes.parent_kind(self.current_node_id) {
|
||||
Some(AstKind::JSXElementName(_)) => {
|
||||
if !ident.name.chars().next().is_some_and(char::is_uppercase) {
|
||||
|
|
@ -1917,7 +1917,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
let reference = Reference::new(
|
||||
ident.span,
|
||||
ident.name.to_compact_str(),
|
||||
ident.name.clone(),
|
||||
self.current_node_id,
|
||||
ReferenceFlag::read(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ pub struct Semantic<'a> {
|
|||
|
||||
nodes: AstNodes<'a>,
|
||||
|
||||
scopes: ScopeTree,
|
||||
scopes: ScopeTree<'a>,
|
||||
|
||||
symbols: SymbolTable,
|
||||
symbols: SymbolTable<'a>,
|
||||
|
||||
classes: ClassTable,
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ pub struct Semantic<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Semantic<'a> {
|
||||
pub fn into_symbol_table_and_scope_tree(self) -> (SymbolTable, ScopeTree) {
|
||||
pub fn into_symbol_table_and_scope_tree(self) -> (SymbolTable<'a>, ScopeTree<'a>) {
|
||||
(self.symbols, self.scopes)
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ impl<'a> Semantic<'a> {
|
|||
&self.classes
|
||||
}
|
||||
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]`
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use oxc_span::{CompactStr, Span};
|
||||
use oxc_span::{Atom, Span};
|
||||
pub use oxc_syntax::reference::{ReferenceFlag, ReferenceId};
|
||||
#[cfg(feature = "serialize")]
|
||||
use serde::Serialize;
|
||||
|
|
@ -13,10 +13,10 @@ use crate::{symbol::SymbolId, AstNodeId};
|
|||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
|
||||
pub struct Reference {
|
||||
pub struct Reference<'a> {
|
||||
span: Span,
|
||||
/// The name of the identifier that was referred to
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
node_id: AstNodeId,
|
||||
symbol_id: Option<SymbolId>,
|
||||
/// Describes how this referenced is used by other AST nodes. References can
|
||||
|
|
@ -24,14 +24,14 @@ pub struct Reference {
|
|||
flag: ReferenceFlag,
|
||||
}
|
||||
|
||||
impl Reference {
|
||||
pub fn new(span: Span, name: CompactStr, node_id: AstNodeId, flag: ReferenceFlag) -> Self {
|
||||
impl<'a> Reference<'a> {
|
||||
pub fn new(span: Span, name: Atom<'a>, node_id: AstNodeId, flag: ReferenceFlag) -> Self {
|
||||
Self { span, name, node_id, symbol_id: None, flag }
|
||||
}
|
||||
|
||||
pub fn new_with_symbol_id(
|
||||
span: Span,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
node_id: AstNodeId,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
|
|
@ -43,7 +43,7 @@ impl Reference {
|
|||
self.span
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &CompactStr {
|
||||
pub fn name(&self) -> &Atom<'a> {
|
||||
&self.name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::hash::BuildHasherDefault;
|
|||
|
||||
use indexmap::IndexMap;
|
||||
use oxc_index::IndexVec;
|
||||
use oxc_span::CompactStr;
|
||||
use oxc_span::{Atom, CompactStr};
|
||||
pub use oxc_syntax::scope::{ScopeFlags, ScopeId};
|
||||
use rustc_hash::{FxHashMap, FxHasher};
|
||||
|
||||
|
|
@ -11,13 +11,13 @@ use crate::{reference::ReferenceId, symbol::SymbolId, AstNodeId};
|
|||
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
|
||||
|
||||
type Bindings = FxIndexMap<CompactStr, SymbolId>;
|
||||
type UnresolvedReferences = FxHashMap<CompactStr, Vec<ReferenceId>>;
|
||||
type UnresolvedReferences<'a> = FxHashMap<Atom<'a>, Vec<ReferenceId>>;
|
||||
|
||||
/// Scope Tree
|
||||
///
|
||||
/// `SoA` (Struct of Arrays) for memory efficiency.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ScopeTree {
|
||||
pub struct ScopeTree<'a> {
|
||||
/// Maps a scope to the parent scope it belongs in
|
||||
parent_ids: IndexVec<ScopeId, Option<ScopeId>>,
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ pub struct ScopeTree {
|
|||
node_ids: FxHashMap<ScopeId, AstNodeId>,
|
||||
flags: IndexVec<ScopeId, ScopeFlags>,
|
||||
bindings: IndexVec<ScopeId, Bindings>,
|
||||
unresolved_references: IndexVec<ScopeId, UnresolvedReferences>,
|
||||
unresolved_references: IndexVec<ScopeId, UnresolvedReferences<'a>>,
|
||||
}
|
||||
|
||||
impl ScopeTree {
|
||||
impl<'a> ScopeTree<'a> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.parent_ids.len()
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ impl ScopeTree {
|
|||
self.get_binding(self.root_scope_id(), name)
|
||||
}
|
||||
|
||||
pub fn add_root_unresolved_reference(&mut self, name: CompactStr, reference_id: ReferenceId) {
|
||||
pub fn add_root_unresolved_reference(&mut self, name: Atom<'a>, reference_id: ReferenceId) {
|
||||
self.add_unresolved_reference(self.root_scope_id(), name, reference_id);
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ impl ScopeTree {
|
|||
pub(crate) fn add_unresolved_reference(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
reference_id: ReferenceId,
|
||||
) {
|
||||
self.unresolved_references[scope_id].entry(name).or_default().push(reference_id);
|
||||
|
|
@ -217,7 +217,7 @@ impl ScopeTree {
|
|||
pub(crate) fn extend_unresolved_reference(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
reference_ids: Vec<ReferenceId>,
|
||||
) {
|
||||
self.unresolved_references[scope_id].entry(name).or_default().extend(reference_ids);
|
||||
|
|
@ -226,7 +226,7 @@ impl ScopeTree {
|
|||
pub(crate) fn unresolved_references_mut(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
) -> &mut UnresolvedReferences {
|
||||
) -> &mut UnresolvedReferences<'a> {
|
||||
&mut self.unresolved_references[scope_id]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export type IndexVec<I, T> = Array<T>;
|
|||
/// `SoA` (Struct of Arrays) for memory efficiency.
|
||||
#[derive(Debug, Default)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify), serde(rename_all = "camelCase"))]
|
||||
pub struct SymbolTable {
|
||||
pub struct SymbolTable<'a> {
|
||||
pub spans: IndexVec<SymbolId, Span>,
|
||||
pub names: IndexVec<SymbolId, CompactStr>,
|
||||
pub flags: IndexVec<SymbolId, SymbolFlags>,
|
||||
|
|
@ -36,11 +36,11 @@ pub struct SymbolTable {
|
|||
/// Pointer to the AST Node where this symbol is declared
|
||||
pub declarations: IndexVec<SymbolId, AstNodeId>,
|
||||
pub resolved_references: IndexVec<SymbolId, Vec<ReferenceId>>,
|
||||
pub references: IndexVec<ReferenceId, Reference>,
|
||||
pub references: IndexVec<ReferenceId, Reference<'a>>,
|
||||
pub redeclare_variables: IndexVec<SymbolId, Vec<Span>>,
|
||||
}
|
||||
|
||||
impl SymbolTable {
|
||||
impl<'a> SymbolTable<'a> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.spans.len()
|
||||
}
|
||||
|
|
@ -136,15 +136,15 @@ impl SymbolTable {
|
|||
self.redeclare_variables[symbol_id].push(span);
|
||||
}
|
||||
|
||||
pub fn create_reference(&mut self, reference: Reference) -> ReferenceId {
|
||||
pub fn create_reference(&mut self, reference: Reference<'a>) -> ReferenceId {
|
||||
self.references.push(reference)
|
||||
}
|
||||
|
||||
pub fn get_reference(&self, reference_id: ReferenceId) -> &Reference {
|
||||
pub fn get_reference(&self, reference_id: ReferenceId) -> &Reference<'a> {
|
||||
&self.references[reference_id]
|
||||
}
|
||||
|
||||
pub fn get_reference_mut(&mut self, reference_id: ReferenceId) -> &mut Reference {
|
||||
pub fn get_reference_mut(&mut self, reference_id: ReferenceId) -> &mut Reference<'a> {
|
||||
&mut self.references[reference_id]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,18 +110,24 @@ impl<'a> SymbolTester<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
// Note: can't use `Reference::is_read()` due to error warning about overly
|
||||
// generic FnMut impl.
|
||||
|
||||
#[must_use]
|
||||
pub fn has_number_of_reads(self, ref_count: usize) -> Self {
|
||||
self.has_number_of_references_where(ref_count, Reference::is_read)
|
||||
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||
self.has_number_of_references_where(ref_count, |r| r.is_read())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn has_number_of_writes(self, ref_count: usize) -> Self {
|
||||
self.has_number_of_references_where(ref_count, Reference::is_write)
|
||||
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||
self.has_number_of_references_where(ref_count, |r| r.is_write())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn has_number_of_references(self, ref_count: usize) -> Self {
|
||||
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||
self.has_number_of_references_where(ref_count, |_| true)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -986,8 +986,7 @@ fn get_read_identifier_reference<'a>(
|
|||
name: Atom<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id =
|
||||
ctx.create_reference_in_current_scope(name.to_compact_str(), ReferenceFlag::Read);
|
||||
let reference_id = ctx.create_reference_in_current_scope(name.clone(), ReferenceFlag::Read);
|
||||
IdentifierReference::new_read(span, name, Some(reference_id))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -540,11 +540,8 @@ struct Assignment<'a> {
|
|||
impl<'a> Assignment<'a> {
|
||||
// Creates `this.name = name`
|
||||
fn create_this_property_assignment(&self, ctx: &mut TraverseCtx<'a>) -> Statement<'a> {
|
||||
let reference_id = ctx.create_bound_reference(
|
||||
self.name.to_compact_str(),
|
||||
self.symbol_id,
|
||||
ReferenceFlag::Read,
|
||||
);
|
||||
let reference_id =
|
||||
ctx.create_bound_reference(self.name.clone(), self.symbol_id, ReferenceFlag::Read);
|
||||
let id = IdentifierReference::new_read(self.span, self.name.clone(), Some(reference_id));
|
||||
|
||||
ctx.ast.expression_statement(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use oxc_ast::{
|
|||
AstBuilder,
|
||||
};
|
||||
use oxc_semantic::{ScopeTree, SymbolTable};
|
||||
use oxc_span::{Atom, CompactStr, Span};
|
||||
use oxc_span::{Atom, Span};
|
||||
use oxc_syntax::{
|
||||
reference::{ReferenceFlag, ReferenceId},
|
||||
scope::{ScopeFlags, ScopeId},
|
||||
|
|
@ -106,7 +106,7 @@ pub use scoping::TraverseScoping;
|
|||
/// [`alloc`]: `TraverseCtx::alloc`
|
||||
pub struct TraverseCtx<'a> {
|
||||
pub ancestry: TraverseAncestry<'a>,
|
||||
pub scoping: TraverseScoping,
|
||||
pub scoping: TraverseScoping<'a>,
|
||||
pub ast: AstBuilder<'a>,
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,11 @@ pub enum FinderRet<T> {
|
|||
// Public methods
|
||||
impl<'a> TraverseCtx<'a> {
|
||||
/// Create new traversal context.
|
||||
pub(crate) fn new(scopes: ScopeTree, symbols: SymbolTable, allocator: &'a Allocator) -> Self {
|
||||
pub(crate) fn new(
|
||||
scopes: ScopeTree<'a>,
|
||||
symbols: SymbolTable<'a>,
|
||||
allocator: &'a Allocator,
|
||||
) -> Self {
|
||||
let ancestry = TraverseAncestry::new();
|
||||
let scoping = TraverseScoping::new(scopes, symbols);
|
||||
let ast = AstBuilder::new(allocator);
|
||||
|
|
@ -224,7 +228,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.scopes`.
|
||||
#[inline]
|
||||
pub fn scopes(&self) -> &ScopeTree {
|
||||
pub fn scopes(&self) -> &ScopeTree<'a> {
|
||||
self.scoping.scopes()
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +236,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.scopes_mut`.
|
||||
#[inline]
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
self.scoping.scopes_mut()
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +244,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.symbols`.
|
||||
#[inline]
|
||||
pub fn symbols(&self) -> &SymbolTable {
|
||||
pub fn symbols(&self) -> &SymbolTable<'a> {
|
||||
self.scoping.symbols()
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +252,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.symbols_mut`.
|
||||
#[inline]
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable {
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable<'a> {
|
||||
self.scoping.symbols_mut()
|
||||
}
|
||||
|
||||
|
|
@ -351,7 +355,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
/// This is a shortcut for `ctx.scoping.create_bound_reference`.
|
||||
pub fn create_bound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
|
|
@ -374,11 +378,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
/// Create an unbound reference.
|
||||
///
|
||||
/// This is a shortcut for `ctx.scoping.create_unbound_reference`.
|
||||
pub fn create_unbound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
pub fn create_unbound_reference(&mut self, name: Atom<'a>, flag: ReferenceFlag) -> ReferenceId {
|
||||
self.scoping.create_unbound_reference(name, flag)
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +402,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
/// This is a shortcut for `ctx.scoping.create_reference`.
|
||||
pub fn create_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
symbol_id: Option<SymbolId>,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
|
|
@ -430,7 +430,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
/// This is a shortcut for `ctx.scoping.create_reference_in_current_scope`.
|
||||
pub fn create_reference_in_current_scope(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
self.scoping.create_reference_in_current_scope(name, flag)
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ use super::FinderRet;
|
|||
///
|
||||
/// `current_scope_id` is the ID of current scope during traversal.
|
||||
/// `walk_*` functions update this field when entering/exiting a scope.
|
||||
pub struct TraverseScoping {
|
||||
scopes: ScopeTree,
|
||||
symbols: SymbolTable,
|
||||
pub struct TraverseScoping<'a> {
|
||||
scopes: ScopeTree<'a>,
|
||||
symbols: SymbolTable<'a>,
|
||||
current_scope_id: ScopeId,
|
||||
}
|
||||
|
||||
// Public methods
|
||||
impl TraverseScoping {
|
||||
impl<'a> TraverseScoping<'a> {
|
||||
/// Get current scope ID
|
||||
#[inline]
|
||||
pub fn current_scope_id(&self) -> ScopeId {
|
||||
|
|
@ -44,25 +44,25 @@ impl TraverseScoping {
|
|||
|
||||
/// Get scopes tree
|
||||
#[inline]
|
||||
pub fn scopes(&self) -> &ScopeTree {
|
||||
pub fn scopes(&self) -> &ScopeTree<'a> {
|
||||
&self.scopes
|
||||
}
|
||||
|
||||
/// Get mutable scopes tree
|
||||
#[inline]
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
/// Get symbols table
|
||||
#[inline]
|
||||
pub fn symbols(&self) -> &SymbolTable {
|
||||
pub fn symbols(&self) -> &SymbolTable<'a> {
|
||||
&self.symbols
|
||||
}
|
||||
|
||||
/// Get mutable symbols table
|
||||
#[inline]
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable {
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable<'a> {
|
||||
&mut self.symbols
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ impl TraverseScoping {
|
|||
/// Create a reference bound to a `SymbolId`
|
||||
pub fn create_bound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
|
|
@ -271,14 +271,14 @@ impl TraverseScoping {
|
|||
}
|
||||
|
||||
/// Create an `IdentifierReference` bound to a `SymbolId`
|
||||
pub fn create_bound_reference_id<'a>(
|
||||
pub fn create_bound_reference_id(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_bound_reference(name.to_compact_str(), symbol_id, flag);
|
||||
let reference_id = self.create_bound_reference(name.clone(), symbol_id, flag);
|
||||
IdentifierReference {
|
||||
span,
|
||||
name,
|
||||
|
|
@ -288,11 +288,7 @@ impl TraverseScoping {
|
|||
}
|
||||
|
||||
/// Create an unbound reference
|
||||
pub fn create_unbound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
pub fn create_unbound_reference(&mut self, name: Atom<'a>, flag: ReferenceFlag) -> ReferenceId {
|
||||
let reference = Reference::new(SPAN, name.clone(), AstNodeId::dummy(), flag);
|
||||
let reference_id = self.symbols.create_reference(reference);
|
||||
self.scopes.add_root_unresolved_reference(name, reference_id);
|
||||
|
|
@ -300,13 +296,13 @@ impl TraverseScoping {
|
|||
}
|
||||
|
||||
/// Create an unbound `IdentifierReference`
|
||||
pub fn create_unbound_reference_id<'a>(
|
||||
pub fn create_unbound_reference_id(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
flag: ReferenceFlag,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_unbound_reference(name.to_compact_str(), flag);
|
||||
let reference_id = self.create_unbound_reference(name.clone(), flag);
|
||||
IdentifierReference {
|
||||
span,
|
||||
name,
|
||||
|
|
@ -321,12 +317,12 @@ impl TraverseScoping {
|
|||
/// or `TraverseCtx::create_unbound_reference`.
|
||||
pub fn create_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
symbol_id: Option<SymbolId>,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
if let Some(symbol_id) = symbol_id {
|
||||
self.create_bound_reference(name, symbol_id, flag)
|
||||
self.create_bound_reference(name.clone(), symbol_id, flag)
|
||||
} else {
|
||||
self.create_unbound_reference(name, flag)
|
||||
}
|
||||
|
|
@ -336,7 +332,7 @@ impl TraverseScoping {
|
|||
///
|
||||
/// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_reference_id`
|
||||
/// or `TraverseCtx::create_unbound_reference_id`.
|
||||
pub fn create_reference_id<'a>(
|
||||
pub fn create_reference_id(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
|
|
@ -353,7 +349,7 @@ impl TraverseScoping {
|
|||
/// Create reference in current scope, looking up binding for `name`
|
||||
pub fn create_reference_in_current_scope(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
name: Atom<'a>,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
let symbol_id = self.scopes.find_binding(self.current_scope_id, name.as_str());
|
||||
|
|
@ -362,9 +358,9 @@ impl TraverseScoping {
|
|||
}
|
||||
|
||||
// Methods used internally within crate
|
||||
impl TraverseScoping {
|
||||
impl<'a> TraverseScoping<'a> {
|
||||
/// Create new `TraverseScoping`
|
||||
pub(super) fn new(scopes: ScopeTree, symbols: SymbolTable) -> Self {
|
||||
pub(super) fn new(scopes: ScopeTree<'a>, symbols: SymbolTable<'a>) -> Self {
|
||||
Self {
|
||||
scopes,
|
||||
symbols,
|
||||
|
|
|
|||
Loading…
Reference in a new issue