1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-18 03:44:05 -05:00

fix(lsp): regression where certain diagnostics were showing for disabled files (#13530)

This commit is contained in:
David Sherret 2022-01-29 17:50:15 -05:00 committed by GitHub
parent 5cf23176dc
commit a2e4fa471b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,6 +4,7 @@ use super::analysis;
use super::client::Client;
use super::config::ConfigSnapshot;
use super::documents;
use super::documents::Document;
use super::documents::Documents;
use super::language_server;
use super::performance::Performance;
@ -211,14 +212,14 @@ impl DiagnosticsServer {
let mark =
performance.mark("update_diagnostics_ts", None::<()>);
let diagnostics =
generate_ts_diagnostics(snapshot.clone(), &ts_server)
let diagnostics = generate_ts_diagnostics(
snapshot.clone(),
&config,
&ts_server,
)
.await
.map_err(|err| {
error!(
"Error generating TypeScript diagnostics: {}",
err
);
error!("Error generating TypeScript diagnostics: {}", err);
})
.unwrap_or_default();
@ -257,8 +258,8 @@ impl DiagnosticsServer {
let mark =
performance.mark("update_diagnostics_deps", None::<()>);
let diagnostics = generate_deps_diagnostics(
snapshot.clone(),
config.clone(),
&snapshot,
&config,
token.clone(),
)
.await;
@ -439,13 +440,33 @@ async fn generate_lint_diagnostics(
}
let version = document.maybe_lsp_version();
let is_allowed = match &maybe_lint_config {
Some(lint_config) => {
lint_config.files.matches_specifier(document.specifier())
diagnostics_vec.push((
document.specifier().clone(),
version,
generate_document_lint_diagnostics(
config,
&maybe_lint_config,
&document,
),
));
}
}
diagnostics_vec
}
fn generate_document_lint_diagnostics(
config: &ConfigSnapshot,
maybe_lint_config: &Option<LintConfig>,
document: &Document,
) -> Vec<lsp::Diagnostic> {
if !config.specifier_enabled(document.specifier()) {
return Vec::new();
}
if let Some(lint_config) = &maybe_lint_config {
if !lint_config.files.matches_specifier(document.specifier()) {
return Vec::new();
}
}
None => true,
};
let diagnostics = if is_allowed {
match document.maybe_parsed_source() {
Some(Ok(parsed_source)) => {
if let Ok(references) = analysis::get_lint_references(
@ -466,21 +487,11 @@ async fn generate_lint_diagnostics(
Vec::new()
}
}
} else {
Vec::new()
};
diagnostics_vec.push((
document.specifier().clone(),
version,
diagnostics,
));
}
}
diagnostics_vec
}
async fn generate_ts_diagnostics(
snapshot: Arc<language_server::StateSnapshot>,
config: &ConfigSnapshot,
ts_server: &tsc::TsServer,
) -> Result<DiagnosticVec, AnyError> {
let mut diagnostics_vec = Vec::new();
@ -490,23 +501,41 @@ async fn generate_ts_diagnostics(
.iter()
.map(|d| d.specifier().clone())
.collect::<Vec<_>>();
if !specifiers.is_empty() {
let req = tsc::RequestMethod::GetDiagnostics(specifiers);
let ts_diagnostics_map: TsDiagnosticsMap =
ts_server.request(snapshot.clone(), req).await?;
for (specifier_str, ts_diagnostics) in ts_diagnostics_map {
let (enabled_specifiers, disabled_specifiers) = specifiers
.iter()
.cloned()
.partition::<Vec<_>, _>(|s| config.specifier_enabled(s));
let ts_diagnostics_map: TsDiagnosticsMap = if !enabled_specifiers.is_empty() {
let req = tsc::RequestMethod::GetDiagnostics(enabled_specifiers);
ts_server.request(snapshot.clone(), req).await?
} else {
Default::default()
};
for (specifier_str, ts_json_diagnostics) in ts_diagnostics_map {
let specifier = resolve_url(&specifier_str)?;
let version = snapshot
.documents
.get(&specifier)
.map(|d| d.maybe_lsp_version())
.flatten();
diagnostics_vec.push((
specifier,
version,
ts_json_to_diagnostics(ts_diagnostics),
));
// check if the specifier is enabled again just in case TS returns us
// diagnostics for a disabled specifier
let ts_diagnostics = if config.specifier_enabled(&specifier) {
ts_json_to_diagnostics(ts_json_diagnostics)
} else {
Vec::new()
};
diagnostics_vec.push((specifier, version, ts_diagnostics));
}
// add an empty diagnostic publish for disabled specifiers in order
// to clear those diagnostics if they exist
for specifier in disabled_specifiers {
let version = snapshot
.documents
.get(&specifier)
.map(|d| d.maybe_lsp_version())
.flatten();
diagnostics_vec.push((specifier, version, Vec::new()));
}
Ok(diagnostics_vec)
}
@ -619,8 +648,8 @@ fn diagnose_dependency(
/// Generate diagnostics for dependencies of a module, attempting to resolve
/// 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>,
snapshot: &language_server::StateSnapshot,
config: &ConfigSnapshot,
token: CancellationToken,
) -> DiagnosticVec {
let mut diagnostics_vec = Vec::new();
@ -629,10 +658,8 @@ async fn generate_deps_diagnostics(
if token.is_cancelled() {
break;
}
if !config.specifier_enabled(document.specifier()) {
continue;
}
let mut diagnostics = Vec::new();
if config.specifier_enabled(document.specifier()) {
for (_, dependency) in document.dependencies() {
diagnose_dependency(
&mut diagnostics,
@ -649,6 +676,7 @@ async fn generate_deps_diagnostics(
dependency.maybe_assert_type.as_deref(),
);
}
}
diagnostics_vec.push((
document.specifier().clone(),
document.maybe_lsp_version(),
@ -664,6 +692,7 @@ mod tests {
use super::*;
use crate::lsp::config::ConfigSnapshot;
use crate::lsp::config::Settings;
use crate::lsp::config::SpecifierSettings;
use crate::lsp::config::WorkspaceSettings;
use crate::lsp::documents::LanguageId;
use crate::lsp::language_server::StateSnapshot;
@ -708,31 +737,95 @@ mod tests {
fn setup(
sources: &[(&str, &str, i32, LanguageId)],
) -> (StateSnapshot, PathBuf, ConfigSnapshot) {
) -> (StateSnapshot, PathBuf) {
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 config = mock_config();
(state_snapshot, location, config)
(state_snapshot, location)
}
#[tokio::test]
async fn test_generate_lint_diagnostics() {
let (snapshot, _, config) = setup(&[(
async fn test_enabled_then_disabled_specifier() {
let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap();
let (snapshot, _) = setup(&[(
"file:///a.ts",
r#"import * as b from "./b.ts";
let a = "a";
console.log(a);
let a: any = "a";
let c: number = "a";
"#,
1,
LanguageId::TypeScript,
)]);
let diagnostics =
generate_lint_diagnostics(&snapshot, &config, None, Default::default())
let snapshot = Arc::new(snapshot);
let ts_server = TsServer::new(Default::default());
// test enabled
{
let enabled_config = mock_config();
let diagnostics = generate_lint_diagnostics(
&snapshot,
&enabled_config,
None,
Default::default(),
)
.await;
assert_eq!(diagnostics.len(), 1);
let (_, _, diagnostics) = &diagnostics[0];
assert_eq!(diagnostics.len(), 2);
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 6);
let diagnostics =
generate_ts_diagnostics(snapshot.clone(), &enabled_config, &ts_server)
.await
.unwrap();
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 4);
let diagnostics = generate_deps_diagnostics(
&snapshot,
&enabled_config,
Default::default(),
)
.await;
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 1);
}
// now test disabled specifier
{
let mut disabled_config = mock_config();
disabled_config.settings.specifiers.insert(
specifier.clone(),
(
specifier.clone(),
SpecifierSettings {
enable: false,
code_lens: Default::default(),
},
),
);
let diagnostics = generate_lint_diagnostics(
&snapshot,
&disabled_config,
None,
Default::default(),
)
.await;
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 0);
let diagnostics =
generate_ts_diagnostics(snapshot.clone(), &disabled_config, &ts_server)
.await
.unwrap();
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 0);
let diagnostics = generate_deps_diagnostics(
&snapshot,
&disabled_config,
Default::default(),
)
.await;
assert_eq!(get_diagnostics_for_single(diagnostics).len(), 0);
}
}
fn get_diagnostics_for_single(
diagnostic_vec: DiagnosticVec,
) -> Vec<lsp::Diagnostic> {
assert_eq!(diagnostic_vec.len(), 1);
let (_, _, diagnostics) = diagnostic_vec.into_iter().next().unwrap();
diagnostics
}
}