SD
SWC Developers•5mo ago
w00t

how can I mark a context?

I'm trying to mark a call expression for checking if I visited it later, but this doesn't print that it worked:
impl VisitMut for CleanMarker {
fn visit_mut_module_item(&mut self, node: &mut ast::ModuleItem) {
if let ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) = node {
match &*expr.expr {
ast::Expr::Call(e) => {
e.ctxt.apply_mark(self.mark);
println!("mark call expression {:?}", e.ctxt);
println!("has mark {:?}", e.ctxt.has_mark(self.mark));
}
_ => {}
}
}
}
}
impl VisitMut for CleanMarker {
fn visit_mut_module_item(&mut self, node: &mut ast::ModuleItem) {
if let ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) = node {
match &*expr.expr {
ast::Expr::Call(e) => {
e.ctxt.apply_mark(self.mark);
println!("mark call expression {:?}", e.ctxt);
println!("has mark {:?}", e.ctxt.has_mark(self.mark));
}
_ => {}
}
}
}
}
how can I make this work?
3 Replies
kdy1
kdy1•5mo ago
You can add a FxHashSet<Span> to your transformer struct and perform contains check.
w00t
w00tOP•5mo ago
I cannot make it work 😭 . Sorry I'm a Rust newbie. It doesn't let me use the same mutable hashset in two visitors. Any hints on how I could restructure this?
use std::collections::HashSet;
use swc_common::{Mark, Span, Spanned};
use swc_ecmascript::ast;
use swc_ecmascript::visit::VisitMut;

pub struct Treeshaker<'a> {
pub marker: CleanMarker<'a>,
pub cleaner: CleanSideEffects<'a>,
}

pub struct CleanSideEffects<'a> {
pub did_drop: bool,
pub set: &'a mut HashSet<Span>,
}

pub struct CleanMarker<'a> {
pub set: &'a mut HashSet<Span>,
}

impl Treeshaker<'_> {
pub fn new() -> Self {
let mut set = HashSet::new();
Self {
marker: CleanMarker { set: &mut set },
cleaner: CleanSideEffects {
did_drop: false,
set: &mut set,
},
}
}
}

impl VisitMut for CleanMarker<'_> {
fn visit_mut_module_item(&mut self, node: &mut ast::ModuleItem) {
if let ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) = node {
match &*expr.expr {
ast::Expr::New(e) => {
self.set.insert(e.span());
}
ast::Expr::Call(e) => {
self.set.insert(e.span());
}
_ => {}
}
}
}
}
use std::collections::HashSet;
use swc_common::{Mark, Span, Spanned};
use swc_ecmascript::ast;
use swc_ecmascript::visit::VisitMut;

pub struct Treeshaker<'a> {
pub marker: CleanMarker<'a>,
pub cleaner: CleanSideEffects<'a>,
}

pub struct CleanSideEffects<'a> {
pub did_drop: bool,
pub set: &'a mut HashSet<Span>,
}

pub struct CleanMarker<'a> {
pub set: &'a mut HashSet<Span>,
}

impl Treeshaker<'_> {
pub fn new() -> Self {
let mut set = HashSet::new();
Self {
marker: CleanMarker { set: &mut set },
cleaner: CleanSideEffects {
did_drop: false,
set: &mut set,
},
}
}
}

impl VisitMut for CleanMarker<'_> {
fn visit_mut_module_item(&mut self, node: &mut ast::ModuleItem) {
if let ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) = node {
match &*expr.expr {
ast::Expr::New(e) => {
self.set.insert(e.span());
}
ast::Expr::Call(e) => {
self.set.insert(e.span());
}
_ => {}
}
}
}
}
ctd
impl VisitMut for CleanSideEffects<'_> {
fn visit_mut_module(&mut self, node: &mut ast::Module) {
node.body.retain(|item| match item {
ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) => match &*expr.expr {
ast::Expr::New(e) => {
if self.set.contains(&e.span()) {
return true;
}
self.did_drop = true;
false
}
ast::Expr::Call(e) => {
if self.set.contains(&e.span()) {
return true;
}
self.did_drop = true;
false
}
_ => true,
},
_ => true,
});
}
}
impl VisitMut for CleanSideEffects<'_> {
fn visit_mut_module(&mut self, node: &mut ast::Module) {
node.body.retain(|item| match item {
ast::ModuleItem::Stmt(ast::Stmt::Expr(expr)) => match &*expr.expr {
ast::Expr::New(e) => {
if self.set.contains(&e.span()) {
return true;
}
self.did_drop = true;
false
}
ast::Expr::Call(e) => {
if self.set.contains(&e.span()) {
return true;
}
self.did_drop = true;
false
}
_ => true,
},
_ => true,
});
}
}
Me and copilot figured it out 😎 I'll drop the url soon

Did you find this page helpful?