Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visitor for stable rust #743

Merged
merged 32 commits into from
Apr 2, 2020
Merged

Visitor for stable rust #743

merged 32 commits into from
Apr 2, 2020

Conversation

kdy1
Copy link
Member

@kdy1 kdy1 commented Apr 1, 2020

I've implemented a Visitor for stable rustc.
The implementation is naive, but it works.

Generated code looks like

pub trait Visit {
   #[allow(unused_variables)]
    fn visit_array_lit(&self, n: &ArrayLit, _parent: &dyn Node) {
        match n {
            ArrayLit { span, elems } => {
                self.visit_span(&*span, n as _);
                self.visit_opt_vec_expr_or_spreads(&*elems, n as _);
            }
        }
    }
    // .. LOTS of generated methods
    #[allow(unused_variables)]
    fn visit_decl(&self, n: &Decl, _parent: &dyn Node) {
        match n {
            Decl::Class { 0: _0 } => {
                self.visit_class_decl(&*_0, n as _);
            }
            Decl::Fn { 0: _0 } => {
                self.visit_fn_decl(&*_0, n as _);
            }
            Decl::Var { 0: _0 } => {
                self.visit_var_decl(&*_0, n as _);
            }
            Decl::TsInterface { 0: _0 } => {
                self.visit_ts_interface_decl(&*_0, n as _);
            }
            Decl::TsTypeAlias { 0: _0 } => {
                self.visit_ts_type_alias_decl(&*_0, n as _);
            }
            Decl::TsEnum { 0: _0 } => {
                self.visit_ts_enum_decl(&*_0, n as _);
            }
            Decl::TsModule { 0: _0 } => {
                self.visit_ts_module_decl(&*_0, n as _);
            }
        }
    }
     // .. LOTS of generated methods
}

where Node is declared as

pub trait Node: Any {}
impl<T: ?Sized> Node for T where T: Any {}

cc @ry @bartlomieju

@kdy1 kdy1 added this to the v1.1.38 milestone Apr 1, 2020
@kdy1 kdy1 self-assigned this Apr 1, 2020
@bartlomieju
Copy link
Contributor

@kdy1 I tried Visit in local checkout of your branch, a few questions arise:
Say I want to override some method to do custom processing:

impl Visit for LintContext {
  fn visit_module(&self, module: &Module, parent: &dyn Node) {
    assert!(self.scope_stack.is_empty());

    let module_node = Box::new(AstNode::Module(module.clone()));
    let current_scope = self.get_current_scope();

    let module_scope = Rc::new(RefCell::new(Scope::new(
      module_node.clone(),
      ScopeKind::Module,
      Some(current_scope.clone()),
    )));

    // Entering module scope
    self.scope_stack.push(module_scope);

    // Call default implementation and walk children
    // NOTE: this doesn't work 
    Visit::visit_module(self, module, parent);

    // Exiting module scope
    self.scope_stack.pop();
  }
}

How do I go about calling default implementation of visit_module(AFAIK that's not possible in Rust)?
Is it possible to do something like self.visit_children(module)?

@kdy1
Copy link
Member Author

kdy1 commented Apr 1, 2020

@bartlomieju It can be solved by extracting default behavior as a function.

It would be like

pub trait Visit {
    fn visit_module(&mut self, n: &Module, parent: &dyn Node) {
        visit_module(self, n, parent)
    }
}

pub fn visit_module<V>(v: &mut V, module: &Module, parent: &Node) {
     // default implementation lives here
}

I'll do it tomorrow (well, actually it's today for me as it's over 12pm).

@bartlomieju
Copy link
Contributor

@kdy1 awesome, thank you!

@kdy1
Copy link
Member Author

kdy1 commented Apr 2, 2020

@bartlomieju I did it. Can you check it, please?

@bartlomieju
Copy link
Contributor

@kdy1 any chance you could release it today?

@kdy1 kdy1 merged commit b279e7a into swc-project:master Apr 2, 2020
@kdy1 kdy1 deleted the visitor branch April 2, 2020 09:43
@kdy1
Copy link
Member Author

kdy1 commented Apr 2, 2020

@bartlomieju I published it.

@bartlomieju
Copy link
Contributor

@kdy1 kudos!

@swc-project swc-project locked as resolved and limited conversation to collaborators Nov 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants