diff --git a/crates/turbo-tasks-fs/src/lib.rs b/crates/turbo-tasks-fs/src/lib.rs index 78d4bf9455720..61f0aaca1d794 100644 --- a/crates/turbo-tasks-fs/src/lib.rs +++ b/crates/turbo-tasks-fs/src/lib.rs @@ -1300,16 +1300,19 @@ pub async fn rebase( Ok(new_base.fs.root().join(new_path)) } -// Not turbo-tasks functions, only delegating +#[turbo_tasks::value_impl] impl FileSystemPath { - pub fn read(self: Vc) -> Vc { + #[turbo_tasks::function] + pub async fn read(self: Vc) -> Vc { self.fs().read(self) } - pub fn read_link(self: Vc) -> Vc { + #[turbo_tasks::function] + pub async fn read_link(self: Vc) -> Vc { self.fs().read_link(self) } + #[turbo_tasks::function] pub fn read_json(self: Vc) -> Vc { self.fs().read(self).parse_json() } @@ -1318,41 +1321,26 @@ impl FileSystemPath { /// /// DETERMINISM: Result is in random order. Either sort result or do not /// depend on the order. - pub fn read_dir(self: Vc) -> Vc { + #[turbo_tasks::function] + pub async fn read_dir(self: Vc) -> Vc { self.fs().read_dir(self) } - pub fn track(self: Vc) -> Vc { + #[turbo_tasks::function] + pub async fn track(self: Vc) -> Vc { self.fs().track(self) } + #[turbo_tasks::function] pub fn write(self: Vc, content: Vc) -> Vc { self.fs().write(self, content) } + #[turbo_tasks::function] pub fn write_link(self: Vc, target: Vc) -> Vc { self.fs().write_link(self, target) } - pub fn metadata(self: Vc) -> Vc { - self.fs().metadata(self) - } - - pub fn realpath(self: Vc) -> Vc { - self.realpath_with_links().path() - } - - pub fn rebase( - fs_path: Vc, - old_base: Vc, - new_base: Vc, - ) -> Vc { - rebase(fs_path, old_base, new_base) - } -} - -#[turbo_tasks::value_impl] -impl FileSystemPath { #[turbo_tasks::function] pub async fn parent(self: Vc) -> Result> { let this = self.await?; @@ -1367,6 +1355,11 @@ impl FileSystemPath { Ok(FileSystemPath::new_normalized(this.fs, p)) } + #[turbo_tasks::function] + pub fn metadata(self: Vc) -> Vc { + self.fs().metadata(self) + } + #[turbo_tasks::function] // It is important that get_type uses read_dir and not stat/metadata. // - `get_type` is called very very often during resolving and stat would @@ -1398,6 +1391,11 @@ impl FileSystemPath { } } + #[turbo_tasks::function] + pub fn realpath(self: Vc) -> Vc { + self.realpath_with_links().path() + } + #[turbo_tasks::function] pub async fn realpath_with_links(self: Vc) -> Result> { let this = self.await?; @@ -1444,6 +1442,16 @@ impl FileSystemPath { } } +impl FileSystemPath { + pub fn rebase( + fs_path: Vc, + old_base: Vc, + new_base: Vc, + ) -> Vc { + rebase(fs_path, old_base, new_base) + } +} + #[turbo_tasks::value_impl] impl ValueToString for FileSystemPath { #[turbo_tasks::function] diff --git a/crates/turbopack-core/src/issue/resolve.rs b/crates/turbopack-core/src/issue/resolve.rs index 71b7404741d34..77f90122316ea 100644 --- a/crates/turbopack-core/src/issue/resolve.rs +++ b/crates/turbopack-core/src/issue/resolve.rs @@ -81,12 +81,9 @@ impl Issue for ResolvingIssue { request_type = self.request_type, )?; if let Some(import_map) = &self.resolve_options.await?.import_map { - let result = import_map - .await? - .lookup(self.file_path, self.request) - .await?; + let result = import_map.lookup(self.file_path, self.request); - match result.cell().to_string().await { + match result.to_string().await { Ok(str) => writeln!(detail, "Import map: {}", str)?, Err(err) => { writeln!( diff --git a/crates/turbopack-core/src/resolve/mod.rs b/crates/turbopack-core/src/resolve/mod.rs index 97511ac5085c3..74125a1c9dea3 100644 --- a/crates/turbopack-core/src/resolve/mod.rs +++ b/crates/turbopack-core/src/resolve/mod.rs @@ -1010,7 +1010,7 @@ pub async fn resolve( request: Vc, options: Vc, ) -> Result> { - let raw_result = resolve_internal(lookup_path, request, options).await?; + let raw_result = resolve_internal(lookup_path, request, options); let result = handle_resolve_plugins(lookup_path, request, options, raw_result); Ok(result) } @@ -1080,15 +1080,7 @@ async fn handle_resolve_plugins( .cell()) } -fn resolve_internal_boxed( - lookup_path: Vc, - request: Vc, - options: Vc, -) -> Pin>> + Send>> { - Box::pin(resolve_internal(lookup_path, request, options)) -} - -// Not a turbo-tasks function: Called too often +#[turbo_tasks::function] async fn resolve_internal( lookup_path: Vc, request: Vc, @@ -1100,10 +1092,11 @@ async fn resolve_internal( // Apply import mappings if provided if let Some(import_map) = &options_value.import_map { - let result = import_map.await?.lookup(lookup_path, request).await?; + let result_ref = import_map.lookup(lookup_path, request).await?; + let result = &*result_ref; if !matches!(result, ImportMapResult::NoEntry) { let resolved_result = resolve_import_map_result( - &result, + result, lookup_path, lookup_path, request, @@ -1129,9 +1122,8 @@ async fn resolve_internal( Request::Alternatives { requests } => { let results = requests .iter() - .map(|req| resolve_internal_boxed(lookup_path, *req, options)) - .try_join() - .await?; + .map(|req| resolve_internal(lookup_path, *req, options)) + .collect(); merge_results(results) } @@ -1180,17 +1172,14 @@ async fn resolve_internal( // This ensures the order of the patterns (extensions) is // preserved, `Pattern::Alternatives` inside a `Request::Raw` does not preserve // the order - let results = patterns - .into_iter() - .map(|pattern| { - resolve_internal_boxed( - lookup_path, - Request::raw(Value::new(pattern), *query, *force_in_lookup_dir), - options, - ) - }) - .try_join() - .await?; + let mut results = Vec::new(); + for pattern in patterns { + results.push(resolve_internal( + lookup_path, + Request::raw(Value::new(pattern), *query, *force_in_lookup_dir), + options, + )); + } merge_results(results) } @@ -1223,7 +1212,7 @@ async fn resolve_internal( .cell() .emit(); - resolve_internal_boxed(lookup_path.root(), relative, options).await? + resolve_internal(lookup_path.root(), relative, options) } Request::Windows { path: _, query: _ } => { ResolvingIssue { @@ -1291,9 +1280,10 @@ async fn resolve_internal( // Apply fallback import mappings if provided if let Some(import_map) = &options_value.fallback_import_map { if *result.is_unresolveable().await? { - let result = import_map.await?.lookup(lookup_path, request).await?; + let result_ref = import_map.lookup(lookup_path, request).await?; + let result = &*result_ref; let resolved_result = resolve_import_map_result( - &result, + result, lookup_path, lookup_path, request, @@ -1328,7 +1318,7 @@ async fn resolve_into_folder( ) })?; let request = Request::parse(Value::new(str.into())); - return resolve_internal_boxed(package_path, request, options).await; + return Ok(resolve_internal(package_path, request, options)); } ResolveIntoPackage::MainField(name) => { if let Some(package_json) = &*read_package_json(package_json_path).await? { @@ -1336,9 +1326,7 @@ async fn resolve_into_folder( let request = Request::parse(Value::new(normalize_request(field_value).into())); - let resolved = - resolve_internal_boxed(package_path, request, options).await?; - let result = &*resolved.await?; + let result = &*resolve_internal(package_path, request, options).await?; // we are not that strict when a main field fails to resolve // we continue to try other alternatives if !result.is_unresolveable_ref() { @@ -1512,7 +1500,7 @@ async fn resolve_module_request( new_pat.push_front(".".to_string().into()); let relative = Request::relative(Value::new(new_pat), query, true); - results.push(resolve_internal_boxed(*package_path, relative, options).await?); + results.push(resolve_internal(*package_path, relative, options)); } Ok(merge_results_with_affecting_sources( @@ -1540,7 +1528,7 @@ async fn resolve_import_map_result( { None } else { - Some(resolve_internal_boxed(lookup_path, request, options).await?) + Some(resolve_internal(lookup_path, request, options)) } } ImportMapResult::Alternatives(list) => { @@ -1577,14 +1565,17 @@ fn resolve_import_map_result_boxed<'a>( options: Vc, query: Vc, ) -> Pin + Send + 'a>> { - Box::pin(resolve_import_map_result( - result, - lookup_path, - original_lookup_path, - original_request, - options, - query, - )) + Box::pin(async move { + resolve_import_map_result( + result, + lookup_path, + original_lookup_path, + original_request, + options, + query, + ) + .await + }) } async fn resolve_alias_field_result( @@ -1604,12 +1595,11 @@ async fn resolve_alias_field_result( } if let Some(value) = result.as_str() { - return Ok(resolve_internal_boxed( + return Ok(resolve_internal( package_path, Request::parse(Value::new(Pattern::Constant(value.to_string()))).with_query(query), resolve_options, ) - .await? .with_affecting_sources(refs)); } @@ -1756,7 +1746,7 @@ async fn handle_exports_imports_field( for path in results { if let Some(path) = normalize_path(path) { let request = Request::parse(Value::new(format!("./{}", path).into())); - resolved_results.push(resolve_internal_boxed(package_path, request, options).await?); + resolved_results.push(resolve_internal(package_path, request, options)); } } diff --git a/crates/turbopack-core/src/resolve/options.rs b/crates/turbopack-core/src/resolve/options.rs index 1185a1bd531fa..c2d5e5ebb9a30 100644 --- a/crates/turbopack-core/src/resolve/options.rs +++ b/crates/turbopack-core/src/resolve/options.rs @@ -345,26 +345,28 @@ fn import_mapping_to_result_boxed( Box::pin(async move { import_mapping_to_result(mapping, lookup_path, request).await }) } +#[turbo_tasks::value_impl] impl ImportMap { - // Not a turbo-tasks function: the map lookup should be cheaper than the cache - // lookup + #[turbo_tasks::function] pub async fn lookup( - &self, + self: Vc, lookup_path: Vc, request: Vc, - ) -> Result { + ) -> Result> { + let this = self.await?; // TODO lookup pattern if let Some(request_string) = request.await?.request() { - if let Some(result) = self.map.lookup(&request_string).next() { - return import_mapping_to_result( + if let Some(result) = this.map.lookup(&request_string).next() { + return Ok(import_mapping_to_result( result.try_join_into_self().await?.into_owned(), lookup_path, request, ) - .await; + .await? + .into()); } } - Ok(ImportMapResult::NoEntry) + Ok(ImportMapResult::NoEntry.into()) } } diff --git a/crates/turbopack-ecmascript/src/references/async_module.rs b/crates/turbopack-ecmascript/src/references/async_module.rs index cda5cb48d14ed..a549caa76fdba 100644 --- a/crates/turbopack-ecmascript/src/references/async_module.rs +++ b/crates/turbopack-ecmascript/src/references/async_module.rs @@ -6,7 +6,7 @@ use swc_core::{ ecma::ast::{ArrayLit, ArrayPat, Expr, Ident, Pat, Program}, quote, }; -use turbo_tasks::{trace::TraceRawVcs, TryFlatJoinIterExt, Value, Vc}; +use turbo_tasks::{primitives::Bools, trace::TraceRawVcs, TryFlatJoinIterExt, Value, Vc}; use turbopack_core::chunk::availability_info::AvailabilityInfo; use super::esm::base::ReferencedAsset; @@ -102,6 +102,17 @@ struct AsyncModuleScc { #[turbo_tasks::value(transparent)] struct OptionAsyncModuleScc(Option>); +#[turbo_tasks::function] +async fn is_placeable_self_async( + placeable: Vc>, +) -> Result> { + let Some(async_module) = &*placeable.get_async_module().await? else { + return Ok(Vc::cell(false)); + }; + + Ok(async_module.is_self_async()) +} + #[turbo_tasks::value_impl] impl AsyncModuleScc { #[turbo_tasks::function] @@ -113,23 +124,19 @@ impl AsyncModuleScc { async fn is_async(self: Vc) -> Result> { let this = self.await?; + let mut bools = Vec::new(); + for placeable in &*this.scc.await? { - if let Some(async_module) = &*placeable.get_async_module().await? { - if *async_module.is_self_async().await? { - return Ok(Vc::cell(true)); - } - } + bools.push(is_placeable_self_async(*placeable)); } for scc in &*this.scope.get_scc_children(this.scc).await? { // Because we generated SCCs there can be no loops in the children, so calling // recursively is fine. - if *AsyncModuleScc::new(*scc, this.scope).is_async().await? { - return Ok(Vc::cell(true)); - } + bools.push(AsyncModuleScc::new(*scc, this.scope).is_async()); } - Ok(Vc::cell(false)) + Ok(Vc::::cell(bools).any()) } }