From 14c167a9f6da07024a5101ffa04bc2f79ce64353 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 8 Dec 2019 00:54:18 +0200 Subject: Omit default parameter types --- crates/ra_hir/src/lib.rs | 5 +- crates/ra_hir_ty/src/display.rs | 21 ++++-- crates/ra_hir_ty/src/lib.rs | 33 +++++++++- crates/ra_ide/src/inlay_hints.rs | 90 ++++++++++++++++++++------ crates/ra_ide/src/lib.rs | 7 +- crates/ra_lsp_server/src/config.rs | 2 + crates/ra_lsp_server/src/main_loop.rs | 1 + crates/ra_lsp_server/src/main_loop/handlers.rs | 6 +- crates/ra_lsp_server/src/world.rs | 1 + editors/code/package.json | 5 ++ editors/code/src/config.ts | 6 ++ editors/code/src/server.ts | 2 + 12 files changed, 150 insertions(+), 29 deletions(-) diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 2e52a1f5c..e9ca548ca 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -60,4 +60,7 @@ pub use hir_def::{ pub use hir_expand::{ name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, }; -pub use hir_ty::{display::HirDisplay, CallableDef}; +pub use hir_ty::{ + display::{HirDisplay, TruncateOptions}, + CallableDef, +}; diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index 9bb3ece6c..9176c0629 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs @@ -9,7 +9,7 @@ pub struct HirFormatter<'a, 'b, DB> { fmt: &'a mut fmt::Formatter<'b>, buf: String, curr_size: usize, - max_size: Option, + truncate_options: Option<&'a TruncateOptions>, } pub trait HirDisplay { @@ -25,12 +25,12 @@ pub trait HirDisplay { fn display_truncated<'a, DB>( &'a self, db: &'a DB, - max_size: Option, + truncate_options: &'a TruncateOptions, ) -> HirDisplayWrapper<'a, DB, Self> where Self: Sized, { - HirDisplayWrapper(db, self, max_size) + HirDisplayWrapper(db, self, Some(truncate_options)) } } @@ -66,15 +66,24 @@ where } pub fn should_truncate(&self) -> bool { - if let Some(max_size) = self.max_size { + if let Some(max_size) = self.truncate_options.and_then(|options| options.max_length) { self.curr_size >= max_size } else { false } } + + pub fn should_display_default_types(&self) -> bool { + self.truncate_options.map(|options| options.show_default_types).unwrap_or(true) + } +} + +pub struct TruncateOptions { + pub max_length: Option, + pub show_default_types: bool, } -pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option); +pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T, Option<&'a TruncateOptions>); impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T> where @@ -87,7 +96,7 @@ where fmt: f, buf: String::with_capacity(20), curr_size: 0, - max_size: self.2, + truncate_options: self.2, }) } } diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 3ad913e55..7ca9e6b8a 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -906,7 +906,38 @@ impl HirDisplay for ApplicationTy { write!(f, "{}", name)?; if self.parameters.len() > 0 { write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; + + let mut non_default_parameters = Vec::with_capacity(self.parameters.len()); + let parameters_to_write = if f.should_display_default_types() { + self.parameters.0.as_ref() + } else { + match self + .ctor + .as_generic_def() + .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) + .filter(|defaults| !defaults.is_empty()) + { + Option::None => self.parameters.0.as_ref(), + Option::Some(default_parameters) => { + for (i, parameter) in self.parameters.into_iter().enumerate() { + match (parameter, default_parameters.get(i)) { + (&Ty::Unknown, _) | (_, None) => { + non_default_parameters.push(parameter.clone()) + } + (_, Some(default_parameter)) + if parameter != default_parameter => + { + non_default_parameters.push(parameter.clone()) + } + _ => (), + } + } + &non_default_parameters + } + } + }; + + f.write_joined(parameters_to_write, ", ")?; write!(f, ">")?; } } diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 3730121af..8674912a6 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs @@ -1,7 +1,7 @@ //! FIXME: write short doc here use crate::{db::RootDatabase, FileId}; -use hir::{HirDisplay, SourceAnalyzer}; +use hir::{HirDisplay, SourceAnalyzer, TruncateOptions}; use ra_syntax::{ ast::{self, AstNode, TypeAscriptionOwner}, match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, @@ -23,11 +23,11 @@ pub(crate) fn inlay_hints( db: &RootDatabase, file_id: FileId, file: &SourceFile, - max_inlay_hint_length: Option, + truncate_options: &TruncateOptions, ) -> Vec { file.syntax() .descendants() - .map(|node| get_inlay_hints(db, file_id, &node, max_inlay_hint_length).unwrap_or_default()) + .map(|node| get_inlay_hints(db, file_id, &node, truncate_options).unwrap_or_default()) .flatten() .collect() } @@ -36,7 +36,7 @@ fn get_inlay_hints( db: &RootDatabase, file_id: FileId, node: &SyntaxNode, - max_inlay_hint_length: Option, + truncate_options: &TruncateOptions, ) -> Option> { let analyzer = SourceAnalyzer::new(db, hir::InFile::new(file_id.into(), node), None); match_ast! { @@ -46,7 +46,7 @@ fn get_inlay_hints( return None; } let pat = it.pat()?; - Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) + Some(get_pat_type_hints(db, &analyzer, pat, false, truncate_options)) }, ast::LambdaExpr(it) => { it.param_list().map(|param_list| { @@ -54,22 +54,22 @@ fn get_inlay_hints( .params() .filter(|closure_param| closure_param.ascribed_type().is_none()) .filter_map(|closure_param| closure_param.pat()) - .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false, max_inlay_hint_length)) + .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false, truncate_options)) .flatten() .collect() }) }, ast::ForExpr(it) => { let pat = it.pat()?; - Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) + Some(get_pat_type_hints(db, &analyzer, pat, false, truncate_options)) }, ast::IfExpr(it) => { let pat = it.condition()?.pat()?; - Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) + Some(get_pat_type_hints(db, &analyzer, pat, true, truncate_options)) }, ast::WhileExpr(it) => { let pat = it.condition()?.pat()?; - Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) + Some(get_pat_type_hints(db, &analyzer, pat, true, truncate_options)) }, ast::MatchArmList(it) => { Some( @@ -77,7 +77,7 @@ fn get_inlay_hints( .arms() .map(|match_arm| match_arm.pats()) .flatten() - .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true, max_inlay_hint_length)) + .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true, truncate_options)) .flatten() .collect(), ) @@ -92,7 +92,7 @@ fn get_pat_type_hints( analyzer: &SourceAnalyzer, root_pat: ast::Pat, skip_root_pat_hint: bool, - max_inlay_hint_length: Option, + truncate_options: &TruncateOptions, ) -> Vec { let original_pat = &root_pat.clone(); @@ -109,7 +109,7 @@ fn get_pat_type_hints( .map(|(range, pat_type)| InlayHint { range, kind: InlayKind::TypeHint, - label: pat_type.display_truncated(db, max_inlay_hint_length).to_string().into(), + label: pat_type.display_truncated(db, truncate_options).to_string().into(), }) .collect() } @@ -159,6 +159,58 @@ mod tests { use crate::mock_analysis::single_file; + #[test] + fn default_generic_types_disabled() { + let (analysis, file_id) = single_file( + r#" +struct Test { +k: K, + t: T, +} + +fn main() { + let zz = Test { t: 23, k: 33 }; +}"#, + ); + + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, false).unwrap(), @r###" + [ + InlayHint { + range: [65; 67), + kind: TypeHint, + label: "Test", + }, + ] + "### + ); + } + + #[test] + fn default_generic_types_enabled() { + let (analysis, file_id) = single_file( + r#" +struct Test { + k: K, + t: T, +} + +fn main() { + let zz = Test { t: 23, k: 33 }; +}"#, + ); + + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" + [ + InlayHint { + range: [69; 71), + kind: TypeHint, + label: "Test", + }, + ] + "### + ); + } + #[test] fn let_statement() { let (analysis, file_id) = single_file( @@ -199,7 +251,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [193; 197), @@ -273,7 +325,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [21; 30), @@ -302,7 +354,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [21; 30), @@ -350,7 +402,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [166; 170), @@ -413,7 +465,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [166; 170), @@ -476,7 +528,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, None, true).unwrap(), @r###" [ InlayHint { range: [311; 315), @@ -518,7 +570,7 @@ fn main() { }"#, ); - assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" + assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8), true).unwrap(), @r###" [ InlayHint { range: [74; 75), diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 779a81b2c..c3244a8dd 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -348,9 +348,14 @@ impl Analysis { &self, file_id: FileId, max_inlay_hint_length: Option, + show_default_types_in_inlay_hints: bool, ) -> Cancelable> { + let truncate_options = hir::TruncateOptions { + max_length: max_inlay_hint_length, + show_default_types: show_default_types_in_inlay_hints, + }; self.with_db(|db| { - inlay_hints::inlay_hints(db, file_id, &db.parse(file_id).tree(), max_inlay_hint_length) + inlay_hints::inlay_hints(db, file_id, &db.parse(file_id).tree(), &truncate_options) }) } diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index 67942aa41..a916c5fd6 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs @@ -31,6 +31,7 @@ pub struct ServerConfig { pub lru_capacity: Option, pub max_inlay_hint_length: Option, + pub show_default_types_in_inlay_hints: bool, /// For internal usage to make integrated tests faster. #[serde(deserialize_with = "nullable_bool_true")] @@ -51,6 +52,7 @@ impl Default for ServerConfig { use_client_watching: false, lru_capacity: None, max_inlay_hint_length: None, + show_default_types_in_inlay_hints: false, with_sysroot: true, feature_flags: FxHashMap::default(), cargo_features: Default::default(), diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 965e7c53c..01fde3b2d 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -125,6 +125,7 @@ pub fn main_loop( .and_then(|it| it.line_folding_only) .unwrap_or(false), max_inlay_hint_length: config.max_inlay_hint_length, + show_default_types_in_inlay_hints: config.show_default_types_in_inlay_hints, } }; diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5b64b27cd..9069d1f1d 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -895,7 +895,11 @@ pub fn handle_inlay_hints( let analysis = world.analysis(); let line_index = analysis.file_line_index(file_id)?; Ok(analysis - .inlay_hints(file_id, world.options.max_inlay_hint_length)? + .inlay_hints( + file_id, + world.options.max_inlay_hint_length, + world.options.show_default_types_in_inlay_hints, + )? .into_iter() .map(|api_type| InlayHint { label: api_type.label.to_string(), diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 16cc11e8c..0b6eefcbc 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -31,6 +31,7 @@ pub struct Options { pub supports_location_link: bool, pub line_folding_only: bool, pub max_inlay_hint_length: Option, + pub show_default_types_in_inlay_hints: bool, } /// `WorldState` is the primary mutable state of the language server diff --git a/editors/code/package.json b/editors/code/package.json index f2e8e647e..bda0002b7 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -285,6 +285,11 @@ "default": 20, "description": "Maximum length for inlay hints" }, + "rust-analyzer.showDefaultTypesInInlayHints": { + "type": "boolean", + "default": false, + "description": "Display default types in inlay hints" + }, "rust-analyzer.cargoFeatures.noDefaultFeatures": { "type": "boolean", "default": false, diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index e131f09df..26bf30e7f 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -30,6 +30,7 @@ export class Config { public lruCapacity: null | number = null; public displayInlayHints = true; public maxInlayHintLength: null | number = null; + public showDefaultTypesInInlayHints = false; public excludeGlobs = []; public useClientWatching = true; public featureFlags = {}; @@ -153,6 +154,11 @@ export class Config { 'maxInlayHintLength', ) as number; } + if (config.has('showDefaultTypesInInlayHints')) { + this.showDefaultTypesInInlayHints = config.get( + 'showDefaultTypesInInlayHints', + ) as boolean; + } if (config.has('excludeGlobs')) { this.excludeGlobs = config.get('excludeGlobs') || []; } diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts index 5ace1d0fa..e7d1df943 100644 --- a/editors/code/src/server.ts +++ b/editors/code/src/server.ts @@ -55,6 +55,8 @@ export class Server { publishDecorations: true, lruCapacity: Server.config.lruCapacity, maxInlayHintLength: Server.config.maxInlayHintLength, + showDefaultTypesInInlayHints: + Server.config.showDefaultTypesInInlayHints, excludeGlobs: Server.config.excludeGlobs, useClientWatching: Server.config.useClientWatching, featureFlags: Server.config.featureFlags, -- cgit v1.2.3