diff --git a/crates/turbopack-build/src/chunking_context.rs b/crates/turbopack-build/src/chunking_context.rs index c8c39a68bf0ee..3f2ee63d1db4e 100644 --- a/crates/turbopack-build/src/chunking_context.rs +++ b/crates/turbopack-build/src/chunking_context.rs @@ -8,7 +8,7 @@ use turbo_tasks::{ }; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ - chunk::{Chunk, ChunkableModule, ChunkingContext, Chunks, EvaluatableAssets}, + chunk::{Chunk, ChunkableModuleExt, ChunkingContext, Chunks, EvaluatableAssets}, environment::Environment, ident::AssetIdent, module::Module, diff --git a/crates/turbopack-build/src/ecmascript/node/content.rs b/crates/turbopack-build/src/ecmascript/node/content.rs index b935edf9ba525..6cca8255f1c78 100644 --- a/crates/turbopack-build/src/ecmascript/node/content.rs +++ b/crates/turbopack-build/src/ecmascript/node/content.rs @@ -6,6 +6,7 @@ use turbo_tasks::{TryJoinIterExt, Value, Vc}; use turbo_tasks_fs::File; use turbopack_core::{ asset::AssetContent, + chunk::ChunkItemExt, code_builder::{Code, CodeBuilder}, output::OutputAsset, source_map::{GenerateSourceMap, OptionSourceMap}, diff --git a/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs b/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs index fbb050889d9d0..42bd1d6319312 100644 --- a/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs +++ b/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs @@ -6,16 +6,13 @@ use turbo_tasks::{ValueToString, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{ChunkingContext, EvaluatableAssets}, + chunk::{ChunkItemExt, ChunkableModule, ChunkingContext, EvaluatableAssets}, code_builder::{Code, CodeBuilder}, ident::AssetIdent, output::{OutputAsset, OutputAssets}, source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, }; -use turbopack_ecmascript::{ - chunk::{EcmascriptChunkItemExt, EcmascriptChunkPlaceable}, - utils::StringifyJs, -}; +use turbopack_ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}; use super::runtime::EcmascriptBuildNodeRuntimeChunk; use crate::BuildChunkingContext; diff --git a/crates/turbopack-cli/src/build/mod.rs b/crates/turbopack-cli/src/build/mod.rs index 20c931d512dc4..23453b6bf7ec3 100644 --- a/crates/turbopack-cli/src/build/mod.rs +++ b/crates/turbopack-cli/src/build/mod.rs @@ -14,7 +14,7 @@ use turbopack_build::{BuildChunkingContext, MinifyType}; use turbopack_cli_utils::issue::{ConsoleUi, LogOptions}; use turbopack_core::{ asset::Asset, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkableModule, ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, environment::{BrowserEnvironment, Environment, ExecutionEnvironment}, issue::{handle_issues, IssueReporter, IssueSeverity}, module::Module, diff --git a/crates/turbopack-core/src/chunk/chunking_context.rs b/crates/turbopack-core/src/chunk/chunking_context.rs index a9dcfe9fa34af..9fbf680cee0f3 100644 --- a/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/crates/turbopack-core/src/chunk/chunking_context.rs @@ -1,9 +1,10 @@ use anyhow::Result; -use turbo_tasks::Vc; +use turbo_tasks::{ValueToString, Vc}; use turbo_tasks_fs::FileSystemPath; use super::{Chunk, EvaluatableAssets}; use crate::{ + chunk::{ChunkItem, ModuleId}, environment::Environment, ident::AssetIdent, module::Module, @@ -63,4 +64,16 @@ pub trait ChunkingContext { entry: Vc>, evaluatable_assets: Vc, ) -> Vc; + + async fn chunk_item_id( + self: Vc, + chunk_item: Vc>, + ) -> Result> { + let layer = self.layer(); + let mut ident = chunk_item.asset_ident(); + if !layer.await?.is_empty() { + ident = ident.with_modifier(layer) + } + Ok(ModuleId::String(ident.to_string().await?.clone_value()).cell()) + } } diff --git a/crates/turbopack-core/src/chunk/mod.rs b/crates/turbopack-core/src/chunk/mod.rs index 984cccb5cee39..3b425c362effa 100644 --- a/crates/turbopack-core/src/chunk/mod.rs +++ b/crates/turbopack-core/src/chunk/mod.rs @@ -22,7 +22,7 @@ use turbo_tasks::{ debug::ValueDebugFormat, graph::{AdjacencyMap, GraphTraversal, GraphTraversalResult, Visit, VisitControlFlow}, trace::TraceRawVcs, - ReadRef, TryJoinIterExt, Value, ValueToString, Vc, + ReadRef, TryJoinIterExt, Upcast, Value, ValueToString, Vc, }; use turbo_tasks_fs::FileSystemPath; use turbo_tasks_hash::DeterministicHash; @@ -85,22 +85,46 @@ pub struct ModuleIds(Vec>); /// A [Module] that can be converted into a [Chunk]. #[turbo_tasks::value_trait] pub trait ChunkableModule: Module + Asset { + fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Vc>; +} + +pub trait ChunkableModuleExt { + fn as_chunk( + self: Vc, + chunking_context: Vc>, + availability_info: Value, + ) -> Vc> + where + Self: Send; + fn as_root_chunk( + self: Vc, + chunking_context: Vc>, + ) -> Vc> + where + Self: Send; +} + +impl>> ChunkableModuleExt for T { fn as_chunk( self: Vc, chunking_context: Vc>, availability_info: Value, - ) -> Vc>; + ) -> Vc> { + let chunk_item = self.as_chunk_item(chunking_context); + chunk_item.as_chunk(availability_info) + } fn as_root_chunk( self: Vc, chunking_context: Vc>, ) -> Vc> { - self.as_chunk( - chunking_context, - Value::new(AvailabilityInfo::Root { - current_availability_root: Vc::upcast(self), - }), - ) + let chunk_item = self.as_chunk_item(chunking_context); + chunk_item.as_chunk(Value::new(AvailabilityInfo::Root { + current_availability_root: Vc::upcast(self), + })) } } @@ -672,6 +696,8 @@ where #[turbo_tasks::value_trait] pub trait ChunkItem { + fn as_chunk(self: Vc, availability_info: Value) -> Vc>; + /// The [AssetIdent] of the [Module] that this [ChunkItem] was created from. /// For most chunk types this must uniquely identify the asset as it's the /// source of the module id used at runtime. @@ -681,7 +707,25 @@ pub trait ChunkItem { /// TODO(alexkirsz) This should have a default impl that returns empty /// references. fn references(self: Vc) -> Vc; + + fn chunking_context(self: Vc) -> Vc>; } #[turbo_tasks::value(transparent)] pub struct ChunkItems(Vec>>); + +pub trait ChunkItemExt: Send { + /// Returns the module id of this chunk item. + fn id(self: Vc) -> Vc; +} + +impl ChunkItemExt for T +where + T: Upcast>, +{ + /// Returns the module id of this chunk item. + fn id(self: Vc) -> Vc { + let chunk_item = Vc::upcast(self); + chunk_item.chunking_context().chunk_item_id(chunk_item) + } +} diff --git a/crates/turbopack-css/src/asset.rs b/crates/turbopack-css/src/asset.rs index 11faffafbab12..04697bad2ab2c 100644 --- a/crates/turbopack-css/src/asset.rs +++ b/crates/turbopack-css/src/asset.rs @@ -111,27 +111,11 @@ impl Asset for CssModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for CssModuleAsset { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(CssChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl CssChunkPlaceable for CssModuleAsset { #[turbo_tasks::function] fn as_chunk_item( self: Vc, chunking_context: Vc>, - ) -> Vc> { + ) -> Vc> { Vc::upcast(CssModuleChunkItem::cell(CssModuleChunkItem { module: self, chunking_context, @@ -139,6 +123,9 @@ impl CssChunkPlaceable for CssModuleAsset { } } +#[turbo_tasks::value_impl] +impl CssChunkPlaceable for CssModuleAsset {} + #[turbo_tasks::value_impl] impl ResolveOrigin for CssModuleAsset { #[turbo_tasks::function] @@ -169,6 +156,20 @@ impl ChunkItem for CssModuleChunkItem { fn references(&self) -> Vc { self.module.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(CssChunk::new( + self.chunking_context, + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -192,10 +193,12 @@ impl CssChunkItem for CssModuleChunkItem { if let Some(placeable) = Vc::try_resolve_downcast::>(module).await? { - imports.push(CssImport::Internal( - import_ref, - placeable.as_chunk_item(chunking_context), - )); + let item = placeable.as_chunk_item(chunking_context); + if let Some(css_item) = + Vc::try_resolve_downcast::>(item).await? + { + imports.push(CssImport::Internal(import_ref, css_item)); + } } } } else if let Some(compose_ref) = @@ -210,9 +213,12 @@ impl CssChunkItem for CssModuleChunkItem { if let Some(placeable) = Vc::try_resolve_downcast::>(module).await? { - imports.push(CssImport::Composes( - placeable.as_chunk_item(chunking_context), - )); + let item = placeable.as_chunk_item(chunking_context); + if let Some(css_item) = + Vc::try_resolve_downcast::>(item).await? + { + imports.push(CssImport::Composes(css_item)); + } } } } diff --git a/crates/turbopack-css/src/chunk/mod.rs b/crates/turbopack-css/src/chunk/mod.rs index 56d51b80fc1ea..7b457398caebf 100644 --- a/crates/turbopack-css/src/chunk/mod.rs +++ b/crates/turbopack-css/src/chunk/mod.rs @@ -12,7 +12,7 @@ use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ availability_info::AvailabilityInfo, chunk_content, chunk_content_split, Chunk, - ChunkContentResult, ChunkItem, ChunkableModule, ChunkingContext, Chunks, + ChunkContentResult, ChunkItem, ChunkItemExt, ChunkableModule, ChunkingContext, Chunks, FromChunkableModule, ModuleId, OutputChunk, OutputChunkRuntimeInfo, }, code_builder::{Code, CodeBuilder}, @@ -144,9 +144,13 @@ impl CssChunkContent { for entry in this.main_entries.await?.iter() { let entry_item = entry.as_chunk_item(this.chunking_context); - // TODO(WEB-1261) - for external_import in expand_imports(&mut body, entry_item).await? { - external_imports.insert(external_import.await?.to_owned()); + if let Some(css_item) = + Vc::try_resolve_downcast::>(entry_item).await? + { + // TODO(WEB-1261) + for external_import in expand_imports(&mut body, css_item).await? { + external_imports.insert(external_import.await?.to_owned()); + } } } @@ -332,7 +336,12 @@ impl OutputChunk for CssChunk { let imports_chunk_items: Vec<_> = entries_chunk_items .iter() .map(|&chunk_item| async move { - Ok(chunk_item + let Some(css_item) = + Vc::try_resolve_downcast::>(chunk_item).await? + else { + return Ok(vec![]); + }; + Ok(css_item .content() .await? .imports @@ -492,13 +501,9 @@ impl CssChunkContext { } } +// TODO: remove #[turbo_tasks::value_trait] -pub trait CssChunkPlaceable: ChunkableModule + Module + Asset { - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc>; -} +pub trait CssChunkPlaceable: ChunkableModule + Module + Asset {} #[turbo_tasks::value(transparent)] pub struct CssChunkPlaceables(Vec>>); @@ -523,7 +528,7 @@ pub trait CssChunkItem: ChunkItem { fn content(self: Vc) -> Vc; fn chunking_context(self: Vc) -> Vc>; fn id(self: Vc) -> Vc { - CssChunkContext::of(self.chunking_context()).chunk_item_id(self) + CssChunkContext::of(CssChunkItem::chunking_context(self)).chunk_item_id(self) } } @@ -536,7 +541,10 @@ impl FromChunkableModule for Box { if let Some(placeable) = Vc::try_resolve_downcast::>(asset).await? { - return Ok(Some(placeable.as_chunk_item(chunking_context))); + let item = placeable.as_chunk_item(chunking_context); + if let Some(css_item) = Vc::try_resolve_downcast::>(item).await? { + return Ok(Some(css_item)); + } } Ok(None) } diff --git a/crates/turbopack-css/src/module_asset.rs b/crates/turbopack-css/src/module_asset.rs index 5de8ef3929f5d..49523329e9e3d 100644 --- a/crates/turbopack-css/src/module_asset.rs +++ b/crates/turbopack-css/src/module_asset.rs @@ -1,6 +1,6 @@ use std::{fmt::Write, iter::once, sync::Arc}; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indexmap::IndexMap; use indoc::formatdoc; use swc_core::{ @@ -12,7 +12,8 @@ use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkableModule, ChunkingContext, + availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkItemExt, ChunkableModule, + ChunkingContext, }, context::AssetContext, ident::AssetIdent, @@ -25,8 +26,8 @@ use turbopack_core::{ }; use turbopack_ecmascript::{ chunk::{ - EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemExt, - EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkingContext, EcmascriptExports, }, utils::StringifyJs, ParseResultSourceMap, @@ -211,35 +212,28 @@ impl ModuleCssAsset { #[turbo_tasks::value_impl] impl ChunkableModule for ModuleCssAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for ModuleCssAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use ModuleCssAsset", + )?; + Ok(Vc::upcast( ModuleChunkItem { chunking_context, module: self, } .cell(), - ) + )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ModuleCssAsset { #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() @@ -276,6 +270,20 @@ impl ChunkItem for ModuleChunkItem { fn references(&self) -> Vc { self.module.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -338,7 +346,10 @@ impl EcmascriptChunkItem for ModuleChunkItem { let placeable: Vc> = Vc::upcast(css_module); - let module_id = placeable.as_chunk_item(self.chunking_context).id().await?; + let module_id = placeable + .as_chunk_item(Vc::upcast(self.chunking_context)) + .id() + .await?; let module_id = StringifyJs(&*module_id); let original_name = StringifyJs(&original_name); exported_class_names.push(format! { diff --git a/crates/turbopack-dev-server/src/html.rs b/crates/turbopack-dev-server/src/html.rs index 0b8ecb375af9c..13e60ae7b290f 100644 --- a/crates/turbopack-dev-server/src/html.rs +++ b/crates/turbopack-dev-server/src/html.rs @@ -5,7 +5,7 @@ use turbo_tasks_fs::{File, FileSystemPath}; use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssets}, + chunk::{ChunkableModule, ChunkableModuleExt, ChunkingContext, EvaluatableAssets}, ident::AssetIdent, output::{OutputAsset, OutputAssets}, version::{Version, VersionedContent}, diff --git a/crates/turbopack-dev/src/chunking_context.rs b/crates/turbopack-dev/src/chunking_context.rs index d73916456b505..b9b52099fad4a 100644 --- a/crates/turbopack-dev/src/chunking_context.rs +++ b/crates/turbopack-dev/src/chunking_context.rs @@ -6,7 +6,7 @@ use turbo_tasks::{ }; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ - chunk::{Chunk, ChunkableModule, ChunkingContext, Chunks, EvaluatableAssets}, + chunk::{Chunk, ChunkableModuleExt, ChunkingContext, Chunks, EvaluatableAssets}, environment::Environment, ident::AssetIdent, module::Module, diff --git a/crates/turbopack-dev/src/ecmascript/content_entry.rs b/crates/turbopack-dev/src/ecmascript/content_entry.rs index 60f841a9469ba..4a48b8c744a10 100644 --- a/crates/turbopack-dev/src/ecmascript/content_entry.rs +++ b/crates/turbopack-dev/src/ecmascript/content_entry.rs @@ -5,7 +5,7 @@ use indexmap::IndexMap; use tracing::{info_span, Instrument}; use turbo_tasks::{ReadRef, TryJoinIterExt, Value, ValueToString, Vc}; use turbopack_core::{ - chunk::{availability_info::AvailabilityInfo, ChunkItem, ModuleId}, + chunk::{availability_info::AvailabilityInfo, ChunkItem, ChunkItemExt, ModuleId}, code_builder::{Code, CodeBuilder}, error::PrettyPrintError, issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity}, diff --git a/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs b/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs index 38d76e744e8d9..a6e1e92865b74 100644 --- a/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs +++ b/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs @@ -7,7 +7,10 @@ use turbo_tasks::{ReadRef, TryJoinIterExt, Value, ValueToString, Vc}; use turbo_tasks_fs::File; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{Chunk, ChunkData, ChunkingContext, ChunksData, EvaluatableAssets, ModuleId}, + chunk::{ + Chunk, ChunkData, ChunkItemExt, ChunkableModule, ChunkingContext, ChunksData, + EvaluatableAssets, ModuleId, + }, code_builder::{Code, CodeBuilder}, ident::AssetIdent, module::Module, @@ -15,7 +18,7 @@ use turbopack_core::{ source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, }; use turbopack_ecmascript::{ - chunk::{EcmascriptChunkData, EcmascriptChunkItemExt, EcmascriptChunkPlaceable}, + chunk::{EcmascriptChunkData, EcmascriptChunkPlaceable}, utils::StringifyJs, }; use turbopack_ecmascript_runtime::RuntimeType; diff --git a/crates/turbopack-ecmascript/src/chunk/context.rs b/crates/turbopack-ecmascript/src/chunk/context.rs index 6b9ff4973dfdb..d558e1d701ce2 100644 --- a/crates/turbopack-ecmascript/src/chunk/context.rs +++ b/crates/turbopack-ecmascript/src/chunk/context.rs @@ -1,8 +1,5 @@ -use anyhow::Result; -use turbo_tasks::{ValueToString, Vc}; -use turbopack_core::chunk::{ChunkItem, ChunkingContext, ModuleId}; - -use super::item::EcmascriptChunkItem; +use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; /// [`EcmascriptChunkingContext`] must be implemented by [`ChunkingContext`] /// implementors that want to operate on [`EcmascriptChunk`]s. @@ -13,16 +10,4 @@ pub trait EcmascriptChunkingContext: ChunkingContext { fn has_react_refresh(self: Vc) -> Vc { Vc::cell(false) } - - async fn chunk_item_id( - self: Vc, - chunk_item: Vc>, - ) -> Result> { - let layer = self.layer(); - let mut ident = chunk_item.asset_ident(); - if !layer.await?.is_empty() { - ident = ident.with_modifier(layer) - } - Ok(ModuleId::String(ident.to_string().await?.clone_value()).cell()) - } } diff --git a/crates/turbopack-ecmascript/src/chunk/item.rs b/crates/turbopack-ecmascript/src/chunk/item.rs index 7d4210af21b2d..753deefd8f0b1 100644 --- a/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/crates/turbopack-ecmascript/src/chunk/item.rs @@ -7,7 +7,7 @@ use turbo_tasks_fs::rope::Rope; use turbopack_core::{ chunk::{ availability_info::AvailabilityInfo, available_modules::AvailableAssets, ChunkItem, - ChunkableModule, ChunkingContext, FromChunkableModule, ModuleId, + ChunkItemExt, ChunkableModule, ChunkingContext, FromChunkableModule, }, code_builder::{Code, CodeBuilder}, error::PrettyPrintError, @@ -180,9 +180,6 @@ pub trait EcmascriptChunkItem: ChunkItem { } pub trait EcmascriptChunkItemExt: Send { - /// Returns the module id of this chunk item. - fn id(self: Vc) -> Vc; - /// Generates the module factory for this chunk item. fn code(self: Vc, availability_info: Value) -> Vc; } @@ -191,12 +188,6 @@ impl EcmascriptChunkItemExt for T where T: Upcast>, { - /// Returns the module id of this chunk item. - fn id(self: Vc) -> Vc { - let chunk_item = Vc::upcast(self); - chunk_item.chunking_context().chunk_item_id(chunk_item) - } - /// Generates the module factory for this chunk item. fn code(self: Vc, availability_info: Value) -> Vc { module_factory_with_code_generation_issue(Vc::upcast(self), availability_info) @@ -255,14 +246,13 @@ impl FromChunkableModule for Box { return Ok(None); }; - let Some(context) = - Vc::try_resolve_sidecast::>(chunking_context) - .await? + let item = placeable.as_chunk_item(Vc::upcast(chunking_context)); + let Some(ecmascript_item) = + Vc::try_resolve_downcast::>(item).await? else { return Ok(None); }; - - Ok(Some(placeable.as_chunk_item(context))) + Ok(Some(ecmascript_item)) } async fn from_async_asset( @@ -271,7 +261,7 @@ impl FromChunkableModule for Box { availability_info: Value, ) -> Result>> { let Some(context) = - Vc::try_resolve_sidecast::>(chunking_context) + Vc::try_resolve_downcast::>(chunking_context) .await? else { return Ok(None); @@ -296,7 +286,10 @@ impl FromChunkableModule for Box { let manifest_asset = ManifestChunkAsset::new(module, context, Value::new(next_availability_info)); - Ok(Some(Vc::upcast(ManifestLoaderItem::new(manifest_asset)))) + Ok(Some(Vc::upcast(ManifestLoaderItem::new( + manifest_asset, + chunking_context, + )))) } } diff --git a/crates/turbopack-ecmascript/src/chunk/mod.rs b/crates/turbopack-ecmascript/src/chunk/mod.rs index ee627599b79de..3d48a2ba3fccc 100644 --- a/crates/turbopack-ecmascript/src/chunk/mod.rs +++ b/crates/turbopack-ecmascript/src/chunk/mod.rs @@ -14,7 +14,8 @@ use turbo_tasks_fs::FileSystemPathOption; use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkingContext, Chunks, ModuleIds, + availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkItemExt, ChunkableModule, + ChunkingContext, Chunks, ModuleIds, }, ident::AssetIdent, introspect::{ @@ -76,7 +77,7 @@ impl EcmascriptChunk { availability_info: Value, ) -> Result> { let Some(context) = - Vc::try_resolve_sidecast::>(chunking_context) + Vc::try_resolve_downcast::>(chunking_context) .await? else { bail!("Ecmascript chunking context not found"); @@ -96,7 +97,7 @@ impl EcmascriptChunk { main_entry: Vc>, ) -> Result> { let Some(context) = - Vc::try_resolve_sidecast::>(chunking_context) + Vc::try_resolve_downcast::>(chunking_context) .await? else { bail!("Ecmascript chunking context not found"); @@ -165,7 +166,7 @@ impl EcmascriptChunk { .main_entries .await? .iter() - .map(|&entry| entry.as_chunk_item(this.chunking_context).id()) + .map(|&entry| entry.as_chunk_item(Vc::upcast(this.chunking_context)).id()) .collect(); Ok(Vc::cell(entries)) } diff --git a/crates/turbopack-ecmascript/src/chunk/placeable.rs b/crates/turbopack-ecmascript/src/chunk/placeable.rs index 04bcc7fe156e3..25000d3302e70 100644 --- a/crates/turbopack-ecmascript/src/chunk/placeable.rs +++ b/crates/turbopack-ecmascript/src/chunk/placeable.rs @@ -1,15 +1,10 @@ use turbo_tasks::Vc; use turbopack_core::{asset::Asset, chunk::ChunkableModule, module::Module}; -use super::{item::EcmascriptChunkItem, EcmascriptChunkingContext}; use crate::references::{async_module::OptionAsyncModule, esm::EsmExports}; #[turbo_tasks::value_trait] pub trait EcmascriptChunkPlaceable: ChunkableModule + Module + Asset { - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc>; fn get_exports(self: Vc) -> Vc; fn get_async_module(self: Vc) -> Vc { Vc::cell(None) diff --git a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs index c257d1b2b3533..20b2b98637693 100644 --- a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs +++ b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs @@ -1,12 +1,12 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use indexmap::IndexSet; use turbo_tasks::{TryJoinIterExt, Value, ValueToString, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkableModule, ChunkingContext, - EvaluatableAssets, + availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkableModule, ChunkableModuleExt, + ChunkingContext, EvaluatableAssets, }, ident::AssetIdent, introspect::{ @@ -90,28 +90,19 @@ impl Asset for ChunkGroupFilesAsset { #[turbo_tasks::value_impl] impl ChunkableModule for ChunkGroupFilesAsset { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for ChunkGroupFilesAsset { #[turbo_tasks::function] async fn as_chunk_item( self: Vc, - chunking_context: Vc>, - ) -> Result>> { + chunking_context: Vc>, + ) -> Result>> { let this = self.await?; + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + ChunkGroupFilesAsset", + )?; Ok(Vc::upcast( ChunkGroupFilesChunkItem { chunking_context, @@ -121,7 +112,10 @@ impl EcmascriptChunkPlaceable for ChunkGroupFilesAsset { .cell(), )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ChunkGroupFilesAsset { #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() @@ -226,6 +220,20 @@ impl ChunkItem for ChunkGroupFilesChunkItem { .collect(), )) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.inner), + availability_info, + )) + } } #[turbo_tasks::value_impl] diff --git a/crates/turbopack-ecmascript/src/lib.rs b/crates/turbopack-ecmascript/src/lib.rs index a1691a6b3dd7f..048c6017f803f 100644 --- a/crates/turbopack-ecmascript/src/lib.rs +++ b/crates/turbopack-ecmascript/src/lib.rs @@ -28,7 +28,7 @@ pub mod typescript; pub mod utils; pub mod webpack; -use anyhow::Result; +use anyhow::{Context, Result}; use chunk::{ EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkPlaceables, EcmascriptChunkingContext, }; @@ -404,32 +404,26 @@ impl Asset for EcmascriptModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for EcmascriptModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + EcmascriptModuleAsset", + )?; + Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { + module: self, chunking_context, - Vc::upcast(self), - availability_info, - )) + }))) } } #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for EcmascriptModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { - module: self, - chunking_context, - })) - } - #[turbo_tasks::function] async fn get_exports(self: Vc) -> Result> { Ok(self.failsafe_analyze().await?.exports) @@ -487,6 +481,20 @@ impl ChunkItem for ModuleChunkItem { fn references(&self) -> Vc { self.module.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] diff --git a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs index e99795a7f8814..05f9612a30f89 100644 --- a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs +++ b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs @@ -1,8 +1,11 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use turbo_tasks::{Value, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{availability_info::AvailabilityInfo, Chunk, ChunkableModule, ChunkingContext}, + chunk::{ + availability_info::AvailabilityInfo, Chunk, ChunkableModule, ChunkableModuleExt, + ChunkingContext, + }, ident::AssetIdent, module::Module, output::OutputAssets, @@ -10,10 +13,7 @@ use turbopack_core::{ }; use super::chunk_item::ManifestChunkItem; -use crate::chunk::{ - EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkPlaceable, EcmascriptChunkingContext, - EcmascriptExports, -}; +use crate::chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}; #[turbo_tasks::function] fn modifier() -> Vc { @@ -119,27 +119,18 @@ impl Asset for ManifestChunkAsset { #[turbo_tasks::value_impl] impl ChunkableModule for ManifestChunkAsset { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for ManifestChunkAsset { #[turbo_tasks::function] async fn as_chunk_item( self: Vc, - chunking_context: Vc>, - ) -> Result>> { + chunking_context: Vc>, + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + ManifestChunkAsset", + )?; Ok(Vc::upcast( ManifestChunkItem { chunking_context, @@ -148,7 +139,10 @@ impl EcmascriptChunkPlaceable for ManifestChunkAsset { .cell(), )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ManifestChunkAsset { #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() diff --git a/crates/turbopack-ecmascript/src/manifest/chunk_item.rs b/crates/turbopack-ecmascript/src/manifest/chunk_item.rs index 01f097fa0c8fd..7b327dff37987 100644 --- a/crates/turbopack-ecmascript/src/manifest/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/manifest/chunk_item.rs @@ -1,8 +1,11 @@ use anyhow::Result; use indoc::formatdoc; -use turbo_tasks::{TryJoinIterExt, Vc}; +use turbo_tasks::{TryJoinIterExt, Value, Vc}; use turbopack_core::{ - chunk::{ChunkData, ChunkItem, ChunkingContext, ChunksData}, + chunk::{ + availability_info::AvailabilityInfo, Chunk, ChunkData, ChunkItem, ChunkingContext, + ChunksData, + }, ident::AssetIdent, module::Module, reference::{ModuleReferences, SingleOutputAssetReference}, @@ -11,8 +14,8 @@ use turbopack_core::{ use super::chunk_asset::ManifestChunkAsset; use crate::{ chunk::{ - data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, - EcmascriptChunkingContext, + data::EcmascriptChunkData, EcmascriptChunk, EcmascriptChunkItem, + EcmascriptChunkItemContent, EcmascriptChunkingContext, }, utils::StringifyJs, }; @@ -91,4 +94,18 @@ impl ChunkItem for ManifestChunkItem { Ok(Vc::cell(references)) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.manifest), + availability_info, + )) + } } diff --git a/crates/turbopack-ecmascript/src/manifest/loader_item.rs b/crates/turbopack-ecmascript/src/manifest/loader_item.rs index 3f3338f9876a6..894a738d22ee2 100644 --- a/crates/turbopack-ecmascript/src/manifest/loader_item.rs +++ b/crates/turbopack-ecmascript/src/manifest/loader_item.rs @@ -2,9 +2,12 @@ use std::io::Write as _; use anyhow::{anyhow, Result}; use indoc::writedoc; -use turbo_tasks::{TryJoinIterExt, Vc}; +use turbo_tasks::{TryJoinIterExt, Value, Vc}; use turbopack_core::{ - chunk::{ChunkData, ChunkItem, ChunkingContext, ChunksData}, + chunk::{ + availability_info::AvailabilityInfo, Chunk, ChunkData, ChunkItem, ChunkItemExt, + ChunkableModule, ChunkingContext, ChunksData, + }, ident::AssetIdent, module::Module, reference::{ModuleReference, ModuleReferences, SingleOutputAssetReference}, @@ -13,7 +16,7 @@ use turbopack_core::{ use super::chunk_asset::ManifestChunkAsset; use crate::{ chunk::{ - data::EcmascriptChunkData, item::EcmascriptChunkItemExt, EcmascriptChunkItem, + data::EcmascriptChunkData, EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptChunkingContext, }, utils::StringifyJs, @@ -39,22 +42,28 @@ fn modifier() -> Vc { #[turbo_tasks::value] pub struct ManifestLoaderItem { manifest: Vc, + chunking_context: Vc>, } #[turbo_tasks::value_impl] impl ManifestLoaderItem { #[turbo_tasks::function] - pub fn new(manifest: Vc) -> Vc { - Self::cell(ManifestLoaderItem { manifest }) + pub fn new( + manifest: Vc, + chunking_context: Vc>, + ) -> Vc { + Self::cell(ManifestLoaderItem { + manifest, + chunking_context, + }) } #[turbo_tasks::function] pub async fn chunks_data(self: Vc) -> Result> { let this = self.await?; let chunks = this.manifest.manifest_chunks(); - let manifest = this.manifest.await?; Ok(ChunkData::from_assets( - manifest.chunking_context.output_root(), + this.chunking_context.output_root(), chunks, )) } @@ -105,6 +114,20 @@ impl ChunkItem for ManifestLoaderItem { Ok(Vc::cell(references)) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Result>> { + Ok(Vc::upcast(self.chunking_context)) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + self.chunking_context, + Vc::upcast(self.manifest), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -131,7 +154,7 @@ impl EcmascriptChunkItem for ManifestLoaderItem { // exports a promise for all of the necessary chunk loads. let item_id = &*this .manifest - .as_chunk_item(manifest.chunking_context) + .as_chunk_item(Vc::upcast(manifest.chunking_context)) .id() .await?; @@ -142,7 +165,7 @@ impl EcmascriptChunkItem for ManifestLoaderItem { .await? .ok_or_else(|| anyhow!("asset is not placeable in ecmascript chunk"))?; let dynamic_id = &*placeable - .as_chunk_item(manifest.chunking_context) + .as_chunk_item(Vc::upcast(manifest.chunking_context)) .id() .await?; diff --git a/crates/turbopack-ecmascript/src/references/esm/base.rs b/crates/turbopack-ecmascript/src/references/esm/base.rs index a23ecae70b3b9..42f0fd4b2c9cd 100644 --- a/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -8,7 +8,8 @@ use swc_core::{ use turbo_tasks::{Value, ValueToString, Vc}; use turbopack_core::{ chunk::{ - ChunkableModuleReference, ChunkingContext, ChunkingType, ChunkingTypeOption, ModuleId, + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, ModuleId, }, issue::{IssueSeverity, OptionIssueSource}, module::Module, @@ -23,7 +24,7 @@ use turbopack_core::{ use crate::{ analyzer::imports::ImportAnnotations, - chunk::{item::EcmascriptChunkItemExt, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext}, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, magic_identifier, references::util::{request_to_string, throw_module_not_found_expr}, @@ -233,7 +234,10 @@ impl CodeGenerateable for EsmAssetReference { if let Some(ident) = referenced_asset.get_ident().await? { match &*referenced_asset { ReferencedAsset::Some(asset) => { - let id = asset.as_chunk_item(chunking_context).id().await?; + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { let stmt = quote!( "var $name = __turbopack_import__($id);" as Stmt, diff --git a/crates/turbopack-ecmascript/src/references/esm/module_id.rs b/crates/turbopack-ecmascript/src/references/esm/module_id.rs index 2443692717eb8..ab74a9ba90cc9 100644 --- a/crates/turbopack-ecmascript/src/references/esm/module_id.rs +++ b/crates/turbopack-ecmascript/src/references/esm/module_id.rs @@ -2,14 +2,16 @@ use anyhow::Result; use swc_core::{ecma::ast::Expr, quote}; use turbo_tasks::{ValueToString, Vc}; use turbopack_core::{ - chunk::{ChunkableModuleReference, ChunkingTypeOption, ModuleId}, + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingTypeOption, ModuleId, + }, reference::ModuleReference, resolve::ModuleResolveResult, }; use super::{base::ReferencedAsset, EsmAssetReference}; use crate::{ - chunk::{item::EcmascriptChunkItemExt, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -67,13 +69,17 @@ impl CodeGenerateable for EsmModuleIdAssetReference { let mut visitors = Vec::new(); if let ReferencedAsset::Some(asset) = &*self.inner.get_referenced_asset().await? { - let id = asset.as_chunk_item(chunking_context).id().await?; + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + let id = Expr::Lit(match &*id { + ModuleId::String(s) => s.clone().into(), + ModuleId::Number(n) => (*n as f64).into(), + }); visitors.push( create_visitor!(self.ast_path.await?, visit_mut_expr(expr: &mut Expr) { - *expr = Expr::Lit(match &*id { - ModuleId::String(s) => s.clone().into(), - ModuleId::Number(n) => (*n as f64).into(), - }) + *expr = id.clone() }), ); } else { diff --git a/crates/turbopack-ecmascript/src/references/esm/url.rs b/crates/turbopack-ecmascript/src/references/esm/url.rs index bf58806b53959..28e4c6d845c10 100644 --- a/crates/turbopack-ecmascript/src/references/esm/url.rs +++ b/crates/turbopack-ecmascript/src/references/esm/url.rs @@ -5,7 +5,9 @@ use swc_core::{ }; use turbo_tasks::{Value, ValueToString, Vc}; use turbopack_core::{ - chunk::{ChunkableModuleReference, ChunkingType, ChunkingTypeOption}, + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingType, ChunkingTypeOption, + }, environment::Rendering, issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity, IssueSource}, reference::ModuleReference, @@ -15,7 +17,7 @@ use turbopack_core::{ use super::base::ReferencedAsset; use crate::{ - chunk::{item::EcmascriptChunkItemExt, EcmascriptChunkPlaceable, EcmascriptChunkingContext}, + chunk::EcmascriptChunkingContext, code_gen::{CodeGenerateable, CodeGeneration}, create_visitor, references::AstPath, @@ -151,7 +153,10 @@ impl CodeGenerateable for UrlAssetReference { ReferencedAsset::Some(asset) => { // We rewrite the first `new URL()` arguments to be a require() of the chunk // item, which exports the static asset path to the linked file. - let id = asset.as_chunk_item(chunking_context).id().await?; + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; visitors.push( create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) { diff --git a/crates/turbopack-ecmascript/src/references/pattern_mapping.rs b/crates/turbopack-ecmascript/src/references/pattern_mapping.rs index 6c05ceb2b5139..4cbb6c37304aa 100644 --- a/crates/turbopack-ecmascript/src/references/pattern_mapping.rs +++ b/crates/turbopack-ecmascript/src/references/pattern_mapping.rs @@ -7,8 +7,8 @@ use swc_core::{ use turbo_tasks::{debug::ValueDebug, Value, Vc}; use turbopack_core::{ chunk::{ - availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext, FromChunkableModule, - ModuleId, + availability_info::AvailabilityInfo, ChunkItemExt, ChunkableModule, ChunkingContext, + FromChunkableModule, ModuleId, }, issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity}, resolve::{ @@ -17,10 +17,7 @@ use turbopack_core::{ }; use super::util::{request_to_string, throw_module_not_found_expr}; -use crate::{ - chunk::{item::EcmascriptChunkItemExt, EcmascriptChunkItem}, - utils::module_id_to_lit, -}; +use crate::{chunk::EcmascriptChunkItem, utils::module_id_to_lit}; /// A mapping from a request pattern (e.g. "./module", `./images/${name}.png`) /// to corresponding module ids. The same pattern can map to multiple module ids diff --git a/crates/turbopack-ecmascript/src/references/require_context.rs b/crates/turbopack-ecmascript/src/references/require_context.rs index 36116a171795f..79a8d3001161e 100644 --- a/crates/turbopack-ecmascript/src/references/require_context.rs +++ b/crates/turbopack-ecmascript/src/references/require_context.rs @@ -1,6 +1,6 @@ use std::{collections::VecDeque, sync::Arc}; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indexmap::IndexMap; use swc_core::{ common::DUMMY_SP, @@ -18,7 +18,7 @@ use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemPath}; use turbopack_core::{ asset::{Asset, AssetContent}, chunk::{ - availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkableModule, + availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, }, ident::AssetIdent, @@ -31,8 +31,8 @@ use turbopack_core::{ use crate::{ chunk::{ - item::EcmascriptChunkItemExt, EcmascriptChunk, EcmascriptChunkItem, - EcmascriptChunkItemContent, EcmascriptChunkingContext, EcmascriptExports, + EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkItemContent, + EcmascriptChunkingContext, EcmascriptExports, }, code_gen::CodeGeneration, create_visitor, @@ -282,7 +282,7 @@ impl CodeGenerateable for RequireContextAssetReference { &self, chunking_context: Vc>, ) -> Result> { - let chunk_item = self.inner.as_chunk_item(chunking_context); + let chunk_item = self.inner.as_chunk_item(Vc::upcast(chunking_context)); let module_id = chunk_item.id().await?.clone_value(); let mut visitors = Vec::new(); @@ -374,27 +374,18 @@ impl Asset for RequireContextAsset { #[turbo_tasks::value_impl] impl ChunkableModule for RequireContextAsset { - #[turbo_tasks::function] - fn as_chunk( - self: Vc, - chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for RequireContextAsset { #[turbo_tasks::function] async fn as_chunk_item( self: Vc, - chunking_context: Vc>, - ) -> Result>> { + chunking_context: Vc>, + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + RequireContextAsset", + )?; let this = self.await?; Ok(Vc::upcast( RequireContextChunkItem { @@ -407,7 +398,10 @@ impl EcmascriptChunkPlaceable for RequireContextAsset { .cell(), )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for RequireContextAsset { #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() @@ -515,4 +509,18 @@ impl ChunkItem for RequireContextChunkItem { fn references(&self) -> Vc { self.inner.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.inner), + availability_info, + )) + } } diff --git a/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/crates/turbopack-ecmascript/src/tree_shake/asset.rs index 5ec7e1c784bb8..aca45d5a033a6 100644 --- a/crates/turbopack-ecmascript/src/tree_shake/asset.rs +++ b/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -1,8 +1,8 @@ use anyhow::{bail, Context, Result}; -use turbo_tasks::{Value, Vc}; +use turbo_tasks::Vc; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{availability_info::AvailabilityInfo, Chunk, ChunkableModule, ChunkingContext}, + chunk::{ChunkableModule, ChunkingContext}, ident::AssetIdent, module::Module, reference::{ModuleReferences, SingleModuleReference}, @@ -11,10 +11,7 @@ use turbopack_core::{ use super::{chunk_item::EcmascriptModulePartChunkItem, get_part_id, split_module, SplitResult}; use crate::{ - chunk::{ - EcmascriptChunk, EcmascriptChunkItem, EcmascriptChunkPlaceable, EcmascriptChunkingContext, - EcmascriptExports, - }, + chunk::{EcmascriptChunkPlaceable, EcmascriptChunkingContext, EcmascriptExports}, references::analyze_ecmascript_module, AnalyzeEcmascriptModuleResult, EcmascriptModuleAsset, }; @@ -108,20 +105,6 @@ impl Asset for EcmascriptModulePartAsset { #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { - #[turbo_tasks::function] - async fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Result>> { - Ok(Vc::upcast( - EcmascriptModulePartChunkItem { - module: self, - chunking_context, - } - .cell(), - )) - } - #[turbo_tasks::function] async fn get_exports(self: Vc) -> Result> { Ok(self.analyze().await?.exports) @@ -131,15 +114,23 @@ impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { #[turbo_tasks::value_impl] impl ChunkableModule for EcmascriptModulePartAsset { #[turbo_tasks::function] - async fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + EcmascriptModulePartAsset", + )?; + Ok(Vc::upcast( + EcmascriptModulePartChunkItem { + module: self, + chunking_context, + } + .cell(), )) } } diff --git a/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs index 4e9939a1b866b..3d0b9c60854a2 100644 --- a/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs +++ b/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -1,7 +1,7 @@ use anyhow::Result; use turbo_tasks::{Value, Vc}; use turbopack_core::{ - chunk::{availability_info::AvailabilityInfo, ChunkItem}, + chunk::{availability_info::AvailabilityInfo, Chunk, ChunkItem, ChunkingContext}, ident::AssetIdent, module::Module, reference::ModuleReferences, @@ -10,8 +10,8 @@ use turbopack_core::{ use super::{asset::EcmascriptModulePartAsset, part_of_module, split_module}; use crate::{ chunk::{ - placeable::EcmascriptChunkPlaceable, EcmascriptChunkItem, EcmascriptChunkItemContent, - EcmascriptChunkingContext, + placeable::EcmascriptChunkPlaceable, EcmascriptChunk, EcmascriptChunkItem, + EcmascriptChunkItemContent, EcmascriptChunkingContext, }, EcmascriptModuleContent, }; @@ -86,4 +86,18 @@ impl ChunkItem for EcmascriptModulePartChunkItem { async fn asset_ident(&self) -> Result> { Ok(self.module.ident()) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } diff --git a/crates/turbopack-json/src/lib.rs b/crates/turbopack-json/src/lib.rs index 8081229976857..e9ceeffc3555f 100644 --- a/crates/turbopack-json/src/lib.rs +++ b/crates/turbopack-json/src/lib.rs @@ -11,7 +11,7 @@ use std::fmt::Write; -use anyhow::{bail, Error, Result}; +use anyhow::{bail, Context, Error, Result}; use turbo_tasks::{Value, ValueToString, Vc}; use turbo_tasks_fs::{FileContent, FileJsonContent}; use turbopack_core::{ @@ -66,32 +66,25 @@ impl Asset for JsonModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for JsonModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use JsonModuleAsset", + )?; + Ok(Vc::upcast(JsonChunkItem::cell(JsonChunkItem { + module: self, chunking_context, - Vc::upcast(self), - availability_info, - )) + }))) } } #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for JsonModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast(JsonChunkItem::cell(JsonChunkItem { - module: self, - chunking_context, - })) - } - #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() @@ -115,6 +108,20 @@ impl ChunkItem for JsonChunkItem { fn references(&self) -> Vc { self.module.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] diff --git a/crates/turbopack-mdx/src/lib.rs b/crates/turbopack-mdx/src/lib.rs index 116b96e222539..2f0640113077c 100644 --- a/crates/turbopack-mdx/src/lib.rs +++ b/crates/turbopack-mdx/src/lib.rs @@ -2,7 +2,7 @@ #![feature(arbitrary_self_types)] #![feature(async_fn_in_trait)] -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use mdxjs::{compile, Options}; use turbo_tasks::{Value, ValueDefault, Vc}; use turbo_tasks_fs::{rope::Rope, File, FileContent, FileSystemPath}; @@ -189,32 +189,25 @@ impl Asset for MdxModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for MdxModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use MdxModuleAsset", + )?; + Ok(Vc::upcast(MdxChunkItem::cell(MdxChunkItem { + module: self, chunking_context, - Vc::upcast(self), - availability_info, - )) + }))) } } #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for MdxModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast(MdxChunkItem::cell(MdxChunkItem { - module: self, - chunking_context, - })) - } - #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.cell() @@ -251,6 +244,20 @@ impl ChunkItem for MdxChunkItem { fn references(&self) -> Vc { self.module.references() } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -264,10 +271,13 @@ impl EcmascriptChunkItem for MdxChunkItem { /// apply all of the ecma transforms #[turbo_tasks::function] async fn content(&self) -> Result> { - Ok(into_ecmascript_module_asset(&self.module) + let item = into_ecmascript_module_asset(&self.module) + .await? + .as_chunk_item(Vc::upcast(self.chunking_context)); + let ecmascript_item = Vc::try_resolve_downcast::>(item) .await? - .as_chunk_item(self.chunking_context) - .content()) + .context("MdxChunkItem must generate an EcmascriptChunkItem")?; + Ok(ecmascript_item.content()) } } diff --git a/crates/turbopack-node/src/evaluate.rs b/crates/turbopack-node/src/evaluate.rs index c06b1a59f7cc3..aa3385af692f3 100644 --- a/crates/turbopack-node/src/evaluate.rs +++ b/crates/turbopack-node/src/evaluate.rs @@ -22,7 +22,7 @@ use turbo_tasks_fs::{ }; use turbopack_core::{ asset::AssetContent, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset, EvaluatableAssets}, + chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAsset, EvaluatableAssets}, context::AssetContext, file_source::FileSource, ident::AssetIdent, diff --git a/crates/turbopack-node/src/lib.rs b/crates/turbopack-node/src/lib.rs index ea42d53e670b6..42a753ea5c7f1 100644 --- a/crates/turbopack-node/src/lib.rs +++ b/crates/turbopack-node/src/lib.rs @@ -17,7 +17,7 @@ use turbo_tasks_env::ProcessEnv; use turbo_tasks_fs::{to_sys_path, File, FileSystemPath}; use turbopack_core::{ asset::{Asset, AssetContent}, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset, EvaluatableAssets}, + chunk::{ChunkableModuleExt, ChunkingContext, EvaluatableAsset, EvaluatableAssets}, module::Module, output::{OutputAsset, OutputAssetsSet}, source_map::GenerateSourceMap, diff --git a/crates/turbopack-static/src/lib.rs b/crates/turbopack-static/src/lib.rs index b637a335642f7..1a3b9aeb5d062 100644 --- a/crates/turbopack-static/src/lib.rs +++ b/crates/turbopack-static/src/lib.rs @@ -14,7 +14,7 @@ pub mod fixed; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use turbo_tasks::{Value, ValueToString, Vc}; use turbo_tasks_fs::FileContent; use turbopack_core::{ @@ -91,33 +91,26 @@ impl Asset for StaticModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for StaticModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use StaticModuleAsset", + )?; + Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { + module: self, chunking_context, - Vc::upcast(self), - availability_info, - )) + static_asset: self.static_asset(Vc::upcast(chunking_context)), + }))) } } #[turbo_tasks::value_impl] impl EcmascriptChunkPlaceable for StaticModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { - module: self, - chunking_context, - static_asset: self.static_asset(Vc::upcast(chunking_context)), - })) - } - #[turbo_tasks::function] fn get_exports(&self) -> Vc { EcmascriptExports::Value.into() @@ -197,6 +190,20 @@ impl ChunkItem for ModuleChunkItem { )), ))])) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index 6196ad3540457..9c8da2f1ea4d6 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -29,7 +29,10 @@ use turbopack::{ use turbopack_build::{BuildChunkingContext, MinifyType}; use turbopack_core::{ asset::Asset, - chunk::{ChunkableModule, ChunkingContext, EvaluatableAssetExt, EvaluatableAssets}, + chunk::{ + ChunkableModule, ChunkableModuleExt, ChunkingContext, EvaluatableAssetExt, + EvaluatableAssets, + }, compile_time_defines, compile_time_info::CompileTimeInfo, context::AssetContext, diff --git a/crates/turbopack-wasm/src/module_asset.rs b/crates/turbopack-wasm/src/module_asset.rs index bac27d6cf9f20..1d0a65484b1d0 100644 --- a/crates/turbopack-wasm/src/module_asset.rs +++ b/crates/turbopack-wasm/src/module_asset.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indexmap::indexmap; use turbo_tasks::{Value, Vc}; use turbo_tasks_fs::FileSystemPath; @@ -115,35 +115,29 @@ impl Asset for WebAssemblyModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for WebAssemblyModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for WebAssemblyModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + WebAssemblyModuleAsset", + )?; + Ok(Vc::upcast( ModuleChunkItem { module: self, chunking_context, } .cell(), - ) + )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for WebAssemblyModuleAsset { #[turbo_tasks::function] fn get_exports(self: Vc) -> Vc { self.loader().get_exports() @@ -188,10 +182,27 @@ impl ChunkItem for ModuleChunkItem { #[turbo_tasks::function] async fn references(&self) -> Result> { - let loader = self.module.loader().as_chunk_item(self.chunking_context); + let loader = self + .module + .loader() + .as_chunk_item(Vc::upcast(self.chunking_context)); Ok(loader.references()) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl] @@ -212,9 +223,13 @@ impl EcmascriptChunkItem for ModuleChunkItem { availability_info: Value, ) -> Result> { let loader_asset = self.module.loader(); + let item = loader_asset.as_chunk_item(Vc::upcast(self.chunking_context)); + + let ecmascript_item = Vc::try_resolve_downcast::>(item) + .await? + .context("EcmascriptModuleAsset must implement EcmascriptChunkItem")?; - let chunk_item_content = loader_asset - .as_chunk_item(self.chunking_context) + let chunk_item_content = ecmascript_item .content_with_availability_info(availability_info) .await?; diff --git a/crates/turbopack-wasm/src/raw.rs b/crates/turbopack-wasm/src/raw.rs index 9a70e8d2a9d98..00a80845251a8 100644 --- a/crates/turbopack-wasm/src/raw.rs +++ b/crates/turbopack-wasm/src/raw.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use turbo_tasks::{Value, ValueToString, Vc}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -73,36 +73,30 @@ impl Asset for RawWebAssemblyModuleAsset { #[turbo_tasks::value_impl] impl ChunkableModule for RawWebAssemblyModuleAsset { #[turbo_tasks::function] - fn as_chunk( + async fn as_chunk_item( self: Vc, chunking_context: Vc>, - availability_info: Value, - ) -> Vc> { - Vc::upcast(EcmascriptChunk::new( - chunking_context, - Vc::upcast(self), - availability_info, - )) - } -} - -#[turbo_tasks::value_impl] -impl EcmascriptChunkPlaceable for RawWebAssemblyModuleAsset { - #[turbo_tasks::function] - fn as_chunk_item( - self: Vc, - chunking_context: Vc>, - ) -> Vc> { - Vc::upcast( + ) -> Result>> { + let chunking_context = + Vc::try_resolve_downcast::>(chunking_context) + .await? + .context( + "chunking context must impl EcmascriptChunkingContext to use \ + RawWebAssemblyModuleAsset", + )?; + Ok(Vc::upcast( RawModuleChunkItem { module: self, chunking_context, wasm_asset: self.wasm_asset(Vc::upcast(chunking_context)), } .cell(), - ) + )) } +} +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for RawWebAssemblyModuleAsset { #[turbo_tasks::function] fn get_exports(self: Vc) -> Vc { EcmascriptExports::Value.cell() @@ -133,6 +127,20 @@ impl ChunkItem for RawModuleChunkItem { )), ))])) } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn as_chunk(&self, availability_info: Value) -> Vc> { + Vc::upcast(EcmascriptChunk::new( + Vc::upcast(self.chunking_context), + Vc::upcast(self.module), + availability_info, + )) + } } #[turbo_tasks::value_impl]