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

Code before:
  pub diagnostics: &'a mut Vec<Diagnostic>,
}

impl<'a> Fold for EnvReplacer<'a> {
  fn fold_expr(&mut self, node: Expr) -> Expr {
    // Replace assignments to process.browser with `true`
    // TODO: this seems questionable but we did it in the JS version??
    if let Expr::Assign(ref assign) = node {
      if let PatOrExpr::Pat(ref pat) = assign.left {
        if let Pat::Expr(ref expr) = &**pat {
          if let Expr::Member(ref member) = &**expr {
            if self.is_browser && match_member_expr(member, vec!["process", "browser"], self.decls)
            {
              let mut res = assign.clone();
              res.right = Box::new(Expr::Lit(Lit::Bool(Bool {
                value: true,
                span: DUMMY_SP,
              })));
              return Expr::Assign(res);
            }
          }
        }
      }
    }

    if let Expr::Bin(ref binary) = node {
      if let Expr::Member(ref member) = &*binary.right {
        if let Expr::Lit(Lit::Str(ref left)) = &*binary.left {
          if let Expr::Ident(ref ident) = &*member.obj {
            if !self.decls.contains(&id!(ident)) && &ident.sym == "process" {
              if let MemberProp::Ident(ref prop) = member.prop {
                if &prop.sym == "env" {
                  return Expr::Lit(Lit::Bool(Bool {
                    value: self.env.contains_key(&left.value),
                    span: DUMMY_SP,
                  }));
                }
              }
            }
          }
        }
      }
    }

    if let Expr::Member(ref member) = node {
      if self.is_browser && match_member_expr(member, vec!["process", "browser"], self.decls) {
        return Expr::Lit(Lit::Bool(Bool {
          value: true,
          span: DUMMY_SP,
        }));
      }

Review comment (suggestion):
We should probably check that the binary expression is actually an `in`. There are other binary expression operators that shouldn't be replaced.

Code after:
}

impl<'a> Fold for EnvReplacer<'a> {
  fn fold_expr(&mut self, node: Expr) -> Expr {
    // Replace assignments to process.browser with `true`
    // TODO: this seems questionable but we did it in the JS version??
    if let Expr::Assign(ref assign) = node {
      if let PatOrExpr::Pat(ref pat) = assign.left {
        if let Pat::Expr(ref expr) = &**pat {
          if let Expr::Member(ref member) = &**expr {
            if self.is_browser && match_member_expr(member, vec!["process", "browser"], self.decls)
            {
              let mut res = assign.clone();
              res.right = Box::new(Expr::Lit(Lit::Bool(Bool {
                value: true,
                span: DUMMY_SP,
              })));
              return Expr::Assign(res);
            }
          }
        }
      }
    }

    // Replace `'foo' in process.env` with a boolean.
    match &node {
      Expr::Bin(binary) if binary.op == BinaryOp::In => {
        if let (Expr::Lit(Lit::Str(left)), Expr::Member(member)) = (&*binary.left, &*binary.right) {
          if match_member_expr(member, vec!["process", "env"], self.decls) {
            return Expr::Lit(Lit::Bool(Bool {
              value: self.env.contains_key(&left.value),
              span: DUMMY_SP,
            }));
          }
        }
      }
      _ => {}
    }

    if let Expr::Member(ref member) = node {
      if self.is_browser && match_member_expr(member, vec!["process", "browser"], self.decls) {
        return Expr::Lit(Lit::Bool(Bool {
          value: true,
          span: DUMMY_SP,
        }));
      }

      if !self.replace_env {
        return node.fold_children_with(self);
      }