diff --git a/Cargo.lock b/Cargo.lock index e29f791feca13c..5f609532a9a8ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1528,9 +1528,9 @@ dependencies = [ [[package]] name = "deno_config" -version = "0.46.0" +version = "0.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08fe512a72c4300bd997c6849450a1f050da0c909a2a4fbdc44891647392bacf" +checksum = "2f7883c48549bab8e446a58c64ee3d106a13052d2ff5e864de765a60260cb02b" dependencies = [ "boxed_error", "capacity_builder 0.5.0", @@ -5278,6 +5278,7 @@ dependencies = [ "async-trait", "boxed_error", "dashmap", + "deno_config", "deno_error", "deno_media_type", "deno_package_json", @@ -7910,9 +7911,9 @@ dependencies = [ [[package]] name = "sys_traits" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b46ac05dfbe9fd3a9703eff20e17f5b31e7b6a54daf27a421dcd56c7a27ecdd" +checksum = "638f0e61b5134e56b2abdf4c704fd44672603f15ca09013f314649056f3fee4d" dependencies = [ "filetime", "getrandom", diff --git a/Cargo.toml b/Cargo.toml index 61367d98f44b6e..4ffcd867c31ce7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ deno_ast = { version = "=0.44.0", features = ["transpiling"] } deno_core = { version = "0.333.0" } deno_bench_util = { version = "0.181.0", path = "./bench_util" } -deno_config = { version = "=0.46.0", features = ["workspace"] } +deno_config = { version = "=0.47.1", features = ["workspace"] } deno_lockfile = "=0.24.0" deno_media_type = { version = "=0.2.5", features = ["module_specifier"] } deno_npm = "=0.27.2" @@ -204,7 +204,7 @@ slab = "0.4" smallvec = "1.8" socket2 = { version = "0.5.3", features = ["all"] } spki = "0.7.2" -sys_traits = "=0.1.7" +sys_traits = "=0.1.8" tar = "=0.4.40" tempfile = "3.4.0" termcolor = "1.1.3" diff --git a/cli/factory.rs b/cli/factory.rs index e41fa1b73e91b4..d4ad8fae52073e 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -711,7 +711,7 @@ impl CliFactory { pub async fn workspace_resolver( &self, - ) -> Result<&Arc, AnyError> { + ) -> Result<&Arc>, AnyError> { self.initialize_npm_resolution_if_managed().await?; self.resolver_factory()?.workspace_resolver().await } diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index 44e9bf4dfd0c08..fd7337df263dc8 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -1343,9 +1343,11 @@ impl CodeActionCollection { .tree .data_for_specifier(file_referrer?)?; let workspace_resolver = config_data.resolver.clone(); - let npm_ref = if let Ok(resolution) = - workspace_resolver.resolve(&dep_key, document.specifier()) - { + let npm_ref = if let Ok(resolution) = workspace_resolver.resolve( + &dep_key, + document.specifier(), + deno_config::workspace::ResolutionKind::Execution, + ) { let specifier = match resolution { MappedResolution::Normal { specifier, .. } | MappedResolution::ImportMap { specifier, .. } => specifier, diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 4ca4255fea1c51..e4570031fb7884 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -1205,7 +1205,7 @@ pub struct ConfigData { pub vendor_dir: Option, pub lockfile: Option>, pub npmrc: Option>, - pub resolver: Arc, + pub resolver: Arc>, pub sloppy_imports_resolver: Option>, pub import_map_from_settings: Option, pub unstable: BTreeSet, @@ -1572,7 +1572,7 @@ impl ConfigData { let resolver = member_dir .workspace .create_resolver( - &CliSys::default(), + CliSys::default(), CreateResolverOptions { pkg_json_dep_resolution, specified_import_map, @@ -1593,11 +1593,14 @@ impl ConfigData { member_dir.workspace.resolver_jsr_pkgs().collect(), member_dir.workspace.package_jsons().cloned().collect(), pkg_json_dep_resolution, + Default::default(), + Default::default(), + CliSys::default(), ) }); if !resolver.diagnostics().is_empty() { lsp_warn!( - " Import map diagnostics:\n{}", + " Resolver diagnostics:\n{}", resolver .diagnostics() .iter() diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index f0ab45f5aef69d..a21d0f7d9af8a3 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -851,6 +851,9 @@ impl<'a> ResolverFactory<'a> { Vec::new(), Vec::new(), PackageJsonDepResolution::Disabled, + Default::default(), + Default::default(), + self.sys.clone(), )) }), is_byonm: self.config_data.map(|d| d.byonm).unwrap_or(false), diff --git a/cli/rt/run.rs b/cli/rt/run.rs index 53190f24339e13..df5388e0d1a18e 100644 --- a/cli/rt/run.rs +++ b/cli/rt/run.rs @@ -104,7 +104,7 @@ struct SharedModuleLoaderState { npm_registry_permission_checker: NpmRegistryReadPermissionChecker, npm_req_resolver: Arc, vfs: Arc, - workspace_resolver: WorkspaceResolver, + workspace_resolver: WorkspaceResolver, } impl SharedModuleLoaderState { @@ -201,10 +201,11 @@ impl ModuleLoader for EmbeddedModuleLoader { ); } - let mapped_resolution = self - .shared - .workspace_resolver - .resolve(raw_specifier, &referrer); + let mapped_resolution = self.shared.workspace_resolver.resolve( + raw_specifier, + &referrer, + deno_config::workspace::ResolutionKind::Execution, + ); match mapped_resolution { Ok(MappedResolution::WorkspaceJsrPackage { specifier, .. }) => { @@ -859,6 +860,9 @@ pub async fn run( .collect(), pkg_jsons, metadata.workspace_resolver.pkg_json_resolution, + Default::default(), + Default::default(), + sys.clone(), ) }; let code_cache = match metadata.code_cache_key { diff --git a/cli/schemas/config-file.v1.json b/cli/schemas/config-file.v1.json index d644072f4cfa5b..ce1bad07c6e81c 100644 --- a/cli/schemas/config-file.v1.json +++ b/cli/schemas/config-file.v1.json @@ -175,6 +175,14 @@ "default": false, "markdownDescription": "Raise an error when a function parameter isn't read\n\nSee more: https://www.typescriptlang.org/tsconfig#noUnusedParameters" }, + "rootDirs": { + "description": "Declare many “virtual” directories acting as a single root.", + "type": "array", + "items": { + "type": "string" + }, + "markdownDescription": "Declare many “virtual” directories acting as a single root.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDirs" + }, "strict": { "description": "Enable all strict type checking options.", "type": "boolean", diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index 59744a0c72509e..4f0ce5a3c00f63 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -62,6 +62,7 @@ use crate::http_util::HttpClientProvider; use crate::node::CliCjsCodeAnalyzer; use crate::npm::CliNpmResolver; use crate::resolver::CliCjsTracker; +use crate::sys::CliSys; use crate::util::archive; use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBarStyle; @@ -194,7 +195,7 @@ pub struct DenoCompileBinaryWriter<'a> { emitter: &'a Emitter, http_client_provider: &'a HttpClientProvider, npm_resolver: &'a CliNpmResolver, - workspace_resolver: &'a WorkspaceResolver, + workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, } @@ -208,7 +209,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { emitter: &'a Emitter, http_client_provider: &'a HttpClientProvider, npm_resolver: &'a CliNpmResolver, - workspace_resolver: &'a WorkspaceResolver, + workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, ) -> Self { Self { diff --git a/cli/tools/info.rs b/cli/tools/info.rs index e297cd5b72a3eb..e6bf1baa36b5d2 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -56,9 +56,11 @@ pub async fn info( let cwd_url = url::Url::from_directory_path(cli_options.initial_cwd()).unwrap(); - let maybe_import_specifier = if let Ok(resolved) = - resolver.resolve(&specifier, &cwd_url) - { + let maybe_import_specifier = if let Ok(resolved) = resolver.resolve( + &specifier, + &cwd_url, + deno_config::workspace::ResolutionKind::Execution, + ) { match resolved { deno_config::workspace::MappedResolution::Normal { specifier, .. diff --git a/cli/tools/lint/rules/mod.rs b/cli/tools/lint/rules/mod.rs index c3d96e46aa4f85..f8c65428aca6ad 100644 --- a/cli/tools/lint/rules/mod.rs +++ b/cli/tools/lint/rules/mod.rs @@ -16,6 +16,7 @@ use deno_lint::rules::LintRule; use deno_lint::tags; use crate::resolver::CliSloppyImportsResolver; +use crate::sys::CliSys; mod no_sloppy_imports; mod no_slow_types; @@ -141,13 +142,13 @@ impl ConfiguredRules { pub struct LintRuleProvider { sloppy_imports_resolver: Option>, - workspace_resolver: Option>, + workspace_resolver: Option>>, } impl LintRuleProvider { pub fn new( sloppy_imports_resolver: Option>, - workspace_resolver: Option>, + workspace_resolver: Option>>, ) -> Self { Self { sloppy_imports_resolver, diff --git a/cli/tools/lint/rules/no_sloppy_imports.rs b/cli/tools/lint/rules/no_sloppy_imports.rs index cf84b3b24f99f6..34eeef521d95ae 100644 --- a/cli/tools/lint/rules/no_sloppy_imports.rs +++ b/cli/tools/lint/rules/no_sloppy_imports.rs @@ -24,18 +24,19 @@ use text_lines::LineAndColumnIndex; use super::ExtendedLintRule; use crate::graph_util::CliJsrUrlProvider; use crate::resolver::CliSloppyImportsResolver; +use crate::sys::CliSys; #[derive(Debug)] pub struct NoSloppyImportsRule { sloppy_imports_resolver: Option>, // None for making printing out the lint rules easy - workspace_resolver: Option>, + workspace_resolver: Option>>, } impl NoSloppyImportsRule { pub fn new( sloppy_imports_resolver: Option>, - workspace_resolver: Option>, + workspace_resolver: Option>>, ) -> Self { NoSloppyImportsRule { sloppy_imports_resolver, @@ -174,7 +175,7 @@ impl LintRule for NoSloppyImportsRule { #[derive(Debug)] struct SloppyImportCaptureResolver<'a> { - workspace_resolver: &'a WorkspaceResolver, + workspace_resolver: &'a WorkspaceResolver, sloppy_imports_resolver: &'a CliSloppyImportsResolver, captures: RefCell>, } @@ -188,7 +189,18 @@ impl<'a> deno_graph::source::Resolver for SloppyImportCaptureResolver<'a> { ) -> Result { let resolution = self .workspace_resolver - .resolve(specifier_text, &referrer_range.specifier) + .resolve( + specifier_text, + &referrer_range.specifier, + match resolution_kind { + ResolutionKind::Execution => { + deno_config::workspace::ResolutionKind::Execution + } + ResolutionKind::Types => { + deno_config::workspace::ResolutionKind::Types + } + }, + ) .map_err(|err| ResolveError::Other(JsErrorBox::from_err(err)))?; match resolution { diff --git a/cli/tools/registry/unfurl.rs b/cli/tools/registry/unfurl.rs index 66610217f3f61e..469a19fdf4124f 100644 --- a/cli/tools/registry/unfurl.rs +++ b/cli/tools/registry/unfurl.rs @@ -33,6 +33,7 @@ use deno_semver::Version; use deno_semver::VersionReq; use crate::resolver::CliSloppyImportsResolver; +use crate::sys::CliSys; #[derive(Debug, Clone)] pub enum SpecifierUnfurlerDiagnostic { @@ -190,14 +191,14 @@ enum UnfurlSpecifierError { pub struct SpecifierUnfurler { sloppy_imports_resolver: Option>, - workspace_resolver: Arc, + workspace_resolver: Arc>, bare_node_builtins: bool, } impl SpecifierUnfurler { pub fn new( sloppy_imports_resolver: Option>, - workspace_resolver: Arc, + workspace_resolver: Arc>, bare_node_builtins: bool, ) -> Self { debug_assert_eq!( @@ -252,9 +253,11 @@ impl SpecifierUnfurler { specifier: &str, resolution_kind: SloppyImportsResolutionKind, ) -> Result, UnfurlSpecifierError> { - let resolved = if let Ok(resolved) = - self.workspace_resolver.resolve(specifier, referrer) - { + let resolved = if let Ok(resolved) = self.workspace_resolver.resolve( + specifier, + referrer, + resolution_kind.into(), + ) { match resolved { MappedResolution::Normal { specifier, .. } | MappedResolution::ImportMap { specifier, .. } => Some(specifier), @@ -758,6 +761,9 @@ mod tests { }], vec![Arc::new(package_json)], deno_config::workspace::PackageJsonDepResolution::Enabled, + Default::default(), + Default::default(), + CliSys::default(), ); let unfurler = SpecifierUnfurler::new( Some(Arc::new(CliSloppyImportsResolver::new( @@ -900,6 +906,7 @@ export type * from "./c.d.ts"; cwd.join("package.json"), json!({ "workspaces": ["./publish", "./subtract", "./add"] }), ); + let sys = CliSys::default(); let workspace_resolver = WorkspaceResolver::new_raw( Arc::new(ModuleSpecifier::from_directory_path(&cwd).unwrap()), None, @@ -920,8 +927,10 @@ export type * from "./c.d.ts"; Arc::new(pkg_json_publishing), ], deno_config::workspace::PackageJsonDepResolution::Enabled, + Default::default(), + Default::default(), + sys.clone(), ); - let sys = CliSys::default(); let unfurler = SpecifierUnfurler::new( Some(Arc::new(CliSloppyImportsResolver::new( SloppyImportsCachedFs::new(sys), diff --git a/resolvers/deno/factory.rs b/resolvers/deno/factory.rs index 95db8415d4798a..e993d8c7342162 100644 --- a/resolvers/deno/factory.rs +++ b/resolvers/deno/factory.rs @@ -203,43 +203,32 @@ pub struct WorkspaceFactoryOptions< pub type WorkspaceFactoryRc = crate::sync::MaybeArc>; -pub struct WorkspaceFactory< - TSys: EnvCacheDir - + EnvHomeDir - + EnvVar - + EnvCurrentDir - + FsCanonicalize - + FsCreateDirAll - + FsMetadata - + FsOpen - + FsRead - + FsReadDir - + FsRemoveFile - + FsRename - + SystemRandom - + SystemTimeNow - + ThreadSleep - + std::fmt::Debug - + MaybeSend - + MaybeSync - + Clone - + 'static, -> { - sys: TSys, - deno_dir_path: DenoDirPathProviderRc, - global_http_cache: Deferred>, - http_cache: Deferred, - node_modules_dir_path: Deferred>, - npm_cache_dir: Deferred, - npmrc: Deferred, - node_modules_dir_mode: Deferred, - workspace_directory: Deferred, - initial_cwd: PathBuf, - options: WorkspaceFactoryOptions, +pub trait WorkspaceFactorySys: + EnvCacheDir + + EnvHomeDir + + EnvVar + + EnvCurrentDir + + FsCanonicalize + + FsCreateDirAll + + FsMetadata + + FsOpen + + FsRead + + FsReadDir + + FsRemoveFile + + FsRename + + SystemRandom + + SystemTimeNow + + ThreadSleep + + std::fmt::Debug + + MaybeSend + + MaybeSync + + Clone + + 'static +{ } impl< - TSys: EnvCacheDir + T: EnvCacheDir + EnvHomeDir + EnvVar + EnvCurrentDir @@ -259,8 +248,25 @@ impl< + MaybeSync + Clone + 'static, - > WorkspaceFactory + > WorkspaceFactorySys for T { +} + +pub struct WorkspaceFactory { + sys: TSys, + deno_dir_path: DenoDirPathProviderRc, + global_http_cache: Deferred>, + http_cache: Deferred, + node_modules_dir_path: Deferred>, + npm_cache_dir: Deferred, + npmrc: Deferred, + node_modules_dir_mode: Deferred, + workspace_directory: Deferred, + initial_cwd: PathBuf, + options: WorkspaceFactoryOptions, +} + +impl WorkspaceFactory { pub fn new( sys: TSys, initial_cwd: PathBuf, @@ -561,28 +567,7 @@ pub struct ResolverFactoryOptions { pub unstable_sloppy_imports: bool, } -pub struct ResolverFactory< - TSys: EnvCacheDir - + EnvCurrentDir - + EnvHomeDir - + EnvVar - + FsCanonicalize - + FsCreateDirAll - + FsMetadata - + FsOpen - + FsRead - + FsReadDir - + FsRemoveFile - + FsRename - + ThreadSleep - + SystemRandom - + SystemTimeNow - + std::fmt::Debug - + MaybeSend - + MaybeSync - + Clone - + 'static, -> { +pub struct ResolverFactory { options: ResolverFactoryOptions, deno_resolver: async_once_cell::OnceCell>, in_npm_package_checker: Deferred, @@ -608,32 +593,10 @@ pub struct ResolverFactory< sloppy_imports_resolver: Deferred>>>, workspace_factory: WorkspaceFactoryRc, - workspace_resolver: async_once_cell::OnceCell, + workspace_resolver: async_once_cell::OnceCell>, } -impl< - TSys: EnvCacheDir - + EnvCurrentDir - + EnvHomeDir - + EnvVar - + FsCanonicalize - + FsCreateDirAll - + FsMetadata - + FsOpen - + FsRead - + FsReadDir - + FsRemoveFile - + FsRename - + ThreadSleep - + SystemRandom - + SystemTimeNow - + std::fmt::Debug - + MaybeSend - + MaybeSync - + Clone - + 'static, - > ResolverFactory -{ +impl ResolverFactory { pub fn new( workspace_factory: WorkspaceFactoryRc, options: ResolverFactoryOptions, @@ -834,7 +797,7 @@ impl< pub async fn workspace_resolver( &self, - ) -> Result<&WorkspaceResolverRc, anyhow::Error> { + ) -> Result<&WorkspaceResolverRc, anyhow::Error> { self .workspace_resolver .get_or_try_init( @@ -865,13 +828,13 @@ impl< }, specified_import_map, }; - let resolver = - workspace.create_resolver(&self.workspace_factory.sys, options)?; + let resolver = workspace + .create_resolver(self.workspace_factory.sys.clone(), options)?; if !resolver.diagnostics().is_empty() { // todo(dsherret): do not log this in this crate... that should be // a CLI responsibility log::warn!( - "Import map diagnostics:\n{}", + "Resolver diagnostics:\n{}", resolver .diagnostics() .iter() diff --git a/resolvers/deno/lib.rs b/resolvers/deno/lib.rs index 0ac073821cb671..26272af3bcb1ca 100644 --- a/resolvers/deno/lib.rs +++ b/resolvers/deno/lib.rs @@ -49,7 +49,8 @@ pub mod sloppy_imports; mod sync; #[allow(clippy::disallowed_types)] -pub type WorkspaceResolverRc = crate::sync::MaybeArc; +pub type WorkspaceResolverRc = + crate::sync::MaybeArc>; #[allow(clippy::disallowed_types)] pub(crate) type NpmCacheDirRc = crate::sync::MaybeArc; @@ -141,7 +142,7 @@ pub struct DenoResolverOptions< >, pub sloppy_imports_resolver: Option>, - pub workspace_resolver: WorkspaceResolverRc, + 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. @@ -197,7 +198,7 @@ pub struct DenoResolver< >, sloppy_imports_resolver: Option>, - workspace_resolver: WorkspaceResolverRc, + workspace_resolver: WorkspaceResolverRc, is_byonm: bool, maybe_vendor_specifier: Option, } @@ -269,7 +270,7 @@ impl< // Attempt to resolve with the workspace resolver let result: Result<_, DenoResolveError> = self .workspace_resolver - .resolve(raw_specifier, referrer) + .resolve(raw_specifier, referrer, resolution_kind.into()) .map_err(|err| err.into()); let result = match result { Ok(resolution) => match resolution { diff --git a/resolvers/deno/sloppy_imports.rs b/resolvers/deno/sloppy_imports.rs index 486d2dab1e8902..8a43be16aa3917 100644 --- a/resolvers/deno/sloppy_imports.rs +++ b/resolvers/deno/sloppy_imports.rs @@ -97,6 +97,17 @@ impl SloppyImportsResolutionKind { } } +impl From + for deno_config::workspace::ResolutionKind +{ + fn from(value: SloppyImportsResolutionKind) -> Self { + match value { + SloppyImportsResolutionKind::Execution => Self::Execution, + SloppyImportsResolutionKind::Types => Self::Types, + } + } +} + pub trait SloppyImportResolverFs { fn stat_sync(&self, path: &Path) -> Option; diff --git a/resolvers/node/Cargo.toml b/resolvers/node/Cargo.toml index 0fef5205336789..03065dc05623ea 100644 --- a/resolvers/node/Cargo.toml +++ b/resolvers/node/Cargo.toml @@ -21,6 +21,7 @@ anyhow.workspace = true async-trait.workspace = true boxed_error.workspace = true dashmap.workspace = true +deno_config.workspace = true deno_error.workspace = true deno_media_type.workspace = true deno_package_json.workspace = true diff --git a/resolvers/node/resolution.rs b/resolvers/node/resolution.rs index 0764698998dd7d..481e4d679f581f 100644 --- a/resolvers/node/resolution.rs +++ b/resolvers/node/resolution.rs @@ -109,6 +109,15 @@ pub enum NodeResolutionKind { Types, } +impl From for deno_config::workspace::ResolutionKind { + fn from(value: NodeResolutionKind) -> Self { + match value { + NodeResolutionKind::Execution => Self::Execution, + NodeResolutionKind::Types => Self::Types, + } + } +} + impl NodeResolutionKind { pub fn is_types(&self) -> bool { matches!(self, NodeResolutionKind::Types) diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index dad292951d5641..a07d71a1cbdbb1 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -306,7 +306,6 @@ fn lsp_import_map() { } }"#; temp_dir.write("import-map.json", import_map); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().build(); @@ -439,7 +438,6 @@ fn lsp_import_map_config_file() { } }"#, ); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().build(); @@ -501,7 +499,6 @@ fn lsp_import_map_embedded_in_config_file() { } }"#, ); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().build(); @@ -555,7 +552,6 @@ fn lsp_import_map_embedded_in_config_file_after_initialize() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); temp_dir.write("deno.embedded_import_map.jsonc", "{}"); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().build(); @@ -627,7 +623,6 @@ fn lsp_import_map_embedded_in_config_file_after_initialize() { fn lsp_import_map_config_file_auto_discovered() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().capture_stderr().build(); @@ -747,7 +742,6 @@ fn lsp_import_map_config_file_auto_discovered_symlink() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().capture_stderr().build(); @@ -755,7 +749,6 @@ fn lsp_import_map_config_file_auto_discovered_symlink() { // now create a symlink in the current directory to a subdir/deno.json // and ensure the watched files notification still works - temp_dir.create_dir_all("subdir"); temp_dir.write("subdir/deno.json", r#"{ }"#); temp_dir.symlink_file( temp_dir.path().join("subdir").join("deno.json"), @@ -1052,10 +1045,6 @@ fn lsp_workspace_enable_paths_no_workspace_configuration() { fn lsp_did_refresh_deno_configuration_tree_notification() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("workspace/member1"); - temp_dir.create_dir_all("workspace/member2"); - temp_dir.create_dir_all("non_workspace1"); - temp_dir.create_dir_all("non_workspace2"); temp_dir.write( "workspace/deno.json", json!({ @@ -1541,7 +1530,6 @@ fn lsp_import_map_import_completions() { }) .to_string(), ); - temp_dir.create_dir_all("lib"); temp_dir.write("lib/b.ts", r#"export const b = "b";"#); let mut client = context.new_lsp_command().build(); @@ -2168,7 +2156,6 @@ fn lsp_workspace_disable_enable_paths() { fn run_test(use_trailing_slash: bool) { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("worker"); temp_dir.write("worker/shared.ts", "export const a = 1"); temp_dir.write("worker/other.ts", "import { a } from './shared.ts';\na;"); temp_dir.write("worker/node.ts", "Buffer.alloc(1);"); @@ -2386,13 +2373,11 @@ fn lsp_workspace_disable_enable_paths() { fn lsp_exclude_config() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("other"); temp_dir.write( "other/shared.ts", // this should not be found in the "find references" since this file is excluded "import { a } from '../worker/shared.ts'; console.log(a);", ); - temp_dir.create_dir_all("worker"); temp_dir.write("worker/shared.ts", "export const a = 1"); temp_dir.write( "deno.json", @@ -6425,7 +6410,6 @@ fn lsp_code_actions_deno_types_for_npm() { }) .to_string(), ); - temp_dir.create_dir_all("managed_node_modules"); temp_dir.write( "managed_node_modules/deno.json", json!({ @@ -13848,7 +13832,6 @@ fn lsp_closed_file_find_references() { fn lsp_closed_file_find_references_low_document_pre_load() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("sub_dir"); temp_dir.write("./other_file.ts", "export const b = 5;"); temp_dir.write("./sub_dir/mod.ts", "export const a = 5;"); temp_dir.write( @@ -13893,8 +13876,6 @@ fn lsp_closed_file_find_references_excluded_path() { // the config file from being pre-loaded let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("sub_dir"); - temp_dir.create_dir_all("other_dir/sub_dir"); temp_dir.write("./sub_dir/mod.ts", "export const a = 5;"); temp_dir.write( "./sub_dir/mod.test.ts", @@ -14374,8 +14355,6 @@ fn lsp_vendor_dir() { fn lsp_deno_json_scopes_import_map() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2/project3"); temp_dir.write( "project1/deno.json", json!({ @@ -14508,8 +14487,6 @@ fn lsp_deno_json_scopes_vendor_dir() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2/project3"); temp_dir.write( "project1/deno.json", json!({ @@ -14693,8 +14670,6 @@ fn lsp_deno_json_scopes_node_modules_dir() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2/project3"); temp_dir.write( "project1/deno.json", json!({ @@ -14878,8 +14853,6 @@ fn lsp_deno_json_scopes_node_modules_dir() { fn lsp_deno_json_scopes_ts_config() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write( "project2/deno.json", @@ -14952,8 +14925,6 @@ fn lsp_deno_json_scopes_ts_config() { fn lsp_deno_json_scopes_declaration_files() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); temp_dir.write("project1/foo.d.ts", "declare type Foo = number;\n"); @@ -15020,8 +14991,6 @@ fn lsp_deno_json_scopes_declaration_files() { fn lsp_deno_json_scopes_find_references() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); let file1 = source_file( @@ -15064,8 +15033,6 @@ fn lsp_deno_json_scopes_find_references() { fn lsp_deno_json_scopes_file_rename_import_edits() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); let file1 = source_file(temp_dir.path().join("project1/file.ts"), ""); @@ -15112,8 +15079,6 @@ fn lsp_deno_json_scopes_file_rename_import_edits() { fn lsp_deno_json_scopes_goto_implementations() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); let file1 = source_file( @@ -15153,9 +15118,6 @@ fn lsp_deno_json_scopes_goto_implementations() { fn lsp_deno_json_scopes_call_hierarchy() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); - temp_dir.create_dir_all("project3"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); temp_dir.write("project3/deno.json", json!({}).to_string()); @@ -15266,8 +15228,6 @@ fn lsp_deno_json_scopes_call_hierarchy() { fn lsp_deno_json_scopes_rename_symbol() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); let file1 = source_file( @@ -15326,8 +15286,6 @@ fn lsp_deno_json_scopes_rename_symbol() { fn lsp_deno_json_scopes_search_symbol() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1"); - temp_dir.create_dir_all("project2"); temp_dir.write("project1/deno.json", json!({}).to_string()); temp_dir.write("project2/deno.json", json!({}).to_string()); let file1 = source_file( @@ -15382,7 +15340,6 @@ fn lsp_deno_json_workspace_fmt_config() { }) .to_string(), ); - temp_dir.create_dir_all("project1"); temp_dir.write( "project1/deno.json", json!({ @@ -15392,7 +15349,6 @@ fn lsp_deno_json_workspace_fmt_config() { }) .to_string(), ); - temp_dir.create_dir_all("project2"); temp_dir.write("project2/deno.json", json!({}).to_string()); let mut client = context.new_lsp_command().build(); client.initialize_default(); @@ -15507,7 +15463,6 @@ fn lsp_deno_json_workspace_lint_config() { }) .to_string(), ); - temp_dir.create_dir_all("project1"); temp_dir.write( "project1/deno.json", json!({ @@ -15519,7 +15474,6 @@ fn lsp_deno_json_workspace_lint_config() { }) .to_string(), ); - temp_dir.create_dir_all("project2"); temp_dir.write("project2/deno.json", json!({}).to_string()); let mut client = context.new_lsp_command().build(); client.initialize_default(); @@ -15644,7 +15598,6 @@ fn lsp_deno_json_workspace_lint_config() { fn lsp_deno_json_workspace_import_map() { let context = TestContextBuilder::new().use_temp_cwd().build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1/project2"); temp_dir.write( "project1/deno.json", json!({ @@ -15747,7 +15700,6 @@ fn lsp_workspace_lockfile() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1/project2"); temp_dir.write( "project1/deno.json", json!({ @@ -15812,7 +15764,6 @@ fn lsp_deno_json_workspace_vendor_dir() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1/project2"); temp_dir.write( "project1/deno.json", json!({ @@ -15884,7 +15835,6 @@ fn lsp_deno_json_workspace_node_modules_dir() { .use_temp_cwd() .build(); let temp_dir = context.temp_dir(); - temp_dir.create_dir_all("project1/project2"); temp_dir.write( "project1/deno.json", json!({ @@ -15963,7 +15913,6 @@ fn lsp_deno_json_workspace_jsr_resolution() { }) .to_string(), ); - temp_dir.create_dir_all("project1"); temp_dir.write( "project1/deno.json", json!({ @@ -16013,6 +15962,66 @@ fn lsp_deno_json_workspace_jsr_resolution() { client.shutdown(); } +#[test] +fn lsp_workspace_compiler_options_root_dirs() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.json", + json!({ + "workspace": ["member"], + "compilerOptions": { + "rootDirs": ["member", "non_member", "non_member_types"], + }, + }) + .to_string(), + ); + temp_dir.write( + "member/deno.json", + json!({ + "compilerOptions": { + "rootDirs": ["subdir", "subdir_types"], + }, + }) + .to_string(), + ); + let file1 = source_file( + temp_dir.path().join("member/subdir/mod.ts"), + r#" + import type { someType } from "./import.ts"; + const foo: someType = ""; + console.log(foo); + "#, + ); + source_file( + temp_dir.path().join("member/subdir_types/import.ts"), + r#" + export type someType = string; + "#, + ); + let file2 = source_file( + temp_dir.path().join("non_member/mod.ts"), + r#" + import type { someType } from "./import.ts"; + const foo: someType = 0; + console.log(foo); + "#, + ); + source_file( + temp_dir.path().join("non_member_types/import.ts"), + r#" + export type someType = number; + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open_file(&file1); + assert_eq!(json!(diagnostics.all()), json!([])); + let diagnostics = client.did_open_file(&file2); + assert_eq!(json!(diagnostics.all()), json!([])); + client.shutdown(); +} + #[test] fn lsp_npm_workspace() { let context = TestContextBuilder::new() @@ -16037,7 +16046,6 @@ fn lsp_npm_workspace() { .to_string(), ); { - temp_dir.create_dir_all("packages/add"); temp_dir.write( "packages/add/package.json", json!({ @@ -16053,7 +16061,6 @@ fn lsp_npm_workspace() { ); } { - temp_dir.create_dir_all("packages/subtract"); temp_dir.write( "packages/subtract/package.json", json!({ diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/__test__.jsonc b/tests/specs/check/workspace_compiler_options_root_dirs/__test__.jsonc new file mode 100644 index 00000000000000..8e273fb5122b11 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/__test__.jsonc @@ -0,0 +1,4 @@ +{ + "args": "check --quiet member/subdir/mod.ts non_member/mod.ts", + "output": "" +} diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/deno.json b/tests/specs/check/workspace_compiler_options_root_dirs/deno.json new file mode 100644 index 00000000000000..828a3b51831823 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/deno.json @@ -0,0 +1,6 @@ +{ + "workspace": ["member"], + "compilerOptions": { + "rootDirs": ["member", "non_member", "non_member_types"] + } +} diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/member/deno.json b/tests/specs/check/workspace_compiler_options_root_dirs/member/deno.json new file mode 100644 index 00000000000000..6380aaefad9257 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/member/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "rootDirs": ["subdir", "subdir_types"] + } +} diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir/mod.ts b/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir/mod.ts new file mode 100644 index 00000000000000..68aee671dc5954 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir/mod.ts @@ -0,0 +1,3 @@ +import type { someType } from "./import.ts"; +const foo: someType = ""; +console.log(foo); diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir_types/import.ts b/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir_types/import.ts new file mode 100644 index 00000000000000..423236068f24f4 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/member/subdir_types/import.ts @@ -0,0 +1 @@ +export type someType = string; diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/non_member/mod.ts b/tests/specs/check/workspace_compiler_options_root_dirs/non_member/mod.ts new file mode 100644 index 00000000000000..ef2ed1e0b6bd7c --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/non_member/mod.ts @@ -0,0 +1,3 @@ +import type { someType } from "./import.ts"; +const foo: someType = 0; +console.log(foo); diff --git a/tests/specs/check/workspace_compiler_options_root_dirs/non_member_types/import.ts b/tests/specs/check/workspace_compiler_options_root_dirs/non_member_types/import.ts new file mode 100644 index 00000000000000..c891e2e06aa693 --- /dev/null +++ b/tests/specs/check/workspace_compiler_options_root_dirs/non_member_types/import.ts @@ -0,0 +1 @@ +export type someType = number; diff --git a/tests/util/server/src/fs.rs b/tests/util/server/src/fs.rs index 19b94731eb26a9..062ca59ef3a202 100644 --- a/tests/util/server/src/fs.rs +++ b/tests/util/server/src/fs.rs @@ -162,7 +162,11 @@ impl PathRef { #[track_caller] pub fn rename(&self, to: impl AsRef) { - fs::rename(self, self.join(to)).unwrap(); + let to = self.join(to); + if let Some(parent_path) = to.as_path().parent() { + fs::create_dir_all(parent_path).unwrap() + } + fs::rename(self, to).unwrap(); } #[track_caller] @@ -173,6 +177,9 @@ impl PathRef { #[track_caller] pub fn write(&self, text: impl AsRef<[u8]>) { + if let Some(parent_path) = self.as_path().parent() { + fs::create_dir_all(parent_path).unwrap() + } fs::write(self, text).unwrap(); } @@ -188,17 +195,20 @@ impl PathRef { oldpath: impl AsRef, newpath: impl AsRef, ) { + let oldpath = self.as_path().join(oldpath); + let newpath = self.as_path().join(newpath); + if let Some(parent_path) = newpath.parent() { + fs::create_dir_all(parent_path).unwrap() + } #[cfg(unix)] { use std::os::unix::fs::symlink; - symlink(self.as_path().join(oldpath), self.as_path().join(newpath)) - .unwrap(); + symlink(oldpath, newpath).unwrap(); } #[cfg(not(unix))] { use std::os::windows::fs::symlink_dir; - symlink_dir(self.as_path().join(oldpath), self.as_path().join(newpath)) - .unwrap(); + symlink_dir(oldpath, newpath).unwrap(); } } @@ -208,17 +218,20 @@ impl PathRef { oldpath: impl AsRef, newpath: impl AsRef, ) { + let oldpath = self.as_path().join(oldpath); + let newpath = self.as_path().join(newpath); + if let Some(parent_path) = newpath.as_path().parent() { + fs::create_dir_all(parent_path).unwrap() + } #[cfg(unix)] { use std::os::unix::fs::symlink; - symlink(self.as_path().join(oldpath), self.as_path().join(newpath)) - .unwrap(); + symlink(oldpath, newpath).unwrap(); } #[cfg(not(unix))] { use std::os::windows::fs::symlink_file; - symlink_file(self.as_path().join(oldpath), self.as_path().join(newpath)) - .unwrap(); + symlink_file(oldpath, newpath).unwrap(); } }