mirror of
https://github.com/swc-project/swc.git
synced 2024-11-22 06:46:41 +03:00
feat(visit): Add experimental traverse APIs (#9464)
Some checks are pending
CI / Cargo fmt (push) Waiting to run
CI / Cargo clippy (push) Waiting to run
CI / Check license of dependencies (push) Waiting to run
CI / Check (macos-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / Test wasm (binding_core_wasm) (push) Waiting to run
CI / Test wasm (binding_minifier_wasm) (push) Waiting to run
CI / Test wasm (binding_typescript_wasm) (push) Waiting to run
CI / List crates (push) Waiting to run
CI / Test - ${{ matrix.settings.crate }} - ${{ matrix.settings.os }} (push) Blocked by required conditions
CI / Test node bindings - ${{ matrix.os }} (macos-latest) (push) Waiting to run
CI / Test node bindings - ${{ matrix.os }} (windows-latest) (push) Waiting to run
CI / Test with @swc/cli (push) Waiting to run
CI / Miri (better_scoped_tls) (push) Waiting to run
CI / Miri (string_enum) (push) Waiting to run
CI / Miri (swc) (push) Waiting to run
CI / Miri (swc_bundler) (push) Waiting to run
CI / Miri (swc_ecma_codegen) (push) Waiting to run
CI / Miri (swc_ecma_minifier) (push) Waiting to run
CI / Done (push) Blocked by required conditions
Benchmark / Bench everything (push) Waiting to run
Some checks are pending
CI / Cargo fmt (push) Waiting to run
CI / Cargo clippy (push) Waiting to run
CI / Check license of dependencies (push) Waiting to run
CI / Check (macos-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / Test wasm (binding_core_wasm) (push) Waiting to run
CI / Test wasm (binding_minifier_wasm) (push) Waiting to run
CI / Test wasm (binding_typescript_wasm) (push) Waiting to run
CI / List crates (push) Waiting to run
CI / Test - ${{ matrix.settings.crate }} - ${{ matrix.settings.os }} (push) Blocked by required conditions
CI / Test node bindings - ${{ matrix.os }} (macos-latest) (push) Waiting to run
CI / Test node bindings - ${{ matrix.os }} (windows-latest) (push) Waiting to run
CI / Test with @swc/cli (push) Waiting to run
CI / Miri (better_scoped_tls) (push) Waiting to run
CI / Miri (string_enum) (push) Waiting to run
CI / Miri (swc) (push) Waiting to run
CI / Miri (swc_bundler) (push) Waiting to run
CI / Miri (swc_ecma_codegen) (push) Waiting to run
CI / Miri (swc_ecma_minifier) (push) Waiting to run
CI / Done (push) Blocked by required conditions
Benchmark / Bench everything (push) Waiting to run
This commit is contained in:
parent
a212ab0f2b
commit
3ee8980dbe
9
.changeset/shaggy-cats-promise.md
Normal file
9
.changeset/shaggy-cats-promise.md
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
swc_css_visit: patch
|
||||
swc_html_visit: patch
|
||||
swc_xml_visit: patch
|
||||
swc_ecma_visit: patch
|
||||
swc_core: patch
|
||||
---
|
||||
|
||||
feat(visit): Add experimental traverse APIs
|
@ -113036,8 +113036,9 @@ pub enum NodeRef<'ast> {
|
||||
WqName(&'ast WqName),
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" This is not a part of semver-stable API. It is experimental and subject to change."]
|
||||
#[allow(unreachable_patterns)]
|
||||
pub fn raw_children(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
pub fn experimental_raw_children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = NodeRef<'ast>>> {
|
||||
match self {
|
||||
NodeRef::AbsoluteColorBase(node) => match node {
|
||||
AbsoluteColorBase::HexColor(v0) => {
|
||||
@ -114614,5 +114615,23 @@ impl<'ast> NodeRef<'ast> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" Visit all nodes in self in preorder."]
|
||||
#[doc = r""]
|
||||
#[doc = r" This is not a part of semver-stable API. It is"]
|
||||
#[doc = r" experimental and subject to change."]
|
||||
pub fn experimental_traverse(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
let mut queue = std::collections::VecDeque::<NodeRef<'ast>>::new();
|
||||
queue.push_back(*self);
|
||||
Box::new(std::iter::from_fn(move || {
|
||||
let node: NodeRef<'ast> = queue.pop_front()?;
|
||||
{
|
||||
let children = node.experimental_raw_children();
|
||||
queue.extend(children);
|
||||
}
|
||||
Some(node)
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(any(docsrs, feature = "path"))]
|
||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||
|
@ -143163,8 +143163,9 @@ pub enum NodeRef<'ast> {
|
||||
YieldExpr(&'ast YieldExpr),
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" This is not a part of semver-stable API. It is experimental and subject to change."]
|
||||
#[allow(unreachable_patterns)]
|
||||
pub fn raw_children(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
pub fn experimental_raw_children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = NodeRef<'ast>>> {
|
||||
match self {
|
||||
NodeRef::Accessibility(node) => match node {
|
||||
_ => Box::new(::std::iter::empty::<NodeRef<'ast>>()),
|
||||
@ -145509,5 +145510,23 @@ impl<'ast> NodeRef<'ast> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" Visit all nodes in self in preorder."]
|
||||
#[doc = r""]
|
||||
#[doc = r" This is not a part of semver-stable API. It is"]
|
||||
#[doc = r" experimental and subject to change."]
|
||||
pub fn experimental_traverse(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
let mut queue = std::collections::VecDeque::<NodeRef<'ast>>::new();
|
||||
queue.push_back(*self);
|
||||
Box::new(std::iter::from_fn(move || {
|
||||
let node: NodeRef<'ast> = queue.pop_front()?;
|
||||
{
|
||||
let children = node.experimental_raw_children();
|
||||
queue.extend(children);
|
||||
}
|
||||
Some(node)
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(any(docsrs, feature = "path"))]
|
||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use swc_common::{chain, DUMMY_SP};
|
||||
use swc_ecma_ast::{Module, Program};
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{NodeRef, Visit, VisitWith};
|
||||
|
||||
#[test]
|
||||
fn should_visit_program() {
|
||||
@ -29,3 +29,30 @@ fn should_visit_program() {
|
||||
|
||||
assert_eq!(counter, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn traverse_lookup() {
|
||||
let node = Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Callee::Expr(
|
||||
AwaitExpr {
|
||||
span: DUMMY_SP,
|
||||
arg: Ident::new_no_ctxt("foo".into(), DUMMY_SP).into(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
args: Vec::new(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let node_ref = NodeRef::from(&node);
|
||||
let iter = node_ref.experimental_traverse();
|
||||
|
||||
let mut has_await = false;
|
||||
|
||||
for node in iter {
|
||||
has_await |= matches!(node, NodeRef::AwaitExpr(..));
|
||||
}
|
||||
|
||||
assert!(has_await);
|
||||
}
|
||||
|
@ -11289,8 +11289,9 @@ pub enum NodeRef<'ast> {
|
||||
TokenAndSpan(&'ast TokenAndSpan),
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" This is not a part of semver-stable API. It is experimental and subject to change."]
|
||||
#[allow(unreachable_patterns)]
|
||||
pub fn raw_children(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
pub fn experimental_raw_children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = NodeRef<'ast>>> {
|
||||
match self {
|
||||
NodeRef::Attribute(node) => {
|
||||
let iterator = ::std::iter::empty::<NodeRef<'ast>>().chain(
|
||||
@ -11381,5 +11382,23 @@ impl<'ast> NodeRef<'ast> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" Visit all nodes in self in preorder."]
|
||||
#[doc = r""]
|
||||
#[doc = r" This is not a part of semver-stable API. It is"]
|
||||
#[doc = r" experimental and subject to change."]
|
||||
pub fn experimental_traverse(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
let mut queue = std::collections::VecDeque::<NodeRef<'ast>>::new();
|
||||
queue.push_back(*self);
|
||||
Box::new(std::iter::from_fn(move || {
|
||||
let node: NodeRef<'ast> = queue.pop_front()?;
|
||||
{
|
||||
let children = node.experimental_raw_children();
|
||||
queue.extend(children);
|
||||
}
|
||||
Some(node)
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(any(docsrs, feature = "path"))]
|
||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||
|
@ -10857,8 +10857,9 @@ pub enum NodeRef<'ast> {
|
||||
TokenAndSpan(&'ast TokenAndSpan),
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" This is not a part of semver-stable API. It is experimental and subject to change."]
|
||||
#[allow(unreachable_patterns)]
|
||||
pub fn raw_children(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
pub fn experimental_raw_children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = NodeRef<'ast>>> {
|
||||
match self {
|
||||
NodeRef::Attribute(node) => {
|
||||
let iterator = ::std::iter::empty::<NodeRef<'ast>>().chain(
|
||||
@ -10942,5 +10943,23 @@ impl<'ast> NodeRef<'ast> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
#[doc = r" Visit all nodes in self in preorder."]
|
||||
#[doc = r""]
|
||||
#[doc = r" This is not a part of semver-stable API. It is"]
|
||||
#[doc = r" experimental and subject to change."]
|
||||
pub fn experimental_traverse(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
let mut queue = std::collections::VecDeque::<NodeRef<'ast>>::new();
|
||||
queue.push_back(*self);
|
||||
Box::new(std::iter::from_fn(move || {
|
||||
let node: NodeRef<'ast> = queue.pop_front()?;
|
||||
{
|
||||
let children = node.experimental_raw_children();
|
||||
queue.extend(children);
|
||||
}
|
||||
Some(node)
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(any(docsrs, feature = "path"))]
|
||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||
|
@ -1599,14 +1599,39 @@ fn define_fields(crate_name: &Ident, node_types: &[&Item]) -> Vec<Item> {
|
||||
));
|
||||
items.push(parse_quote!(
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
/// This is not a part of semver-stable API. It is experimental and subject to change.
|
||||
#[allow(unreachable_patterns)]
|
||||
pub fn raw_children(&'ast self) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
pub fn experimental_raw_children<'a>(&'a self) -> Box<dyn 'a + Iterator<Item = NodeRef<'ast>>> {
|
||||
match self {
|
||||
#(#node_ref_iter_next_arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
items.push(parse_quote!(
|
||||
impl<'ast> NodeRef<'ast> {
|
||||
/// Visit all nodes in self in preorder.
|
||||
///
|
||||
/// This is not a part of semver-stable API. It is
|
||||
/// experimental and subject to change.
|
||||
pub fn experimental_traverse(
|
||||
&'ast self,
|
||||
) -> Box<dyn 'ast + Iterator<Item = NodeRef<'ast>>> {
|
||||
let mut queue = std::collections::VecDeque::<NodeRef<'ast>>::new();
|
||||
queue.push_back(*self);
|
||||
|
||||
Box::new(std::iter::from_fn(move || {
|
||||
let node: NodeRef<'ast> = queue.pop_front()?;
|
||||
{
|
||||
let children = node.experimental_raw_children();
|
||||
queue.extend(children);
|
||||
}
|
||||
Some(node)
|
||||
}))
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
items.insert(
|
||||
|
Loading…
Reference in New Issue
Block a user