Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/hir/src/base_db/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ impl ProjectConfig {
!self.profiles.is_empty()
}

pub fn profile_ids(&self) -> Vec<CompilationProfileId> {
(0..self.profiles.len())
.map(|idx| CompilationProfileId(u32::try_from(idx).unwrap_or(u32::MAX)))
.collect()
}

pub fn preprocess_for_profile(
&self,
profile_id: Option<CompilationProfileId>,
Expand Down
11 changes: 11 additions & 0 deletions crates/ide/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ impl Analysis {
self.with_db(|db| diagnostics::diagnostics(db, file_id))
}

pub fn compilation_diagnostics(
&self,
file_id: FileId,
) -> Cancellable<Vec<diagnostics::Diagnostic>> {
self.with_db(|db| diagnostics::compilation_diagnostics(db, file_id))
}

pub fn source_root_diagnostics(
&self,
file_id: FileId,
Expand Down Expand Up @@ -123,6 +130,10 @@ impl Analysis {
self.with_db(|db| db.project_config().has_compilation_profiles())
}

pub fn compilation_profile_ids(&self) -> Cancellable<Vec<CompilationProfileId>> {
self.with_db(|db| db.project_config().profile_ids())
}

pub fn compilation_profile_file_ids(
&self,
profile_id: CompilationProfileId,
Expand Down
47 changes: 8 additions & 39 deletions crates/ide/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ pub(crate) fn parse_diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagnostic>
.collect()
}

fn compilation_diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagnostic> {
pub(crate) fn compilation_diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagnostic> {
db.file_compilation_diagnostics(file_id)
.iter()
.map(|diag| slang_diagnostic(diag.file_id, diag.source, &diag.diagnostic))
Expand Down Expand Up @@ -234,17 +234,7 @@ pub(crate) fn diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagnostic> {
return Vec::new();
}

let mut diagnostics = if slang_semantic_diagnostics_active(db, file_id) {
inactive_preprocessor_branch_diagnostics(db, file_id)
} else {
syntax_diagnostics(db, file_id)
};

diagnostics.extend(
compilation_diagnostics(db, file_id).into_iter().filter(|diag| diag.file_id == file_id),
);

diagnostics
syntax_diagnostics(db, file_id)
}

pub(crate) fn source_root_diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagnostic> {
Expand All @@ -258,28 +248,7 @@ pub(crate) fn source_root_diagnostics(db: &RootDb, file_id: FileId) -> Vec<Diagn
SourceRootDiagnosticScope::Workspace => {}
}

let mut diagnostics = Vec::new();

if slang_semantic_diagnostics_active(db, file_id) {
diagnostics.extend(compilation_diagnostics(db, file_id));
diagnostics.extend(
source_root
.iter()
.flat_map(|file_id| inactive_preprocessor_branch_diagnostics(db, file_id)),
);
} else {
for file_id in source_root.iter() {
diagnostics.extend(syntax_diagnostics(db, file_id));
}

diagnostics.extend(db.source_root_semantic_diagnostics(file_id).iter().map(
|(diag_file_id, diag)| {
slang_diagnostic(*diag_file_id, SlangDiagnosticSource::Semantic, diag)
},
));
}

diagnostics
source_root.iter().flat_map(|file_id| syntax_diagnostics(db, file_id)).collect()
}

pub(crate) fn source_root_file_ids(db: &RootDb, file_id: FileId) -> Vec<FileId> {
Expand Down Expand Up @@ -468,7 +437,7 @@ mod tests {

use super::{
AMBIGUOUS_MODULE_INSTANTIATION, DIAGNOSTIC_INACTIVE_PREPROCESSOR_BRANCH, DiagnosticSource,
DiagnosticTag, INACTIVE_PREPROCESSOR_BRANCH, diagnostics, source_root_diagnostics,
DiagnosticTag, INACTIVE_PREPROCESSOR_BRANCH, compilation_profile_diagnostics, diagnostics,
};
use crate::db::root_db::RootDb;

Expand Down Expand Up @@ -747,7 +716,7 @@ mod tests {
true,
);

let diagnostics = diagnostics(&db, FileId(1));
let diagnostics = compilation_profile_diagnostics(&db, CompilationProfileId(0));

assert!(
diagnostics.iter().any(|diag| diag.message.contains("port 'b' has no connection")),
Expand Down Expand Up @@ -909,7 +878,7 @@ mod tests {
)));
db.apply_change(change);

let diagnostics = diagnostics(&db, FileId(1));
let diagnostics = compilation_profile_diagnostics(&db, CompilationProfileId(0));

assert!(
diagnostics.iter().any(|diag| diag.message.contains("missing_name")),
Expand Down Expand Up @@ -962,7 +931,7 @@ mod tests {
assert!(plan.include_only.contains(&FileId(1)));
assert_eq!(plan.roots, vec![FileId(0)]);

let diagnostics = diagnostics(&db, FileId(1));
let diagnostics = compilation_profile_diagnostics(&db, CompilationProfileId(0));

assert!(
diagnostics
Expand Down Expand Up @@ -1033,7 +1002,7 @@ mod tests {
assert!(plan.include_only.contains(&FileId(1)));
assert!(plan.include_only.contains(&FileId(2)));

let diagnostics = source_root_diagnostics(&db, FileId(0));
let diagnostics = compilation_profile_diagnostics(&db, CompilationProfileId(0));

assert!(
diagnostics
Expand Down
25 changes: 22 additions & 3 deletions src/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod qihe;
pub mod reload;
pub mod respond;
mod response_effect;
mod semantic_compiler;
pub(crate) mod snapshot;
pub(crate) mod task;
mod trace;
Expand All @@ -20,7 +21,7 @@ use std::{sync::Arc as StdArc, time::Instant};

use crossbeam_channel::{Receiver, Sender, unbounded};
use hir::base_db::{
project::{ProjectConfig, SharedProjectConfig},
project::{CompilationProfileId, ProjectConfig, SharedProjectConfig},
salsa::Durability,
source_db::SourceDb,
source_root::SourceRootConfig,
Expand Down Expand Up @@ -48,7 +49,7 @@ use self::{
},
mem_docs::MemDocs,
snapshot::GlobalStateSnapshot,
task::{QiheTask, Task, TaskPool},
task::{QiheTask, SemanticCompilerTask, Task, TaskPool},
trace::LspTrace,
workspace_state::WorkspaceVfsReadiness,
};
Expand All @@ -72,6 +73,7 @@ pub(crate) struct GlobalState {
pub(crate) diagnostics: DiagnosticsState,
pub(crate) workspace: WorkspaceState,
pub(crate) qihe: qihe::Qihe,
pub(crate) semantic_compiler: semantic_compiler::SemanticCompiler,
pub(crate) external_sources: Vec<StdArc<dyn DiagnosticSource>>,
pub(crate) tasks: TaskState,
}
Expand Down Expand Up @@ -151,7 +153,11 @@ impl GlobalState {
let qihe_diagnostics = qihe::QiheDiagnostics::new();
let qihe = qihe::Qihe::new(qihe_diagnostics);
let qihe_source: StdArc<dyn DiagnosticSource> = StdArc::new(qihe.diagnostics_snapshot());
let external_sources = vec![qihe_source];
let semantic_diagnostics = semantic_compiler::SemanticDiagnostics::new();
let semantic_compiler = semantic_compiler::SemanticCompiler::new(semantic_diagnostics);
let semantic_source: StdArc<dyn DiagnosticSource> =
StdArc::new(semantic_compiler.diagnostics_snapshot());
let external_sources = vec![qihe_source, semantic_source];

GlobalState {
client: ClientState {
Expand Down Expand Up @@ -188,6 +194,7 @@ impl GlobalState {
registered_client_file_watcher_globs: None,
},
qihe,
semantic_compiler,
external_sources,
tasks: TaskState { task_pool },
}
Expand Down Expand Up @@ -232,6 +239,18 @@ impl GlobalState {
qihe::with_global_ctx(self, |qihe, ctx| qihe.handle(task, ctx));
}

pub(crate) fn schedule_semantic_compiler(&mut self, profile_ids: Vec<CompilationProfileId>) {
semantic_compiler::with_global_ctx(self, |semantic_compiler, ctx| {
semantic_compiler.schedule(profile_ids, ctx)
});
}

pub(crate) fn handle_semantic_compiler_task(&mut self, task: SemanticCompilerTask) {
semantic_compiler::with_global_ctx(self, |semantic_compiler, ctx| {
semantic_compiler.handle(task, ctx)
});
}

pub(crate) fn cancel_work_done_progress(
&mut self,
params: lsp_types::WorkDoneProgressCancelParams,
Expand Down
17 changes: 16 additions & 1 deletion src/global_state/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,26 @@ impl DiagnosticCommitFreshness {
}

pub(crate) trait DiagnosticSource: Send + Sync {
/// Domain diagnostics consumed by IDE features before protocol conversion.
fn diagnostics(
&self,
file_id: FileId,
freshness: &DiagnosticCommitFreshness,
) -> Vec<lsp_types::Diagnostic>;
) -> Vec<ide::diagnostics::Diagnostic> {
let _ = (file_id, freshness);
Vec::new()
}

/// Protocol-native diagnostics for sources that are produced outside the
/// IDE model.
fn lsp_diagnostics(
&self,
file_id: FileId,
freshness: &DiagnosticCommitFreshness,
) -> Vec<lsp_types::Diagnostic> {
let _ = (file_id, freshness);
Vec::new()
}

fn external_revision(
&self,
Expand Down
1 change: 1 addition & 0 deletions src/global_state/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ impl GlobalState {
}
Task::Diagnostics(diags) => self.publish_diagnostics_tasks(diags),
Task::Qihe(task) => self.handle_qihe_task(task),
Task::SemanticCompiler(task) => self.handle_semantic_compiler_task(task),
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/global_state/handlers/request/code_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ fn server_diagnostics_for_code_action(
client_diagnostics: &[lsp_types::Diagnostic],
line_info: &utils::lines::LineInfo,
) -> anyhow::Result<Vec<ide_diagnostics::Diagnostic>> {
let server_diagnostics = snap.diagnostics(file_id)?;
let mut server_diagnostics = snap.diagnostics(file_id)?;
server_diagnostics.extend(snap.external_diagnostics(file_id));
let client_locators = client_diagnostics
.iter()
.filter_map(|diag| DiagnosticLocator::from_lsp(line_info, diag))
Expand Down
5 changes: 1 addition & 4 deletions src/global_state/handlers/request/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ pub(crate) fn handle_workspace_diagnostic(
.into_iter()
.map(|diag| to_proto::diagnostic(snap.config.i18n, &line_info, diag))
.collect::<Vec<_>>();
let freshness = snap.diagnostic_commit_freshness();
diag_items.extend(
snap.external_sources.iter().flat_map(|source| source.diagnostics(file_id, &freshness)),
);
diag_items.extend(snap.external_lsp_diagnostics(file_id)?);

for target in targets {
let uri = target.uri().clone();
Expand Down
40 changes: 39 additions & 1 deletion src/global_state/process_changes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::hash_map::Entry::{Occupied, Vacant};

use hir::base_db::change::Change;
use hir::base_db::{change::Change, project::CompilationProfileId};
use itertools::Itertools;
use lsp_types::request::WorkspaceDiagnosticRefresh;
use nohash_hasher::IntMap;
Expand Down Expand Up @@ -169,6 +169,9 @@ impl GlobalState {
return;
}

let semantic_profile_ids = self.semantic_compiler_profiles_for_invalidation(&invalidation);
self.schedule_semantic_compiler(semantic_profile_ids);

if self.config_state.config.cli_pull_diagnostics_support()
&& self.config_state.config.cli_workspace_diagnostic_refresh_support()
&& match &invalidation {
Expand All @@ -191,6 +194,41 @@ impl GlobalState {
self.request_diagnostics(file_ids);
}

fn semantic_compiler_profiles_for_invalidation(
&self,
invalidation: &DiagnosticInvalidation,
) -> Vec<CompilationProfileId> {
let config = self.config_state.config.diagnostics_config();
if !config.enabled || !config.semantic.enabled {
return Vec::new();
}

let snapshot = self.make_snapshot();
let profile_ids = match snapshot.compilation_profile_ids() {
Ok(profile_ids) => profile_ids,
Err(error) => {
tracing::debug!("skipping semantic compiler profile discovery: {error:#}");
return Vec::new();
}
};

match invalidation {
DiagnosticInvalidation::WorkspaceChanged => profile_ids,
DiagnosticInvalidation::FileChanges(changed_file_ids) => profile_ids
.into_iter()
.filter(|profile_id| {
snapshot.analysis.compilation_profile_file_ids(*profile_id).is_ok_and(
|profile_file_ids| {
profile_file_ids
.iter()
.any(|file_id| changed_file_ids.contains(file_id))
},
)
})
.collect(),
}
}

fn clear_deleted_push_diagnostics(&mut self, deleted_files: &[(FileId, VfsPath)]) {
if deleted_files.is_empty() || self.config_state.config.cli_pull_diagnostics_support() {
return;
Expand Down
3 changes: 2 additions & 1 deletion src/global_state/qihe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl QiheDiagnostics {
}

impl DiagnosticSource for QiheDiagnostics {
fn diagnostics(
fn lsp_diagnostics(
&self,
file_id: FileId,
freshness: &DiagnosticCommitFreshness,
Expand Down Expand Up @@ -679,6 +679,7 @@ pub(super) fn with_global_ctx<T>(
diagnostics,
workspace,
qihe,
semantic_compiler: _,
external_sources,
tasks,
} = state;
Expand Down
4 changes: 2 additions & 2 deletions src/global_state/qihe/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ fn qihe_diagnostics_are_scoped_to_diagnostic_commit_freshness() {
let diagnostics = snapshot
.external_sources
.iter()
.flat_map(|source| source.diagnostics(file_id, &freshness))
.flat_map(|source| source.lsp_diagnostics(file_id, &freshness))
.collect::<Vec<_>>();
assert_eq!(diagnostics, vec![diagnostic]);

Expand All @@ -325,7 +325,7 @@ fn qihe_diagnostics_are_scoped_to_diagnostic_commit_freshness() {
snapshot
.external_sources
.iter()
.flat_map(|source| source.diagnostics(file_id, &freshness))
.flat_map(|source| source.lsp_diagnostics(file_id, &freshness))
.collect::<Vec<_>>()
.is_empty()
);
Expand Down
Loading
Loading