turbopack_ecmascript/rename/
module.rs1use anyhow::{Result, bail};
2use turbo_frozenmap::FrozenMap;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::{File, FileContent};
5use turbopack_core::{
6 asset::{Asset, AssetContent},
7 chunk::{
8 AsyncModuleInfo, ChunkableModule, ChunkingContext, EvaluatableAsset, MergeableModule,
9 MergeableModules, MergeableModulesExposed,
10 },
11 ident::AssetIdent,
12 module::{Module, ModuleSideEffects},
13 module_graph::ModuleGraph,
14 reference::ModuleReferences,
15 resolve::{ExportUsage, ModulePart},
16 source::OptionSource,
17};
18
19use crate::{
20 AnalyzeEcmascriptModuleResult, EcmascriptAnalyzable, EcmascriptAnalyzableExt,
21 EcmascriptModuleContent, EcmascriptModuleContentOptions, EcmascriptOptions, EnvVarInfo,
22 MergedEcmascriptModule, SpecifiedModuleType,
23 chunk::{
24 EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptExports,
25 ecmascript_chunk_item,
26 },
27 code_gen::CodeGens,
28 references::{
29 async_module::{AsyncModule, OptionAsyncModule},
30 esm::{EsmExport, EsmExports, base::EsmAssetReferences},
31 },
32 side_effect_optimization::reference::EcmascriptModulePartReference,
33};
34
35#[turbo_tasks::value]
38pub struct EcmascriptModuleRenameModule {
39 module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
40 part: ModulePart,
44}
45
46#[turbo_tasks::value_impl]
47impl EcmascriptModuleRenameModule {
48 #[turbo_tasks::function]
49 pub fn new(
50 module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
51 part: ModulePart,
52 ) -> Vc<Self> {
53 assert!(
54 matches!(
55 part,
56 ModulePart::RenamedExport { .. }
57 | ModulePart::RenamedNamespace { .. }
58 | ModulePart::RenamedPartialNamespace { .. }
59 ),
60 "{part:?} is unexpected for EcmascriptModuleRenameModule"
61 );
62 EcmascriptModuleRenameModule { module, part }.cell()
63 }
64
65 #[turbo_tasks::function]
66 pub async fn async_module(&self) -> Result<Vc<AsyncModule>> {
67 let (import_externals, has_top_level_await) =
68 if let Some(async_module) = *self.module.get_async_module().await? {
69 (
70 async_module.await?.import_externals,
71 async_module.await?.has_top_level_await,
72 )
73 } else {
74 (false, false)
75 };
76 Ok(AsyncModule {
77 has_top_level_await,
78 import_externals,
79 }
80 .cell())
81 }
82}
83
84impl EcmascriptModuleRenameModule {
85 pub async fn module_reference(&self) -> Result<ResolvedVc<EcmascriptModulePartReference>> {
86 match &self.part {
87 ModulePart::RenamedNamespace { .. } => {
88 EcmascriptModulePartReference::new_normal(
89 *self.module,
90 self.part.clone(),
91 ExportUsage::all(),
92 )
93 .to_resolved()
94 .await
95 }
96 ModulePart::RenamedPartialNamespace { member, .. } => {
97 EcmascriptModulePartReference::new_normal(
98 *self.module,
99 self.part.clone(),
100 ExportUsage::partial_namespace_object(vec![member.clone()]),
101 )
102 .to_resolved()
103 .await
104 }
105 ModulePart::RenamedExport {
106 original_export, ..
107 } => {
108 EcmascriptModulePartReference::new_normal(
109 *self.module,
110 self.part.clone(),
111 ExportUsage::named(original_export.clone()),
112 )
113 .to_resolved()
114 .await
115 }
116 _ => {
117 bail!("Unexpected ModulePart for EcmascriptModuleRenameModule");
118 }
119 }
120 }
121}
122
123#[turbo_tasks::value_impl]
124impl Module for EcmascriptModuleRenameModule {
125 #[turbo_tasks::function]
126 fn source(&self) -> Vc<OptionSource> {
127 Vc::cell(None)
128 }
129
130 #[turbo_tasks::function]
131 async fn ident(&self) -> Result<Vc<AssetIdent>> {
132 Ok(self
133 .module
134 .ident()
135 .owned()
136 .await?
137 .with_part(self.part.clone())
138 .into_vc())
139 }
140
141 #[turbo_tasks::function]
142 async fn references(self: Vc<Self>) -> Result<Vc<ModuleReferences>> {
143 let reference = self.await?.module_reference().await?;
144 Ok(Vc::cell(vec![ResolvedVc::upcast(reference)]))
145 }
146
147 #[turbo_tasks::function]
148 async fn is_self_async(self: Vc<Self>) -> Result<Vc<bool>> {
149 let async_module = self.async_module();
150 let references = self.references();
151 let is_self_async = async_module
152 .to_resolved()
153 .await?
154 .is_self_async(*references.to_resolved().await?)
155 .to_resolved()
156 .await?;
157 Ok(*is_self_async)
158 }
159
160 #[turbo_tasks::function]
161 fn side_effects(&self) -> Vc<ModuleSideEffects> {
162 ModuleSideEffects::ModuleEvaluationIsSideEffectFree.cell()
164 }
165}
166
167#[turbo_tasks::value_impl]
168impl Asset for EcmascriptModuleRenameModule {
169 #[turbo_tasks::function]
170 fn content(&self) -> Vc<AssetContent> {
171 let f = File::from("");
172
173 AssetContent::file(FileContent::Content(f).cell())
174 }
175}
176
177#[turbo_tasks::value_impl]
178impl EcmascriptAnalyzable for EcmascriptModuleRenameModule {
179 #[turbo_tasks::function]
180 fn analyze(&self) -> Result<Vc<AnalyzeEcmascriptModuleResult>> {
181 bail!("EcmascriptModuleRenameModule::analyze shouldn't be called");
182 }
183
184 #[turbo_tasks::function]
185 fn env_var_info(self: Vc<Self>) -> Vc<EnvVarInfo> {
186 EnvVarInfo::empty()
187 }
188
189 #[turbo_tasks::function]
190 fn module_content_without_analysis(
191 &self,
192 _generate_source_map: bool,
193 ) -> Result<Vc<EcmascriptModuleContent>> {
194 bail!("EcmascriptModuleRenameModule::module_content_without_analysis shouldn't be called");
195 }
196
197 #[turbo_tasks::function]
198 async fn module_content_options(
199 self: ResolvedVc<Self>,
200 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
201 async_module_info: Option<ResolvedVc<AsyncModuleInfo>>,
202 ) -> Result<Vc<EcmascriptModuleContentOptions>> {
203 let reference = self.await?.module_reference().await?;
204
205 Ok(EcmascriptModuleContentOptions {
206 parsed: None,
207 module: ResolvedVc::upcast(self),
208 specified_module_type: SpecifiedModuleType::EcmaScript,
209 chunking_context,
210 references: self.references().to_resolved().await?,
211 part_references: vec![reference],
212 esm_references: EsmAssetReferences::empty().to_resolved().await?,
213 code_generation: CodeGens::empty().to_resolved().await?,
214 async_module: ResolvedVc::cell(Some(self.async_module().to_resolved().await?)),
215 generate_source_map: false,
219 original_source_map: None,
220 exports: self.get_exports().to_resolved().await?,
221 export_registration_mode: None,
222 async_module_info,
223 }
224 .cell())
225 }
226}
227
228#[turbo_tasks::value_impl]
229impl EcmascriptChunkPlaceable for EcmascriptModuleRenameModule {
230 #[turbo_tasks::function]
231 async fn get_exports(&self) -> Result<Vc<EcmascriptExports>> {
232 let reference = self.module_reference().await?;
233
234 let export = match &self.part {
235 ModulePart::RenamedExport {
236 original_export,
237 export,
238 } => (
239 export.clone(),
240 EsmExport::ImportedBinding(
241 ResolvedVc::upcast(reference),
242 original_export.clone(),
243 false,
244 ),
245 ),
246 ModulePart::RenamedNamespace { export }
247 | ModulePart::RenamedPartialNamespace { export, .. } => (
248 export.clone(),
249 EsmExport::ImportedNamespace(ResolvedVc::upcast(reference)),
250 ),
251 _ => bail!("Unexpected ModulePart for EcmascriptModuleRenameModule"),
252 };
253
254 let exports = EsmExports {
255 exports: FrozenMap::from_unique_sorted_box(Box::new([export])),
256 star_exports: Vec::new(),
257 mangle_export_names: match &*self.module.get_exports().await? {
260 EcmascriptExports::EsmExports(exports) => exports.await?.mangle_export_names,
261 _ => false,
262 },
263 }
264 .resolved_cell();
265 Ok(EcmascriptExports::EsmExports(exports).cell())
266 }
267
268 #[turbo_tasks::function]
269 async fn get_async_module(self: Vc<Self>) -> Result<Vc<OptionAsyncModule>> {
270 Ok(Vc::cell(Some(self.async_module().to_resolved().await?)))
271 }
272
273 #[turbo_tasks::function]
274 async fn chunk_item_content(
275 self: Vc<Self>,
276 chunking_context: Vc<Box<dyn ChunkingContext>>,
277 _module_graph: Vc<ModuleGraph>,
278 async_module_info: Option<Vc<AsyncModuleInfo>>,
279 _estimated: bool,
280 ) -> Result<Vc<EcmascriptChunkItemContent>> {
281 let async_module_options = self.get_async_module().module_options(async_module_info);
282 let content = self.module_content(chunking_context, async_module_info);
283 Ok(EcmascriptChunkItemContent::new(
284 content,
285 chunking_context,
286 async_module_options,
287 ))
288 }
289}
290
291#[turbo_tasks::value_impl]
292impl ChunkableModule for EcmascriptModuleRenameModule {
293 #[turbo_tasks::function]
294 fn as_chunk_item(
295 self: ResolvedVc<Self>,
296 module_graph: ResolvedVc<ModuleGraph>,
297 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
298 ) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
299 ecmascript_chunk_item(ResolvedVc::upcast(self), module_graph, chunking_context)
300 }
301}
302
303#[turbo_tasks::value_impl]
304impl EvaluatableAsset for EcmascriptModuleRenameModule {}
305
306#[turbo_tasks::value_impl]
307impl MergeableModule for EcmascriptModuleRenameModule {
308 #[turbo_tasks::function]
309 async fn merge(
310 self: Vc<Self>,
311 modules: Vc<MergeableModulesExposed>,
312 entry_points: Vc<MergeableModules>,
313 ) -> Result<Vc<Box<dyn ChunkableModule>>> {
314 Ok(Vc::upcast(
315 *MergedEcmascriptModule::new(
316 modules,
317 entry_points,
318 EcmascriptOptions::default().resolved_cell(),
319 )
320 .await?,
321 ))
322 }
323}