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),
|
WqName(&'ast WqName),
|
||||||
}
|
}
|
||||||
impl<'ast> NodeRef<'ast> {
|
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)]
|
#[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 {
|
match self {
|
||||||
NodeRef::AbsoluteColorBase(node) => match node {
|
NodeRef::AbsoluteColorBase(node) => match node {
|
||||||
AbsoluteColorBase::HexColor(v0) => {
|
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"))]
|
#[cfg(any(docsrs, feature = "path"))]
|
||||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||||
|
@ -143163,8 +143163,9 @@ pub enum NodeRef<'ast> {
|
|||||||
YieldExpr(&'ast YieldExpr),
|
YieldExpr(&'ast YieldExpr),
|
||||||
}
|
}
|
||||||
impl<'ast> NodeRef<'ast> {
|
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)]
|
#[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 {
|
match self {
|
||||||
NodeRef::Accessibility(node) => match node {
|
NodeRef::Accessibility(node) => match node {
|
||||||
_ => Box::new(::std::iter::empty::<NodeRef<'ast>>()),
|
_ => 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"))]
|
#[cfg(any(docsrs, feature = "path"))]
|
||||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use swc_common::{chain, DUMMY_SP};
|
use swc_common::{chain, DUMMY_SP};
|
||||||
use swc_ecma_ast::{Module, Program};
|
use swc_ecma_ast::*;
|
||||||
use swc_ecma_visit::{Visit, VisitWith};
|
use swc_ecma_visit::{NodeRef, Visit, VisitWith};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_visit_program() {
|
fn should_visit_program() {
|
||||||
@ -29,3 +29,30 @@ fn should_visit_program() {
|
|||||||
|
|
||||||
assert_eq!(counter, 1);
|
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),
|
TokenAndSpan(&'ast TokenAndSpan),
|
||||||
}
|
}
|
||||||
impl<'ast> NodeRef<'ast> {
|
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)]
|
#[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 {
|
match self {
|
||||||
NodeRef::Attribute(node) => {
|
NodeRef::Attribute(node) => {
|
||||||
let iterator = ::std::iter::empty::<NodeRef<'ast>>().chain(
|
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"))]
|
#[cfg(any(docsrs, feature = "path"))]
|
||||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
||||||
|
@ -10857,8 +10857,9 @@ pub enum NodeRef<'ast> {
|
|||||||
TokenAndSpan(&'ast TokenAndSpan),
|
TokenAndSpan(&'ast TokenAndSpan),
|
||||||
}
|
}
|
||||||
impl<'ast> NodeRef<'ast> {
|
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)]
|
#[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 {
|
match self {
|
||||||
NodeRef::Attribute(node) => {
|
NodeRef::Attribute(node) => {
|
||||||
let iterator = ::std::iter::empty::<NodeRef<'ast>>().chain(
|
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"))]
|
#[cfg(any(docsrs, feature = "path"))]
|
||||||
pub use self::fields::{AstParentKind, AstParentNodeRef};
|
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!(
|
items.push(parse_quote!(
|
||||||
impl<'ast> NodeRef<'ast> {
|
impl<'ast> NodeRef<'ast> {
|
||||||
|
/// This is not a part of semver-stable API. It is experimental and subject to change.
|
||||||
#[allow(unreachable_patterns)]
|
#[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 {
|
match self {
|
||||||
#(#node_ref_iter_next_arms)*
|
#(#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(
|
items.insert(
|
||||||
|
Loading…
Reference in New Issue
Block a user