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,
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 { .. } | ModulePart::RenamedNamespace { .. }
57 ),
58 "{part:?} is unexpected for EcmascriptModuleRenameModule"
59 );
60 EcmascriptModuleRenameModule { module, part }.cell()
61 }
62
63 #[turbo_tasks::function]
64 pub async fn async_module(&self) -> Result<Vc<AsyncModule>> {
65 let (import_externals, has_top_level_await) =
66 if let Some(async_module) = *self.module.get_async_module().await? {
67 (
68 async_module.await?.import_externals,
69 async_module.await?.has_top_level_await,
70 )
71 } else {
72 (false, false)
73 };
74 Ok(AsyncModule {
75 has_top_level_await,
76 import_externals,
77 }
78 .cell())
79 }
80}
81
82impl EcmascriptModuleRenameModule {
83 pub async fn module_reference(&self) -> Result<ResolvedVc<EcmascriptModulePartReference>> {
84 match &self.part {
85 ModulePart::RenamedNamespace { .. } => {
86 EcmascriptModulePartReference::new_normal(
87 *self.module,
88 self.part.clone(),
89 ExportUsage::all(),
90 )
91 .to_resolved()
92 .await
93 }
94 ModulePart::RenamedExport {
95 original_export, ..
96 } => {
97 EcmascriptModulePartReference::new_normal(
98 *self.module,
99 self.part.clone(),
100 ExportUsage::named(original_export.clone()),
101 )
102 .to_resolved()
103 .await
104 }
105 _ => {
106 bail!("Unexpected ModulePart for EcmascriptModuleRenameModule");
107 }
108 }
109 }
110}
111
112#[turbo_tasks::value_impl]
113impl Module for EcmascriptModuleRenameModule {
114 #[turbo_tasks::function]
115 fn source(&self) -> Vc<OptionSource> {
116 Vc::cell(None)
117 }
118
119 #[turbo_tasks::function]
120 fn ident(&self) -> Vc<AssetIdent> {
121 self.module.ident().with_part(self.part.clone())
122 }
123
124 #[turbo_tasks::function]
125 async fn references(self: Vc<Self>) -> Result<Vc<ModuleReferences>> {
126 let reference = self.await?.module_reference().await?;
127 Ok(Vc::cell(vec![ResolvedVc::upcast(reference)]))
128 }
129
130 #[turbo_tasks::function]
131 async fn is_self_async(self: Vc<Self>) -> Result<Vc<bool>> {
132 let async_module = self.async_module();
133 let references = self.references();
134 let is_self_async = async_module
135 .to_resolved()
136 .await?
137 .is_self_async(*references.to_resolved().await?)
138 .to_resolved()
139 .await?;
140 Ok(*is_self_async)
141 }
142
143 #[turbo_tasks::function]
144 fn side_effects(&self) -> Vc<ModuleSideEffects> {
145 ModuleSideEffects::ModuleEvaluationIsSideEffectFree.cell()
147 }
148}
149
150#[turbo_tasks::value_impl]
151impl Asset for EcmascriptModuleRenameModule {
152 #[turbo_tasks::function]
153 fn content(&self) -> Vc<AssetContent> {
154 let f = File::from("");
155
156 AssetContent::file(FileContent::Content(f).cell())
157 }
158}
159
160#[turbo_tasks::value_impl]
161impl EcmascriptAnalyzable for EcmascriptModuleRenameModule {
162 #[turbo_tasks::function]
163 fn analyze(&self) -> Result<Vc<AnalyzeEcmascriptModuleResult>> {
164 bail!("EcmascriptModuleRenameModule::analyze shouldn't be called");
165 }
166
167 #[turbo_tasks::function]
168 fn module_content_without_analysis(
169 &self,
170 _generate_source_map: bool,
171 ) -> Result<Vc<EcmascriptModuleContent>> {
172 bail!("EcmascriptModuleRenameModule::module_content_without_analysis shouldn't be called");
173 }
174
175 #[turbo_tasks::function]
176 async fn module_content_options(
177 self: ResolvedVc<Self>,
178 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
179 async_module_info: Option<ResolvedVc<AsyncModuleInfo>>,
180 ) -> Result<Vc<EcmascriptModuleContentOptions>> {
181 let reference = self.await?.module_reference().await?;
182
183 Ok(EcmascriptModuleContentOptions {
184 parsed: None,
185 module: ResolvedVc::upcast(self),
186 specified_module_type: SpecifiedModuleType::EcmaScript,
187 chunking_context,
188 references: self.references().to_resolved().await?,
189 part_references: vec![reference],
190 esm_references: EsmAssetReferences::empty().to_resolved().await?,
191 code_generation: CodeGens::empty().to_resolved().await?,
192 async_module: ResolvedVc::cell(Some(self.async_module().to_resolved().await?)),
193 generate_source_map: false,
197 original_source_map: None,
198 exports: self.get_exports().to_resolved().await?,
199 async_module_info,
200 }
201 .cell())
202 }
203}
204
205#[turbo_tasks::value_impl]
206impl EcmascriptChunkPlaceable for EcmascriptModuleRenameModule {
207 #[turbo_tasks::function]
208 async fn get_exports(&self) -> Result<Vc<EcmascriptExports>> {
209 let reference = self.module_reference().await?;
210
211 let export = match &self.part {
212 ModulePart::RenamedExport {
213 original_export,
214 export,
215 } => (
216 export.clone(),
217 EsmExport::ImportedBinding(
218 ResolvedVc::upcast(reference),
219 original_export.clone(),
220 false,
221 ),
222 ),
223 ModulePart::RenamedNamespace { export } => (
224 export.clone(),
225 EsmExport::ImportedNamespace(ResolvedVc::upcast(reference)),
226 ),
227 _ => bail!("Unexpected ModulePart for EcmascriptModuleRenameModule"),
228 };
229
230 let exports = EsmExports {
231 exports: FrozenMap::from_unique_sorted_box(Box::new([export])),
232 star_exports: Vec::new(),
233 }
234 .resolved_cell();
235 Ok(EcmascriptExports::EsmExports(exports).cell())
236 }
237
238 #[turbo_tasks::function]
239 async fn get_async_module(self: Vc<Self>) -> Result<Vc<OptionAsyncModule>> {
240 Ok(Vc::cell(Some(self.async_module().to_resolved().await?)))
241 }
242
243 #[turbo_tasks::function]
244 async fn chunk_item_content(
245 self: Vc<Self>,
246 chunking_context: Vc<Box<dyn ChunkingContext>>,
247 _module_graph: Vc<ModuleGraph>,
248 async_module_info: Option<Vc<AsyncModuleInfo>>,
249 _estimated: bool,
250 ) -> Result<Vc<EcmascriptChunkItemContent>> {
251 let async_module_options = self.get_async_module().module_options(async_module_info);
252 let content = self.module_content(chunking_context, async_module_info);
253 Ok(EcmascriptChunkItemContent::new(
254 content,
255 chunking_context,
256 async_module_options,
257 ))
258 }
259}
260
261#[turbo_tasks::value_impl]
262impl ChunkableModule for EcmascriptModuleRenameModule {
263 #[turbo_tasks::function]
264 fn as_chunk_item(
265 self: ResolvedVc<Self>,
266 module_graph: ResolvedVc<ModuleGraph>,
267 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
268 ) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
269 ecmascript_chunk_item(ResolvedVc::upcast(self), module_graph, chunking_context)
270 }
271}
272
273#[turbo_tasks::value_impl]
274impl EvaluatableAsset for EcmascriptModuleRenameModule {}
275
276#[turbo_tasks::value_impl]
277impl MergeableModule for EcmascriptModuleRenameModule {
278 #[turbo_tasks::function]
279 async fn merge(
280 self: Vc<Self>,
281 modules: Vc<MergeableModulesExposed>,
282 entry_points: Vc<MergeableModules>,
283 ) -> Result<Vc<Box<dyn ChunkableModule>>> {
284 Ok(Vc::upcast(
285 *MergedEcmascriptModule::new(
286 modules,
287 entry_points,
288 EcmascriptOptions::default().resolved_cell(),
289 )
290 .await?,
291 ))
292 }
293}