mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
Revert "perf(semantic): use Atom<'a> for References" (#3974)
Reverts oxc-project/oxc#3972 @DonIsaac As it turns out we can't have lifetimes on these structures because semantic data is exposed to downstream users to use freely, detached from the ast and allocator.
This commit is contained in:
parent
dbbb6fca56
commit
54c653ebd4
12 changed files with 88 additions and 88 deletions
|
|
@ -66,9 +66,7 @@ impl Rule for NoGlobalAssign {
|
|||
let reference = symbol_table.get_reference(reference_id);
|
||||
if reference.is_write() {
|
||||
let name = reference.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) {
|
||||
if !self.excludes.contains(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<'a> {
|
||||
symbol_table: SymbolTable<'a>,
|
||||
pub struct Mangler {
|
||||
symbol_table: SymbolTable,
|
||||
}
|
||||
|
||||
impl<'a> Mangler<'a> {
|
||||
impl Mangler {
|
||||
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::{Atom, CompactStr, SourceType, Span};
|
||||
use oxc_span::{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<'a>,
|
||||
pub symbols: SymbolTable<'a>,
|
||||
pub scope: ScopeTree,
|
||||
pub symbols: SymbolTable,
|
||||
|
||||
pub(crate) module_record: Arc<ModuleRecord>,
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
|
||||
pub fn declare_reference(
|
||||
&mut self,
|
||||
reference: Reference<'a>,
|
||||
reference: Reference,
|
||||
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, vec![reference_id]);
|
||||
self.resolve_reference_ids(reference_name.clone(), vec![reference_id]);
|
||||
}
|
||||
reference_id
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_reference_ids(&mut self, name: Atom<'a>, reference_ids: Vec<ReferenceId>) {
|
||||
fn resolve_reference_ids(&mut self, name: CompactStr, 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<'a>) {
|
||||
fn reference_identifier(&mut self, ident: &IdentifierReference) {
|
||||
let flag = self.resolve_reference_usages();
|
||||
let name = ident.name.clone();
|
||||
let name = ident.name.to_compact_str();
|
||||
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<'a>) {
|
||||
fn reference_jsx_identifier(&mut self, ident: &JSXIdentifier) {
|
||||
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.clone(),
|
||||
ident.name.to_compact_str(),
|
||||
self.current_node_id,
|
||||
ReferenceFlag::read(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ pub struct Semantic<'a> {
|
|||
|
||||
nodes: AstNodes<'a>,
|
||||
|
||||
scopes: ScopeTree<'a>,
|
||||
scopes: ScopeTree,
|
||||
|
||||
symbols: SymbolTable<'a>,
|
||||
symbols: SymbolTable,
|
||||
|
||||
classes: ClassTable,
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ pub struct Semantic<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Semantic<'a> {
|
||||
pub fn into_symbol_table_and_scope_tree(self) -> (SymbolTable<'a>, ScopeTree<'a>) {
|
||||
pub fn into_symbol_table_and_scope_tree(self) -> (SymbolTable, ScopeTree) {
|
||||
(self.symbols, self.scopes)
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ impl<'a> Semantic<'a> {
|
|||
&self.classes
|
||||
}
|
||||
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Silence erroneous warnings from Rust Analyser for `#[derive(Tsify)]`
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use oxc_span::{Atom, Span};
|
||||
use oxc_span::{CompactStr, 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<'a> {
|
||||
pub struct Reference {
|
||||
span: Span,
|
||||
/// The name of the identifier that was referred to
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
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<'a> {
|
|||
flag: ReferenceFlag,
|
||||
}
|
||||
|
||||
impl<'a> Reference<'a> {
|
||||
pub fn new(span: Span, name: Atom<'a>, node_id: AstNodeId, flag: ReferenceFlag) -> Self {
|
||||
impl Reference {
|
||||
pub fn new(span: Span, name: CompactStr, node_id: AstNodeId, flag: ReferenceFlag) -> Self {
|
||||
Self { span, name, node_id, symbol_id: None, flag }
|
||||
}
|
||||
|
||||
pub fn new_with_symbol_id(
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
node_id: AstNodeId,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
|
|
@ -43,7 +43,7 @@ impl<'a> Reference<'a> {
|
|||
self.span
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &Atom<'a> {
|
||||
pub fn name(&self) -> &CompactStr {
|
||||
&self.name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::hash::BuildHasherDefault;
|
|||
|
||||
use indexmap::IndexMap;
|
||||
use oxc_index::IndexVec;
|
||||
use oxc_span::{Atom, CompactStr};
|
||||
use oxc_span::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<'a> = FxHashMap<Atom<'a>, Vec<ReferenceId>>;
|
||||
type UnresolvedReferences = FxHashMap<CompactStr, Vec<ReferenceId>>;
|
||||
|
||||
/// Scope Tree
|
||||
///
|
||||
/// `SoA` (Struct of Arrays) for memory efficiency.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ScopeTree<'a> {
|
||||
pub struct ScopeTree {
|
||||
/// Maps a scope to the parent scope it belongs in
|
||||
parent_ids: IndexVec<ScopeId, Option<ScopeId>>,
|
||||
|
||||
|
|
@ -27,10 +27,10 @@ pub struct ScopeTree<'a> {
|
|||
node_ids: FxHashMap<ScopeId, AstNodeId>,
|
||||
flags: IndexVec<ScopeId, ScopeFlags>,
|
||||
bindings: IndexVec<ScopeId, Bindings>,
|
||||
unresolved_references: IndexVec<ScopeId, UnresolvedReferences<'a>>,
|
||||
unresolved_references: IndexVec<ScopeId, UnresolvedReferences>,
|
||||
}
|
||||
|
||||
impl<'a> ScopeTree<'a> {
|
||||
impl ScopeTree {
|
||||
pub fn len(&self) -> usize {
|
||||
self.parent_ids.len()
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ impl<'a> ScopeTree<'a> {
|
|||
self.get_binding(self.root_scope_id(), name)
|
||||
}
|
||||
|
||||
pub fn add_root_unresolved_reference(&mut self, name: Atom<'a>, reference_id: ReferenceId) {
|
||||
pub fn add_root_unresolved_reference(&mut self, name: CompactStr, reference_id: ReferenceId) {
|
||||
self.add_unresolved_reference(self.root_scope_id(), name, reference_id);
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ impl<'a> ScopeTree<'a> {
|
|||
pub(crate) fn add_unresolved_reference(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
reference_id: ReferenceId,
|
||||
) {
|
||||
self.unresolved_references[scope_id].entry(name).or_default().push(reference_id);
|
||||
|
|
@ -217,7 +217,7 @@ impl<'a> ScopeTree<'a> {
|
|||
pub(crate) fn extend_unresolved_reference(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
reference_ids: Vec<ReferenceId>,
|
||||
) {
|
||||
self.unresolved_references[scope_id].entry(name).or_default().extend(reference_ids);
|
||||
|
|
@ -226,7 +226,7 @@ impl<'a> ScopeTree<'a> {
|
|||
pub(crate) fn unresolved_references_mut(
|
||||
&mut self,
|
||||
scope_id: ScopeId,
|
||||
) -> &mut UnresolvedReferences<'a> {
|
||||
) -> &mut UnresolvedReferences {
|
||||
&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<'a> {
|
||||
pub struct SymbolTable {
|
||||
pub spans: IndexVec<SymbolId, Span>,
|
||||
pub names: IndexVec<SymbolId, CompactStr>,
|
||||
pub flags: IndexVec<SymbolId, SymbolFlags>,
|
||||
|
|
@ -36,11 +36,11 @@ pub struct SymbolTable<'a> {
|
|||
/// 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<'a>>,
|
||||
pub references: IndexVec<ReferenceId, Reference>,
|
||||
pub redeclare_variables: IndexVec<SymbolId, Vec<Span>>,
|
||||
}
|
||||
|
||||
impl<'a> SymbolTable<'a> {
|
||||
impl SymbolTable {
|
||||
pub fn len(&self) -> usize {
|
||||
self.spans.len()
|
||||
}
|
||||
|
|
@ -136,15 +136,15 @@ impl<'a> SymbolTable<'a> {
|
|||
self.redeclare_variables[symbol_id].push(span);
|
||||
}
|
||||
|
||||
pub fn create_reference(&mut self, reference: Reference<'a>) -> ReferenceId {
|
||||
pub fn create_reference(&mut self, reference: Reference) -> ReferenceId {
|
||||
self.references.push(reference)
|
||||
}
|
||||
|
||||
pub fn get_reference(&self, reference_id: ReferenceId) -> &Reference<'a> {
|
||||
pub fn get_reference(&self, reference_id: ReferenceId) -> &Reference {
|
||||
&self.references[reference_id]
|
||||
}
|
||||
|
||||
pub fn get_reference_mut(&mut self, reference_id: ReferenceId) -> &mut Reference<'a> {
|
||||
pub fn get_reference_mut(&mut self, reference_id: ReferenceId) -> &mut Reference {
|
||||
&mut self.references[reference_id]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,24 +110,18 @@ 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 {
|
||||
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||
self.has_number_of_references_where(ref_count, |r| r.is_read())
|
||||
self.has_number_of_references_where(ref_count, Reference::is_read)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn has_number_of_writes(self, ref_count: usize) -> Self {
|
||||
#[allow(clippy::redundant_closure_for_method_calls)]
|
||||
self.has_number_of_references_where(ref_count, |r| r.is_write())
|
||||
self.has_number_of_references_where(ref_count, Reference::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,7 +986,8 @@ 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.clone(), ReferenceFlag::Read);
|
||||
let reference_id =
|
||||
ctx.create_reference_in_current_scope(name.to_compact_str(), ReferenceFlag::Read);
|
||||
IdentifierReference::new_read(span, name, Some(reference_id))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -540,8 +540,11 @@ 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.clone(), self.symbol_id, ReferenceFlag::Read);
|
||||
let reference_id = ctx.create_bound_reference(
|
||||
self.name.to_compact_str(),
|
||||
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, Span};
|
||||
use oxc_span::{Atom, CompactStr, 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<'a>,
|
||||
pub scoping: TraverseScoping,
|
||||
pub ast: AstBuilder<'a>,
|
||||
}
|
||||
|
||||
|
|
@ -120,11 +120,7 @@ pub enum FinderRet<T> {
|
|||
// Public methods
|
||||
impl<'a> TraverseCtx<'a> {
|
||||
/// Create new traversal context.
|
||||
pub(crate) fn new(
|
||||
scopes: ScopeTree<'a>,
|
||||
symbols: SymbolTable<'a>,
|
||||
allocator: &'a Allocator,
|
||||
) -> Self {
|
||||
pub(crate) fn new(scopes: ScopeTree, symbols: SymbolTable, allocator: &'a Allocator) -> Self {
|
||||
let ancestry = TraverseAncestry::new();
|
||||
let scoping = TraverseScoping::new(scopes, symbols);
|
||||
let ast = AstBuilder::new(allocator);
|
||||
|
|
@ -228,7 +224,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.scopes`.
|
||||
#[inline]
|
||||
pub fn scopes(&self) -> &ScopeTree<'a> {
|
||||
pub fn scopes(&self) -> &ScopeTree {
|
||||
self.scoping.scopes()
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +232,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.scopes_mut`.
|
||||
#[inline]
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
self.scoping.scopes_mut()
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +240,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.symbols`.
|
||||
#[inline]
|
||||
pub fn symbols(&self) -> &SymbolTable<'a> {
|
||||
pub fn symbols(&self) -> &SymbolTable {
|
||||
self.scoping.symbols()
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +248,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
///
|
||||
/// Shortcut for `ctx.scoping.symbols_mut`.
|
||||
#[inline]
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable<'a> {
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable {
|
||||
self.scoping.symbols_mut()
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +351,7 @@ impl<'a> TraverseCtx<'a> {
|
|||
/// This is a shortcut for `ctx.scoping.create_bound_reference`.
|
||||
pub fn create_bound_reference(
|
||||
&mut self,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
|
|
@ -378,7 +374,11 @@ 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: Atom<'a>, flag: ReferenceFlag) -> ReferenceId {
|
||||
pub fn create_unbound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
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: Atom<'a>,
|
||||
name: CompactStr,
|
||||
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: Atom<'a>,
|
||||
name: CompactStr,
|
||||
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<'a> {
|
||||
scopes: ScopeTree<'a>,
|
||||
symbols: SymbolTable<'a>,
|
||||
pub struct TraverseScoping {
|
||||
scopes: ScopeTree,
|
||||
symbols: SymbolTable,
|
||||
current_scope_id: ScopeId,
|
||||
}
|
||||
|
||||
// Public methods
|
||||
impl<'a> TraverseScoping<'a> {
|
||||
impl TraverseScoping {
|
||||
/// Get current scope ID
|
||||
#[inline]
|
||||
pub fn current_scope_id(&self) -> ScopeId {
|
||||
|
|
@ -44,25 +44,25 @@ impl<'a> TraverseScoping<'a> {
|
|||
|
||||
/// Get scopes tree
|
||||
#[inline]
|
||||
pub fn scopes(&self) -> &ScopeTree<'a> {
|
||||
pub fn scopes(&self) -> &ScopeTree {
|
||||
&self.scopes
|
||||
}
|
||||
|
||||
/// Get mutable scopes tree
|
||||
#[inline]
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree<'a> {
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
/// Get symbols table
|
||||
#[inline]
|
||||
pub fn symbols(&self) -> &SymbolTable<'a> {
|
||||
pub fn symbols(&self) -> &SymbolTable {
|
||||
&self.symbols
|
||||
}
|
||||
|
||||
/// Get mutable symbols table
|
||||
#[inline]
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable<'a> {
|
||||
pub fn symbols_mut(&mut self) -> &mut SymbolTable {
|
||||
&mut self.symbols
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ impl<'a> TraverseScoping<'a> {
|
|||
/// Create a reference bound to a `SymbolId`
|
||||
pub fn create_bound_reference(
|
||||
&mut self,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
|
|
@ -271,14 +271,14 @@ impl<'a> TraverseScoping<'a> {
|
|||
}
|
||||
|
||||
/// Create an `IdentifierReference` bound to a `SymbolId`
|
||||
pub fn create_bound_reference_id(
|
||||
pub fn create_bound_reference_id<'a>(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
symbol_id: SymbolId,
|
||||
flag: ReferenceFlag,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_bound_reference(name.clone(), symbol_id, flag);
|
||||
let reference_id = self.create_bound_reference(name.to_compact_str(), symbol_id, flag);
|
||||
IdentifierReference {
|
||||
span,
|
||||
name,
|
||||
|
|
@ -288,7 +288,11 @@ impl<'a> TraverseScoping<'a> {
|
|||
}
|
||||
|
||||
/// Create an unbound reference
|
||||
pub fn create_unbound_reference(&mut self, name: Atom<'a>, flag: ReferenceFlag) -> ReferenceId {
|
||||
pub fn create_unbound_reference(
|
||||
&mut self,
|
||||
name: CompactStr,
|
||||
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);
|
||||
|
|
@ -296,13 +300,13 @@ impl<'a> TraverseScoping<'a> {
|
|||
}
|
||||
|
||||
/// Create an unbound `IdentifierReference`
|
||||
pub fn create_unbound_reference_id(
|
||||
pub fn create_unbound_reference_id<'a>(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
flag: ReferenceFlag,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_unbound_reference(name.clone(), flag);
|
||||
let reference_id = self.create_unbound_reference(name.to_compact_str(), flag);
|
||||
IdentifierReference {
|
||||
span,
|
||||
name,
|
||||
|
|
@ -317,12 +321,12 @@ impl<'a> TraverseScoping<'a> {
|
|||
/// or `TraverseCtx::create_unbound_reference`.
|
||||
pub fn create_reference(
|
||||
&mut self,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
symbol_id: Option<SymbolId>,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
if let Some(symbol_id) = symbol_id {
|
||||
self.create_bound_reference(name.clone(), symbol_id, flag)
|
||||
self.create_bound_reference(name, symbol_id, flag)
|
||||
} else {
|
||||
self.create_unbound_reference(name, flag)
|
||||
}
|
||||
|
|
@ -332,7 +336,7 @@ impl<'a> TraverseScoping<'a> {
|
|||
///
|
||||
/// 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(
|
||||
pub fn create_reference_id<'a>(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom<'a>,
|
||||
|
|
@ -349,7 +353,7 @@ impl<'a> TraverseScoping<'a> {
|
|||
/// Create reference in current scope, looking up binding for `name`
|
||||
pub fn create_reference_in_current_scope(
|
||||
&mut self,
|
||||
name: Atom<'a>,
|
||||
name: CompactStr,
|
||||
flag: ReferenceFlag,
|
||||
) -> ReferenceId {
|
||||
let symbol_id = self.scopes.find_binding(self.current_scope_id, name.as_str());
|
||||
|
|
@ -358,9 +362,9 @@ impl<'a> TraverseScoping<'a> {
|
|||
}
|
||||
|
||||
// Methods used internally within crate
|
||||
impl<'a> TraverseScoping<'a> {
|
||||
impl TraverseScoping {
|
||||
/// Create new `TraverseScoping`
|
||||
pub(super) fn new(scopes: ScopeTree<'a>, symbols: SymbolTable<'a>) -> Self {
|
||||
pub(super) fn new(scopes: ScopeTree, symbols: SymbolTable) -> Self {
|
||||
Self {
|
||||
scopes,
|
||||
symbols,
|
||||
|
|
|
|||
Loading…
Reference in a new issue