Skip to content

Commit 2c54812

Browse files
use apply when expanding amd pattern matches (vercel/turborepo#3677)
1 parent aa9c07c commit 2c54812

File tree

1 file changed

+102
-93
lines changed
  • crates/turbopack-ecmascript/src/references

1 file changed

+102
-93
lines changed

crates/turbopack-ecmascript/src/references/amd.rs

Lines changed: 102 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ use serde::{Deserialize, Serialize};
55
use swc_core::{
66
common::DUMMY_SP,
77
ecma::{
8-
ast::{CallExpr, Callee, Expr, ExprOrSpread, Ident},
8+
ast::{CallExpr, Callee, Expr, ExprOrSpread},
99
utils::private_ident,
1010
},
11-
quote,
11+
quote, quote_expr,
1212
};
1313
use turbo_tasks::{
1414
debug::ValueDebugFormat, primitives::StringVc, trace::TraceRawVcs, TryJoinIterExt, Value,
@@ -118,11 +118,6 @@ impl CodeGenerateable for AmdDefineWithDependenciesCodeGen {
118118
async fn code_generation(&self, context: ChunkingContextVc) -> Result<CodeGenerationVc> {
119119
let mut visitors = Vec::new();
120120

121-
enum ResolvedElement {
122-
PatternMapping(PatternMappingReadRef),
123-
Expr(Expr),
124-
}
125-
126121
let resolved_elements = self
127122
.dependencies_requests
128123
.iter()
@@ -138,6 +133,7 @@ impl CodeGenerateable for AmdDefineWithDependenciesCodeGen {
138133
Value::new(Cjs),
139134
)
140135
.await?,
136+
request.await?.request(),
141137
)
142138
}
143139
AmdDefineDependencyElement::Exports => {
@@ -158,96 +154,109 @@ impl CodeGenerateable for AmdDefineWithDependenciesCodeGen {
158154

159155
let path = self.path.await?;
160156
visitors.push(
161-
// Transforms `define([dep1, dep2], factory)` into:
162-
// ```js
163-
// __turbopack_export_value__(
164-
// factory(
165-
// __turbopack_require__(dep1),
166-
// __turbopack_require__(dep2),
167-
// ),
168-
// );
169-
// ```
170157
create_visitor!(exact path, visit_mut_call_expr(call_expr: &mut CallExpr) {
171-
let CallExpr { args, callee, .. } = call_expr;
172-
if let Some(factory) = take(args).pop().map(|e| e.expr) {
173-
let deps = resolved_elements.iter().map(|element| {
174-
match element {
175-
ResolvedElement::PatternMapping(pm) => {
176-
match &**pm {
177-
PatternMapping::Invalid => Expr::Ident(Ident::new("undefined".into(), DUMMY_SP)),
178-
pm => Expr::Call(CallExpr {
179-
span: DUMMY_SP,
180-
callee: Callee::Expr(
181-
box Expr::Ident(Ident::new(
182-
if pm.is_internal_import() {
183-
"__turbopack_require__"
184-
} else {
185-
"__turbopack_external_require__"
186-
}.into(), DUMMY_SP
187-
))
188-
),
189-
args: vec![
190-
pm.create().into(),
191-
],
192-
type_args: None
193-
}),
194-
}
195-
}
196-
ResolvedElement::Expr(expr) => {
197-
expr.clone()
198-
}
199-
}
200-
}).map(|expr| ExprOrSpread {
201-
expr: box expr,
202-
spread: None,
203-
}).collect();
204-
match factory_type {
205-
AmdDefineFactoryType::Unknown => {
206-
// ((f, r = typeof f !== "function" ? f : f([...])) => r !== undefined && __turbopack_export_value__(r))(...)
207-
let f = private_ident!("f");
208-
let call_f = Expr::Call(CallExpr {
209-
args: deps,
210-
callee: Callee::Expr(box Expr::Ident(f.clone())),
211-
span: DUMMY_SP,
212-
type_args: None
213-
});
214-
*callee = Callee::Expr(box quote!("($f1, r = typeof $f2 !== \"function\" ? $f3 : $call_f) => r !== undefined && __turbopack_export_value(r)" as Expr,
215-
f1 = f.clone(),
216-
f2 = f.clone(),
217-
f3 = f,
218-
call_f: Expr = call_f
219-
));
220-
args.push(ExprOrSpread {
221-
expr: factory,
222-
spread: None
223-
});
224-
},
225-
AmdDefineFactoryType::Function => {
226-
// (r => r !== undefined && __turbopack_export_value__(r))(...([...]))
227-
*callee = Callee::Expr(box quote!("r => r !== undefined && __turbopack_export_value__(r)" as Expr));
228-
args.push(ExprOrSpread {
229-
expr: box Expr::Call(CallExpr {
230-
args: deps,
231-
callee: Callee::Expr(factory),
232-
span: DUMMY_SP,
233-
type_args: None
234-
}),
235-
spread: None
236-
});
237-
},
238-
AmdDefineFactoryType::Value => {
239-
// __turbopack_export_value__(...)
240-
*callee = Callee::Expr(box quote!("__turbopack_export_value__" as Expr));
241-
args.push(ExprOrSpread {
242-
expr: factory,
243-
spread: None
244-
});
245-
},
246-
}
247-
}
158+
transform_amd_factory(call_expr, &resolved_elements, factory_type)
248159
}),
249160
);
250161

251162
Ok(CodeGeneration { visitors }.into())
252163
}
253164
}
165+
166+
enum ResolvedElement {
167+
PatternMapping(PatternMappingReadRef, Option<String>),
168+
Expr(Expr),
169+
}
170+
171+
/// Transforms `define([dep1, dep2], factory)` into:
172+
/// ```js
173+
/// __turbopack_export_value__(
174+
/// factory(
175+
/// __turbopack_require__(dep1),
176+
/// __turbopack_require__(dep2),
177+
/// ),
178+
/// );
179+
/// ```
180+
fn transform_amd_factory(
181+
call_expr: &mut CallExpr,
182+
resolved_elements: &[ResolvedElement],
183+
factory_type: AmdDefineFactoryType,
184+
) {
185+
let CallExpr { args, callee, .. } = call_expr;
186+
let Some(factory) = take(args).pop().map(|e| e.expr) else {
187+
return;
188+
};
189+
190+
let deps = resolved_elements
191+
.iter()
192+
.map(|element| match element {
193+
ResolvedElement::PatternMapping(pm, req) => match &**pm {
194+
PatternMapping::Invalid => quote_expr!("undefined"),
195+
pm => {
196+
let arg = if let Some(req) = req {
197+
pm.apply(req.as_str().into())
198+
} else {
199+
pm.create()
200+
};
201+
202+
if pm.is_internal_import() {
203+
quote_expr!("__turbopack_require__($arg)", arg: Expr = arg)
204+
} else {
205+
quote_expr!("__turbopack_external_require__($arg)", arg: Expr = arg)
206+
}
207+
}
208+
},
209+
ResolvedElement::Expr(expr) => Box::new(expr.clone()),
210+
})
211+
.map(ExprOrSpread::from)
212+
.collect();
213+
214+
match factory_type {
215+
AmdDefineFactoryType::Unknown => {
216+
// ((f, r = typeof f !== "function" ? f : f([...])) => r !== undefined &&
217+
// __turbopack_export_value__(r))(...)
218+
let f = private_ident!("f");
219+
let call_f = Expr::Call(CallExpr {
220+
args: deps,
221+
callee: Callee::Expr(box Expr::Ident(f.clone())),
222+
span: DUMMY_SP,
223+
type_args: None,
224+
});
225+
*callee = Callee::Expr(quote_expr!(
226+
"($f1, r = typeof $f2 !== \"function\" ? $f3 : $call_f) => r !== undefined && \
227+
__turbopack_export_value(r)",
228+
f1 = f.clone(),
229+
f2 = f.clone(),
230+
f3 = f,
231+
call_f: Expr = call_f
232+
));
233+
args.push(ExprOrSpread {
234+
expr: factory,
235+
spread: None,
236+
});
237+
}
238+
AmdDefineFactoryType::Function => {
239+
// (r => r !== undefined && __turbopack_export_value__(r))(...([...]))
240+
*callee = Callee::Expr(quote_expr!(
241+
"r => r !== undefined && __turbopack_export_value__(r)"
242+
));
243+
args.push(ExprOrSpread {
244+
expr: box Expr::Call(CallExpr {
245+
args: deps,
246+
callee: Callee::Expr(factory),
247+
span: DUMMY_SP,
248+
type_args: None,
249+
}),
250+
spread: None,
251+
});
252+
}
253+
AmdDefineFactoryType::Value => {
254+
// __turbopack_export_value__(...)
255+
*callee = Callee::Expr(quote_expr!("__turbopack_export_value__"));
256+
args.push(ExprOrSpread {
257+
expr: factory,
258+
spread: None,
259+
});
260+
}
261+
}
262+
}

0 commit comments

Comments
 (0)