turbopack_ecmascript/references/
dynamic_expression.rs

1use anyhow::Result;
2use bincode::{Decode, Encode};
3use swc_core::quote;
4use turbo_tasks::{NonLocalValue, Vc, debug::ValueDebugFormat, trace::TraceRawVcs};
5use turbopack_core::chunk::ChunkingContext;
6
7use crate::{
8    code_gen::{CodeGen, CodeGeneration},
9    create_visitor,
10    references::AstPath,
11};
12
13#[derive(
14    PartialEq, Eq, TraceRawVcs, ValueDebugFormat, NonLocalValue, Hash, Debug, Encode, Decode,
15)]
16enum DynamicExpressionType {
17    Promise,
18    Normal,
19}
20
21#[derive(
22    PartialEq, Eq, TraceRawVcs, ValueDebugFormat, NonLocalValue, Debug, Hash, Encode, Decode,
23)]
24pub struct DynamicExpression {
25    path: AstPath,
26    ty: DynamicExpressionType,
27}
28
29impl DynamicExpression {
30    pub fn new(path: AstPath) -> Self {
31        DynamicExpression {
32            path,
33            ty: DynamicExpressionType::Normal,
34        }
35    }
36
37    pub fn new_promise(path: AstPath) -> Self {
38        DynamicExpression {
39            path,
40            ty: DynamicExpressionType::Promise,
41        }
42    }
43
44    pub async fn code_generation(
45        &self,
46        _chunking_context: Vc<Box<dyn ChunkingContext>>,
47    ) -> Result<CodeGeneration> {
48        let visitor = match self.ty {
49            DynamicExpressionType::Normal => {
50                create_visitor!(self.path, visit_mut_expr, |expr: &mut Expr| {
51                    *expr = quote!(
52                        "(() => { const e = new Error(\"Cannot find module as expression is too \
53                         dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })()"
54                            as Expr
55                    );
56                })
57            }
58            DynamicExpressionType::Promise => {
59                create_visitor!(self.path, visit_mut_expr, |expr: &mut Expr| {
60                    *expr = quote!(
61                        "Promise.resolve().then(() => { const e = new Error(\"Cannot find module \
62                         as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })"
63                            as Expr
64                    );
65                })
66            }
67        };
68
69        Ok(CodeGeneration::visitors(vec![visitor]))
70    }
71}
72
73impl From<DynamicExpression> for CodeGen {
74    fn from(val: DynamicExpression) -> Self {
75        CodeGen::DynamicExpression(val)
76    }
77}