mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
fix(lsp): allow caching deps in non-saved files (#16353)
This commit is contained in:
parent
a48d05fac7
commit
da906de184
4 changed files with 79 additions and 26 deletions
|
@ -21,6 +21,7 @@ use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::futures::future;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::url;
|
use deno_core::url;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
@ -1111,6 +1112,33 @@ impl Documents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loader that will look at the open documents.
|
||||||
|
pub struct DocumentsDenoGraphLoader<'a> {
|
||||||
|
pub inner_loader: &'a mut dyn deno_graph::source::Loader,
|
||||||
|
pub open_docs: &'a HashMap<ModuleSpecifier, Document>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> deno_graph::source::Loader for DocumentsDenoGraphLoader<'a> {
|
||||||
|
fn load(
|
||||||
|
&mut self,
|
||||||
|
specifier: &ModuleSpecifier,
|
||||||
|
is_dynamic: bool,
|
||||||
|
) -> deno_graph::source::LoadFuture {
|
||||||
|
if specifier.scheme() == "file" {
|
||||||
|
if let Some(doc) = self.open_docs.get(specifier) {
|
||||||
|
return Box::pin(future::ready(Ok(Some(
|
||||||
|
deno_graph::source::LoadResponse::Module {
|
||||||
|
content: doc.content(),
|
||||||
|
specifier: doc.specifier().clone(),
|
||||||
|
maybe_headers: None,
|
||||||
|
},
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.inner_loader.load(specifier, is_dynamic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The default parser from `deno_graph` does not include the configuration
|
/// The default parser from `deno_graph` does not include the configuration
|
||||||
/// options we require for the lsp.
|
/// options we require for the lsp.
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
|
@ -14,6 +14,7 @@ use import_map::ImportMap;
|
||||||
use log::error;
|
use log::error;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use serde_json::from_value;
|
use serde_json::from_value;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -2825,9 +2826,19 @@ impl Inner {
|
||||||
async fn create_graph_for_caching(
|
async fn create_graph_for_caching(
|
||||||
cli_options: CliOptions,
|
cli_options: CliOptions,
|
||||||
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
||||||
|
open_docs: Vec<Document>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
|
let open_docs = open_docs
|
||||||
|
.into_iter()
|
||||||
|
.map(|d| (d.specifier().clone(), d))
|
||||||
|
.collect::<HashMap<_, _>>();
|
||||||
let ps = ProcState::from_options(Arc::new(cli_options)).await?;
|
let ps = ProcState::from_options(Arc::new(cli_options)).await?;
|
||||||
let graph = ps.create_graph(roots).await?;
|
let mut inner_loader = ps.create_graph_loader();
|
||||||
|
let mut loader = crate::lsp::documents::DocumentsDenoGraphLoader {
|
||||||
|
inner_loader: &mut inner_loader,
|
||||||
|
open_docs: &open_docs,
|
||||||
|
};
|
||||||
|
let graph = ps.create_graph_with_loader(roots, &mut loader).await?;
|
||||||
graph_valid(&graph, true, false)?;
|
graph_valid(&graph, true, false)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2867,10 +2878,11 @@ impl Inner {
|
||||||
|
|
||||||
// todo(dsherret): why is running this on a new thread necessary? It does
|
// todo(dsherret): why is running this on a new thread necessary? It does
|
||||||
// a compile error otherwise.
|
// a compile error otherwise.
|
||||||
|
let open_docs = self.documents.documents(true, true);
|
||||||
let handle = tokio::task::spawn_blocking(|| {
|
let handle = tokio::task::spawn_blocking(|| {
|
||||||
run_local(
|
run_local(async move {
|
||||||
async move { create_graph_for_caching(cli_options, roots).await },
|
create_graph_for_caching(cli_options, roots, open_docs).await
|
||||||
)
|
})
|
||||||
});
|
});
|
||||||
if let Err(err) = handle.await.unwrap() {
|
if let Err(err) = handle.await.unwrap() {
|
||||||
self.client.show_message(MessageType::WARNING, err).await;
|
self.client.show_message(MessageType::WARNING, err).await;
|
||||||
|
|
|
@ -589,16 +589,29 @@ impl ProcState {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_graph(
|
/// Creates the default loader used for creating a graph.
|
||||||
&self,
|
pub fn create_graph_loader(&self) -> cache::FetchCacher {
|
||||||
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
cache::FetchCacher::new(
|
||||||
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
|
||||||
let mut cache = cache::FetchCacher::new(
|
|
||||||
self.emit_cache.clone(),
|
self.emit_cache.clone(),
|
||||||
self.file_fetcher.clone(),
|
self.file_fetcher.clone(),
|
||||||
Permissions::allow_all(),
|
Permissions::allow_all(),
|
||||||
Permissions::allow_all(),
|
Permissions::allow_all(),
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_graph(
|
||||||
|
&self,
|
||||||
|
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
||||||
|
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||||
|
let mut cache = self.create_graph_loader();
|
||||||
|
self.create_graph_with_loader(roots, &mut cache).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_graph_with_loader(
|
||||||
|
&self,
|
||||||
|
roots: Vec<(ModuleSpecifier, ModuleKind)>,
|
||||||
|
loader: &mut dyn Loader,
|
||||||
|
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||||
let maybe_locker = as_maybe_locker(self.lockfile.clone());
|
let maybe_locker = as_maybe_locker(self.lockfile.clone());
|
||||||
let maybe_import_map_resolver =
|
let maybe_import_map_resolver =
|
||||||
self.maybe_import_map.clone().map(ImportMapResolver::new);
|
self.maybe_import_map.clone().map(ImportMapResolver::new);
|
||||||
|
@ -620,7 +633,7 @@ impl ProcState {
|
||||||
roots,
|
roots,
|
||||||
false,
|
false,
|
||||||
maybe_imports,
|
maybe_imports,
|
||||||
&mut cache,
|
loader,
|
||||||
maybe_resolver,
|
maybe_resolver,
|
||||||
maybe_locker,
|
maybe_locker,
|
||||||
Some(&*analyzer),
|
Some(&*analyzer),
|
||||||
|
|
|
@ -1084,21 +1084,21 @@ fn lsp_inlay_hints() {
|
||||||
"text": r#"function a(b: string) {
|
"text": r#"function a(b: string) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
a("foo");
|
a("foo");
|
||||||
|
|
||||||
enum C {
|
enum C {
|
||||||
A,
|
A,
|
||||||
}
|
}
|
||||||
|
|
||||||
parseInt("123", 8);
|
parseInt("123", 8);
|
||||||
|
|
||||||
const d = Date.now();
|
const d = Date.now();
|
||||||
|
|
||||||
class E {
|
class E {
|
||||||
f = Date.now();
|
f = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
["a"].map((v) => v + v);
|
["a"].map((v) => v + v);
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
@ -1234,21 +1234,21 @@ fn lsp_inlay_hints_not_enabled() {
|
||||||
"text": r#"function a(b: string) {
|
"text": r#"function a(b: string) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
a("foo");
|
a("foo");
|
||||||
|
|
||||||
enum C {
|
enum C {
|
||||||
A,
|
A,
|
||||||
}
|
}
|
||||||
|
|
||||||
parseInt("123", 8);
|
parseInt("123", 8);
|
||||||
|
|
||||||
const d = Date.now();
|
const d = Date.now();
|
||||||
|
|
||||||
class E {
|
class E {
|
||||||
f = Date.now();
|
f = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
["a"].map((v) => v + v);
|
["a"].map((v) => v + v);
|
||||||
"#
|
"#
|
||||||
}
|
}
|
||||||
|
@ -1871,7 +1871,7 @@ fn lsp_hover_dependency() {
|
||||||
Some(json!({
|
Some(json!({
|
||||||
"contents": {
|
"contents": {
|
||||||
"kind": "markdown",
|
"kind": "markdown",
|
||||||
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n"
|
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http​://127.0.0.1:4545/xTypeScriptTypes.d.ts\n"
|
||||||
},
|
},
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -1905,7 +1905,7 @@ fn lsp_hover_dependency() {
|
||||||
Some(json!({
|
Some(json!({
|
||||||
"contents": {
|
"contents": {
|
||||||
"kind": "markdown",
|
"kind": "markdown",
|
||||||
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/subdir/type_reference.js\n"
|
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/subdir/type_reference.js\n\n**Types**: http​://127.0.0.1:4545/subdir/type_reference.d.ts\n"
|
||||||
},
|
},
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
|
@ -4256,7 +4256,7 @@ fn lsp_cache_location() {
|
||||||
Some(json!({
|
Some(json!({
|
||||||
"contents": {
|
"contents": {
|
||||||
"kind": "markdown",
|
"kind": "markdown",
|
||||||
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n"
|
"value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http​://127.0.0.1:4545/xTypeScriptTypes.d.ts\n"
|
||||||
},
|
},
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
|
|
Loading…
Reference in a new issue