diff --git a/cli/Cargo.toml b/cli/Cargo.toml index cf76dfe69d..6395910ccd 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -80,7 +80,7 @@ deno_npm.workspace = true deno_npm_cache.workspace = true deno_package_json.workspace = true deno_path_util.workspace = true -deno_resolver.workspace = true +deno_resolver = { workspace = true, features = ["sync"] } deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_semver.workspace = true deno_task_shell = "=0.20.2" diff --git a/resolvers/deno/Cargo.toml b/resolvers/deno/Cargo.toml index 2966b5fef6..4dca044377 100644 --- a/resolvers/deno/Cargo.toml +++ b/resolvers/deno/Cargo.toml @@ -13,11 +13,14 @@ description = "Deno resolution algorithm" [lib] path = "lib.rs" +[features] +sync = ["dashmap"] + [dependencies] anyhow.workspace = true base32.workspace = true boxed_error.workspace = true -dashmap.workspace = true +dashmap = { workspace = true, optional = true } deno_config.workspace = true deno_media_type.workspace = true deno_package_json.workspace = true diff --git a/resolvers/deno/cjs.rs b/resolvers/deno/cjs.rs index 9ae60b6a15..6ae648deab 100644 --- a/resolvers/deno/cjs.rs +++ b/resolvers/deno/cjs.rs @@ -1,13 +1,11 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use std::sync::Arc; - -use dashmap::DashMap; +use crate::sync::MaybeDashMap; use deno_media_type::MediaType; use node_resolver::env::NodeResolverEnv; use node_resolver::errors::ClosestPkgJsonError; -use node_resolver::InNpmPackageChecker; -use node_resolver::PackageJsonResolver; +use node_resolver::InNpmPackageCheckerRc; +use node_resolver::PackageJsonResolverRc; use node_resolver::ResolutionMode; use url::Url; @@ -19,13 +17,13 @@ use url::Url; #[derive(Debug)] pub struct CjsTracker { is_cjs_resolver: IsCjsResolver, - known: DashMap, + known: MaybeDashMap, } impl CjsTracker { pub fn new( - in_npm_pkg_checker: Arc, - pkg_json_resolver: Arc>, + in_npm_pkg_checker: InNpmPackageCheckerRc, + pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, ) -> Self { Self { @@ -127,15 +125,15 @@ pub enum IsCjsResolutionMode { /// Resolves whether a module is CJS or ESM. #[derive(Debug)] pub struct IsCjsResolver { - in_npm_pkg_checker: Arc, - pkg_json_resolver: Arc>, + in_npm_pkg_checker: InNpmPackageCheckerRc, + pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, } impl IsCjsResolver { pub fn new( - in_npm_pkg_checker: Arc, - pkg_json_resolver: Arc>, + in_npm_pkg_checker: InNpmPackageCheckerRc, + pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, ) -> Self { Self { @@ -185,7 +183,7 @@ impl IsCjsResolver { specifier: &Url, media_type: MediaType, is_script: Option, - known_cache: &DashMap, + known_cache: &MaybeDashMap, ) -> Option { if specifier.scheme() != "file" { return Some(ResolutionMode::Import); diff --git a/resolvers/deno/clippy.toml b/resolvers/deno/clippy.toml index 733ac83da1..886ba3fd1a 100644 --- a/resolvers/deno/clippy.toml +++ b/resolvers/deno/clippy.toml @@ -47,6 +47,5 @@ disallowed-methods = [ { path = "url::Url::from_directory_path", reason = "Use deno_path_util instead so it works in Wasm" }, ] disallowed-types = [ - # todo(dsherret): consider for the future - # { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" }, + { path = "std::sync::Arc", reason = "use crate::sync::MaybeArc instead" }, ] diff --git a/resolvers/deno/lib.rs b/resolvers/deno/lib.rs index a74ca614a3..05fa416da1 100644 --- a/resolvers/deno/lib.rs +++ b/resolvers/deno/lib.rs @@ -4,7 +4,6 @@ #![deny(clippy::print_stdout)] use std::path::PathBuf; -use std::sync::Arc; use boxed_error::Boxed; use deno_config::workspace::MappedResolution; @@ -19,20 +18,20 @@ use fs::DenoResolverFs; use node_resolver::env::NodeResolverEnv; use node_resolver::errors::NodeResolveError; use node_resolver::errors::PackageSubpathResolveError; -use node_resolver::InNpmPackageChecker; +use node_resolver::InNpmPackageCheckerRc; use node_resolver::NodeResolution; use node_resolver::NodeResolutionKind; -use node_resolver::NodeResolver; +use node_resolver::NodeResolverRc; use node_resolver::ResolutionMode; use npm::MissingPackageNodeModulesFolderError; use npm::NodeModulesOutOfDateError; -use npm::NpmReqResolver; +use npm::NpmReqResolverRc; use npm::ResolveIfForNpmPackageErrorKind; use npm::ResolvePkgFolderFromDenoReqError; use npm::ResolveReqWithSubPathErrorKind; use sloppy_imports::SloppyImportResolverFs; use sloppy_imports::SloppyImportsResolutionKind; -use sloppy_imports::SloppyImportsResolver; +use sloppy_imports::SloppyImportsResolverRc; use thiserror::Error; use url::Url; @@ -40,6 +39,10 @@ pub mod cjs; pub mod fs; pub mod npm; pub mod sloppy_imports; +mod sync; + +#[allow(clippy::disallowed_types)] +pub type WorkspaceResolverRc = crate::sync::MaybeArc; #[derive(Debug, Clone)] pub struct DenoResolution { @@ -80,8 +83,8 @@ pub struct NodeAndNpmReqResolver< Fs: DenoResolverFs, TNodeResolverEnv: NodeResolverEnv, > { - pub node_resolver: Arc>, - pub npm_req_resolver: Arc>, + pub node_resolver: NodeResolverRc, + pub npm_req_resolver: NpmReqResolverRc, } pub struct DenoResolverOptions< @@ -90,12 +93,12 @@ pub struct DenoResolverOptions< TNodeResolverEnv: NodeResolverEnv, TSloppyImportResolverFs: SloppyImportResolverFs, > { - pub in_npm_pkg_checker: Arc, + pub in_npm_pkg_checker: InNpmPackageCheckerRc, pub node_and_req_resolver: Option>, pub sloppy_imports_resolver: - Option>>, - pub workspace_resolver: Arc, + Option>, + pub workspace_resolver: WorkspaceResolverRc, /// Whether "bring your own node_modules" is enabled where Deno does not /// setup the node_modules directories automatically, but instead uses /// what already exists on the file system. @@ -111,11 +114,11 @@ pub struct DenoResolver< TNodeResolverEnv: NodeResolverEnv, TSloppyImportResolverFs: SloppyImportResolverFs, > { - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: InNpmPackageCheckerRc, node_and_npm_resolver: Option>, sloppy_imports_resolver: - Option>>, - workspace_resolver: Arc, + Option>, + workspace_resolver: WorkspaceResolverRc, is_byonm: bool, maybe_vendor_specifier: Option, } diff --git a/resolvers/deno/npm/byonm.rs b/resolvers/deno/npm/byonm.rs index 6e1be35ca0..08d06f9cac 100644 --- a/resolvers/deno/npm/byonm.rs +++ b/resolvers/deno/npm/byonm.rs @@ -3,10 +3,10 @@ use std::borrow::Cow; use std::path::Path; use std::path::PathBuf; -use std::sync::Arc; use deno_package_json::PackageJson; use deno_package_json::PackageJsonDepValue; +use deno_package_json::PackageJsonRc; use deno_path_util::url_to_file_path; use deno_semver::package::PackageReq; use deno_semver::Version; @@ -49,6 +49,10 @@ pub struct ByonmNpmResolverCreateOptions< pub pkg_json_resolver: PackageJsonResolverRc, } +#[allow(clippy::disallowed_types)] +pub type ByonmNpmResolverRc = + crate::sync::MaybeArc>; + #[derive(Debug)] pub struct ByonmNpmResolver { fs: Fs, @@ -84,7 +88,7 @@ impl ByonmNpmResolver { fn load_pkg_json( &self, path: &Path, - ) -> Result>, PackageJsonLoadError> { + ) -> Result, PackageJsonLoadError> { self.pkg_json_resolver.load_package_json(path) } @@ -93,7 +97,7 @@ impl ByonmNpmResolver { &self, dep_name: &str, referrer: &Url, - ) -> Option> { + ) -> Option { let referrer_path = url_to_file_path(referrer).ok()?; let mut current_folder = referrer_path.parent()?; loop { @@ -173,7 +177,7 @@ impl ByonmNpmResolver { &self, req: &PackageReq, referrer: &Url, - ) -> Result, String)>, PackageJsonLoadError> { + ) -> Result, PackageJsonLoadError> { fn resolve_alias_from_pkg_json( req: &PackageReq, pkg_json: &PackageJson, diff --git a/resolvers/deno/npm/mod.rs b/resolvers/deno/npm/mod.rs index 83db04480a..64ec86fe3f 100644 --- a/resolvers/deno/npm/mod.rs +++ b/resolvers/deno/npm/mod.rs @@ -2,7 +2,6 @@ use std::fmt::Debug; use std::path::PathBuf; -use std::sync::Arc; use boxed_error::Boxed; use deno_semver::npm::NpmPackageReqReference; @@ -15,10 +14,10 @@ use node_resolver::errors::PackageFolderResolveIoError; use node_resolver::errors::PackageNotFoundError; use node_resolver::errors::PackageResolveErrorKind; use node_resolver::errors::PackageSubpathResolveError; -use node_resolver::InNpmPackageChecker; +use node_resolver::InNpmPackageCheckerRc; use node_resolver::NodeResolution; use node_resolver::NodeResolutionKind; -use node_resolver::NodeResolver; +use node_resolver::NodeResolverRc; use node_resolver::ResolutionMode; use thiserror::Error; use url::Url; @@ -28,6 +27,7 @@ use crate::fs::DenoResolverFs; pub use byonm::ByonmInNpmPackageChecker; pub use byonm::ByonmNpmResolver; pub use byonm::ByonmNpmResolverCreateOptions; +pub use byonm::ByonmNpmResolverRc; pub use byonm::ByonmResolvePkgFolderFromDenoReqError; pub use local::normalize_pkg_name_for_node_modules_deno_folder; @@ -81,6 +81,9 @@ pub enum ResolvePkgFolderFromDenoReqError { Byonm(#[from] ByonmResolvePkgFolderFromDenoReqError), } +#[allow(clippy::disallowed_types)] +pub type CliNpmReqResolverRc = crate::sync::MaybeArc; + // todo(dsherret): a temporary trait until we extract // out the CLI npm resolver into here pub trait CliNpmReqResolver: Debug + Send + Sync { @@ -98,21 +101,25 @@ pub struct NpmReqResolverOptions< /// The resolver when "bring your own node_modules" is enabled where Deno /// does not setup the node_modules directories automatically, but instead /// uses what already exists on the file system. - pub byonm_resolver: Option>>, + pub byonm_resolver: Option>, pub fs: Fs, - pub in_npm_pkg_checker: Arc, - pub node_resolver: Arc>, - pub npm_req_resolver: Arc, + pub in_npm_pkg_checker: InNpmPackageCheckerRc, + pub node_resolver: NodeResolverRc, + pub npm_req_resolver: CliNpmReqResolverRc, } +#[allow(clippy::disallowed_types)] +pub type NpmReqResolverRc = + crate::sync::MaybeArc>; + #[derive(Debug)] pub struct NpmReqResolver { - byonm_resolver: Option>>, + byonm_resolver: Option>, fs: Fs, - in_npm_pkg_checker: Arc, - node_resolver: Arc>, - npm_resolver: Arc, + in_npm_pkg_checker: InNpmPackageCheckerRc, + node_resolver: NodeResolverRc, + npm_resolver: CliNpmReqResolverRc, } impl diff --git a/resolvers/deno/sloppy_imports.rs b/resolvers/deno/sloppy_imports.rs index ccaa547435..6644222a8b 100644 --- a/resolvers/deno/sloppy_imports.rs +++ b/resolvers/deno/sloppy_imports.rs @@ -101,6 +101,10 @@ pub trait SloppyImportResolverFs { } } +#[allow(clippy::disallowed_types)] +pub type SloppyImportsResolverRc = + crate::sync::MaybeArc>; + #[derive(Debug)] pub struct SloppyImportsResolver { fs: Fs, diff --git a/resolvers/deno/sync.rs b/resolvers/deno/sync.rs new file mode 100644 index 0000000000..6e62336901 --- /dev/null +++ b/resolvers/deno/sync.rs @@ -0,0 +1,34 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +pub use inner::*; + +#[cfg(feature = "sync")] +mod inner { + #![allow(clippy::disallowed_types)] + + pub use std::sync::Arc as MaybeArc; + + pub use dashmap::DashMap as MaybeDashMap; +} + +#[cfg(not(feature = "sync"))] +mod inner { + use std::hash::RandomState; + pub use std::rc::Rc as MaybeArc; + + // Wrapper struct that exposes a subset of `DashMap` API. + #[derive(Default)] + struct MaybeDashMap(RefCell>); + + impl MaybeDashMap { + pub fn get(&'a self, key: &K) -> Option<&'a V> { + let inner = self.0.borrow(); + inner.get(key) + } + + pub fn insert(&self, key: K, value: V) -> Option { + let inner = self.0.borrow_mut(); + inner.insert(key, value) + } + } +} diff --git a/resolvers/node/lib.rs b/resolvers/node/lib.rs index 8da20c421e..c73c395dfc 100644 --- a/resolvers/node/lib.rs +++ b/resolvers/node/lib.rs @@ -26,6 +26,7 @@ pub use resolution::resolve_specifier_into_node_modules; pub use resolution::NodeResolution; pub use resolution::NodeResolutionKind; pub use resolution::NodeResolver; +pub use resolution::NodeResolverRc; pub use resolution::ResolutionMode; pub use resolution::DEFAULT_CONDITIONS; pub use resolution::REQUIRE_CONDITIONS;