mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +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());
|
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())
|
if let Some(jsr_path) = specifier.as_str().strip_prefix(jsr_url().as_str())
|
||||||
{
|
{
|
||||||
let mut segments = jsr_path.split('/');
|
let mut segments = jsr_path.split('/');
|
||||||
|
@ -298,11 +301,7 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
let version = Version::parse_standard(segments.next()?).ok()?;
|
let version = Version::parse_standard(segments.next()?).ok()?;
|
||||||
let nv = PackageNv { name, version };
|
let nv = PackageNv { name, version };
|
||||||
let path = segments.collect::<Vec<_>>().join("/");
|
let path = segments.collect::<Vec<_>>().join("/");
|
||||||
let export = self.resolver.jsr_lookup_export_for_path(
|
let export = scoped_resolver.jsr_lookup_export_for_path(&nv, &path)?;
|
||||||
&nv,
|
|
||||||
&path,
|
|
||||||
self.scope.as_deref(),
|
|
||||||
)?;
|
|
||||||
let sub_path = (export != ".")
|
let sub_path = (export != ".")
|
||||||
.then_some(export)
|
.then_some(export)
|
||||||
.map(SmallStackString::from_string);
|
.map(SmallStackString::from_string);
|
||||||
|
@ -326,11 +325,7 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
});
|
});
|
||||||
req = req.or_else(|| {
|
req = req.or_else(|| scoped_resolver.jsr_lookup_req_for_nv(&nv));
|
||||||
self
|
|
||||||
.resolver
|
|
||||||
.jsr_lookup_req_for_nv(&nv, self.scope.as_deref())
|
|
||||||
});
|
|
||||||
let spec_str = if let Some(req) = req {
|
let spec_str = if let Some(req) = req {
|
||||||
let req_ref = PackageReqReference { req, sub_path };
|
let req_ref = PackageReqReference { req, sub_path };
|
||||||
JsrPackageReqReference::new(req_ref).to_string()
|
JsrPackageReqReference::new(req_ref).to_string()
|
||||||
|
@ -357,13 +352,10 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
return Some(spec_str);
|
return Some(spec_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(npm_resolver) = self
|
if let Some(npm_resolver) = scoped_resolver.as_maybe_managed_npm_resolver()
|
||||||
.resolver
|
|
||||||
.maybe_managed_npm_resolver(self.scope.as_deref())
|
|
||||||
{
|
{
|
||||||
let in_npm_pkg = self
|
let in_npm_pkg = scoped_resolver
|
||||||
.resolver
|
.as_in_npm_pkg_checker()
|
||||||
.in_npm_pkg_checker(self.scope.as_deref())
|
|
||||||
.in_npm_package(specifier);
|
.in_npm_package(specifier);
|
||||||
if in_npm_pkg {
|
if in_npm_pkg {
|
||||||
if let Ok(Some(pkg_id)) =
|
if let Ok(Some(pkg_id)) =
|
||||||
|
@ -428,9 +420,8 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(dep_name) = self
|
} else if let Some(dep_name) =
|
||||||
.resolver
|
scoped_resolver.file_url_to_package_json_dep(specifier)
|
||||||
.file_url_to_package_json_dep(specifier, self.scope.as_deref())
|
|
||||||
{
|
{
|
||||||
return Some(dep_name);
|
return Some(dep_name);
|
||||||
}
|
}
|
||||||
|
@ -450,9 +441,9 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
package_root_folder: &Path,
|
package_root_folder: &Path,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
let package_json = self
|
let scoped_resolver = self.resolver.get_scoped_resolver(Some(specifier));
|
||||||
.resolver
|
let package_json = scoped_resolver
|
||||||
.pkg_json_resolver(specifier)
|
.as_pkg_json_resolver()
|
||||||
// the specifier might have a closer package.json, but we
|
// the specifier might have a closer package.json, but we
|
||||||
// want the root of the package's package.json
|
// want the root of the package's package.json
|
||||||
.get_closest_package_json(&package_root_folder.join("package.json"))
|
.get_closest_package_json(&package_root_folder.join("package.json"))
|
||||||
|
@ -514,10 +505,11 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ext| Cow::Owned(format!("{specifier_stem}{ext}"))),
|
.map(|ext| Cow::Owned(format!("{specifier_stem}{ext}"))),
|
||||||
);
|
);
|
||||||
|
let scoped_resolver =
|
||||||
|
self.resolver.get_scoped_resolver(self.scope.as_deref());
|
||||||
for specifier in specifiers {
|
for specifier in specifiers {
|
||||||
if let Some(specifier) = self
|
if let Some(specifier) = scoped_resolver
|
||||||
.resolver
|
.as_cli_resolver()
|
||||||
.as_cli_resolver(self.scope.as_deref())
|
|
||||||
.resolve(
|
.resolve(
|
||||||
&specifier,
|
&specifier,
|
||||||
referrer,
|
referrer,
|
||||||
|
@ -553,7 +545,8 @@ impl<'a> TsResponseImportMapper<'a> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self
|
self
|
||||||
.resolver
|
.resolver
|
||||||
.as_cli_resolver(self.scope.as_deref())
|
.get_scoped_resolver(self.scope.as_deref())
|
||||||
|
.as_cli_resolver()
|
||||||
.resolve(
|
.resolve(
|
||||||
specifier_text,
|
specifier_text,
|
||||||
referrer,
|
referrer,
|
||||||
|
|
|
@ -170,8 +170,9 @@ pub async fn get_import_completions(
|
||||||
.map(to_node_resolution_mode)
|
.map(to_node_resolution_mode)
|
||||||
.unwrap_or_else(|| module.resolution_mode);
|
.unwrap_or_else(|| module.resolution_mode);
|
||||||
let range = to_narrow_lsp_range(module.text_info(), graph_range.range);
|
let range = to_narrow_lsp_range(module.text_info(), graph_range.range);
|
||||||
let resolved = resolver
|
let scoped_resolver = resolver.get_scoped_resolver(module.scope.as_deref());
|
||||||
.as_cli_resolver(module.scope.as_deref())
|
let resolved = scoped_resolver
|
||||||
|
.as_cli_resolver()
|
||||||
.resolve(
|
.resolve(
|
||||||
text,
|
text,
|
||||||
&module.specifier,
|
&module.specifier,
|
||||||
|
@ -377,8 +378,9 @@ fn get_local_completions(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let parent = &text[..text.char_indices().rfind(|(_, c)| *c == '/')?.0 + 1];
|
let parent = &text[..text.char_indices().rfind(|(_, c)| *c == '/')?.0 + 1];
|
||||||
let resolved_parent = resolver
|
let scoped_resolver = resolver.get_scoped_resolver(Some(referrer));
|
||||||
.as_cli_resolver(Some(referrer))
|
let resolved_parent = scoped_resolver
|
||||||
|
.as_cli_resolver()
|
||||||
.resolve(
|
.resolve(
|
||||||
parent,
|
parent,
|
||||||
referrer,
|
referrer,
|
||||||
|
|
|
@ -1596,13 +1596,12 @@ fn diagnose_resolution(
|
||||||
match resolution {
|
match resolution {
|
||||||
Resolution::Ok(resolved) => {
|
Resolution::Ok(resolved) => {
|
||||||
let specifier = &resolved.specifier;
|
let specifier = &resolved.specifier;
|
||||||
let managed_npm_resolver = snapshot
|
let scoped_resolver = snapshot
|
||||||
.resolver
|
.resolver
|
||||||
.maybe_managed_npm_resolver(referrer_module.scope.as_deref());
|
.get_scoped_resolver(referrer_module.scope.as_deref());
|
||||||
for (_, headers) in snapshot
|
let managed_npm_resolver =
|
||||||
.resolver
|
scoped_resolver.as_maybe_managed_npm_resolver();
|
||||||
.redirect_chain_headers(specifier, referrer_module.scope.as_deref())
|
for (_, headers) in scoped_resolver.redirect_chain_headers(specifier) {
|
||||||
{
|
|
||||||
if let Some(message) = headers.get("x-deno-warning") {
|
if let Some(message) = headers.get("x-deno-warning") {
|
||||||
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
|
diagnostics.push(DenoDiagnostic::DenoWarn(message.clone()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1041,14 +1041,15 @@ impl DocumentModules {
|
||||||
specifier: &Url,
|
specifier: &Url,
|
||||||
scope: Option<&Url>,
|
scope: Option<&Url>,
|
||||||
) -> Option<Arc<DocumentModule>> {
|
) -> Option<Arc<DocumentModule>> {
|
||||||
|
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||||
let specifier = if let Ok(jsr_req_ref) =
|
let specifier = if let Ok(jsr_req_ref) =
|
||||||
JsrPackageReqReference::from_specifier(specifier)
|
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 {
|
} else {
|
||||||
Cow::Borrowed(specifier)
|
Cow::Borrowed(specifier)
|
||||||
};
|
};
|
||||||
let specifier = self.resolver.resolve_redirects(&specifier, scope)?;
|
let specifier = scoped_resolver.resolve_redirects(&specifier)?;
|
||||||
let document =
|
let document =
|
||||||
self
|
self
|
||||||
.documents
|
.documents
|
||||||
|
@ -1137,14 +1138,15 @@ impl DocumentModules {
|
||||||
specifier: &Url,
|
specifier: &Url,
|
||||||
scope: Option<&Url>,
|
scope: Option<&Url>,
|
||||||
) -> Option<Arc<DocumentModule>> {
|
) -> Option<Arc<DocumentModule>> {
|
||||||
|
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||||
let specifier = if let Ok(jsr_req_ref) =
|
let specifier = if let Ok(jsr_req_ref) =
|
||||||
JsrPackageReqReference::from_specifier(specifier)
|
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 {
|
} else {
|
||||||
Cow::Borrowed(specifier)
|
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)?;
|
let modules = self.modules_for_scope(scope)?;
|
||||||
modules.get_for_specifier(&specifier)
|
modules.get_for_specifier(&specifier)
|
||||||
}
|
}
|
||||||
|
@ -1332,8 +1334,9 @@ impl DocumentModules {
|
||||||
member_dir.to_maybe_jsx_import_source_config().ok()??;
|
member_dir.to_maybe_jsx_import_source_config().ok()??;
|
||||||
let import_source_types = jsx_config.import_source_types.as_ref()?;
|
let import_source_types = jsx_config.import_source_types.as_ref()?;
|
||||||
let import_source = jsx_config.import_source.as_ref()?;
|
let import_source = jsx_config.import_source.as_ref()?;
|
||||||
let cli_resolver =
|
let scoped_resolver =
|
||||||
self.resolver.as_cli_resolver(scope.map(|s| s.as_ref()));
|
self.resolver.get_scoped_resolver(scope.map(|s| s.as_ref()));
|
||||||
|
let cli_resolver = scoped_resolver.as_cli_resolver();
|
||||||
let type_specifier = cli_resolver
|
let type_specifier = cli_resolver
|
||||||
.resolve(
|
.resolve(
|
||||||
&import_source_types.specifier,
|
&import_source_types.specifier,
|
||||||
|
@ -1417,6 +1420,7 @@ impl DocumentModules {
|
||||||
let referrer_module = self.module_for_specifier(referrer, scope);
|
let referrer_module = self.module_for_specifier(referrer, scope);
|
||||||
let dependencies = referrer_module.as_ref().map(|d| &d.dependencies);
|
let dependencies = referrer_module.as_ref().map(|d| &d.dependencies);
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
|
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||||
for (is_cjs, raw_specifier) in raw_specifiers {
|
for (is_cjs, raw_specifier) in raw_specifiers {
|
||||||
let resolution_mode = match is_cjs {
|
let resolution_mode = match is_cjs {
|
||||||
true => ResolutionMode::Require,
|
true => ResolutionMode::Require,
|
||||||
|
@ -1449,15 +1453,13 @@ impl DocumentModules {
|
||||||
} else {
|
} else {
|
||||||
results.push(None);
|
results.push(None);
|
||||||
}
|
}
|
||||||
} else if let Ok(specifier) =
|
} else if let Ok(specifier) = scoped_resolver.as_cli_resolver().resolve(
|
||||||
self.resolver.as_cli_resolver(scope).resolve(
|
|
||||||
raw_specifier,
|
raw_specifier,
|
||||||
referrer,
|
referrer,
|
||||||
deno_graph::Position::zeroed(),
|
deno_graph::Position::zeroed(),
|
||||||
resolution_mode,
|
resolution_mode,
|
||||||
NodeResolutionKind::Types,
|
NodeResolutionKind::Types,
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
results.push(self.resolve_dependency(
|
results.push(self.resolve_dependency(
|
||||||
&specifier,
|
&specifier,
|
||||||
referrer,
|
referrer,
|
||||||
|
@ -1490,12 +1492,9 @@ impl DocumentModules {
|
||||||
let mut specifier = specifier.clone();
|
let mut specifier = specifier.clone();
|
||||||
let mut media_type = None;
|
let mut media_type = None;
|
||||||
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&specifier) {
|
if let Ok(npm_ref) = NpmPackageReqReference::from_specifier(&specifier) {
|
||||||
let (s, mt) = self.resolver.npm_to_file_url(
|
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||||
&npm_ref,
|
let (s, mt) =
|
||||||
referrer,
|
scoped_resolver.npm_to_file_url(&npm_ref, referrer, resolution_mode)?;
|
||||||
resolution_mode,
|
|
||||||
scope,
|
|
||||||
)?;
|
|
||||||
specifier = s;
|
specifier = s;
|
||||||
media_type = Some(mt);
|
media_type = Some(mt);
|
||||||
}
|
}
|
||||||
|
@ -1823,10 +1822,11 @@ fn analyze_module(
|
||||||
) -> (ModuleResult, ResolutionMode) {
|
) -> (ModuleResult, ResolutionMode) {
|
||||||
match parsed_source_result {
|
match parsed_source_result {
|
||||||
Ok(parsed_source) => {
|
Ok(parsed_source) => {
|
||||||
let npm_resolver = resolver.as_graph_npm_resolver(file_referrer);
|
let scoped_resolver = resolver.get_scoped_resolver(file_referrer);
|
||||||
let cli_resolver = resolver.as_cli_resolver(file_referrer);
|
let npm_resolver = scoped_resolver.as_graph_npm_resolver();
|
||||||
let is_cjs_resolver = resolver.as_is_cjs_resolver(file_referrer);
|
let cli_resolver = scoped_resolver.as_cli_resolver();
|
||||||
let config_data = resolver.as_config_data(file_referrer);
|
let is_cjs_resolver = scoped_resolver.as_is_cjs_resolver();
|
||||||
|
let config_data = scoped_resolver.as_config_data();
|
||||||
let valid_referrer = specifier.clone();
|
let valid_referrer = specifier.clone();
|
||||||
let jsx_import_source_config =
|
let jsx_import_source_config =
|
||||||
config_data.and_then(|d| d.maybe_jsx_import_source_config());
|
config_data.and_then(|d| d.maybe_jsx_import_source_config());
|
||||||
|
|
|
@ -1135,7 +1135,9 @@ impl Inner {
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
let specifier = {
|
let specifier = {
|
||||||
let inner = ls.inner.read().await;
|
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(
|
let Ok(specifier) = resolver.resolve(
|
||||||
&specifier,
|
&specifier,
|
||||||
&referrer,
|
&referrer,
|
||||||
|
@ -1783,8 +1785,9 @@ impl Inner {
|
||||||
if let Ok(jsr_req_ref) =
|
if let Ok(jsr_req_ref) =
|
||||||
JsrPackageReqReference::from_specifier(specifier)
|
JsrPackageReqReference::from_specifier(specifier)
|
||||||
{
|
{
|
||||||
|
let scoped_resolver = self.resolver.get_scoped_resolver(scope);
|
||||||
if let Some(url) =
|
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}>)");
|
result = format!("{result} (<{url}>)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ use crate::util::progress_bar::ProgressBar;
|
||||||
use crate::util::progress_bar::ProgressBarStyle;
|
use crate::util::progress_bar::ProgressBarStyle;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct LspScopeResolver {
|
pub struct LspScopedResolver {
|
||||||
resolver: Arc<CliResolver>,
|
resolver: Arc<CliResolver>,
|
||||||
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
in_npm_pkg_checker: DenoInNpmPackageChecker,
|
||||||
is_cjs_resolver: Arc<CliIsCjsResolver>,
|
is_cjs_resolver: Arc<CliIsCjsResolver>,
|
||||||
|
@ -108,7 +108,7 @@ struct LspScopeResolver {
|
||||||
config_data: Option<Arc<ConfigData>>,
|
config_data: Option<Arc<ConfigData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LspScopeResolver {
|
impl Default for LspScopedResolver {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let factory = ResolverFactory::new(None);
|
let factory = ResolverFactory::new(None);
|
||||||
Self {
|
Self {
|
||||||
|
@ -133,7 +133,7 @@ impl Default for LspScopeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LspScopeResolver {
|
impl LspScopedResolver {
|
||||||
async fn from_config_data(
|
async fn from_config_data(
|
||||||
config_data: Option<&Arc<ConfigData>>,
|
config_data: Option<&Arc<ConfigData>>,
|
||||||
cache: &LspCache,
|
cache: &LspCache,
|
||||||
|
@ -294,12 +294,170 @@ impl LspScopeResolver {
|
||||||
config_data: self.config_data.clone(),
|
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)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct LspResolver {
|
pub struct LspResolver {
|
||||||
unscoped: Arc<LspScopeResolver>,
|
unscoped: Arc<LspScopedResolver>,
|
||||||
by_scope: BTreeMap<Arc<Url>, Arc<LspScopeResolver>>,
|
by_scope: BTreeMap<Arc<Url>, Arc<LspScopedResolver>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LspResolver {
|
impl LspResolver {
|
||||||
|
@ -313,7 +471,7 @@ impl LspResolver {
|
||||||
by_scope.insert(
|
by_scope.insert(
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
Arc::new(
|
Arc::new(
|
||||||
LspScopeResolver::from_config_data(
|
LspScopedResolver::from_config_data(
|
||||||
Some(config_data),
|
Some(config_data),
|
||||||
cache,
|
cache,
|
||||||
http_client_provider,
|
http_client_provider,
|
||||||
|
@ -324,7 +482,7 @@ impl LspResolver {
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
unscoped: Arc::new(
|
unscoped: Arc::new(
|
||||||
LspScopeResolver::from_config_data(None, cache, http_client_provider)
|
LspScopedResolver::from_config_data(None, cache, http_client_provider)
|
||||||
.await,
|
.await,
|
||||||
),
|
),
|
||||||
by_scope,
|
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 {
|
pub fn in_node_modules(&self, specifier: &ModuleSpecifier) -> bool {
|
||||||
fn has_node_modules_dir(specifier: &ModuleSpecifier) -> bool {
|
self
|
||||||
// consider any /node_modules/ directory as being in the node_modules
|
.get_scoped_resolver(Some(specifier))
|
||||||
// folder for the LSP because it's pretty complicated to deal with multiple scopes
|
.in_node_modules(specifier)
|
||||||
specifier.scheme() == "file"
|
|
||||||
&& specifier
|
|
||||||
.path()
|
|
||||||
.to_ascii_lowercase()
|
|
||||||
.contains("/node_modules/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(node_resolver) =
|
pub fn get_scoped_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(
|
|
||||||
&self,
|
&self,
|
||||||
file_referrer: Option<&ModuleSpecifier>,
|
file_referrer: Option<&ModuleSpecifier>,
|
||||||
) -> &LspScopeResolver {
|
) -> &LspScopedResolver {
|
||||||
let Some(file_referrer) = file_referrer else {
|
let Some(file_referrer) = file_referrer else {
|
||||||
return self.unscoped.as_ref();
|
return self.unscoped.as_ref();
|
||||||
};
|
};
|
||||||
|
|
|
@ -3881,10 +3881,8 @@ impl CompletionEntry {
|
||||||
let mut new_deno_types_specifier = None;
|
let mut new_deno_types_specifier = None;
|
||||||
if let Some(code_specifier) = language_server
|
if let Some(code_specifier) = language_server
|
||||||
.resolver
|
.resolver
|
||||||
.deno_types_to_code_resolution(
|
.get_scoped_resolver(module.scope.as_deref())
|
||||||
&import_data.normalized,
|
.deno_types_to_code_resolution(&import_data.normalized)
|
||||||
module.scope.as_deref(),
|
|
||||||
)
|
|
||||||
.and_then(|s| {
|
.and_then(|s| {
|
||||||
import_mapper
|
import_mapper
|
||||||
.check_specifier(&s, &module.specifier)
|
.check_specifier(&s, &module.specifier)
|
||||||
|
@ -4684,23 +4682,20 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
|
||||||
|
|
||||||
// inject these next because they're global
|
// inject these next because they're global
|
||||||
for (scope, script_names) in &mut result.by_scope {
|
for (scope, script_names) in &mut result.by_scope {
|
||||||
for (_, specifiers) in state
|
let scoped_resolver = state
|
||||||
.state_snapshot
|
.state_snapshot
|
||||||
.resolver
|
.resolver
|
||||||
.graph_imports_by_referrer(scope)
|
.get_scoped_resolver(Some(scope));
|
||||||
{
|
for (_, specifiers) in scoped_resolver.graph_imports_by_referrer() {
|
||||||
for specifier in specifiers {
|
for specifier in specifiers {
|
||||||
if let Ok(req_ref) =
|
if let Ok(req_ref) =
|
||||||
deno_semver::npm::NpmPackageReqReference::from_specifier(specifier)
|
deno_semver::npm::NpmPackageReqReference::from_specifier(specifier)
|
||||||
{
|
{
|
||||||
let Some((resolved, _)) =
|
let Some((resolved, _)) = scoped_resolver.npm_to_file_url(
|
||||||
state.state_snapshot.resolver.npm_to_file_url(
|
|
||||||
&req_ref,
|
&req_ref,
|
||||||
scope,
|
scope,
|
||||||
ResolutionMode::Import,
|
ResolutionMode::Import,
|
||||||
Some(scope),
|
) else {
|
||||||
)
|
|
||||||
else {
|
|
||||||
lsp_log!("failed to resolve {req_ref} to file URL");
|
lsp_log!("failed to resolve {req_ref} to file URL");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue