summaryrefslogtreecommitdiff
path: root/cli/lsp
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp')
-rw-r--r--cli/lsp/cache.rs7
-rw-r--r--cli/lsp/diagnostics.rs15
-rw-r--r--cli/lsp/documents.rs149
-rw-r--r--cli/lsp/language_server.rs50
4 files changed, 92 insertions, 129 deletions
diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs
index e21bcff2d..b05dcbc38 100644
--- a/cli/lsp/cache.rs
+++ b/cli/lsp/cache.rs
@@ -21,7 +21,10 @@ use std::thread;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
-type Request = (Vec<ModuleSpecifier>, oneshot::Sender<Result<(), AnyError>>);
+type Request = (
+ Vec<(ModuleSpecifier, deno_graph::ModuleKind)>,
+ oneshot::Sender<Result<(), AnyError>>,
+);
/// A "server" that handles requests from the language server to cache modules
/// in its own thread.
@@ -105,7 +108,7 @@ impl CacheServer {
/// client.
pub async fn cache(
&self,
- roots: Vec<ModuleSpecifier>,
+ roots: Vec<(ModuleSpecifier, deno_graph::ModuleKind)>,
) -> Result<(), AnyError> {
let (tx, rx) = oneshot::channel::<Result<(), AnyError>>();
if self.0.send((roots, tx)).is_err() {
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index f1ed42544..62b89e526 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -20,6 +20,7 @@ use deno_core::error::AnyError;
use deno_core::resolve_url;
use deno_core::serde_json::json;
use deno_core::ModuleSpecifier;
+use deno_graph::Resolved;
use deno_runtime::tokio_util::create_basic_runtime;
use log::error;
use lspower::lsp;
@@ -547,13 +548,13 @@ fn resolution_error_as_code(
use deno_graph::SpecifierError;
match err {
- ResolutionError::InvalidDowngrade(_, _) => {
+ ResolutionError::InvalidDowngrade { .. } => {
lsp::NumberOrString::String("invalid-downgrade".to_string())
}
- ResolutionError::InvalidLocalImport(_, _) => {
+ ResolutionError::InvalidLocalImport { .. } => {
lsp::NumberOrString::String("invalid-local-import".to_string())
}
- ResolutionError::InvalidSpecifier(err, _) => match err {
+ ResolutionError::InvalidSpecifier { error, .. } => match error {
SpecifierError::ImportPrefixMissing(_, _) => {
lsp::NumberOrString::String("import-prefix-missing".to_string())
}
@@ -561,7 +562,7 @@ fn resolution_error_as_code(
lsp::NumberOrString::String("invalid-url".to_string())
}
},
- ResolutionError::ResolverError(_, _, _) => {
+ ResolutionError::ResolverError { .. } => {
lsp::NumberOrString::String("resolver-error".to_string())
}
}
@@ -575,7 +576,9 @@ fn diagnose_dependency(
maybe_assert_type: Option<&str>,
) {
match resolved {
- Some(Ok((specifier, range))) => {
+ Resolved::Ok {
+ specifier, range, ..
+ } => {
if let Some(doc) = documents.get(specifier) {
if let Some(message) = doc.maybe_warning() {
diagnostics.push(lsp::Diagnostic {
@@ -633,7 +636,7 @@ fn diagnose_dependency(
});
}
}
- Some(Err(err)) => diagnostics.push(lsp::Diagnostic {
+ Resolved::Err(err) => diagnostics.push(lsp::Diagnostic {
range: documents::to_lsp_range(err.range()),
severity: Some(lsp::DiagnosticSeverity::ERROR),
code: Some(resolution_error_as_code(err)),
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 5d583330d..19753389d 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -22,7 +22,9 @@ use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
use deno_core::url;
use deno_core::ModuleSpecifier;
+use deno_graph::source::ResolveResponse;
use deno_graph::Module;
+use deno_graph::Resolved;
use lspower::lsp;
use once_cell::sync::Lazy;
use std::collections::BTreeMap;
@@ -213,58 +215,6 @@ impl AssetOrDocument {
}
}
-// TODO(@kitsonk) expose the synthetic module from deno_graph
-#[derive(Debug)]
-struct SyntheticModule {
- dependencies: BTreeMap<String, deno_graph::Resolved>,
- specifier: ModuleSpecifier,
-}
-
-impl SyntheticModule {
- pub fn new(
- specifier: ModuleSpecifier,
- dependencies: Vec<(String, Option<lsp::Range>)>,
- maybe_resolver: Option<&dyn deno_graph::source::Resolver>,
- ) -> Self {
- let dependencies = dependencies
- .iter()
- .map(|(dep, maybe_range)| {
- let range = to_deno_graph_range(&specifier, maybe_range.as_ref());
- let result = if let Some(resolver) = maybe_resolver {
- resolver.resolve(dep, &specifier).map_err(|err| {
- if let Some(specifier_error) =
- err.downcast_ref::<deno_graph::SpecifierError>()
- {
- deno_graph::ResolutionError::InvalidSpecifier(
- specifier_error.clone(),
- range.clone(),
- )
- } else {
- deno_graph::ResolutionError::ResolverError(
- Arc::new(err),
- dep.to_string(),
- range.clone(),
- )
- }
- })
- } else {
- deno_core::resolve_import(dep, specifier.as_str()).map_err(|err| {
- deno_graph::ResolutionError::ResolverError(
- Arc::new(err.into()),
- dep.to_string(),
- range.clone(),
- )
- })
- };
- (dep.to_string(), Some(result.map(|s| (s, range))))
- })
- .collect();
- Self {
- dependencies,
- specifier,
- }
- }
-}
#[derive(Debug, Clone)]
struct DocumentInner {
/// contains the last-known-good set of dependencies from parsing the module
@@ -274,7 +224,7 @@ struct DocumentInner {
maybe_language_id: Option<LanguageId>,
maybe_lsp_version: Option<i32>,
maybe_module:
- Option<Result<deno_graph::EsModule, deno_graph::ModuleGraphError>>,
+ Option<Result<deno_graph::Module, deno_graph::ModuleGraphError>>,
maybe_navigation_tree: Option<Arc<tsc::NavigationTree>>,
maybe_warning: Option<String>,
specifier: ModuleSpecifier,
@@ -299,16 +249,14 @@ impl Document {
// we only ever do `Document::new` on on disk resources that are supposed to
// be diagnosable, unlike `Document::open`, so it is safe to unconditionally
// parse the module.
- let maybe_module = match deno_graph::parse_module(
+ let maybe_module = Some(deno_graph::parse_module(
&specifier,
maybe_headers,
content.clone(),
+ Some(&deno_graph::ModuleKind::Esm),
maybe_resolver,
Some(&parser),
- ) {
- Ok(m) => m.to_maybe_es_module().map(Ok),
- Err(err) => Some(Err(err)),
- };
+ ));
let dependencies = if let Some(Ok(module)) = &maybe_module {
Arc::new(module.dependencies.clone())
} else {
@@ -340,16 +288,14 @@ impl Document {
let maybe_headers = language_id.as_headers();
let parser = SourceParser::default();
let maybe_module = if language_id.is_diagnosable() {
- match deno_graph::parse_module(
+ Some(deno_graph::parse_module(
&specifier,
maybe_headers,
content.clone(),
+ Some(&deno_graph::ModuleKind::Esm),
maybe_resolver,
Some(&parser),
- ) {
- Ok(m) => m.to_maybe_es_module().map(Ok),
- Err(err) => Some(Err(err)),
- }
+ ))
} else {
None
};
@@ -411,16 +357,14 @@ impl Document {
.map(|li| li.as_headers())
.flatten();
let parser = SourceParser::default();
- match deno_graph::parse_module(
+ Some(deno_graph::parse_module(
&self.0.specifier,
maybe_headers,
content.clone(),
+ Some(&deno_graph::ModuleKind::Esm),
maybe_resolver,
Some(&parser),
- ) {
- Ok(m) => m.to_maybe_es_module().map(Ok),
- Err(err) => Some(Err(err)),
- }
+ ))
} else {
None
};
@@ -504,10 +448,19 @@ impl Document {
}
pub fn maybe_types_dependency(&self) -> deno_graph::Resolved {
- let module_result = self.0.maybe_module.as_ref()?;
- let module = module_result.as_ref().ok()?;
- let (_, maybe_dep) = module.maybe_types_dependency.as_ref()?;
- maybe_dep.clone()
+ let module_result = match self.0.maybe_module.as_ref() {
+ Some(module_result) => module_result,
+ _ => return deno_graph::Resolved::None,
+ };
+ let module = match module_result.as_ref() {
+ Ok(module) => module,
+ Err(_) => return deno_graph::Resolved::None,
+ };
+ if let Some((_, maybe_dep)) = module.maybe_types_dependency.as_ref() {
+ maybe_dep.clone()
+ } else {
+ deno_graph::Resolved::None
+ }
}
pub fn media_type(&self) -> MediaType {
@@ -525,18 +478,18 @@ impl Document {
fn maybe_module(
&self,
- ) -> Option<&Result<deno_graph::EsModule, deno_graph::ModuleGraphError>> {
+ ) -> Option<&Result<deno_graph::Module, deno_graph::ModuleGraphError>> {
self.0.maybe_module.as_ref()
}
pub fn maybe_parsed_source(
&self,
) -> Option<Result<deno_ast::ParsedSource, deno_graph::ModuleGraphError>> {
- self.maybe_module().map(|r| {
- r.as_ref()
- .map(|m| m.parsed_source.clone())
- .map_err(|err| err.clone())
- })
+ let module_result = self.maybe_module()?;
+ match module_result {
+ Ok(module) => Some(Ok(module.maybe_parsed_source.clone()?)),
+ Err(err) => Some(Err(err.clone())),
+ }
}
pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> {
@@ -576,14 +529,9 @@ impl Document {
}
}
-pub(crate) fn to_hover_text(
- result: &Result<
- (ModuleSpecifier, deno_graph::Range),
- deno_graph::ResolutionError,
- >,
-) -> String {
+pub(crate) fn to_hover_text(result: &Resolved) -> String {
match result {
- Ok((specifier, _)) => match specifier.scheme() {
+ Resolved::Ok { specifier, .. } => match specifier.scheme() {
"data" => "_(a data url)_".to_string(),
"blob" => "_(a blob url)_".to_string(),
_ => format!(
@@ -593,7 +541,8 @@ pub(crate) fn to_hover_text(
)
.replace('@', "&#8203;@"),
},
- Err(_) => "_[errored]_".to_string(),
+ Resolved::Err(_) => "_[errored]_".to_string(),
+ Resolved::None => "_[missing]_".to_string(),
}
}
@@ -802,7 +751,7 @@ pub(crate) struct Documents {
file_system_docs: Arc<Mutex<FileSystemDocuments>>,
/// Any imports to the context supplied by configuration files. This is like
/// the imports into the a module graph in CLI.
- imports: Arc<HashMap<ModuleSpecifier, SyntheticModule>>,
+ imports: Arc<HashMap<ModuleSpecifier, Module>>,
/// The optional import map that should be used when resolving dependencies.
maybe_import_map: Option<ImportMapResolver>,
/// The optional JSX resolver, which is used when JSX imports are configured.
@@ -913,7 +862,7 @@ impl Documents {
) -> bool {
let maybe_resolver = self.get_maybe_resolver();
let maybe_specifier = if let Some(resolver) = maybe_resolver {
- resolver.resolve(specifier, referrer).ok()
+ resolver.resolve(specifier, referrer).to_result().ok()
} else {
deno_core::resolve_import(specifier, referrer.as_str()).ok()
};
@@ -1043,14 +992,14 @@ impl Documents {
results.push(None);
}
} else if let Some(dep) = dependencies.get(&specifier) {
- if let Some(Ok((specifier, _))) = &dep.maybe_type {
+ if let Resolved::Ok { specifier, .. } = &dep.maybe_type {
results.push(self.resolve_dependency(specifier));
- } else if let Some(Ok((specifier, _))) = &dep.maybe_code {
+ } else if let Resolved::Ok { specifier, .. } = &dep.maybe_code {
results.push(self.resolve_dependency(specifier));
} else {
results.push(None);
}
- } else if let Some(Some(Ok((specifier, _)))) =
+ } else if let Some(Resolved::Ok { specifier, .. }) =
self.resolve_imports_dependency(&specifier)
{
// clone here to avoid double borrow of self
@@ -1121,9 +1070,7 @@ impl Documents {
imports
.into_iter()
.map(|(referrer, dependencies)| {
- let dependencies =
- dependencies.into_iter().map(|s| (s, None)).collect();
- let module = SyntheticModule::new(
+ let module = Module::new_from_type_imports(
referrer.clone(),
dependencies,
self.get_maybe_resolver(),
@@ -1167,7 +1114,9 @@ impl Documents {
.insert(specifier.clone());
}
}
- if let Some((_, Some(Ok((dep, _))))) = &module.maybe_types_dependency {
+ if let Some((_, Resolved::Ok { specifier: dep, .. })) =
+ &module.maybe_types_dependency
+ {
dependents_map
.entry(dep.clone())
.or_default()
@@ -1198,12 +1147,10 @@ impl Documents {
.map(|m| {
m.maybe_types_dependency
.as_ref()
- .map(|(_, o)| o.as_ref().map(|r| r.as_ref().ok()).flatten())
- .flatten()
+ .map(|(_, resolved)| resolved.clone())
})
- .flatten()
- .cloned();
- if let Some((specifier, _)) = maybe_types_dependency {
+ .flatten();
+ if let Some(Resolved::Ok { specifier, .. }) = maybe_types_dependency {
self.resolve_dependency(&specifier)
} else {
let media_type = doc.media_type();
@@ -1221,7 +1168,7 @@ impl Documents {
for module in self.imports.values() {
let maybe_dep = module.dependencies.get(specifier);
if maybe_dep.is_some() {
- return maybe_dep;
+ return maybe_dep.map(|d| &d.maybe_type);
}
}
None
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index b21081e85..426710b83 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -8,6 +8,7 @@ use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::ModuleSpecifier;
+use deno_graph::Resolved;
use import_map::ImportMap;
use log::error;
use log::info;
@@ -1058,34 +1059,38 @@ impl Inner {
.get_code()
.map(|s| self.documents.get(s))
.flatten()
- .map(|d| d.maybe_types_dependency())
- .flatten();
- let value = match (&dep.maybe_code, &dep.maybe_type, &dep_maybe_types_dependency) {
- (Some(code_dep), Some(type_dep), None) => format!(
+ .map(|d| d.maybe_types_dependency());
+ let value = match (dep.maybe_code.is_none(), dep.maybe_type.is_none(), &dep_maybe_types_dependency) {
+ (false, false, None) => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
- to_hover_text(code_dep),
- to_hover_text(type_dep)
+ to_hover_text(&dep.maybe_code),
+ to_hover_text(&dep.maybe_type)
),
- (Some(code_dep), Some(type_dep), Some(types_dep)) => format!(
+ (false, false, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n**Types**: {}\n**Import Types**: {}\n",
- to_hover_text(code_dep),
- to_hover_text(types_dep),
- to_hover_text(type_dep)
+ to_hover_text(&dep.maybe_code),
+ to_hover_text(&dep.maybe_type),
+ to_hover_text(types_dep)
),
- (Some(code_dep), None, None) => format!(
- "**Resolved Dependency**\n\n**Code**: {}\n",
- to_hover_text(code_dep)
+ (false, false, Some(_)) => format!(
+ "**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
+ to_hover_text(&dep.maybe_code),
+ to_hover_text(&dep.maybe_type)
),
- (Some(code_dep), None, Some(types_dep)) => format!(
+ (false, true, Some(types_dep)) if !types_dep.is_none() => format!(
"**Resolved Dependency**\n\n**Code**: {}\n\n**Types**: {}\n",
- to_hover_text(code_dep),
+ to_hover_text(&dep.maybe_code),
to_hover_text(types_dep)
),
- (None, Some(type_dep), _) => format!(
+ (false, true, _) => format!(
+ "**Resolved Dependency**\n\n**Code**: {}\n",
+ to_hover_text(&dep.maybe_code)
+ ),
+ (true, false, _) => format!(
"**Resolved Dependency**\n\n**Types**: {}\n",
- to_hover_text(type_dep)
+ to_hover_text(&dep.maybe_type)
),
- (None, None, _) => unreachable!("{}", json!(params)),
+ (true, true, _) => unreachable!("{}", json!(params)),
};
let value =
if let Some(docs) = self.module_registries.get_hover(&dep).await {
@@ -2677,10 +2682,15 @@ impl Inner {
params
.uris
.iter()
- .map(|t| self.url_map.normalize_url(&t.uri))
+ .map(|t| {
+ (
+ self.url_map.normalize_url(&t.uri),
+ deno_graph::ModuleKind::Esm,
+ )
+ })
.collect()
} else {
- vec![referrer.clone()]
+ vec![(referrer.clone(), deno_graph::ModuleKind::Esm)]
};
if self.maybe_cache_server.is_none() {