mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(traverse)!: replace find_scope with ancestor_scopes returning iterator (#4693)
Same as #4692. Replace `find_scope` and `find_scope_by_flags` with `ancestor_scopes ` method which returns an iterator. This does the same thing, but is more idiomatic.
This commit is contained in:
parent
506709f51d
commit
75f22072be
4 changed files with 17 additions and 94 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
use oxc_diagnostics::OxcDiagnostic;
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
use oxc_span::{Span, SPAN};
|
use oxc_span::{Span, SPAN};
|
||||||
use oxc_traverse::{Ancestor, FinderRet, TraverseCtx};
|
use oxc_traverse::{Ancestor, TraverseCtx};
|
||||||
|
|
||||||
use crate::context::Ctx;
|
use crate::context::Ctx;
|
||||||
|
|
||||||
|
|
@ -44,13 +44,14 @@ impl<'a> ReactJsxSelf<'a> {
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
fn is_inside_constructor(&self, ctx: &TraverseCtx<'a>) -> bool {
|
fn is_inside_constructor(&self, ctx: &TraverseCtx<'a>) -> bool {
|
||||||
ctx.find_scope_by_flags(|flags| {
|
for scope_id in ctx.ancestor_scopes() {
|
||||||
|
let flags = ctx.scopes().get_flags(scope_id);
|
||||||
if flags.is_block() || flags.is_arrow() {
|
if flags.is_block() || flags.is_arrow() {
|
||||||
return FinderRet::Continue;
|
continue;
|
||||||
}
|
}
|
||||||
FinderRet::Found(flags.is_constructor())
|
return flags.is_constructor();
|
||||||
})
|
}
|
||||||
.unwrap_or(false)
|
unreachable!(); // Always hit `Program` and exit before loop ends
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_no_super_class(ctx: &TraverseCtx<'a>) -> bool {
|
fn has_no_super_class(ctx: &TraverseCtx<'a>) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ pub use scoping::TraverseScoping;
|
||||||
/// Provides ability to:
|
/// Provides ability to:
|
||||||
/// * Query parent/ancestor of current node via [`parent`], [`ancestor`], [`ancestors`].
|
/// * Query parent/ancestor of current node via [`parent`], [`ancestor`], [`ancestors`].
|
||||||
/// * Get scopes tree and symbols table via [`scopes`], [`symbols`], [`scopes_mut`], [`symbols_mut`],
|
/// * Get scopes tree and symbols table via [`scopes`], [`symbols`], [`scopes_mut`], [`symbols_mut`],
|
||||||
/// [`find_scope`], [`find_scope_by_flags`].
|
/// [`ancestor_scopes`].
|
||||||
/// * Create AST nodes via AST builder [`ast`].
|
/// * Create AST nodes via AST builder [`ast`].
|
||||||
/// * Allocate into arena via [`alloc`].
|
/// * Allocate into arena via [`alloc`].
|
||||||
///
|
///
|
||||||
|
|
@ -100,8 +100,7 @@ pub use scoping::TraverseScoping;
|
||||||
/// [`symbols`]: `TraverseCtx::symbols`
|
/// [`symbols`]: `TraverseCtx::symbols`
|
||||||
/// [`scopes_mut`]: `TraverseCtx::scopes_mut`
|
/// [`scopes_mut`]: `TraverseCtx::scopes_mut`
|
||||||
/// [`symbols_mut`]: `TraverseCtx::symbols_mut`
|
/// [`symbols_mut`]: `TraverseCtx::symbols_mut`
|
||||||
/// [`find_scope`]: `TraverseCtx::find_scope`
|
/// [`ancestor_scopes`]: `TraverseCtx::ancestor_scopes`
|
||||||
/// [`find_scope_by_flags`]: `TraverseCtx::find_scope_by_flags`
|
|
||||||
/// [`ast`]: `TraverseCtx::ast`
|
/// [`ast`]: `TraverseCtx::ast`
|
||||||
/// [`alloc`]: `TraverseCtx::alloc`
|
/// [`alloc`]: `TraverseCtx::alloc`
|
||||||
pub struct TraverseCtx<'a> {
|
pub struct TraverseCtx<'a> {
|
||||||
|
|
@ -110,13 +109,6 @@ pub struct TraverseCtx<'a> {
|
||||||
pub ast: AstBuilder<'a>,
|
pub ast: AstBuilder<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return value of closure when using [`TraverseCtx::find_scope`].
|
|
||||||
pub enum FinderRet<T> {
|
|
||||||
Found(T),
|
|
||||||
Stop,
|
|
||||||
Continue,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public methods
|
// Public methods
|
||||||
impl<'a> TraverseCtx<'a> {
|
impl<'a> TraverseCtx<'a> {
|
||||||
/// Create new traversal context.
|
/// Create new traversal context.
|
||||||
|
|
@ -223,38 +215,11 @@ impl<'a> TraverseCtx<'a> {
|
||||||
self.scoping.symbols_mut()
|
self.scoping.symbols_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walk up trail of scopes to find a scope.
|
/// Get iterator over scopes, starting with current scope and working up.
|
||||||
///
|
///
|
||||||
/// `finder` is called with `ScopeId`.
|
/// This is a shortcut for `ctx.scoping.parent_scopes`.
|
||||||
///
|
pub fn ancestor_scopes(&self) -> impl Iterator<Item = ScopeId> + '_ {
|
||||||
/// `finder` should return:
|
self.scoping.ancestor_scopes()
|
||||||
/// * `FinderRet::Found(value)` to stop walking and return `Some(value)`.
|
|
||||||
/// * `FinderRet::Stop` to stop walking and return `None`.
|
|
||||||
/// * `FinderRet::Continue` to continue walking up.
|
|
||||||
///
|
|
||||||
/// This is a shortcut for `ctx.scoping.find_scope`.
|
|
||||||
pub fn find_scope<F, O>(&self, finder: F) -> Option<O>
|
|
||||||
where
|
|
||||||
F: Fn(ScopeId) -> FinderRet<O>,
|
|
||||||
{
|
|
||||||
self.scoping.find_scope(finder)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walk up trail of scopes to find a scope by checking `ScopeFlags`.
|
|
||||||
///
|
|
||||||
/// `finder` is called with `ScopeFlags`.
|
|
||||||
///
|
|
||||||
/// `finder` should return:
|
|
||||||
/// * `FinderRet::Found(value)` to stop walking and return `Some(value)`.
|
|
||||||
/// * `FinderRet::Stop` to stop walking and return `None`.
|
|
||||||
/// * `FinderRet::Continue` to continue walking up.
|
|
||||||
///
|
|
||||||
/// This is a shortcut for `ctx.scoping.find_scope_by_flags`.
|
|
||||||
pub fn find_scope_by_flags<F, O>(&self, finder: F) -> Option<O>
|
|
||||||
where
|
|
||||||
F: Fn(ScopeFlags) -> FinderRet<O>,
|
|
||||||
{
|
|
||||||
self.scoping.find_scope_by_flags(finder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new scope as child of provided scope.
|
/// Create new scope as child of provided scope.
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ use oxc_syntax::{
|
||||||
symbol::{SymbolFlags, SymbolId},
|
symbol::{SymbolFlags, SymbolId},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::FinderRet;
|
|
||||||
|
|
||||||
/// Traverse scope context.
|
/// Traverse scope context.
|
||||||
///
|
///
|
||||||
/// Contains the scope tree and symbols table, and provides methods to access them.
|
/// Contains the scope tree and symbols table, and provides methods to access them.
|
||||||
|
|
@ -70,50 +68,9 @@ impl TraverseScoping {
|
||||||
&mut self.symbols
|
&mut self.symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walk up trail of scopes to find a scope.
|
/// Get iterator over scopes, starting with current scope and working up
|
||||||
///
|
pub fn ancestor_scopes(&self) -> impl Iterator<Item = ScopeId> + '_ {
|
||||||
/// `finder` is called with `ScopeId`.
|
self.scopes.ancestors(self.current_scope_id)
|
||||||
///
|
|
||||||
/// `finder` should return:
|
|
||||||
/// * `FinderRet::Found(value)` to stop walking and return `Some(value)`.
|
|
||||||
/// * `FinderRet::Stop` to stop walking and return `None`.
|
|
||||||
/// * `FinderRet::Continue` to continue walking up.
|
|
||||||
pub fn find_scope<F, O>(&self, finder: F) -> Option<O>
|
|
||||||
where
|
|
||||||
F: Fn(ScopeId) -> FinderRet<O>,
|
|
||||||
{
|
|
||||||
let mut scope_id = self.current_scope_id;
|
|
||||||
loop {
|
|
||||||
match finder(scope_id) {
|
|
||||||
FinderRet::Found(res) => return Some(res),
|
|
||||||
FinderRet::Stop => return None,
|
|
||||||
FinderRet::Continue => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(parent_scope_id) = self.scopes.get_parent_id(scope_id) {
|
|
||||||
scope_id = parent_scope_id;
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walk up trail of scopes to find a scope by checking `ScopeFlags`.
|
|
||||||
///
|
|
||||||
/// `finder` is called with `ScopeFlags`.
|
|
||||||
///
|
|
||||||
/// `finder` should return:
|
|
||||||
/// * `FinderRet::Found(value)` to stop walking and return `Some(value)`.
|
|
||||||
/// * `FinderRet::Stop` to stop walking and return `None`.
|
|
||||||
/// * `FinderRet::Continue` to continue walking up.
|
|
||||||
pub fn find_scope_by_flags<F, O>(&self, finder: F) -> Option<O>
|
|
||||||
where
|
|
||||||
F: Fn(ScopeFlags) -> FinderRet<O>,
|
|
||||||
{
|
|
||||||
self.find_scope(|scope_id| {
|
|
||||||
let flags = self.scopes.get_flags(scope_id);
|
|
||||||
finder(flags)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create new scope as child of provided scope.
|
/// Create new scope as child of provided scope.
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ use oxc_semantic::{ScopeTree, SymbolTable};
|
||||||
pub mod ancestor;
|
pub mod ancestor;
|
||||||
pub use ancestor::Ancestor;
|
pub use ancestor::Ancestor;
|
||||||
mod context;
|
mod context;
|
||||||
pub use context::{FinderRet, TraverseAncestry, TraverseCtx, TraverseScoping};
|
pub use context::{TraverseAncestry, TraverseCtx, TraverseScoping};
|
||||||
#[allow(clippy::module_inception)]
|
#[allow(clippy::module_inception)]
|
||||||
mod traverse;
|
mod traverse;
|
||||||
pub use traverse::Traverse;
|
pub use traverse::Traverse;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue