turbopack_ecmascript/references/
dynamic_expression.rs1use 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}