diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index f883ea8d4fc..3d6cfddb3b6 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs @@ -155,6 +155,8 @@ fn default() -> Self { #[derive(Debug, Clone)] pub struct DiagnosticsConfig { + /// Whether native diagnostics are enabled. + pub enabled: bool, pub proc_macros_enabled: bool, pub proc_attr_macros_enabled: bool, pub disable_experimental: bool, @@ -171,6 +173,7 @@ pub fn test_sample() -> Self { use ide_db::imports::insert_use::ImportGranularity; Self { + enabled: true, proc_macros_enabled: Default::default(), proc_attr_macros_enabled: Default::default(), disable_experimental: Default::default(), diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index f195f78b3ab..cb2a1140ba8 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -642,7 +642,7 @@ pub fn assists_with_fixes( }; self.with_db(|db| { - let diagnostic_assists = if include_fixes { + let diagnostic_assists = if diagnostics_config.enabled && include_fixes { ide_diagnostics::diagnostics(db, diagnostics_config, &resolve, frange.file_id) .into_iter() .flat_map(|it| it.fixes.unwrap_or_default()) diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 826b89926bf..1ceda8d824e 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -15,7 +15,7 @@ hir::{ExprId, PatId}, }; use hir_ty::{Interner, Substitution, TyExt, TypeFlags}; -use ide::{LineCol, RootDatabase}; +use ide::{Analysis, AnnotationConfig, DiagnosticsConfig, InlayHintsConfig, LineCol, RootDatabase}; use ide_db::{ base_db::{ salsa::{self, debug::DebugQueryTable, ParallelDatabase}, @@ -30,7 +30,7 @@ use rayon::prelude::*; use rustc_hash::FxHashSet; use syntax::{AstNode, SyntaxNode}; -use vfs::{AbsPathBuf, Vfs, VfsPath}; +use vfs::{AbsPathBuf, FileId, Vfs, VfsPath}; use crate::cli::{ flags::{self, OutputFormat}, @@ -149,8 +149,10 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { let mut bodies = Vec::new(); let mut adts = Vec::new(); let mut consts = Vec::new(); + let mut file_ids = Vec::new(); while let Some(module) = visit_queue.pop() { if visited_modules.insert(module) { + file_ids.extend(module.as_source_file_id(db)); visit_queue.extend(module.children(db)); for decl in module.declarations(db) { @@ -224,6 +226,10 @@ pub fn run(self, verbosity: Verbosity) -> anyhow::Result<()> { self.run_const_eval(db, &consts, verbosity); } + if self.run_all_ide_things { + self.run_ide_things(host.analysis(), file_ids); + } + let total_span = analysis_sw.elapsed(); eprintln!("{:<20} {total_span}", "Total:"); report_metric("total time", total_span.time.as_millis() as u64, "ms"); @@ -729,6 +735,83 @@ fn run_body_lowering( report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms"); } + fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) { + file_ids.sort(); + file_ids.dedup(); + let mut sw = self.stop_watch(); + + for &file_id in &file_ids { + _ = analysis.diagnostics( + &DiagnosticsConfig { + enabled: true, + proc_macros_enabled: true, + proc_attr_macros_enabled: true, + disable_experimental: false, + disabled: Default::default(), + expr_fill_default: Default::default(), + insert_use: ide_db::imports::insert_use::InsertUseConfig { + granularity: ide_db::imports::insert_use::ImportGranularity::Crate, + enforce_granularity: true, + prefix_kind: hir::PrefixKind::ByCrate, + group: true, + skip_glob_imports: true, + }, + prefer_no_std: Default::default(), + }, + ide::AssistResolveStrategy::All, + file_id, + ); + } + for &file_id in &file_ids { + _ = analysis.inlay_hints( + &InlayHintsConfig { + render_colons: false, + type_hints: true, + discriminant_hints: ide::DiscriminantHints::Always, + parameter_hints: true, + chaining_hints: true, + adjustment_hints: ide::AdjustmentHints::Always, + adjustment_hints_mode: ide::AdjustmentHintsMode::Postfix, + adjustment_hints_hide_outside_unsafe: false, + closure_return_type_hints: ide::ClosureReturnTypeHints::Always, + closure_capture_hints: true, + binding_mode_hints: true, + lifetime_elision_hints: ide::LifetimeElisionHints::Always, + param_names_for_lifetime_elision_hints: true, + hide_named_constructor_hints: false, + hide_closure_initialization_hints: false, + closure_style: hir::ClosureStyle::ImplFn, + max_length: Some(25), + closing_brace_hints_min_lines: Some(20), + }, + file_id, + None, + ); + } + for &file_id in &file_ids { + analysis + .annotations( + &AnnotationConfig { + binary_target: true, + annotate_runnables: true, + annotate_impls: true, + annotate_references: false, + annotate_method_references: false, + annotate_enum_variant_references: false, + location: ide::AnnotationLocation::AboveName, + }, + file_id, + ) + .unwrap() + .into_iter() + .for_each(|annotation| { + _ = analysis.resolve_annotation(annotation); + }); + } + let ide_time = sw.elapsed(); + eprintln!("{:<20} {} ({} files)", "IDE:", ide_time, file_ids.len()); + } + fn stop_watch(&self) -> StopWatch { StopWatch::start().memory(self.memory_usage) } diff --git a/crates/rust-analyzer/src/cli/flags.rs b/crates/rust-analyzer/src/cli/flags.rs index 9848739504a..31be535fc28 100644 --- a/crates/rust-analyzer/src/cli/flags.rs +++ b/crates/rust-analyzer/src/cli/flags.rs @@ -88,6 +88,10 @@ optional --skip-data-layout /// Skip const evaluation optional --skip-const-eval + /// Runs several IDE features after analysis, including semantics highlighting, diagnostics + /// and annotations. This is useful for benchmarking the memory usage on a project that has + /// been worked on for a bit in a longer running session. + optional --run-all-ide-things } /// Run unit tests of the project using mir interpreter @@ -199,6 +203,7 @@ pub struct AnalysisStats { pub skip_mir_stats: bool, pub skip_data_layout: bool, pub skip_const_eval: bool, + pub run_all_ide_things: bool, } #[derive(Debug)] diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 6355c620f78..fa20c796ec2 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -1079,6 +1079,7 @@ pub fn publish_diagnostics(&self) -> bool { pub fn diagnostics(&self) -> DiagnosticsConfig { DiagnosticsConfig { + enabled: self.data.diagnostics_enable, proc_attr_macros_enabled: self.expand_proc_attr_macros(), proc_macros_enabled: self.data.procMacro_enable, disable_experimental: !self.data.diagnostics_experimental_enable,