mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
refactor(lsp): internally expose and use LspScopedResolver
(#28755)
Reduces some repeat hashmap lookups by exposing the `LspScopedResolver`.
This commit is contained in:
parent
37b760e3c6
commit
9d841987ef
7 changed files with 240 additions and 294 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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}>)");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue