Skip to content

Commit

Permalink
fix(lsp): move sloppy import resolution from loader to resolver (deno…
Browse files Browse the repository at this point in the history
…land#23751)

Moves sloppy import resolution from the loader to the resolver.

Also adds some test helper functions to make the lsp tests less verbose

---------

Co-authored-by: David Sherret <[email protected]>
  • Loading branch information
nathanwhit and dsherret committed May 9, 2024
1 parent 263b6b9 commit dc29986
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 286 deletions.
112 changes: 15 additions & 97 deletions cli/lsp/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ use super::tsc::AssetDocument;
use crate::cache::HttpCache;
use crate::graph_util::CliJsrUrlProvider;
use crate::lsp::logging::lsp_warn;
use crate::resolver::SloppyImportsFsEntry;
use crate::resolver::SloppyImportsResolution;
use crate::resolver::SloppyImportsResolver;
use deno_graph::source::Resolver;
use deno_runtime::fs_util::specifier_to_file_path;

use dashmap::DashMap;
Expand Down Expand Up @@ -390,7 +388,7 @@ impl Document {
d.with_new_resolver(
s,
&CliJsrUrlProvider,
Some(graph_resolver),
Some(&graph_resolver),
Some(npm_resolver),
),
)
Expand All @@ -400,7 +398,7 @@ impl Document {
maybe_types_dependency = self.maybe_types_dependency.as_ref().map(|d| {
Arc::new(d.with_new_resolver(
&CliJsrUrlProvider,
Some(graph_resolver),
Some(&graph_resolver),
Some(npm_resolver),
))
});
Expand Down Expand Up @@ -854,8 +852,6 @@ pub struct Documents {
/// Gets if any document had a node: specifier such that a @types/node package
/// should be injected.
has_injected_types_node_package: bool,
/// If --unstable-sloppy-imports is enabled.
unstable_sloppy_imports: bool,
}

impl Documents {
Expand All @@ -869,7 +865,6 @@ impl Documents {
resolver: Default::default(),
npm_specifier_reqs: Default::default(),
has_injected_types_node_package: false,
unstable_sloppy_imports: false,
}
}

Expand Down Expand Up @@ -996,54 +991,17 @@ impl Documents {
&self,
specifier: &ModuleSpecifier,
) -> Option<ModuleSpecifier> {
if self.unstable_sloppy_imports && specifier.scheme() == "file" {
Some(
self
.resolve_unstable_sloppy_import(specifier)
.into_specifier()
.into_owned(),
)
let specifier = if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
Cow::Owned(self.resolver.jsr_to_registry_url(&jsr_req_ref)?)
} else {
let specifier = if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
Cow::Owned(self.resolver.jsr_to_registry_url(&jsr_req_ref)?)
} else {
Cow::Borrowed(specifier)
};
if !DOCUMENT_SCHEMES.contains(&specifier.scheme()) {
return None;
}
self.resolver.resolve_redirects(&specifier)
Cow::Borrowed(specifier)
};
if !DOCUMENT_SCHEMES.contains(&specifier.scheme()) {
return None;
}
}

fn resolve_unstable_sloppy_import<'a>(
&self,
specifier: &'a ModuleSpecifier,
) -> SloppyImportsResolution<'a> {
SloppyImportsResolver::resolve_with_stat_sync(
specifier,
ResolutionMode::Types,
|path| {
if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
if self.open_docs.contains_key(&specifier)
|| self.cache.contains(&specifier)
{
return Some(SloppyImportsFsEntry::File);
}
}
path.metadata().ok().and_then(|m| {
if m.is_file() {
Some(SloppyImportsFsEntry::File)
} else if m.is_dir() {
Some(SloppyImportsFsEntry::Dir)
} else {
None
}
})
},
)
self.resolver.resolve_redirects(&specifier)
}

/// Return `true` if the specifier can be resolved to a document.
Expand Down Expand Up @@ -1226,12 +1184,7 @@ impl Documents {
) {
self.config = Arc::new(config.clone());
self.cache = cache;
let config_data = config.tree.root_data();
let config_file = config_data.and_then(|d| d.config_file.as_deref());
self.resolver = resolver.clone();
self.unstable_sloppy_imports = config_file
.map(|c| c.has_unstable("sloppy-imports"))
.unwrap_or(false);
{
let fs_docs = &self.file_system_docs;
// Clean up non-existent documents.
Expand Down Expand Up @@ -1404,7 +1357,6 @@ fn node_resolve_npm_req_ref(
pub struct OpenDocumentsGraphLoader<'a> {
pub inner_loader: &'a mut dyn deno_graph::source::Loader,
pub open_docs: &'a HashMap<ModuleSpecifier, Arc<Document>>,
pub unstable_sloppy_imports: bool,
}

impl<'a> OpenDocumentsGraphLoader<'a> {
Expand All @@ -1426,32 +1378,6 @@ impl<'a> OpenDocumentsGraphLoader<'a> {
}
None
}

fn resolve_unstable_sloppy_import<'b>(
&self,
specifier: &'b ModuleSpecifier,
) -> SloppyImportsResolution<'b> {
SloppyImportsResolver::resolve_with_stat_sync(
specifier,
ResolutionMode::Types,
|path| {
if let Ok(specifier) = ModuleSpecifier::from_file_path(path) {
if self.open_docs.contains_key(&specifier) {
return Some(SloppyImportsFsEntry::File);
}
}
path.metadata().ok().and_then(|m| {
if m.is_file() {
Some(SloppyImportsFsEntry::File)
} else if m.is_dir() {
Some(SloppyImportsFsEntry::Dir)
} else {
None
}
})
},
)
}
}

impl<'a> deno_graph::source::Loader for OpenDocumentsGraphLoader<'a> {
Expand All @@ -1460,17 +1386,9 @@ impl<'a> deno_graph::source::Loader for OpenDocumentsGraphLoader<'a> {
specifier: &ModuleSpecifier,
options: deno_graph::source::LoadOptions,
) -> deno_graph::source::LoadFuture {
let specifier = if self.unstable_sloppy_imports {
self
.resolve_unstable_sloppy_import(specifier)
.into_specifier()
} else {
Cow::Borrowed(specifier)
};

match self.load_from_docs(&specifier) {
match self.load_from_docs(specifier) {
Some(fut) => fut,
None => self.inner_loader.load(&specifier, options),
None => self.inner_loader.load(specifier, options),
}
}

Expand Down Expand Up @@ -1531,7 +1449,7 @@ fn analyze_module(
// dynamic imports like import(`./dir/${something}`) in the LSP
file_system: &deno_graph::source::NullFileSystem,
jsr_url_provider: &CliJsrUrlProvider,
maybe_resolver: Some(resolver.as_graph_resolver()),
maybe_resolver: Some(&resolver.as_graph_resolver()),
maybe_npm_resolver: Some(resolver.as_graph_npm_resolver()),
},
)),
Expand Down
1 change: 0 additions & 1 deletion cli/lsp/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl LanguageServer {
let mut loader = crate::lsp::documents::OpenDocumentsGraphLoader {
inner_loader: &mut inner_loader,
open_docs: &open_docs,
unstable_sloppy_imports: cli_options.unstable_sloppy_imports(),
};
let graph = module_graph_creator
.create_graph_with_loader(GraphKind::All, roots.clone(), &mut loader)
Expand Down
82 changes: 77 additions & 5 deletions cli/lsp/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::npm::ManagedCliNpmResolver;
use crate::resolver::CliGraphResolver;
use crate::resolver::CliGraphResolverOptions;
use crate::resolver::CliNodeResolver;
use crate::resolver::SloppyImportsFsEntry;
use crate::resolver::SloppyImportsResolver;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
use deno_cache_dir::HttpCache;
Expand Down Expand Up @@ -60,6 +62,7 @@ pub struct LspResolver {
redirect_resolver: Option<Arc<RedirectResolver>>,
graph_imports: Arc<IndexMap<ModuleSpecifier, GraphImport>>,
config: Arc<Config>,
unstable_sloppy_imports: bool,
}

impl Default for LspResolver {
Expand All @@ -73,6 +76,7 @@ impl Default for LspResolver {
redirect_resolver: None,
graph_imports: Default::default(),
config: Default::default(),
unstable_sloppy_imports: false,
}
}
}
Expand Down Expand Up @@ -140,6 +144,10 @@ impl LspResolver {
npm_config_hash,
redirect_resolver,
graph_imports,
unstable_sloppy_imports: config_data
.and_then(|d| d.config_file.as_ref())
.map(|cf| cf.has_unstable("sloppy-imports"))
.unwrap_or(false),
config: Arc::new(config.clone()),
})
}
Expand All @@ -162,6 +170,7 @@ impl LspResolver {
redirect_resolver: self.redirect_resolver.clone(),
graph_imports: self.graph_imports.clone(),
config: self.config.clone(),
unstable_sloppy_imports: self.unstable_sloppy_imports,
})
}

Expand All @@ -181,8 +190,11 @@ impl LspResolver {
Ok(())
}

pub fn as_graph_resolver(&self) -> &dyn Resolver {
self.graph_resolver.as_ref()
pub fn as_graph_resolver(&self) -> LspGraphResolver {
LspGraphResolver {
inner: &self.graph_resolver,
unstable_sloppy_imports: self.unstable_sloppy_imports,
}
}

pub fn as_graph_npm_resolver(&self) -> &dyn NpmResolver {
Expand Down Expand Up @@ -307,6 +319,68 @@ impl LspResolver {
}
}

#[derive(Debug)]
pub struct LspGraphResolver<'a> {
inner: &'a CliGraphResolver,
unstable_sloppy_imports: bool,
}

impl<'a> Resolver for LspGraphResolver<'a> {
fn default_jsx_import_source(&self) -> Option<String> {
self.inner.default_jsx_import_source()
}

fn default_jsx_import_source_types(&self) -> Option<String> {
self.inner.default_jsx_import_source_types()
}

fn jsx_import_source_module(&self) -> &str {
self.inner.jsx_import_source_module()
}

fn resolve(
&self,
specifier_text: &str,
referrer_range: &deno_graph::Range,
mode: deno_graph::source::ResolutionMode,
) -> Result<deno_ast::ModuleSpecifier, deno_graph::source::ResolveError> {
let specifier = self.inner.resolve(specifier_text, referrer_range, mode)?;
if self.unstable_sloppy_imports && specifier.scheme() == "file" {
Ok(
SloppyImportsResolver::resolve_with_stat_sync(
&specifier,
mode,
|path| {
path.metadata().ok().and_then(|m| {
if m.is_file() {
Some(SloppyImportsFsEntry::File)
} else if m.is_dir() {
Some(SloppyImportsFsEntry::Dir)
} else {
None
}
})
},
)
.into_specifier()
.into_owned(),
)
} else {
Ok(specifier)
}
}

fn resolve_types(
&self,
specifier: &deno_ast::ModuleSpecifier,
) -> Result<
Option<(deno_ast::ModuleSpecifier, Option<deno_graph::Range>)>,
deno_graph::source::ResolveError,
> {
self.inner.resolve_types(specifier)
}
}

async fn create_npm_resolver(
config_data: &ConfigData,
global_cache_path: Option<&Path>,
Expand Down Expand Up @@ -399,9 +473,7 @@ fn create_graph_resolver(
bare_node_builtins_enabled: config_file
.map(|cf| cf.has_unstable("bare-node-builtins"))
.unwrap_or(false),
// Don't set this for the LSP because instead we'll use the OpenDocumentsLoader
// because it's much easier and we get diagnostics/quick fixes about a redirected
// specifier for free.
// not used in the LSP as the LspGraphResolver handles this
sloppy_imports_resolver: None,
}))
}
Expand Down

0 comments on commit dc29986

Please sign in to comment.