turbopack_ecmascript/references/
member.rs

1use anyhow::Result;
2use bincode::{Decode, Encode};
3use swc_core::{
4    atoms::atom,
5    base::SwcComments,
6    common::{
7        DUMMY_SP, Span,
8        comments::{Comment, CommentKind, Comments},
9    },
10    ecma::ast::{Expr, MemberExpr, MemberProp},
11    quote,
12};
13use turbo_rcstr::RcStr;
14use turbo_tasks::{NonLocalValue, Vc, debug::ValueDebugFormat, trace::TraceRawVcs};
15use turbopack_core::chunk::ChunkingContext;
16
17use crate::{
18    code_gen::{CodeGen, CodeGeneration},
19    create_visitor,
20    references::AstPath,
21};
22
23#[derive(
24    PartialEq, Eq, TraceRawVcs, ValueDebugFormat, NonLocalValue, Hash, Debug, Encode, Decode,
25)]
26pub struct MemberReplacement {
27    key: RcStr,
28    value: RcStr,
29    path: AstPath,
30}
31
32impl MemberReplacement {
33    pub fn new(key: RcStr, value: RcStr, path: AstPath) -> Self {
34        MemberReplacement { key, value, path }
35    }
36
37    pub async fn code_generation(
38        &self,
39        _chunking_context: Vc<Box<dyn ChunkingContext>>,
40    ) -> Result<CodeGeneration> {
41        let comments = SwcComments::default();
42
43        let key = self.key.clone();
44        let value = self.value.clone();
45
46        let comments_clone = comments.clone();
47        let visitor = create_visitor!(self.path, visit_mut_expr, |expr: &mut Expr| {
48            let span = Span::dummy_with_cmt();
49
50            comments_clone.add_leading(
51                span.lo,
52                Comment {
53                    kind: CommentKind::Block,
54                    span: DUMMY_SP,
55                    text: atom!("TURBOPACK member replacement"),
56                },
57            );
58            let member = Expr::Member(MemberExpr {
59                span,
60                obj: Box::new(Expr::Ident((&*key).into())),
61                prop: MemberProp::Ident((&*value).into()),
62            });
63            *expr = quote!("$e" as Expr, e: Expr = member);
64        });
65
66        Ok(CodeGeneration::visitors_with_comments(
67            vec![visitor],
68            comments,
69        ))
70    }
71}
72
73impl From<MemberReplacement> for CodeGen {
74    fn from(val: MemberReplacement) -> Self {
75        CodeGen::MemberReplacement(val)
76    }
77}