Skip to content

Commit

Permalink
refactor ResolveResult to allow mixing special and assets in alternat…
Browse files Browse the repository at this point in the history
…ives (vercel/turborepo#3675)

Co-authored-by: Justin Ridgewell <justin@ridgewell.name>
  • Loading branch information
sokra and jridgewell committed Feb 7, 2023
1 parent 49505e9 commit ab45970
Show file tree
Hide file tree
Showing 29 changed files with 401 additions and 408 deletions.
2 changes: 1 addition & 1 deletion crates/next-core/src/next_client_chunks/with_chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl ValueToString for WithChunksAssetReference {
impl AssetReference for WithChunksAssetReference {
#[turbo_tasks::function]
fn resolve_reference(&self) -> ResolveResultVc {
ResolveResult::Single(self.asset, Vec::new()).cell()
ResolveResult::asset(self.asset).cell()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ impl ValueToString for WithClientChunksAssetReference {
impl AssetReference for WithClientChunksAssetReference {
#[turbo_tasks::function]
fn resolve_reference(&self) -> ResolveResultVc {
ResolveResult::Single(self.asset, Vec::new()).cell()
ResolveResult::asset(self.asset).cell()
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/next-core/src/next_font_google/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl ImportMappingReplacement for NextFontGoogleReplacer {
.into(),
);

Ok(ImportMapResult::Result(ResolveResult::Single(js_asset.into(), vec![]).into()).into())
Ok(ImportMapResult::Result(ResolveResult::asset(js_asset.into()).into()).into())
}
}

Expand Down Expand Up @@ -227,7 +227,7 @@ impl ImportMappingReplacement for NextFontGoogleCssModuleReplacer {
.into(),
);

Ok(ImportMapResult::Result(ResolveResult::Single(css_asset.into(), vec![]).into()).into())
Ok(ImportMapResult::Result(ResolveResult::asset(css_asset.into()).into()).into())
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/next-core/src/next_server/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use turbopack_core::resolve::{
find_context_file, package_json,
parse::RequestVc,
plugin::{ResolvePlugin, ResolvePluginConditionVc, ResolvePluginVc},
FindContextFileResult, ResolveResult, ResolveResultOptionVc, SpecialType,
FindContextFileResult, PrimaryResolveResult, ResolveResult, ResolveResultOptionVc,
};

#[turbo_tasks::value]
Expand Down Expand Up @@ -91,7 +91,7 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin {

// mark as external
Ok(ResolveResultOptionVc::some(
ResolveResult::Special(SpecialType::OriginalReferenceExternal, Vec::new()).cell(),
ResolveResult::primary(PrimaryResolveResult::OriginalReferenceExternal).cell(),
))
}
}
Expand Down
40 changes: 15 additions & 25 deletions crates/next-core/src/react_refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use turbopack::{
};
use turbopack_core::{
issue::{Issue, IssueSeverity, IssueSeverityVc, IssueVc},
resolve::{origin::ResolveOriginVc, parse::RequestVc, ResolveResult},
resolve::{origin::ResolveOriginVc, parse::RequestVc},
};

#[turbo_tasks::function]
Expand Down Expand Up @@ -57,13 +57,10 @@ pub async fn assert_can_resolve_react_refresh(
let resolve_options =
apply_cjs_specific_options(turbopack::resolve_options(path, resolve_options_context));
for request in [react_refresh_request_in_next(), react_refresh_request()] {
let result = turbopack_core::resolve::resolve(path, request, resolve_options);
let result = turbopack_core::resolve::resolve(path, request, resolve_options).first_asset();

match &*result.await? {
ResolveResult::Single(_, _) | ResolveResult::Alternatives(_, _) => {
return Ok(AssertReactRefreshResult::Found(request).cell())
}
_ => {}
if result.await?.is_some() {
return Ok(AssertReactRefreshResult::Found(request).cell());
}
}
ReactRefreshResolvingIssue {
Expand All @@ -82,26 +79,19 @@ pub async fn assert_can_resolve_react_refresh(
/// Resolves the React Refresh runtime module from the given [AssetContextVc].
#[turbo_tasks::function]
pub async fn resolve_react_refresh(origin: ResolveOriginVc) -> Result<EcmascriptChunkPlaceableVc> {
match &*cjs_resolve(origin, react_refresh_request()).await? {
ResolveResult::Single(asset, _) => {
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(asset).await? {
Ok(placeable)
} else {
Err(anyhow!("React Refresh runtime asset is not placeable"))
}
if let Some(asset) = *cjs_resolve(origin, react_refresh_request())
.first_asset()
.await?
{
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(asset).await? {
Ok(placeable)
} else {
Err(anyhow!("React Refresh runtime asset is not placeable"))
}
ResolveResult::Alternatives(assets, _) if !assets.is_empty() => {
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(assets[0]).await? {
Ok(placeable)
} else {
Err(anyhow!("React Refresh runtime asset is not placeable"))
}
}
// The react-refresh-runtime module is not installed.
ResolveResult::Unresolveable(_) => Err(anyhow!(
} else {
Err(anyhow!(
"could not resolve the `@next/react-refresh-utils/dist/runtime` module"
)),
_ => Err(anyhow!("invalid React Refresh runtime asset")),
))
}
}

Expand Down
30 changes: 9 additions & 21 deletions crates/next-core/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::{anyhow, Result};
use anyhow::{bail, Result};
use turbopack::ecmascript::{chunk::EcmascriptChunkPlaceableVc, resolve::cjs_resolve};
use turbopack_core::resolve::{origin::ResolveOriginVc, parse::RequestVc, ResolveResult};
use turbopack_core::resolve::{origin::ResolveOriginVc, parse::RequestVc};

/// Resolves the turbopack runtime module from the given [AssetContextVc].
#[turbo_tasks::function]
Expand All @@ -11,26 +11,14 @@ pub async fn resolve_runtime_request(
let runtime_request_path = format!("@vercel/turbopack-next/{}", path);
let request = RequestVc::parse_string(runtime_request_path.clone());

match &*cjs_resolve(origin, request).await? {
ResolveResult::Single(asset, _) => {
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(asset).await? {
Ok(placeable)
} else {
Err(anyhow!("turbopack runtime asset is not placeable"))
}
}
ResolveResult::Alternatives(assets, _) if !assets.is_empty() => {
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(assets[0]).await? {
Ok(placeable)
} else {
Err(anyhow!("turbopack runtime asset is not placeable"))
}
if let Some(asset) = *cjs_resolve(origin, request).first_asset().await? {
if let Some(placeable) = EcmascriptChunkPlaceableVc::resolve_from(asset).await? {
Ok(placeable)
} else {
bail!("turbopack runtime asset is not placeable")
}
} else {
// The @vercel/turbopack-runtime module is not installed.
ResolveResult::Unresolveable(_) => Err(anyhow!(
"could not resolve the `{}` module",
runtime_request_path
)),
_ => Err(anyhow!("invalid turbopack runtime asset")),
bail!("could not resolve the `{}` module", runtime_request_path)
}
}
51 changes: 30 additions & 21 deletions crates/turbopack-core/src/chunk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
asset::{Asset, AssetVc, AssetsVc},
environment::EnvironmentVc,
reference::{AssetReference, AssetReferenceVc, AssetReferencesVc},
resolve::{ResolveResult, ResolveResultVc},
resolve::{PrimaryResolveResult, ResolveResult, ResolveResultVc},
};

/// A module id, which can be a number or string
Expand Down Expand Up @@ -132,10 +132,16 @@ impl ChunkGroupVc {
if *pc.is_loaded_in_parallel().await? {
result = r
.resolve_reference()
.primary_assets()
.await?
.primary
.iter()
.map(|r| async move { Ok(ChunkVc::resolve_from(r).await?) })
.map(|r| async move {
Ok(if let PrimaryResolveResult::Asset(a) = r {
ChunkVc::resolve_from(a).await?
} else {
None
})
})
.try_join()
.await?;
}
Expand Down Expand Up @@ -270,7 +276,7 @@ impl ChunkReferenceVc {
impl AssetReference for ChunkReference {
#[turbo_tasks::function]
fn resolve_reference(&self) -> ResolveResultVc {
ResolveResult::Single(self.chunk.into(), Vec::new()).into()
ResolveResult::asset(self.chunk.into()).into()
}
}

Expand Down Expand Up @@ -318,7 +324,7 @@ impl AssetReference for ChunkGroupReference {
.iter()
.map(|c| c.as_asset())
.collect();
Ok(ResolveResult::Alternatives(set, Vec::new()).into())
Ok(ResolveResult::assets(set).into())
}
}

Expand Down Expand Up @@ -369,8 +375,8 @@ pub async fn chunk_content<I: FromChunkableAsset>(

enum ChunkContentWorkItem {
AssetReferences(AssetReferencesVc),
Assets {
assets: AssetsVc,
ResolveResult {
result: ResolveResultVc,
reference: AssetReferenceVc,
chunking_type: ChunkingType,
},
Expand Down Expand Up @@ -413,8 +419,8 @@ async fn chunk_content_internal<I: FromChunkableAsset>(
for r in item.await?.iter() {
if let Some(pc) = ChunkableAssetReferenceVc::resolve_from(r).await? {
if let Some(chunking_type) = *pc.chunking_type(context).await? {
queue.push_back(ChunkContentWorkItem::Assets {
assets: r.resolve_reference().primary_assets(),
queue.push_back(ChunkContentWorkItem::ResolveResult {
result: r.resolve_reference(),
reference: *r,
chunking_type,
});
Expand All @@ -424,8 +430,8 @@ async fn chunk_content_internal<I: FromChunkableAsset>(
external_asset_references.push(*r);
}
}
ChunkContentWorkItem::Assets {
assets,
ChunkContentWorkItem::ResolveResult {
result,
reference,
chunking_type,
} => {
Expand All @@ -444,13 +450,16 @@ async fn chunk_content_internal<I: FromChunkableAsset>(
// not loaded in parallel
let mut inner_chunk_groups = Vec::new();

for asset in assets
.await?
.iter()
.filter(|asset| processed_assets.insert((chunking_type, **asset)))
{
let asset: &AssetVc = asset;

let result = result.await?;
let assets = result.primary.iter().filter_map(|result| {
if let PrimaryResolveResult::Asset(asset) = *result {
if processed_assets.insert((chunking_type, asset)) {
return Some(asset);
}
}
None
});
for asset in assets {
let chunkable_asset = match ChunkableAssetVc::resolve_from(asset).await? {
Some(chunkable_asset) => chunkable_asset,
_ => {
Expand All @@ -461,7 +470,7 @@ async fn chunk_content_internal<I: FromChunkableAsset>(

match chunking_type {
ChunkingType::Placed => {
if let Some(chunk_item) = I::from_asset(context, *asset).await? {
if let Some(chunk_item) = I::from_asset(context, asset).await? {
inner_chunk_items.push(chunk_item);
} else {
return Err(anyhow!(
Expand All @@ -477,9 +486,9 @@ async fn chunk_content_internal<I: FromChunkableAsset>(
}
ChunkingType::PlacedOrParallel => {
// heuristic for being in the same chunk
if !split && *context.can_be_in_same_chunk(entry, *asset).await? {
if !split && *context.can_be_in_same_chunk(entry, asset).await? {
// chunk item, chunk or other asset?
if let Some(chunk_item) = I::from_asset(context, *asset).await? {
if let Some(chunk_item) = I::from_asset(context, asset).await? {
inner_chunk_items.push(chunk_item);
continue;
}
Expand Down
7 changes: 5 additions & 2 deletions crates/turbopack-core/src/introspect/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::{Introspectable, IntrospectableChildrenVc, IntrospectableVc};
use crate::{
asset::{Asset, AssetContent, AssetContentVc, AssetVc},
reference::{AssetReference, AssetReferencesVc},
resolve::PrimaryResolveResult,
};

#[turbo_tasks::value]
Expand Down Expand Up @@ -83,8 +84,10 @@ pub async fn children_from_asset_references(
let mut children = HashSet::new();
let references = references.await?;
for reference in &*references {
for asset in &*reference.resolve_reference().primary_assets().await? {
children.insert((key, IntrospectableAssetVc::new(*asset)));
for result in reference.resolve_reference().await?.primary.iter() {
if let PrimaryResolveResult::Asset(asset) = result {
children.insert((key, IntrospectableAssetVc::new(*asset)));
}
}
}
Ok(IntrospectableChildrenVc::cell(children))
Expand Down
39 changes: 13 additions & 26 deletions crates/turbopack-core/src/reference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use turbo_tasks::{primitives::StringVc, ValueToString, ValueToStringVc};
use crate::{
asset::{Asset, AssetVc, AssetsVc},
issue::IssueVc,
resolve::{ResolveResult, ResolveResultVc},
resolve::{PrimaryResolveResult, ResolveResult, ResolveResultVc},
};
pub mod source_map;

pub use source_map::SourceMapVc;
pub use source_map::SourceMapReferenceVc;

/// A reference to one or multiple [Asset]s or other special things.
/// There are a bunch of optional traits that can influence how these references
Expand Down Expand Up @@ -57,7 +57,7 @@ impl SingleAssetReference {
impl AssetReference for SingleAssetReference {
#[turbo_tasks::function]
fn resolve_reference(&self) -> ResolveResultVc {
ResolveResult::Single(self.asset, vec![]).cell()
ResolveResult::asset(self.asset).cell()
}
}

Expand Down Expand Up @@ -101,31 +101,18 @@ pub async fn all_referenced_assets(asset: AssetVc) -> Result<AssetsVc> {
// while let Some(result) = race_pop(&mut queue).await {
// match &*result? {
while let Some(resolve_result) = queue.pop_front() {
match &*resolve_result.await? {
ResolveResult::Single(module, references) => {
assets.push(*module);
for reference in references {
queue.push_back(reference.resolve_reference());
}
}
ResolveResult::Alternatives(modules, references) => {
assets.extend(modules);
for reference in references {
queue.push_back(reference.resolve_reference());
}
}
ResolveResult::Special(_, references) => {
for reference in references {
queue.push_back(reference.resolve_reference());
}
}
ResolveResult::Keyed(_, _) => todo!(),
ResolveResult::Unresolveable(references) => {
for reference in references {
queue.push_back(reference.resolve_reference());
}
let ResolveResult {
primary,
references,
} = &*resolve_result.await?;
for result in primary {
if let PrimaryResolveResult::Asset(asset) = *result {
assets.push(asset);
}
}
for reference in references {
queue.push_back(reference.resolve_reference());
}
}
Ok(AssetsVc::cell(assets))
}
Expand Down
Loading

0 comments on commit ab45970

Please sign in to comment.