Skip to content

Commit

Permalink
Ensure output assets reference only output assets (#5557)
Browse files Browse the repository at this point in the history
### Description

Ensure output assets reference only output assets

next.js PR: vercel/next.js#52832
  • Loading branch information
sokra authored Jul 18, 2023
1 parent 22f0bf4 commit 3eb3a5f
Show file tree
Hide file tree
Showing 35 changed files with 176 additions and 580 deletions.
22 changes: 11 additions & 11 deletions crates/turbopack-build/src/ecmascript/node/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use turbopack_core::{
chunk::{Chunk, ChunkingContext},
ident::AssetIdent,
introspect::{Introspectable, IntrospectableChildren},
output::OutputAsset,
reference::AssetReferences,
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAssetReference},
output::{OutputAsset, OutputAssets},
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset},
};
use turbopack_ecmascript::chunk::EcmascriptChunk;

Expand Down Expand Up @@ -70,21 +69,22 @@ impl OutputAsset for EcmascriptBuildNodeChunk {
}

#[turbo_tasks::function]
async fn references(self: Vc<Self>) -> Result<Vc<AssetReferences>> {
async fn references(self: Vc<Self>) -> Result<Vc<OutputAssets>> {
let this = self.await?;
let chunk_references = this.chunk.references().await?;
let mut references = Vec::with_capacity(chunk_references.len() + 1);
let include_source_map = *this
.chunking_context
.reference_chunk_source_maps(Vc::upcast(self))
.await?;
let mut references =
Vec::with_capacity(chunk_references.len() + if include_source_map { 1 } else { 0 });

for reference in &*chunk_references {
references.push(*reference);
}

if *this
.chunking_context
.reference_chunk_source_maps(Vc::upcast(self))
.await?
{
references.push(Vc::upcast(SourceMapAssetReference::new(Vc::upcast(self))));
if include_source_map {
references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self))));
}

Ok(Vc::cell(references))
Expand Down
29 changes: 9 additions & 20 deletions crates/turbopack-build/src/ecmascript/node/entry/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ use turbopack_core::{
code_builder::{Code, CodeBuilder},
ident::AssetIdent,
output::{OutputAsset, OutputAssets},
reference::{AssetReferences, SingleAssetReference},
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAssetReference},
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset},
};
use turbopack_ecmascript::{
chunk::{EcmascriptChunkItemExt, EcmascriptChunkPlaceable},
utils::StringifyJs,
};

use super::runtime::EcmascriptBuildNodeRuntimeReference;
use super::runtime::EcmascriptBuildNodeRuntimeChunk;
use crate::BuildChunkingContext;

/// An Ecmascript chunk that loads a list of parallel chunks, then instantiates
Expand Down Expand Up @@ -60,12 +59,7 @@ impl EcmascriptBuildNodeEntryChunk {
let output_root = this.chunking_context.output_root().await?;
let chunk_path = self.ident().path().await?;
let chunk_directory = self.ident().path().parent().await?;
let runtime_path = self
.runtime_reference()
.runtime_chunk()
.ident()
.path()
.await?;
let runtime_path = self.runtime_chunk().ident().path().await?;
let runtime_relative_path =
if let Some(path) = chunk_directory.get_relative_path_to(&runtime_path) {
path
Expand Down Expand Up @@ -153,11 +147,9 @@ impl EcmascriptBuildNodeEntryChunk {
}

#[turbo_tasks::function]
async fn runtime_reference(self: Vc<Self>) -> Result<Vc<EcmascriptBuildNodeRuntimeReference>> {
async fn runtime_chunk(self: Vc<Self>) -> Result<Vc<EcmascriptBuildNodeRuntimeChunk>> {
let this = self.await?;
Ok(EcmascriptBuildNodeRuntimeReference::new(
this.chunking_context,
))
Ok(EcmascriptBuildNodeRuntimeChunk::new(this.chunking_context))
}
}

Expand Down Expand Up @@ -187,24 +179,21 @@ impl OutputAsset for EcmascriptBuildNodeEntryChunk {
}

#[turbo_tasks::function]
async fn references(self: Vc<Self>) -> Result<Vc<AssetReferences>> {
async fn references(self: Vc<Self>) -> Result<Vc<OutputAssets>> {
let this = self.await?;
let mut references = vec![Vc::upcast(self.runtime_reference())];
let mut references = vec![Vc::upcast(self.runtime_chunk())];

if *this
.chunking_context
.reference_chunk_source_maps(Vc::upcast(self))
.await?
{
references.push(Vc::upcast(SourceMapAssetReference::new(Vc::upcast(self))))
references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self))))
}

let other_chunks = this.other_chunks.await?;
for &other_chunk in &*other_chunks {
references.push(Vc::upcast(SingleAssetReference::new(
Vc::upcast(other_chunk),
chunk_reference_description(),
)));
references.push(Vc::upcast(other_chunk));
}

Ok(Vc::cell(references))
Expand Down
50 changes: 4 additions & 46 deletions crates/turbopack-build/src/ecmascript/node/entry/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ use turbopack_core::{
chunk::ChunkingContext,
code_builder::{Code, CodeBuilder},
ident::AssetIdent,
output::OutputAsset,
reference::{AssetReference, AssetReferences},
resolve::ResolveResult,
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAssetReference},
output::{OutputAsset, OutputAssets},
source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset},
};
use turbopack_ecmascript::utils::StringifyJs;
use turbopack_ecmascript_runtime::RuntimeType;
Expand Down Expand Up @@ -99,7 +97,7 @@ impl OutputAsset for EcmascriptBuildNodeRuntimeChunk {
}

#[turbo_tasks::function]
async fn references(self: Vc<Self>) -> Result<Vc<AssetReferences>> {
async fn references(self: Vc<Self>) -> Result<Vc<OutputAssets>> {
let this = self.await?;
let mut references = vec![];

Expand All @@ -108,7 +106,7 @@ impl OutputAsset for EcmascriptBuildNodeRuntimeChunk {
.reference_chunk_source_maps(Vc::upcast(self))
.await?
{
references.push(Vc::upcast(SourceMapAssetReference::new(Vc::upcast(self))))
references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self))))
}

Ok(Vc::cell(references))
Expand All @@ -133,43 +131,3 @@ impl GenerateSourceMap for EcmascriptBuildNodeRuntimeChunk {
self.code().generate_source_map()
}
}

/// A reference to the runtime chunk.
#[turbo_tasks::value]
pub(crate) struct EcmascriptBuildNodeRuntimeReference {
chunking_context: Vc<BuildChunkingContext>,
}

#[turbo_tasks::value_impl]
impl EcmascriptBuildNodeRuntimeReference {
#[turbo_tasks::function]
pub fn new(chunking_context: Vc<BuildChunkingContext>) -> Vc<Self> {
Self::cell(EcmascriptBuildNodeRuntimeReference { chunking_context })
}

#[turbo_tasks::function]
pub async fn runtime_chunk(self: Vc<Self>) -> Result<Vc<EcmascriptBuildNodeRuntimeChunk>> {
Ok(EcmascriptBuildNodeRuntimeChunk::new(
self.await?.chunking_context,
))
}
}

#[turbo_tasks::value_impl]
impl AssetReference for EcmascriptBuildNodeRuntimeReference {
#[turbo_tasks::function]
fn resolve_reference(self: Vc<Self>) -> Vc<ResolveResult> {
ResolveResult::asset(Vc::upcast(self.runtime_chunk())).into()
}
}

#[turbo_tasks::value_impl]
impl ValueToString for EcmascriptBuildNodeRuntimeReference {
#[turbo_tasks::function]
async fn to_string(self: Vc<Self>) -> Result<Vc<String>> {
Ok(Vc::cell(format!(
"runtime chunk {}",
self.runtime_chunk().ident().to_string().await?
)))
}
}
7 changes: 2 additions & 5 deletions crates/turbopack-core/src/changed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ use crate::{
asset::Asset,
module::Module,
output::{OutputAsset, OutputAssets},
reference::{all_referenced_modules, all_referenced_output_assets},
reference::all_referenced_modules,
};

async fn get_referenced_output_assets(
parent: Vc<Box<dyn OutputAsset>>,
) -> Result<impl Iterator<Item = Vc<Box<dyn OutputAsset>>> + Send> {
Ok(all_referenced_output_assets(parent)
.await?
.clone_value()
.into_iter())
Ok(parent.references().await?.clone_value().into_iter())
}

async fn get_referenced_modules(
Expand Down
22 changes: 7 additions & 15 deletions crates/turbopack-core/src/chunk/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use turbo_tasks_fs::FileSystemPath;
use crate::{
chunk::{ModuleId, OutputChunk, OutputChunkRuntimeInfo},
output::{OutputAsset, OutputAssets},
reference::{AssetReferences, SingleAssetReference},
};

#[turbo_tasks::value]
Expand All @@ -14,7 +13,7 @@ pub struct ChunkData {
pub included: Vec<ReadRef<ModuleId>>,
pub excluded: Vec<ReadRef<ModuleId>>,
pub module_chunks: Vec<String>,
pub references: Vc<AssetReferences>,
pub references: Vc<OutputAssets>,
}

#[turbo_tasks::value(transparent)]
Expand Down Expand Up @@ -57,7 +56,7 @@ impl ChunkData {
included: Vec::new(),
excluded: Vec::new(),
module_chunks: Vec::new(),
references: AssetReferences::empty(),
references: OutputAssets::empty(),
}
.cell(),
)));
Expand Down Expand Up @@ -92,15 +91,9 @@ impl ChunkData {

async move {
let chunk_path = chunk.ident().path().await?;
Ok(output_root.get_path_to(&chunk_path).map(|path| {
(
path.to_owned(),
Vc::upcast(SingleAssetReference::new(
Vc::upcast(chunk),
module_chunk_reference_description(),
)),
)
}))
Ok(output_root
.get_path_to(&chunk_path)
.map(|path| (path.to_owned(), chunk)))
}
})
.try_join()
Expand Down Expand Up @@ -142,10 +135,9 @@ impl ChunkData {
))
}

/// Returns [`AssetReferences`] to the assets that this chunk data
/// references.
/// Returns [`OutputAsset`]s that this chunk data references.
#[turbo_tasks::function]
pub async fn references(self: Vc<Self>) -> Result<Vc<AssetReferences>> {
pub async fn references(self: Vc<Self>) -> Result<Vc<OutputAssets>> {
Ok(self.await?.references)
}
}
4 changes: 2 additions & 2 deletions crates/turbopack-core/src/chunk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ pub trait Chunk: Asset {

/// Other things (most likely [Asset]s) referenced from this [Chunk].
// TODO refactor this to ensure that only [OutputAsset]s can be referenced
fn references(self: Vc<Self>) -> Vc<AssetReferences> {
AssetReferences::empty()
fn references(self: Vc<Self>) -> Vc<OutputAssets> {
OutputAssets::empty()
}
}

Expand Down
17 changes: 15 additions & 2 deletions crates/turbopack-core/src/introspect/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
asset::{Asset, AssetContent},
chunk::{ChunkableModuleReference, ChunkingType},
module::Module,
output::OutputAsset,
output::{OutputAsset, OutputAssets},
reference::{AssetReference, AssetReferences},
resolve::PrimaryResolveResult,
source::Source,
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Introspectable for IntrospectableAsset {
} else if let Some(output_asset) =
Vc::try_resolve_downcast::<Box<dyn OutputAsset>>(asset).await?
{
children_from_asset_references(output_asset.references())
children_from_output_assets(output_asset.references())
} else {
bail!("unknown type")
},
Expand Down Expand Up @@ -163,3 +163,16 @@ pub async fn children_from_asset_references(
}
Ok(Vc::cell(children))
}

#[turbo_tasks::function]
pub async fn children_from_output_assets(
references: Vc<OutputAssets>,
) -> Result<Vc<IntrospectableChildren>> {
let key = reference_ty();
let mut children = IndexSet::new();
let references = references.await?;
for &reference in &*references {
children.insert((key, IntrospectableAsset::new(Vc::upcast(reference))));
}
Ok(Vc::cell(children))
}
9 changes: 4 additions & 5 deletions crates/turbopack-core/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use anyhow::{Context, Result};
use indexmap::IndexSet;
use turbo_tasks::Vc;

use crate::{asset::Asset, ident::AssetIdent, reference::AssetReferences};
use crate::{asset::Asset, ident::AssetIdent};

/// An asset that should be outputted, e. g. written to disk or served from a
/// server.
Expand All @@ -13,10 +13,9 @@ pub trait OutputAsset: Asset {
/// capture all properties of the [OutputAsset]. Only path must be used.
fn ident(&self) -> Vc<AssetIdent>;

/// Other things (most likely [Asset]s) referenced from this [OutputAsset].
// TODO refactor this to ensure that only [OutputAsset]s can be referenced
fn references(self: Vc<Self>) -> Vc<AssetReferences> {
AssetReferences::empty()
/// Other references [OutputAsset]s from this [OutputAsset].
fn references(self: Vc<Self>) -> Vc<OutputAssets> {
OutputAssets::empty()
}
}

Expand Down
5 changes: 2 additions & 3 deletions crates/turbopack-core/src/proxied_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use turbo_tasks_fs::FileSystemPath;
use crate::{
asset::{Asset, AssetContent},
ident::AssetIdent,
output::OutputAsset,
reference::AssetReferences,
output::{OutputAsset, OutputAssets},
version::VersionedContent,
};

Expand Down Expand Up @@ -36,7 +35,7 @@ impl OutputAsset for ProxiedAsset {
}

#[turbo_tasks::function]
fn references(&self) -> Vc<AssetReferences> {
fn references(&self) -> Vc<OutputAssets> {
self.asset.references()
}
}
Expand Down
Loading

0 comments on commit 3eb3a5f

Please sign in to comment.