mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
refactor(lsp): reduce data stored in StateSnapshot
(#13426)
This commit is contained in:
parent
6cf05220e3
commit
f73a5fbc89
7 changed files with 181 additions and 211 deletions
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
use super::tsc;
|
||||
|
||||
|
@ -171,14 +172,11 @@ fn code_as_string(code: &Option<lsp::NumberOrString>) -> String {
|
|||
fn check_specifier(
|
||||
specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
snapshot: &language_server::StateSnapshot,
|
||||
documents: &Documents,
|
||||
) -> Option<String> {
|
||||
for ext in SUPPORTED_EXTENSIONS {
|
||||
let specifier_with_ext = format!("{}{}", specifier, ext);
|
||||
if snapshot
|
||||
.documents
|
||||
.contains_import(&specifier_with_ext, referrer)
|
||||
{
|
||||
if documents.contains_import(&specifier_with_ext, referrer) {
|
||||
return Some(specifier_with_ext);
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +188,9 @@ fn check_specifier(
|
|||
pub(crate) fn fix_ts_import_changes(
|
||||
referrer: &ModuleSpecifier,
|
||||
changes: &[tsc::FileTextChanges],
|
||||
language_server: &language_server::Inner,
|
||||
documents: &Documents,
|
||||
) -> Result<Vec<tsc::FileTextChanges>, AnyError> {
|
||||
let mut r = Vec::new();
|
||||
let snapshot = language_server.snapshot()?;
|
||||
for change in changes {
|
||||
let mut text_changes = Vec::new();
|
||||
for text_change in &change.text_changes {
|
||||
|
@ -205,7 +202,7 @@ pub(crate) fn fix_ts_import_changes(
|
|||
.ok_or_else(|| anyhow!("Missing capture."))?
|
||||
.as_str();
|
||||
if let Some(new_specifier) =
|
||||
check_specifier(specifier, referrer, &snapshot)
|
||||
check_specifier(specifier, referrer, documents)
|
||||
{
|
||||
let new_text =
|
||||
text_change.new_text.replace(specifier, &new_specifier);
|
||||
|
@ -234,7 +231,7 @@ pub(crate) fn fix_ts_import_changes(
|
|||
fn fix_ts_import_action(
|
||||
referrer: &ModuleSpecifier,
|
||||
action: &tsc::CodeFixAction,
|
||||
language_server: &language_server::Inner,
|
||||
documents: &Documents,
|
||||
) -> Result<tsc::CodeFixAction, AnyError> {
|
||||
if action.fix_name == "import" {
|
||||
let change = action
|
||||
|
@ -251,9 +248,8 @@ fn fix_ts_import_action(
|
|||
.get(1)
|
||||
.ok_or_else(|| anyhow!("Missing capture."))?
|
||||
.as_str();
|
||||
let snapshot = language_server.snapshot()?;
|
||||
if let Some(new_specifier) =
|
||||
check_specifier(specifier, referrer, &snapshot)
|
||||
check_specifier(specifier, referrer, documents)
|
||||
{
|
||||
let description = action.description.replace(specifier, &new_specifier);
|
||||
let changes = action
|
||||
|
@ -622,7 +618,8 @@ impl CodeActionCollection {
|
|||
"The action returned from TypeScript is unsupported.",
|
||||
));
|
||||
}
|
||||
let action = fix_ts_import_action(specifier, action, language_server)?;
|
||||
let action =
|
||||
fix_ts_import_action(specifier, action, &language_server.documents)?;
|
||||
let edit = ts_changes_to_edit(&action.changes, language_server).await?;
|
||||
let code_action = lsp::CodeAction {
|
||||
title: action.description.clone(),
|
||||
|
|
|
@ -248,7 +248,7 @@ async fn resolve_implementation_code_lens(
|
|||
data.specifier.clone(),
|
||||
line_index.offset_tsc(code_lens.range.start)?,
|
||||
));
|
||||
let snapshot = language_server.snapshot()?;
|
||||
let snapshot = language_server.snapshot();
|
||||
let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> =
|
||||
language_server.ts_server.request(snapshot, req).await?;
|
||||
if let Some(implementations) = maybe_implementations {
|
||||
|
@ -317,7 +317,7 @@ async fn resolve_references_code_lens(
|
|||
data.specifier.clone(),
|
||||
line_index.offset_tsc(code_lens.range.start)?,
|
||||
));
|
||||
let snapshot = language_server.snapshot()?;
|
||||
let snapshot = language_server.snapshot();
|
||||
let maybe_references: Option<Vec<tsc::ReferenceEntry>> =
|
||||
language_server.ts_server.request(snapshot, req).await?;
|
||||
if let Some(references) = maybe_references {
|
||||
|
@ -332,7 +332,8 @@ async fn resolve_references_code_lens(
|
|||
.get_asset_or_document(&reference_specifier)
|
||||
.await?;
|
||||
locations.push(
|
||||
reference.to_location(asset_or_doc.line_index(), language_server),
|
||||
reference
|
||||
.to_location(asset_or_doc.line_index(), &language_server.url_map),
|
||||
);
|
||||
}
|
||||
let command = if !locations.is_empty() {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use super::client::Client;
|
||||
use super::config::ConfigSnapshot;
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
use super::lsp_custom;
|
||||
use super::registries::ModuleRegistry;
|
||||
use super::tsc;
|
||||
|
||||
use crate::fs_util::is_supported_ext;
|
||||
|
@ -37,18 +40,12 @@ pub struct CompletionItemData {
|
|||
/// a notification to the client.
|
||||
async fn check_auto_config_registry(
|
||||
url_str: &str,
|
||||
snapshot: &language_server::StateSnapshot,
|
||||
config: &ConfigSnapshot,
|
||||
client: Client,
|
||||
module_registries: &ModuleRegistry,
|
||||
) {
|
||||
// check to see if auto discovery is enabled
|
||||
if snapshot
|
||||
.config
|
||||
.settings
|
||||
.workspace
|
||||
.suggest
|
||||
.imports
|
||||
.auto_discover
|
||||
{
|
||||
if config.settings.workspace.suggest.imports.auto_discover {
|
||||
if let Ok(specifier) = resolve_url(url_str) {
|
||||
let scheme = specifier.scheme();
|
||||
let path = &specifier[Position::BeforePath..];
|
||||
|
@ -57,26 +54,18 @@ async fn check_auto_config_registry(
|
|||
&& url_str.ends_with(path)
|
||||
{
|
||||
// check to see if this origin is already explicitly set
|
||||
let in_config = snapshot
|
||||
.config
|
||||
.settings
|
||||
.workspace
|
||||
.suggest
|
||||
.imports
|
||||
.hosts
|
||||
.iter()
|
||||
.any(|(h, _)| {
|
||||
resolve_url(h).map(|u| u.origin()) == Ok(specifier.origin())
|
||||
});
|
||||
let in_config =
|
||||
config.settings.workspace.suggest.imports.hosts.iter().any(
|
||||
|(h, _)| {
|
||||
resolve_url(h).map(|u| u.origin()) == Ok(specifier.origin())
|
||||
},
|
||||
);
|
||||
// if it isn't in the configuration, we will check to see if it supports
|
||||
// suggestions and send a notification to the client.
|
||||
if !in_config {
|
||||
let origin = specifier.origin().ascii_serialization();
|
||||
let suggestions = snapshot
|
||||
.module_registries
|
||||
.check_origin(&origin)
|
||||
.await
|
||||
.is_ok();
|
||||
let suggestions =
|
||||
module_registries.check_origin(&origin).await.is_ok();
|
||||
// we are only sending registry state when enabled now, but changing
|
||||
// the custom notification would make older versions of the plugin
|
||||
// incompatible.
|
||||
|
@ -133,10 +122,12 @@ fn to_narrow_lsp_range(
|
|||
pub(crate) async fn get_import_completions(
|
||||
specifier: &ModuleSpecifier,
|
||||
position: &lsp::Position,
|
||||
state_snapshot: &language_server::StateSnapshot,
|
||||
config: &ConfigSnapshot,
|
||||
client: Client,
|
||||
module_registries: &ModuleRegistry,
|
||||
documents: &Documents,
|
||||
) -> Option<lsp::CompletionResponse> {
|
||||
let document = state_snapshot.documents.get(specifier)?;
|
||||
let document = documents.get(specifier)?;
|
||||
let (text, _, range) = document.get_maybe_dependency(position)?;
|
||||
let range = to_narrow_lsp_range(&document.text_info(), &range);
|
||||
// completions for local relative modules
|
||||
|
@ -147,25 +138,19 @@ pub(crate) async fn get_import_completions(
|
|||
}))
|
||||
} else if !text.is_empty() {
|
||||
// completion of modules from a module registry or cache
|
||||
check_auto_config_registry(&text, state_snapshot, client).await;
|
||||
check_auto_config_registry(&text, config, client, module_registries).await;
|
||||
let offset = if position.character > range.start.character {
|
||||
(position.character - range.start.character) as usize
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let maybe_list = state_snapshot
|
||||
.module_registries
|
||||
let maybe_list = module_registries
|
||||
.get_completions(&text, offset, &range, |specifier| {
|
||||
state_snapshot.documents.contains_specifier(specifier)
|
||||
documents.contains_specifier(specifier)
|
||||
})
|
||||
.await;
|
||||
let list = maybe_list.unwrap_or_else(|| lsp::CompletionList {
|
||||
items: get_workspace_completions(
|
||||
specifier,
|
||||
&text,
|
||||
&range,
|
||||
state_snapshot,
|
||||
),
|
||||
items: get_workspace_completions(specifier, &text, &range, documents),
|
||||
is_incomplete: false,
|
||||
});
|
||||
Some(lsp::CompletionResponse::List(list))
|
||||
|
@ -182,9 +167,8 @@ pub(crate) async fn get_import_completions(
|
|||
})
|
||||
.collect();
|
||||
let mut is_incomplete = false;
|
||||
if let Some(origin_items) = state_snapshot
|
||||
.module_registries
|
||||
.get_origin_completions(&text, &range)
|
||||
if let Some(origin_items) =
|
||||
module_registries.get_origin_completions(&text, &range)
|
||||
{
|
||||
is_incomplete = origin_items.is_incomplete;
|
||||
items.extend(origin_items.items);
|
||||
|
@ -302,10 +286,9 @@ fn get_workspace_completions(
|
|||
specifier: &ModuleSpecifier,
|
||||
current: &str,
|
||||
range: &lsp::Range,
|
||||
state_snapshot: &language_server::StateSnapshot,
|
||||
documents: &Documents,
|
||||
) -> Vec<lsp::CompletionItem> {
|
||||
let workspace_specifiers = state_snapshot
|
||||
.documents
|
||||
let workspace_specifiers = documents
|
||||
.documents(false, true)
|
||||
.into_iter()
|
||||
.map(|d| d.specifier().clone())
|
||||
|
@ -454,11 +437,11 @@ mod tests {
|
|||
use std::sync::Arc;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn mock_state_snapshot(
|
||||
fn mock_documents(
|
||||
fixtures: &[(&str, &str, i32, LanguageId)],
|
||||
source_fixtures: &[(&str, &str)],
|
||||
location: &Path,
|
||||
) -> language_server::StateSnapshot {
|
||||
) -> Documents {
|
||||
let mut documents = Documents::new(location);
|
||||
for (specifier, source, version, language_id) in fixtures {
|
||||
let specifier =
|
||||
|
@ -482,19 +465,16 @@ mod tests {
|
|||
"source could not be setup"
|
||||
);
|
||||
}
|
||||
language_server::StateSnapshot {
|
||||
documents,
|
||||
..Default::default()
|
||||
}
|
||||
documents
|
||||
}
|
||||
|
||||
fn setup(
|
||||
documents: &[(&str, &str, i32, LanguageId)],
|
||||
sources: &[(&str, &str)],
|
||||
) -> language_server::StateSnapshot {
|
||||
) -> Documents {
|
||||
let temp_dir = TempDir::new().expect("could not create temp dir");
|
||||
let location = temp_dir.path().join("deps");
|
||||
mock_state_snapshot(documents, sources, &location)
|
||||
mock_documents(documents, sources, &location)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -653,7 +633,7 @@ mod tests {
|
|||
character: 21,
|
||||
},
|
||||
};
|
||||
let state_snapshot = setup(
|
||||
let documents = setup(
|
||||
&[
|
||||
(
|
||||
"file:///a/b/c.ts",
|
||||
|
@ -665,8 +645,7 @@ mod tests {
|
|||
],
|
||||
&[("https://deno.land/x/a/b/c.ts", "console.log(1);\n")],
|
||||
);
|
||||
let actual =
|
||||
get_workspace_completions(&specifier, "h", &range, &state_snapshot);
|
||||
let actual = get_workspace_completions(&specifier, "h", &range, &documents);
|
||||
assert_eq!(
|
||||
actual,
|
||||
vec![lsp::CompletionItem {
|
||||
|
|
|
@ -194,7 +194,6 @@ impl WorkspaceSettings {
|
|||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ConfigSnapshot {
|
||||
pub client_capabilities: ClientCapabilities,
|
||||
pub root_uri: Option<Url>,
|
||||
pub settings: Settings,
|
||||
pub workspace_folders: Option<Vec<lsp::WorkspaceFolder>>,
|
||||
}
|
||||
|
@ -224,7 +223,6 @@ pub struct Settings {
|
|||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
pub client_capabilities: ClientCapabilities,
|
||||
pub root_uri: Option<Url>,
|
||||
settings: Arc<RwLock<Settings>>,
|
||||
tx: mpsc::Sender<ConfigRequest>,
|
||||
pub workspace_folders: Option<Vec<WorkspaceFolder>>,
|
||||
|
@ -326,7 +324,6 @@ impl Config {
|
|||
|
||||
Self {
|
||||
client_capabilities: ClientCapabilities::default(),
|
||||
root_uri: None,
|
||||
settings,
|
||||
tx,
|
||||
workspace_folders: None,
|
||||
|
@ -345,15 +342,10 @@ impl Config {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn snapshot(&self) -> Result<ConfigSnapshot, AnyError> {
|
||||
Ok(ConfigSnapshot {
|
||||
pub fn snapshot(&self) -> Arc<ConfigSnapshot> {
|
||||
Arc::new(ConfigSnapshot {
|
||||
client_capabilities: self.client_capabilities.clone(),
|
||||
root_uri: self.root_uri.clone(),
|
||||
settings: self
|
||||
.settings
|
||||
.try_read()
|
||||
.ok_or_else(|| anyhow!("Error reading settings."))?
|
||||
.clone(),
|
||||
settings: self.settings.read().clone(),
|
||||
workspace_folders: self.workspace_folders.clone(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use super::analysis;
|
||||
use super::client::Client;
|
||||
use super::config::ConfigSnapshot;
|
||||
use super::documents;
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
|
@ -9,6 +10,7 @@ use super::performance::Performance;
|
|||
use super::tsc;
|
||||
use super::tsc::TsServer;
|
||||
|
||||
use crate::config_file::LintConfig;
|
||||
use crate::diagnostics;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
|
@ -193,11 +195,20 @@ impl DiagnosticsServer {
|
|||
dirty = false;
|
||||
debounce_timer.as_mut().reset(Instant::now() + NEVER);
|
||||
|
||||
let snapshot = language_server.lock().await.snapshot().unwrap();
|
||||
let (snapshot, config, maybe_lint_config) = {
|
||||
let language_server = language_server.lock().await;
|
||||
(
|
||||
language_server.snapshot(),
|
||||
language_server.config.snapshot(),
|
||||
language_server.maybe_lint_config.clone(),
|
||||
)
|
||||
};
|
||||
update_diagnostics(
|
||||
&client,
|
||||
collection.clone(),
|
||||
snapshot,
|
||||
config,
|
||||
maybe_lint_config,
|
||||
&ts_server,
|
||||
performance.clone(),
|
||||
).await;
|
||||
|
@ -326,10 +337,11 @@ fn ts_json_to_diagnostics(
|
|||
async fn generate_lint_diagnostics(
|
||||
snapshot: &language_server::StateSnapshot,
|
||||
collection: Arc<Mutex<DiagnosticCollection>>,
|
||||
config: &ConfigSnapshot,
|
||||
maybe_lint_config: Option<LintConfig>,
|
||||
) -> Result<DiagnosticVec, AnyError> {
|
||||
let documents = snapshot.documents.documents(true, true);
|
||||
let workspace_settings = snapshot.config.settings.workspace.clone();
|
||||
let maybe_lint_config = snapshot.maybe_lint_config.clone();
|
||||
let workspace_settings = config.settings.workspace.clone();
|
||||
|
||||
tokio::task::spawn(async move {
|
||||
let mut diagnostics_vec = Vec::new();
|
||||
|
@ -539,13 +551,14 @@ fn diagnose_dependency(
|
|||
/// dependencies on the local file system or in the DENO_DIR cache.
|
||||
async fn generate_deps_diagnostics(
|
||||
snapshot: Arc<language_server::StateSnapshot>,
|
||||
config: Arc<ConfigSnapshot>,
|
||||
collection: Arc<Mutex<DiagnosticCollection>>,
|
||||
) -> Result<DiagnosticVec, AnyError> {
|
||||
tokio::task::spawn(async move {
|
||||
let mut diagnostics_vec = Vec::new();
|
||||
|
||||
for document in snapshot.documents.documents(true, true) {
|
||||
if !snapshot.config.specifier_enabled(document.specifier()) {
|
||||
if !config.specifier_enabled(document.specifier()) {
|
||||
continue;
|
||||
}
|
||||
let version = document.maybe_lsp_version();
|
||||
|
@ -590,11 +603,12 @@ async fn publish_diagnostics(
|
|||
client: &Client,
|
||||
collection: &mut DiagnosticCollection,
|
||||
snapshot: &language_server::StateSnapshot,
|
||||
config: &ConfigSnapshot,
|
||||
) {
|
||||
if let Some(changes) = collection.take_changes() {
|
||||
for specifier in changes {
|
||||
let mut diagnostics: Vec<lsp::Diagnostic> =
|
||||
if snapshot.config.settings.workspace.lint {
|
||||
if config.settings.workspace.lint {
|
||||
collection
|
||||
.get(&specifier, DiagnosticSource::DenoLint)
|
||||
.cloned()
|
||||
|
@ -602,7 +616,7 @@ async fn publish_diagnostics(
|
|||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
if snapshot.config.specifier_enabled(&specifier) {
|
||||
if config.specifier_enabled(&specifier) {
|
||||
diagnostics.extend(
|
||||
collection
|
||||
.get(&specifier, DiagnosticSource::TypeScript)
|
||||
|
@ -629,6 +643,8 @@ async fn update_diagnostics(
|
|||
client: &Client,
|
||||
collection: Arc<Mutex<DiagnosticCollection>>,
|
||||
snapshot: Arc<language_server::StateSnapshot>,
|
||||
config: Arc<ConfigSnapshot>,
|
||||
maybe_lint_config: Option<LintConfig>,
|
||||
ts_server: &tsc::TsServer,
|
||||
performance: Arc<Performance>,
|
||||
) {
|
||||
|
@ -637,18 +653,23 @@ async fn update_diagnostics(
|
|||
let lint = async {
|
||||
let mark = performance.mark("update_diagnostics_lint", None::<()>);
|
||||
let collection = collection.clone();
|
||||
let diagnostics = generate_lint_diagnostics(&snapshot, collection.clone())
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error generating lint diagnostics: {}", err);
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let diagnostics = generate_lint_diagnostics(
|
||||
&snapshot,
|
||||
collection.clone(),
|
||||
&config,
|
||||
maybe_lint_config,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error generating lint diagnostics: {}", err);
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut collection = collection.lock().await;
|
||||
for diagnostic_record in diagnostics {
|
||||
collection.set(DiagnosticSource::DenoLint, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
publish_diagnostics(client, &mut collection, &snapshot, &config).await;
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
|
@ -666,25 +687,28 @@ async fn update_diagnostics(
|
|||
for diagnostic_record in diagnostics {
|
||||
collection.set(DiagnosticSource::TypeScript, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
publish_diagnostics(client, &mut collection, &snapshot, &config).await;
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
let deps = async {
|
||||
let mark = performance.mark("update_diagnostics_deps", None::<()>);
|
||||
let collection = collection.clone();
|
||||
let diagnostics =
|
||||
generate_deps_diagnostics(snapshot.clone(), collection.clone())
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error generating Deno diagnostics: {}", err);
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let diagnostics = generate_deps_diagnostics(
|
||||
snapshot.clone(),
|
||||
config.clone(),
|
||||
collection.clone(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error generating Deno diagnostics: {}", err);
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let mut collection = collection.lock().await;
|
||||
for diagnostic_record in diagnostics {
|
||||
collection.set(DiagnosticSource::Deno, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
publish_diagnostics(client, &mut collection, &snapshot, &config).await;
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
|
@ -719,7 +743,14 @@ mod tests {
|
|||
Arc::new(source.to_string()),
|
||||
);
|
||||
}
|
||||
let config = ConfigSnapshot {
|
||||
StateSnapshot {
|
||||
documents,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn mock_config() -> ConfigSnapshot {
|
||||
ConfigSnapshot {
|
||||
settings: Settings {
|
||||
workspace: WorkspaceSettings {
|
||||
enable: true,
|
||||
|
@ -729,27 +760,28 @@ mod tests {
|
|||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
StateSnapshot {
|
||||
config,
|
||||
documents,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn setup(
|
||||
sources: &[(&str, &str, i32, LanguageId)],
|
||||
) -> (StateSnapshot, Arc<Mutex<DiagnosticCollection>>, PathBuf) {
|
||||
) -> (
|
||||
StateSnapshot,
|
||||
Arc<Mutex<DiagnosticCollection>>,
|
||||
PathBuf,
|
||||
ConfigSnapshot,
|
||||
) {
|
||||
let temp_dir = TempDir::new().expect("could not create temp dir");
|
||||
let location = temp_dir.path().join("deps");
|
||||
let state_snapshot = mock_state_snapshot(sources, &location);
|
||||
let collection = Arc::new(Mutex::new(DiagnosticCollection::default()));
|
||||
(state_snapshot, collection, location)
|
||||
let config = mock_config();
|
||||
(state_snapshot, collection, location, config)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_generate_lint_diagnostics() {
|
||||
let (snapshot, collection, _) = setup(&[(
|
||||
let (snapshot, collection, _, config) = setup(&[(
|
||||
"file:///a.ts",
|
||||
r#"import * as b from "./b.ts";
|
||||
|
||||
|
@ -759,7 +791,8 @@ console.log(a);
|
|||
1,
|
||||
LanguageId::TypeScript,
|
||||
)]);
|
||||
let result = generate_lint_diagnostics(&snapshot, collection).await;
|
||||
let result =
|
||||
generate_lint_diagnostics(&snapshot, collection, &config, None).await;
|
||||
assert!(result.is_ok());
|
||||
let diagnostics = result.unwrap();
|
||||
assert_eq!(diagnostics.len(), 1);
|
||||
|
|
|
@ -74,15 +74,12 @@ const CACHE_PATH: &str = "deps";
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct LanguageServer(Arc<tokio::sync::Mutex<Inner>>);
|
||||
|
||||
/// Snapshot of the state used by TSC.
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct StateSnapshot {
|
||||
pub assets: AssetsSnapshot,
|
||||
pub config: ConfigSnapshot,
|
||||
pub documents: Documents,
|
||||
pub maybe_lint_config: Option<LintConfig>,
|
||||
pub maybe_fmt_config: Option<FmtConfig>,
|
||||
pub module_registries: registries::ModuleRegistry,
|
||||
pub url_map: urls::LspUrlMap,
|
||||
pub root_uri: Option<Url>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -97,7 +94,7 @@ pub(crate) struct Inner {
|
|||
diagnostics_server: diagnostics::DiagnosticsServer,
|
||||
/// The collection of documents that the server is currently handling, either
|
||||
/// on disk or "open" within the client.
|
||||
documents: Documents,
|
||||
pub(crate) documents: Documents,
|
||||
/// Handles module registries, which allow discovery of modules
|
||||
module_registries: registries::ModuleRegistry,
|
||||
/// The path to the module registries cache
|
||||
|
@ -111,7 +108,7 @@ pub(crate) struct Inner {
|
|||
/// options.
|
||||
maybe_config_file: Option<ConfigFile>,
|
||||
/// An optional configuration for linter which has been taken from specified config file.
|
||||
maybe_lint_config: Option<LintConfig>,
|
||||
pub(crate) maybe_lint_config: Option<LintConfig>,
|
||||
/// An optional configuration for formatter which has been taken from specified config file.
|
||||
maybe_fmt_config: Option<FmtConfig>,
|
||||
/// An optional import map which is used to resolve modules.
|
||||
|
@ -120,6 +117,8 @@ pub(crate) struct Inner {
|
|||
maybe_import_map_uri: Option<Url>,
|
||||
/// A collection of measurements which instrument that performance of the LSP.
|
||||
performance: Arc<Performance>,
|
||||
/// Root provided by the initialization parameters.
|
||||
root_uri: Option<Url>,
|
||||
/// A memoized version of fixable diagnostic codes retrieved from TypeScript.
|
||||
ts_fixable_diagnostics: Vec<String>,
|
||||
/// An abstraction that handles interactions with TypeScript.
|
||||
|
@ -169,6 +168,7 @@ impl Inner {
|
|||
maybe_import_map_uri: None,
|
||||
module_registries,
|
||||
module_registries_location,
|
||||
root_uri: None,
|
||||
performance,
|
||||
ts_fixable_diagnostics: Default::default(),
|
||||
ts_server,
|
||||
|
@ -248,12 +248,8 @@ impl Inner {
|
|||
self
|
||||
.assets
|
||||
.get_cached(specifier)
|
||||
.map(|maybe_asset| {
|
||||
maybe_asset
|
||||
.as_ref()
|
||||
.map(|asset| AssetOrDocument::Asset(asset.clone()))
|
||||
})
|
||||
.flatten()
|
||||
.map(AssetOrDocument::Asset)
|
||||
} else {
|
||||
self.documents.get(specifier).map(AssetOrDocument::Document)
|
||||
}
|
||||
|
@ -275,7 +271,7 @@ impl Inner {
|
|||
let navigation_tree: tsc::NavigationTree = self
|
||||
.ts_server
|
||||
.request(
|
||||
self.snapshot()?,
|
||||
self.snapshot(),
|
||||
tsc::RequestMethod::GetNavigationTree(specifier.clone()),
|
||||
)
|
||||
.await?;
|
||||
|
@ -302,7 +298,7 @@ impl Inner {
|
|||
/// If there's no config file specified in settings returns `None`.
|
||||
fn get_config_file(&self) -> Result<Option<ConfigFile>, AnyError> {
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
let maybe_root_uri = self.config.root_uri.clone();
|
||||
let maybe_root_uri = self.root_uri.clone();
|
||||
let maybe_config = workspace_settings.config;
|
||||
if let Some(config_str) = &maybe_config {
|
||||
if !config_str.is_empty() {
|
||||
|
@ -387,39 +383,24 @@ impl Inner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn snapshot(&self) -> LspResult<Arc<StateSnapshot>> {
|
||||
Ok(Arc::new(StateSnapshot {
|
||||
pub(crate) fn snapshot(&self) -> Arc<StateSnapshot> {
|
||||
Arc::new(StateSnapshot {
|
||||
assets: self.assets.snapshot(),
|
||||
config: self.config.snapshot().map_err(|err| {
|
||||
error!("{}", err);
|
||||
LspError::internal_error()
|
||||
})?,
|
||||
documents: self.documents.clone(),
|
||||
maybe_lint_config: self.maybe_lint_config.clone(),
|
||||
maybe_fmt_config: self.maybe_fmt_config.clone(),
|
||||
module_registries: self.module_registries.clone(),
|
||||
// it's ok to get an Arc to the url map because the url_map is a cache
|
||||
// that does not change once the mapping for a specifier is set
|
||||
url_map: self.url_map.clone(),
|
||||
}))
|
||||
root_uri: self.root_uri.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update_cache(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_cache", None::<()>);
|
||||
self.performance.measure(mark);
|
||||
self.maybe_cache_server = None;
|
||||
let (maybe_cache, maybe_root_uri) = {
|
||||
let config = &self.config;
|
||||
(
|
||||
config.get_workspace_settings().cache,
|
||||
config.root_uri.clone(),
|
||||
)
|
||||
};
|
||||
let maybe_cache = self.config.get_workspace_settings().cache;
|
||||
let maybe_cache_path = if let Some(cache_str) = &maybe_cache {
|
||||
lsp_log!("Setting cache path from: \"{}\"", cache_str);
|
||||
let cache_url = if let Ok(url) = Url::from_file_path(cache_str) {
|
||||
Ok(url)
|
||||
} else if let Some(root_uri) = &maybe_root_uri {
|
||||
} else if let Some(root_uri) = &self.root_uri {
|
||||
let root_path = fs_util::specifier_to_file_path(root_uri)?;
|
||||
let cache_path = root_path.join(cache_str);
|
||||
Url::from_file_path(cache_path).map_err(|_| {
|
||||
|
@ -459,13 +440,7 @@ impl Inner {
|
|||
pub async fn update_import_map(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_import_map", None::<()>);
|
||||
self.maybe_cache_server = None;
|
||||
let (maybe_import_map, maybe_root_uri) = {
|
||||
let config = &self.config;
|
||||
(
|
||||
config.get_workspace_settings().import_map,
|
||||
config.root_uri.clone(),
|
||||
)
|
||||
};
|
||||
let maybe_import_map = self.config.get_workspace_settings().import_map;
|
||||
if let Some(import_map_str) = &maybe_import_map {
|
||||
lsp_log!("Setting import map from: \"{}\"", import_map_str);
|
||||
let import_map_url = if let Ok(url) = Url::from_file_path(import_map_str)
|
||||
|
@ -475,7 +450,7 @@ impl Inner {
|
|||
Url::parse(import_map_str).map_err(|_| {
|
||||
anyhow!("Bad data url for import map: {:?}", import_map_str)
|
||||
})
|
||||
} else if let Some(root_uri) = &maybe_root_uri {
|
||||
} else if let Some(root_uri) = &self.root_uri {
|
||||
let root_path = fs_util::specifier_to_file_path(root_uri)?;
|
||||
let import_map_path = root_path.join(import_map_str);
|
||||
Url::from_file_path(import_map_path).map_err(|_| {
|
||||
|
@ -598,7 +573,7 @@ impl Inner {
|
|||
}
|
||||
let _ok: bool = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, tsc::RequestMethod::Configure(tsconfig))
|
||||
.request(self.snapshot(), tsc::RequestMethod::Configure(tsconfig))
|
||||
.await?;
|
||||
self.performance.measure(mark);
|
||||
Ok(())
|
||||
|
@ -646,20 +621,19 @@ impl Inner {
|
|||
}
|
||||
|
||||
{
|
||||
let config = &mut self.config;
|
||||
// sometimes this root uri may not have a trailing slash, so force it to
|
||||
config.root_uri = params
|
||||
self.root_uri = params
|
||||
.root_uri
|
||||
.map(|s| self.url_map.normalize_url(&s))
|
||||
.map(fs_util::ensure_directory_specifier);
|
||||
|
||||
if let Some(value) = params.initialization_options {
|
||||
config.set_workspace_settings(value).map_err(|err| {
|
||||
self.config.set_workspace_settings(value).map_err(|err| {
|
||||
error!("Cannot set workspace settings: {}", err);
|
||||
LspError::internal_error()
|
||||
})?;
|
||||
}
|
||||
config.update_capabilities(¶ms.capabilities);
|
||||
self.config.update_capabilities(¶ms.capabilities);
|
||||
}
|
||||
|
||||
self.update_debug_flag();
|
||||
|
@ -677,7 +651,7 @@ impl Inner {
|
|||
if capabilities.code_action_provider.is_some() {
|
||||
let fixable_diagnostics: Vec<String> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, tsc::RequestMethod::GetSupportedCodeFixes)
|
||||
.request(self.snapshot(), tsc::RequestMethod::GetSupportedCodeFixes)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get fixable diagnostics: {}", err);
|
||||
|
@ -1136,7 +1110,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_quick_info: Option<tsc::QuickInfo> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get quick info: {}", err);
|
||||
|
@ -1216,7 +1190,7 @@ impl Inner {
|
|||
codes,
|
||||
));
|
||||
let actions: Vec<tsc::CodeFixAction> =
|
||||
match self.ts_server.request(self.snapshot()?, req).await {
|
||||
match self.ts_server.request(self.snapshot(), req).await {
|
||||
Ok(items) => items,
|
||||
Err(err) => {
|
||||
// sometimes tsc reports errors when retrieving code actions
|
||||
|
@ -1289,7 +1263,7 @@ impl Inner {
|
|||
));
|
||||
let refactor_infos: Vec<tsc::ApplicableRefactorInfo> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -1336,6 +1310,7 @@ impl Inner {
|
|||
|
||||
let result = if kind.as_str().starts_with(CodeActionKind::QUICKFIX.as_str())
|
||||
{
|
||||
let snapshot = self.snapshot();
|
||||
let code_action_data: CodeActionData =
|
||||
from_value(data).map_err(|err| {
|
||||
error!("Unable to decode code action data: {}", err);
|
||||
|
@ -1347,7 +1322,7 @@ impl Inner {
|
|||
));
|
||||
let combined_code_actions: tsc::CombinedCodeActions = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(snapshot.clone(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get combined fix from TypeScript: {}", err);
|
||||
|
@ -1362,7 +1337,7 @@ impl Inner {
|
|||
fix_ts_import_changes(
|
||||
&code_action_data.specifier,
|
||||
&combined_code_actions.changes,
|
||||
self,
|
||||
&self.documents,
|
||||
)
|
||||
.map_err(|err| {
|
||||
error!("Unable to remap changes: {}", err);
|
||||
|
@ -1379,6 +1354,7 @@ impl Inner {
|
|||
})?;
|
||||
code_action
|
||||
} else if kind.as_str().starts_with(CodeActionKind::REFACTOR.as_str()) {
|
||||
let snapshot = self.snapshot();
|
||||
let mut code_action = params.clone();
|
||||
let action_data: refactor::RefactorCodeActionData = from_value(data)
|
||||
.map_err(|err| {
|
||||
|
@ -1396,11 +1372,8 @@ impl Inner {
|
|||
action_data.refactor_name.clone(),
|
||||
action_data.action_name.clone(),
|
||||
));
|
||||
let refactor_edit_info: tsc::RefactorEditInfo = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
let refactor_edit_info: tsc::RefactorEditInfo =
|
||||
self.ts_server.request(snapshot, req).await.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
LspError::invalid_request()
|
||||
})?;
|
||||
|
@ -1506,7 +1479,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_document_highlights: Option<Vec<tsc::DocumentHighlights>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get document highlights from TypeScript: {}", err);
|
||||
|
@ -1549,7 +1522,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_references: Option<Vec<tsc::ReferenceEntry>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get references from TypeScript: {}", err);
|
||||
|
@ -1571,7 +1544,8 @@ impl Inner {
|
|||
self.get_asset_or_document(&reference_specifier).await?;
|
||||
asset_or_doc.line_index()
|
||||
};
|
||||
results.push(reference.to_location(reference_line_index, self));
|
||||
results
|
||||
.push(reference.to_location(reference_line_index, &self.url_map));
|
||||
}
|
||||
|
||||
self.performance.measure(mark);
|
||||
|
@ -1604,7 +1578,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_definition: Option<tsc::DefinitionInfoAndBoundSpan> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get definition from TypeScript: {}", err);
|
||||
|
@ -1644,7 +1618,7 @@ impl Inner {
|
|||
};
|
||||
let maybe_definition_info: Option<Vec<tsc::DefinitionInfo>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get type definition from TypeScript: {}", err);
|
||||
|
@ -1688,12 +1662,13 @@ impl Inner {
|
|||
// completions, we will use internal logic and if there are completions
|
||||
// for imports, we will return those and not send a message into tsc, where
|
||||
// other completions come from.
|
||||
let snapshot = self.snapshot()?;
|
||||
let response = if let Some(response) = completions::get_import_completions(
|
||||
&specifier,
|
||||
¶ms.text_document_position.position,
|
||||
&snapshot,
|
||||
&self.config.snapshot(),
|
||||
self.client.clone(),
|
||||
&self.module_registries,
|
||||
&self.documents,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
@ -1722,11 +1697,9 @@ impl Inner {
|
|||
trigger_character,
|
||||
},
|
||||
));
|
||||
let maybe_completion_info: Option<tsc::CompletionInfo> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
let snapshot = self.snapshot();
|
||||
let maybe_completion_info: Option<tsc::CompletionInfo> =
|
||||
self.ts_server.request(snapshot, req).await.map_err(|err| {
|
||||
error!("Unable to get completion info from TypeScript: {}", err);
|
||||
LspError::internal_error()
|
||||
})?;
|
||||
|
@ -1762,14 +1735,13 @@ impl Inner {
|
|||
})?;
|
||||
if let Some(data) = data.tsc {
|
||||
let req = tsc::RequestMethod::GetCompletionDetails(data.into());
|
||||
let maybe_completion_info: Option<tsc::CompletionEntryDetails> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get completion info from TypeScript: {}", err);
|
||||
LspError::internal_error()
|
||||
})?;
|
||||
let maybe_completion_info: Option<tsc::CompletionEntryDetails> =
|
||||
self.ts_server.request(self.snapshot(), req).await.map_err(
|
||||
|err| {
|
||||
error!("Unable to get completion info from TypeScript: {}", err);
|
||||
LspError::internal_error()
|
||||
},
|
||||
)?;
|
||||
if let Some(completion_info) = maybe_completion_info {
|
||||
completion_info.as_completion_item(¶ms)
|
||||
} else {
|
||||
|
@ -1817,7 +1789,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_implementations: Option<Vec<tsc::ImplementationLocation>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -1859,7 +1831,7 @@ impl Inner {
|
|||
let req = tsc::RequestMethod::GetOutliningSpans(specifier.clone());
|
||||
let outlining_spans: Vec<tsc::OutliningSpan> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -1907,7 +1879,7 @@ impl Inner {
|
|||
));
|
||||
let incoming_calls: Vec<tsc::CallHierarchyIncomingCall> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -1915,7 +1887,6 @@ impl Inner {
|
|||
})?;
|
||||
|
||||
let maybe_root_path_owned = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
|
@ -1956,7 +1927,7 @@ impl Inner {
|
|||
));
|
||||
let outgoing_calls: Vec<tsc::CallHierarchyOutgoingCall> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -1964,7 +1935,6 @@ impl Inner {
|
|||
})?;
|
||||
|
||||
let maybe_root_path_owned = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
|
@ -2011,7 +1981,7 @@ impl Inner {
|
|||
let maybe_one_or_many: Option<tsc::OneOrMany<tsc::CallHierarchyItem>> =
|
||||
self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -2020,7 +1990,6 @@ impl Inner {
|
|||
|
||||
let response = if let Some(one_or_many) = maybe_one_or_many {
|
||||
let maybe_root_path_owned = self
|
||||
.config
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| fs_util::specifier_to_file_path(uri).ok());
|
||||
|
@ -2087,7 +2056,7 @@ impl Inner {
|
|||
|
||||
let maybe_locations: Option<Vec<tsc::RenameLocation>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -2173,7 +2142,7 @@ impl Inner {
|
|||
|
||||
let selection_range: tsc::SelectionRange = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -2211,7 +2180,7 @@ impl Inner {
|
|||
));
|
||||
let semantic_classification: tsc::Classifications = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -2254,7 +2223,7 @@ impl Inner {
|
|||
));
|
||||
let semantic_classification: tsc::Classifications = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver {}", err);
|
||||
|
@ -2307,7 +2276,7 @@ impl Inner {
|
|||
));
|
||||
let maybe_signature_help_items: Option<tsc::SignatureHelpItems> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to request to tsserver: {}", err);
|
||||
|
@ -2339,7 +2308,7 @@ impl Inner {
|
|||
|
||||
let navigate_to_items: Vec<tsc::NavigateToItem> = self
|
||||
.ts_server
|
||||
.request(self.snapshot()?, req)
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed request to tsserver: {}", err);
|
||||
|
|
|
@ -14,6 +14,7 @@ use super::semantic_tokens;
|
|||
use super::semantic_tokens::SemanticTokensBuilder;
|
||||
use super::text;
|
||||
use super::text::LineIndex;
|
||||
use super::urls::LspUrlMap;
|
||||
use super::urls::INVALID_SPECIFIER;
|
||||
|
||||
use crate::config_file::TsConfig;
|
||||
|
@ -265,13 +266,13 @@ impl Assets {
|
|||
specifier: &ModuleSpecifier,
|
||||
// todo(dsherret): this shouldn't be a parameter, but instead retrieved via
|
||||
// a constructor dependency
|
||||
get_snapshot: impl Fn() -> LspResult<Arc<StateSnapshot>>,
|
||||
get_snapshot: impl Fn() -> Arc<StateSnapshot>,
|
||||
) -> LspResult<Option<AssetDocument>> {
|
||||
// Race conditions are ok to happen here since the assets are static
|
||||
if let Some(maybe_asset) = self.get_cached(specifier) {
|
||||
Ok(maybe_asset)
|
||||
} else {
|
||||
let maybe_asset = get_asset(specifier, &self.ts_server, get_snapshot()?)
|
||||
let maybe_asset = get_asset(specifier, &self.ts_server, get_snapshot())
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Error getting asset {}: {}", specifier, err);
|
||||
|
@ -1528,12 +1529,11 @@ impl ReferenceEntry {
|
|||
pub(crate) fn to_location(
|
||||
&self,
|
||||
line_index: Arc<LineIndex>,
|
||||
language_server: &language_server::Inner,
|
||||
url_map: &LspUrlMap,
|
||||
) -> lsp::Location {
|
||||
let specifier = normalize_specifier(&self.document_span.file_name)
|
||||
.unwrap_or_else(|_| INVALID_SPECIFIER.clone());
|
||||
let uri = language_server
|
||||
.url_map
|
||||
let uri = url_map
|
||||
.normalize_specifier(&specifier)
|
||||
.unwrap_or_else(|_| INVALID_SPECIFIER.clone());
|
||||
lsp::Location {
|
||||
|
@ -2628,7 +2628,6 @@ fn start(
|
|||
state_snapshot: &StateSnapshot,
|
||||
) -> Result<(), AnyError> {
|
||||
let root_uri = state_snapshot
|
||||
.config
|
||||
.root_uri
|
||||
.clone()
|
||||
.unwrap_or_else(|| Url::parse("cache:///").unwrap());
|
||||
|
|
Loading…
Add table
Reference in a new issue