refactor(lsp): internally expose and use LspScopedResolver (#28755)

Reduces some repeat hashmap lookups by exposing the `LspScopedResolver`.
This commit is contained in:
David Sherret 2025-04-04 17:48:04 -04:00 committed by GitHub
parent 37b760e3c6
commit 9d841987ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 240 additions and 294 deletions

View file

@ -280,6 +280,9 @@ impl<'a> TsResponseImportMapper<'a> {
return Some(specifier.to_string());
}
let scoped_resolver =
self.resolver.get_scoped_resolver(self.scope.as_deref());
if let Some(jsr_path) = specifier.as_str().strip_prefix(jsr_url().as_str())
{
let mut segments = jsr_path.split('/');
@ -298,11 +301,7 @@ impl<'a> TsResponseImportMapper<'a> {
let version = Version::parse_standard(segments.next()?).ok()?;
let nv = PackageNv { name, version };
let path = segments.collect::<Vec<_>>().join("/");
let export = self.resolver.jsr_lookup_export_for_path(
&nv,
&path,
self.scope.as_deref(),
)?;
let export = scoped_resolver.jsr_lookup_export_for_path(&nv, &path)?;
let sub_path = (export != ".")
.then_some(export)
.map(SmallStackString::from_string);
@ -326,11 +325,7 @@ impl<'a> TsResponseImportMapper<'a> {
}
None
});
req = req.or_else(|| {
self
.resolver
.jsr_lookup_req_for_nv(&nv, self.scope.as_deref())
});
req = req.or_else(|| scoped_resolver.jsr_lookup_req_for_nv(&nv));
let spec_str = if let Some(req) = req {
let req_ref = PackageReqReference { req, sub_path };
JsrPackageReqReference::new(req_ref).to_string()
@ -357,13 +352,10 @@ impl<'a> TsResponseImportMapper<'a> {
return Some(spec_str);
}
if let Some(npm_resolver) = self
.resolver
.maybe_managed_npm_resolver(self.scope.as_deref())
if let Some(npm_resolver) = scoped_resolver.as_maybe_managed_npm_resolver()
{
let in_npm_pkg = self
.resolver
.in_npm_pkg_checker(self.scope.as_deref())
let in_npm_pkg = scoped_resolver
.as_in_npm_pkg_checker()
.in_npm_package(specifier);
if in_npm_pkg {
if let Ok(Some(pkg_id)) =
@ -428,9 +420,8 @@ impl<'a> TsResponseImportMapper<'a> {
}
}
}
} else if let Some(dep_name) = self
.resolver
.file_url_to_package_json_dep(specifier, self.scope.as_deref())
} else if let Some(dep_name) =
scoped_resolver.file_url_to_package_json_dep(specifier)
{
return Some(dep_name);
}
@ -450,9 +441,9 @@ impl<'a> TsResponseImportMapper<'a> {
specifier: &ModuleSpecifier,
package_root_folder: &Path,
) -> Option<String> {
let package_json = self
.resolver
.pkg_json_resolver(specifier)
let scoped_resolver = self.resolver.get_scoped_resolver(Some(specifier));
let package_json = scoped_resolver
.as_pkg_json_resolver()
// the specifier might have a closer package.json, but we
// want the root of the package's package.json
.get_closest_package_json(&package_root_folder.join("package.json"))
@ -514,10 +505,11 @@ impl<'a> TsResponseImportMapper<'a> {
.iter()
.map(|ext| Cow::Owned(format!("{specifier_stem}{ext}"))),
);
let scoped_resolver =
self.resolver.get_scoped_resolver(self.scope.as_deref());
for specifier in specifiers {
if let Some(specifier) = self
.resolver
.as_cli_resolver(self.scope.as_deref())
if let Some(specifier) = scoped_resolver
.as_cli_resolver()
.resolve(
&specifier,
referrer,
@ -553,7 +545,8 @@ impl<'a> TsResponseImportMapper<'a> {
) -> bool {
self
.resolver
.as_cli_resolver(self.scope.as_deref())
.get_scoped_resolver(self.scope.as_deref())
.as_cli_resolver()
.resolve(
specifier_text,
referrer,

View file

@ -170,8 +170,9 @@ pub async fn get_import_completions(
.map(to_node_resolution_mode)
.unwrap_or_else(|| module.resolution_mode);
let range = to_narrow_lsp_range(module.text_info(), graph_range.range);
let resolved = resolver
.as_cli_resolver(module.scope.as_deref())
let scoped_resolver = resolver.get_scoped_resolver(module.scope.as_deref());
let resolved = scoped_resolver
.as_cli_resolver()
.resolve(
text,
&module.specifier,
@ -377,8 +378,9 @@ fn get_local_completions(
return None;
}
let parent = &text[..text.char_indices().rfind(|(_, c)| *c == '/')?.0 + 1];
let resolved_parent = resolver
.as_cli_resolver(Some(referrer))
let scoped_resolver = resolver.get_scoped_resolver(Some(referrer));
let resolved_parent = scoped_resolver
.as_cli_resolver()
.resolve(
parent,
referrer,

View file

@ -1596,13 +1596,12 @@ fn diagnose_resolution(
match resolution {
Resolution::Ok(resolved) => {
let specifier = &resolved.specifier;
let managed_npm_resolver = snapshot
let scoped_resolver = snapshot
.resolver
.maybe_managed_npm_resolver(referrer_module.scope.as_deref());
for (_, headers) in snapshot
.resolver
.redirect_chain_headers(specifier, referrer_module.scope.as_deref())
{
.get_scoped_resolver(referrer_module.scope.as_deref());
let managed_npm_resolver =
scoped_resolver.as_maybe_managed_npm_resolver();
for (_, headers) in scoped_resolver.redirect_chain_headers(specifier) {
if let Some(message) = headers.get("x-deno-warning") {
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
}

View file

@ -1041,14 +1041,15 @@ impl DocumentModules {
specifier: &Url,
scope: Option<&Url>,
) -> Option<Arc<DocumentModule>> {
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
let specifier = if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
Cow::Owned(self.resolver.jsr_to_resource_url(&jsr_req_ref, scope)?)
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
} else {
Cow::Borrowed(specifier)
};
let specifier = self.resolver.resolve_redirects(&specifier, scope)?;
let specifier = scoped_resolver.resolve_redirects(&specifier)?;
let document =
self
.documents
@ -1137,14 +1138,15 @@ impl DocumentModules {
specifier: &Url,
scope: Option<&Url>,
) -> Option<Arc<DocumentModule>> {
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
let specifier = if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
Cow::Owned(self.resolver.jsr_to_resource_url(&jsr_req_ref, scope)?)
Cow::Owned(scoped_resolver.jsr_to_resource_url(&jsr_req_ref)?)
} else {
Cow::Borrowed(specifier)
};
let specifier = self.resolver.resolve_redirects(&specifier, scope)?;
let specifier = scoped_resolver.resolve_redirects(&specifier)?;
let modules = self.modules_for_scope(scope)?;
modules.get_for_specifier(&specifier)
}
@ -1332,8 +1334,9 @@ impl DocumentModules {
member_dir.to_maybe_jsx_import_source_config().ok()??;
let import_source_types = jsx_config.import_source_types.as_ref()?;
let import_source = jsx_config.import_source.as_ref()?;
let cli_resolver =
self.resolver.as_cli_resolver(scope.map(|s| s.as_ref()));
let scoped_resolver =
self.resolver.get_scoped_resolver(scope.map(|s| s.as_ref()));
let cli_resolver = scoped_resolver.as_cli_resolver();
let type_specifier = cli_resolver
.resolve(
&import_source_types.specifier,
@ -1417,6 +1420,7 @@ impl DocumentModules {
let referrer_module = self.module_for_specifier(referrer, scope);
let dependencies = referrer_module.as_ref().map(|d| &d.dependencies);
let mut results = Vec::new();
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
for (is_cjs, raw_specifier) in raw_specifiers {
let resolution_mode = match is_cjs {
true => ResolutionMode::Require,
@ -1449,15 +1453,13 @@ impl DocumentModules {
} else {
results.push(None);
}
} else if let Ok(specifier) =
self.resolver.as_cli_resolver(scope).resolve(
} else if let Ok(specifier) = scoped_resolver.as_cli_resolver().resolve(
raw_specifier,
referrer,
deno_graph::Position::zeroed(),
resolution_mode,
NodeResolutionKind::Types,
)
{
) {
results.push(self.resolve_dependency(
&specifier,
referrer,
@ -1490,12 +1492,9 @@ impl DocumentModules {
let mut specifier = specifier.clone();
let mut media_type = None;
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&specifier) {
let (s, mt) = self.resolver.npm_to_file_url(
&npm_ref,
referrer,
resolution_mode,
scope,
)?;
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
let (s, mt) =
scoped_resolver.npm_to_file_url(&npm_ref, referrer, resolution_mode)?;
specifier = s;
media_type = Some(mt);
}
@ -1823,10 +1822,11 @@ fn analyze_module(
) -> (ModuleResult, ResolutionMode) {
match parsed_source_result {
Ok(parsed_source) => {
let npm_resolver = resolver.as_graph_npm_resolver(file_referrer);
let cli_resolver = resolver.as_cli_resolver(file_referrer);
let is_cjs_resolver = resolver.as_is_cjs_resolver(file_referrer);
let config_data = resolver.as_config_data(file_referrer);
let scoped_resolver = resolver.get_scoped_resolver(file_referrer);
let npm_resolver = scoped_resolver.as_graph_npm_resolver();
let cli_resolver = scoped_resolver.as_cli_resolver();
let is_cjs_resolver = scoped_resolver.as_is_cjs_resolver();
let config_data = scoped_resolver.as_config_data();
let valid_referrer = specifier.clone();
let jsx_import_source_config =
config_data.and_then(|d| d.maybe_jsx_import_source_config());

View file

@ -1135,7 +1135,9 @@ impl Inner {
spawn(async move {
let specifier = {
let inner = ls.inner.read().await;
let resolver = inner.resolver.as_cli_resolver(Some(&referrer));
let scoped_resolver =
inner.resolver.get_scoped_resolver(Some(&referrer));
let resolver = scoped_resolver.as_cli_resolver();
let Ok(specifier) = resolver.resolve(
&specifier,
&referrer,
@ -1783,8 +1785,9 @@ impl Inner {
if let Ok(jsr_req_ref) =
JsrPackageReqReference::from_specifier(specifier)
{
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
if let Some(url) =
self.resolver.jsr_to_resource_url(&jsr_req_ref, scope)
scoped_resolver.jsr_to_resource_url(&jsr_req_ref)
{
result = format!("{result} (<{url}>)");
}

View file

@ -88,7 +88,7 @@ use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
#[derive(Debug, Clone)]
struct LspScopeResolver {
pub struct LspScopedResolver {
resolver: Arc<CliResolver>,
in_npm_pkg_checker: DenoInNpmPackageChecker,
is_cjs_resolver: Arc<CliIsCjsResolver>,
@ -108,7 +108,7 @@ struct LspScopeResolver {
config_data: Option<Arc<ConfigData>>,
}
impl Default for LspScopeResolver {
impl Default for LspScopedResolver {
fn default() -> Self {
let factory = ResolverFactory::new(None);
Self {
@ -133,7 +133,7 @@ impl Default for LspScopeResolver {
}
}
impl LspScopeResolver {
impl LspScopedResolver {
async fn from_config_data(
config_data: Option<&Arc<ConfigData>>,
cache: &LspCache,
@ -294,12 +294,170 @@ impl LspScopeResolver {
config_data: self.config_data.clone(),
})
}
pub fn as_in_npm_pkg_checker(&self) -> &DenoInNpmPackageChecker {
&self.in_npm_pkg_checker
}
pub fn as_cli_resolver(&self) -> &CliResolver {
self.resolver.as_ref()
}
pub fn as_graph_npm_resolver(&self) -> &Arc<CliNpmGraphResolver> {
&self.npm_graph_resolver
}
pub fn as_is_cjs_resolver(&self) -> &CliIsCjsResolver {
self.is_cjs_resolver.as_ref()
}
pub fn as_config_data(&self) -> Option<&Arc<ConfigData>> {
self.config_data.as_ref()
}
pub fn as_maybe_managed_npm_resolver(
&self,
) -> Option<&CliManagedNpmResolver> {
self.npm_resolver.as_ref().and_then(|r| r.as_managed())
}
pub fn as_pkg_json_resolver(&self) -> &Arc<CliPackageJsonResolver> {
&self.pkg_json_resolver
}
pub fn graph_imports_by_referrer(
&self,
) -> IndexMap<&ModuleSpecifier, Vec<&ModuleSpecifier>> {
self
.graph_imports
.iter()
.map(|(s, i)| {
(
s,
i.dependencies
.values()
.flat_map(|d| d.get_type().or_else(|| d.get_code()))
.collect(),
)
})
.collect()
}
pub fn jsr_to_resource_url(
&self,
req_ref: &JsrPackageReqReference,
) -> Option<ModuleSpecifier> {
self.jsr_resolver.as_ref()?.jsr_to_resource_url(req_ref)
}
pub fn jsr_lookup_export_for_path(
&self,
nv: &PackageNv,
path: &str,
) -> Option<String> {
self.jsr_resolver.as_ref()?.lookup_export_for_path(nv, path)
}
pub fn jsr_lookup_req_for_nv(&self, nv: &PackageNv) -> Option<PackageReq> {
self.jsr_resolver.as_ref()?.lookup_req_for_nv(nv)
}
pub fn npm_to_file_url(
&self,
req_ref: &NpmPackageReqReference,
referrer: &ModuleSpecifier,
resolution_mode: ResolutionMode,
) -> Option<(ModuleSpecifier, MediaType)> {
let npm_pkg_req_resolver = self.npm_pkg_req_resolver.as_ref()?;
Some(into_specifier_and_media_type(Some(
npm_pkg_req_resolver
.resolve_req_reference(
req_ref,
referrer,
resolution_mode,
NodeResolutionKind::Types,
)
.ok()?
.into_url()
.ok()?,
)))
}
pub fn file_url_to_package_json_dep(
&self,
specifier: &ModuleSpecifier,
) -> Option<String> {
self
.package_json_dep_resolutions
.package_ref_from_resolution(specifier)
.or_else(|| {
self
.node_resolver
.as_ref()?
.lookup_package_specifier_for_resolution(specifier)
})
}
pub fn deno_types_to_code_resolution(
&self,
specifier: &ModuleSpecifier,
) -> Option<ModuleSpecifier> {
let dep_info = self.dep_info.lock();
dep_info
.deno_types_to_code_resolutions
.get(specifier)
.cloned()
}
pub fn in_node_modules(&self, specifier: &ModuleSpecifier) -> bool {
fn has_node_modules_dir(specifier: &ModuleSpecifier) -> bool {
// consider any /node_modules/ directory as being in the node_modules
// folder for the LSP because it's pretty complicated to deal with multiple scopes
specifier.scheme() == "file"
&& specifier
.path()
.to_ascii_lowercase()
.contains("/node_modules/")
}
if let Some(node_resolver) = &self.node_resolver {
if node_resolver.in_npm_package(specifier) {
return true;
}
}
has_node_modules_dir(specifier)
}
pub fn resolve_redirects(
&self,
specifier: &ModuleSpecifier,
) -> Option<ModuleSpecifier> {
let Some(redirect_resolver) = self.redirect_resolver.as_ref() else {
return Some(specifier.clone());
};
redirect_resolver.resolve(specifier)
}
pub fn redirect_chain_headers(
&self,
specifier: &ModuleSpecifier,
) -> Vec<(ModuleSpecifier, Arc<HashMap<String, String>>)> {
let Some(redirect_resolver) = self.redirect_resolver.as_ref() else {
return vec![];
};
redirect_resolver
.chain(specifier)
.into_iter()
.map(|(s, e)| (s, e.headers.clone()))
.collect()
}
}
#[derive(Debug, Default, Clone)]
pub struct LspResolver {
unscoped: Arc<LspScopeResolver>,
by_scope: BTreeMap<Arc<Url>, Arc<LspScopeResolver>>,
unscoped: Arc<LspScopedResolver>,
by_scope: BTreeMap<Arc<Url>, Arc<LspScopedResolver>>,
}
impl LspResolver {
@ -313,7 +471,7 @@ impl LspResolver {
by_scope.insert(
scope.clone(),
Arc::new(
LspScopeResolver::from_config_data(
LspScopedResolver::from_config_data(
Some(config_data),
cache,
http_client_provider,
@ -324,7 +482,7 @@ impl LspResolver {
}
Self {
unscoped: Arc::new(
LspScopeResolver::from_config_data(None, cache, http_client_provider)
LspScopedResolver::from_config_data(None, cache, http_client_provider)
.await,
),
by_scope,
@ -388,220 +546,16 @@ impl LspResolver {
}
}
pub fn as_cli_resolver(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> &CliResolver {
let resolver = self.get_scope_resolver(file_referrer);
resolver.resolver.as_ref()
}
pub fn as_graph_npm_resolver(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> &Arc<CliNpmGraphResolver> {
let resolver = self.get_scope_resolver(file_referrer);
&resolver.npm_graph_resolver
}
pub fn as_is_cjs_resolver(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> &CliIsCjsResolver {
let resolver = self.get_scope_resolver(file_referrer);
resolver.is_cjs_resolver.as_ref()
}
pub fn as_config_data(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<&Arc<ConfigData>> {
let resolver = self.get_scope_resolver(file_referrer);
resolver.config_data.as_ref()
}
pub fn in_npm_pkg_checker(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> &DenoInNpmPackageChecker {
let resolver = self.get_scope_resolver(file_referrer);
&resolver.in_npm_pkg_checker
}
pub fn maybe_managed_npm_resolver(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<&CliManagedNpmResolver> {
let resolver = self.get_scope_resolver(file_referrer);
resolver.npm_resolver.as_ref().and_then(|r| r.as_managed())
}
pub fn pkg_json_resolver(
&self,
referrer: &ModuleSpecifier,
) -> &Arc<CliPackageJsonResolver> {
let resolver = self.get_scope_resolver(Some(referrer));
&resolver.pkg_json_resolver
}
pub fn graph_imports_by_referrer(
&self,
file_referrer: &ModuleSpecifier,
) -> IndexMap<&ModuleSpecifier, Vec<&ModuleSpecifier>> {
let resolver = self.get_scope_resolver(Some(file_referrer));
resolver
.graph_imports
.iter()
.map(|(s, i)| {
(
s,
i.dependencies
.values()
.flat_map(|d| d.get_type().or_else(|| d.get_code()))
.collect(),
)
})
.collect()
}
pub fn jsr_to_resource_url(
&self,
req_ref: &JsrPackageReqReference,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<ModuleSpecifier> {
let resolver = self.get_scope_resolver(file_referrer);
resolver.jsr_resolver.as_ref()?.jsr_to_resource_url(req_ref)
}
pub fn jsr_lookup_export_for_path(
&self,
nv: &PackageNv,
path: &str,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<String> {
let resolver = self.get_scope_resolver(file_referrer);
resolver
.jsr_resolver
.as_ref()?
.lookup_export_for_path(nv, path)
}
pub fn jsr_lookup_req_for_nv(
&self,
nv: &PackageNv,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<PackageReq> {
let resolver = self.get_scope_resolver(file_referrer);
resolver.jsr_resolver.as_ref()?.lookup_req_for_nv(nv)
}
pub fn npm_to_file_url(
&self,
req_ref: &NpmPackageReqReference,
referrer: &ModuleSpecifier,
resolution_mode: ResolutionMode,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<(ModuleSpecifier, MediaType)> {
let resolver = self.get_scope_resolver(file_referrer);
let npm_pkg_req_resolver = resolver.npm_pkg_req_resolver.as_ref()?;
Some(into_specifier_and_media_type(Some(
npm_pkg_req_resolver
.resolve_req_reference(
req_ref,
referrer,
resolution_mode,
NodeResolutionKind::Types,
)
.ok()?
.into_url()
.ok()?,
)))
}
pub fn file_url_to_package_json_dep(
&self,
specifier: &ModuleSpecifier,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<String> {
let resolver = self.get_scope_resolver(file_referrer);
resolver
.package_json_dep_resolutions
.package_ref_from_resolution(specifier)
.or_else(|| {
resolver
.node_resolver
.as_ref()?
.lookup_package_specifier_for_resolution(specifier)
})
}
pub fn deno_types_to_code_resolution(
&self,
specifier: &ModuleSpecifier,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<ModuleSpecifier> {
let resolver = self.get_scope_resolver(file_referrer);
let dep_info = resolver.dep_info.lock().clone();
dep_info
.deno_types_to_code_resolutions
.get(specifier)
.cloned()
}
pub fn in_node_modules(&self, specifier: &ModuleSpecifier) -> bool {
fn has_node_modules_dir(specifier: &ModuleSpecifier) -> bool {
// consider any /node_modules/ directory as being in the node_modules
// folder for the LSP because it's pretty complicated to deal with multiple scopes
specifier.scheme() == "file"
&& specifier
.path()
.to_ascii_lowercase()
.contains("/node_modules/")
self
.get_scoped_resolver(Some(specifier))
.in_node_modules(specifier)
}
if let Some(node_resolver) =
&self.get_scope_resolver(Some(specifier)).node_resolver
{
if node_resolver.in_npm_package(specifier) {
return true;
}
}
has_node_modules_dir(specifier)
}
pub fn resolve_redirects(
&self,
specifier: &ModuleSpecifier,
file_referrer: Option<&ModuleSpecifier>,
) -> Option<ModuleSpecifier> {
let resolver = self.get_scope_resolver(file_referrer);
let Some(redirect_resolver) = resolver.redirect_resolver.as_ref() else {
return Some(specifier.clone());
};
redirect_resolver.resolve(specifier)
}
pub fn redirect_chain_headers(
&self,
specifier: &ModuleSpecifier,
file_referrer: Option<&ModuleSpecifier>,
) -> Vec<(ModuleSpecifier, Arc<HashMap<String, String>>)> {
let resolver = self.get_scope_resolver(file_referrer);
let Some(redirect_resolver) = resolver.redirect_resolver.as_ref() else {
return vec![];
};
redirect_resolver
.chain(specifier)
.into_iter()
.map(|(s, e)| (s, e.headers.clone()))
.collect()
}
fn get_scope_resolver(
pub fn get_scoped_resolver(
&self,
file_referrer: Option<&ModuleSpecifier>,
) -> &LspScopeResolver {
) -> &LspScopedResolver {
let Some(file_referrer) = file_referrer else {
return self.unscoped.as_ref();
};

View file

@ -3881,10 +3881,8 @@ impl CompletionEntry {
let mut new_deno_types_specifier = None;
if let Some(code_specifier) = language_server
.resolver
.deno_types_to_code_resolution(
&import_data.normalized,
module.scope.as_deref(),
)
.get_scoped_resolver(module.scope.as_deref())
.deno_types_to_code_resolution(&import_data.normalized)
.and_then(|s| {
import_mapper
.check_specifier(&s, &module.specifier)
@ -4684,23 +4682,20 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
// inject these next because they're global
for (scope, script_names) in &mut result.by_scope {
for (_, specifiers) in state
let scoped_resolver = state
.state_snapshot
.resolver
.graph_imports_by_referrer(scope)
{
.get_scoped_resolver(Some(scope));
for (_, specifiers) in scoped_resolver.graph_imports_by_referrer() {
for specifier in specifiers {
if let Ok(req_ref) =
deno_semver::npm::NpmPackageReqReference::from_specifier(specifier)
{
let Some((resolved, _)) =
state.state_snapshot.resolver.npm_to_file_url(
let Some((resolved, _)) = scoped_resolver.npm_to_file_url(
&req_ref,
scope,
ResolutionMode::Import,
Some(scope),
)
else {
) else {
lsp_log!("failed to resolve {req_ref} to file URL");
continue;
};