Repository: parcel-bundler/parcel
File: packages/transformers/js/core/src/collect.rs (Rust)

Code before:
        } else {
          member.visit_with(self);
        }
      }
      Expr::Ident(ident) => {
        if &*ident.sym == "exports" && !self.decls.contains(&id!(ident)) {
          handle_export!();
        } else if ident.sym == js_word!("module") && !self.decls.contains(&id!(ident)) {
          self.has_cjs_exports = true;
          self.static_cjs_exports = false;
          self.should_wrap = true;
          self.add_bailout(node.span, BailoutReason::FreeModule);
        } else if match_property_name(node).is_none() {
          self
            .non_static_access
            .entry(id!(ident))
            .or_default()
            .push(node.span);
        } else if self.imports.contains_key(&id!(ident)) {
          self.used_imports.insert(id!(ident));
        }
        return;
      }
      Expr::This(_this) => {
        if self.is_module {
          // Don't track this bindings if ESM syntax is present
          return;
        }

        if self.in_module_this {
          handle_export!();
        } else if !self.in_class {
          if let MemberProp::Ident(prop) = &node.prop {
            self.this_exprs.insert(id!(prop), (prop.clone(), node.span));
          }
        }
        return;
      }
      _ => {}
    }

    node.visit_children_with(self);
  }

  fn visit_unary_expr(&mut self, node: &UnaryExpr) {
    if node.op == UnaryOp::TypeOf {
      match &*node.arg {
        Expr::Ident(ident)
          if ident.sym == js_word!("module") && !self.decls.contains(&id!(ident)) =>
        {
          // Do nothing to avoid the ident visitor from marking the module as non-static.

Review comment (suggestion):
I think we might still have to track this_exprs in ESM (the second case below)? For example:

```js
export function a() {
  return this.b();
}

export function b() {
  return 2;
}
```

Looks like we only have a CJS test for that (in hoist.rs).

Code after:
        } else {
          member.visit_with(self);
        }
      }
      Expr::Ident(ident) => {
        if &*ident.sym == "exports" && !self.decls.contains(&id!(ident)) {
          handle_export!();
        } else if ident.sym == js_word!("module") && !self.decls.contains(&id!(ident)) {
          self.has_cjs_exports = true;
          self.static_cjs_exports = false;
          self.should_wrap = true;
          self.add_bailout(node.span, BailoutReason::FreeModule);
        } else if match_property_name(node).is_none() {
          self
            .non_static_access
            .entry(id!(ident))
            .or_default()
            .push(node.span);
        } else if self.imports.contains_key(&id!(ident)) {
          self.used_imports.insert(id!(ident));
        }
        return;
      }
      Expr::This(_this) => {
        if self.in_module_this {
          if !self.is_module {
            handle_export!();
          }
        } else if !self.in_class {
          if let MemberProp::Ident(prop) = &node.prop {
            self.this_exprs.insert(id!(prop), (prop.clone(), node.span));
          }
        }
        return;
      }
      _ => {}
    }

    node.visit_children_with(self);
  }

  fn visit_unary_expr(&mut self, node: &UnaryExpr) {
    if node.op == UnaryOp::TypeOf {
      match &*node.arg {
        Expr::Ident(ident)
          if ident.sym == js_word!("module") && !self.decls.contains(&id!(ident)) =>
        {
          // Do nothing to avoid the ident visitor from marking the module as non-static.
        }
        _ => node.visit_children_with(self),
      }