Skip to main content

turbopack_ecmascript/references/
dynamic_expression.rs

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