summaryrefslogtreecommitdiff
path: root/cli/lsp/diagnostics.rs
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2024-02-12 22:12:49 +0000
committerGitHub <noreply@github.com>2024-02-12 22:12:49 +0000
commit49d82e609f7da97f793900528e800019d502a2ff (patch)
tree9fd726bad9ba1d9f5bd416c2697eaab9321bfdbf /cli/lsp/diagnostics.rs
parentf60720090c7bd8cdf91d7aebd0c42e01c86b3b83 (diff)
feat(lsp): jsr support first pass (#22382)
This implementation heavily depends on there being a lockfile, meaning JSR specifiers will always diagnose as uncached unless it's there. In practice this affects cases where a `deno.json` isn't being used. Our NPM specifier support isn't subject to this. The reason for this is that the version constraint solving code is currently buried in `deno_graph` and not usable from the LSP, so the only way to reuse that logic is the solved-version map in the lockfile's `packages.specifiers`.
Diffstat (limited to 'cli/lsp/diagnostics.rs')
-rw-r--r--cli/lsp/diagnostics.rs19
1 files changed, 15 insertions, 4 deletions
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index 0c193040b..0b3faa551 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -42,6 +42,7 @@ use deno_lint::rules::LintRule;
use deno_runtime::deno_fs;
use deno_runtime::deno_node;
use deno_runtime::tokio_util::create_basic_runtime;
+use deno_semver::jsr::JsrPackageReqReference;
use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageReq;
use log::error;
@@ -329,6 +330,8 @@ impl DiagnosticsState {
if diagnostic.code
== Some(lsp::NumberOrString::String("no-cache".to_string()))
|| diagnostic.code
+ == Some(lsp::NumberOrString::String("no-cache-jsr".to_string()))
+ || diagnostic.code
== Some(lsp::NumberOrString::String("no-cache-npm".to_string()))
{
no_cache_diagnostics.push(diagnostic.clone());
@@ -968,6 +971,8 @@ pub enum DenoDiagnostic {
NoAttributeType,
/// A remote module was not found in the cache.
NoCache(ModuleSpecifier),
+ /// A remote jsr package reference was not found in the cache.
+ NoCacheJsr(PackageReq, ModuleSpecifier),
/// A remote npm package reference was not found in the cache.
NoCacheNpm(PackageReq, ModuleSpecifier),
/// A local module was not found on the local file system.
@@ -994,6 +999,7 @@ impl DenoDiagnostic {
Self::InvalidAttributeType(_) => "invalid-attribute-type",
Self::NoAttributeType => "no-attribute-type",
Self::NoCache(_) => "no-cache",
+ Self::NoCacheJsr(_, _) => "no-cache-jsr",
Self::NoCacheNpm(_, _) => "no-cache-npm",
Self::NoLocal(_) => "no-local",
Self::Redirect { .. } => "redirect",
@@ -1072,7 +1078,7 @@ impl DenoDiagnostic {
}),
..Default::default()
},
- "no-cache" | "no-cache-npm" => {
+ "no-cache" | "no-cache-jsr" | "no-cache-npm" => {
let data = diagnostic
.data
.clone()
@@ -1188,6 +1194,7 @@ impl DenoDiagnostic {
match code.as_str() {
"import-map-remap"
| "no-cache"
+ | "no-cache-jsr"
| "no-cache-npm"
| "no-attribute-type"
| "redirect"
@@ -1226,6 +1233,7 @@ impl DenoDiagnostic {
Self::InvalidAttributeType(assert_type) => (lsp::DiagnosticSeverity::ERROR, format!("The module is a JSON module and expected an attribute type of \"json\". Instead got \"{assert_type}\"."), None),
Self::NoAttributeType => (lsp::DiagnosticSeverity::ERROR, "The module is a JSON module and not being imported with an import attribute. Consider adding `with { type: \"json\" }` to the import statement.".to_string(), None),
Self::NoCache(specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing remote URL: {specifier}"), Some(json!({ "specifier": specifier }))),
+ Self::NoCacheJsr(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing jsr package: {}", pkg_req), Some(json!({ "specifier": specifier }))),
Self::NoCacheNpm(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing npm package: {}", pkg_req), Some(json!({ "specifier": specifier }))),
Self::NoLocal(specifier) => {
let sloppy_resolution = SloppyImportsResolver::resolve_with_fs(&deno_fs::RealFs, specifier);
@@ -1310,7 +1318,7 @@ fn diagnose_resolution(
// If the module was redirected, we want to issue an informational
// diagnostic that indicates this. This then allows us to issue a code
// action to replace the specifier with the final redirected one.
- if doc_specifier != specifier {
+ if specifier.scheme() != "jsr" && doc_specifier != specifier {
diagnostics.push(DenoDiagnostic::Redirect {
from: specifier.clone(),
to: doc_specifier.clone(),
@@ -1332,8 +1340,11 @@ fn diagnose_resolution(
None => diagnostics.push(DenoDiagnostic::NoAttributeType),
}
}
- } else if specifier.scheme() == "jsr" {
- // TODO(nayeemrmn): Check if jsr specifiers are cached.
+ } else if let Ok(pkg_ref) =
+ JsrPackageReqReference::from_specifier(specifier)
+ {
+ let req = pkg_ref.into_inner().req;
+ diagnostics.push(DenoDiagnostic::NoCacheJsr(req, specifier.clone()));
} else if let Ok(pkg_ref) =
NpmPackageReqReference::from_specifier(specifier)
{