Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints.rs')
| -rw-r--r-- | crates/ide/src/inlay_hints.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 42009ea649..7a8edfea83 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -14,7 +14,7 @@ use smallvec::{smallvec, SmallVec}; use stdx::never; use syntax::{ ast::{self, AstNode}, - match_ast, NodeOrToken, SyntaxNode, TextRange, + match_ast, NodeOrToken, SyntaxNode, TextRange, TextSize, }; use text_edit::TextEdit; @@ -359,6 +359,23 @@ fn label_of_ty( Some(r) } +fn ty_to_text_edit( + sema: &Semantics<'_, RootDatabase>, + node_for_hint: &SyntaxNode, + ty: &hir::Type, + offset_to_insert: TextSize, + prefix: String, +) -> Option<TextEdit> { + let scope = sema.scope(node_for_hint)?; + // FIXME: Limit the length and bail out on excess somehow? + let rendered = ty.display_source_code(scope.db, scope.module().into(), false).ok()?; + + let mut builder = TextEdit::builder(); + builder.insert(offset_to_insert, prefix); + builder.insert(offset_to_insert, rendered); + Some(builder.finish()) +} + // Feature: Inlay Hints // // rust-analyzer shows additional information inline with the source code. @@ -566,6 +583,37 @@ mod tests { expect.assert_debug_eq(&inlay_hints) } + /// Computes inlay hints for the fixture, applies all the provided text edits and then runs + /// expect test. + #[track_caller] + pub(super) fn check_edit(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { + let (analysis, file_id) = fixture::file(ra_fixture); + let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap(); + + let edits = inlay_hints + .into_iter() + .filter_map(|hint| hint.text_edit) + .reduce(|mut acc, next| { + acc.union(next).expect("merging text edits failed"); + acc + }) + .expect("no edit returned"); + + let mut actual = analysis.file_text(file_id).unwrap().to_string(); + edits.apply(&mut actual); + expect.assert_eq(&actual); + } + + #[track_caller] + pub(super) fn check_no_edit(config: InlayHintsConfig, ra_fixture: &str) { + let (analysis, file_id) = fixture::file(ra_fixture); + let inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap(); + + let edits: Vec<_> = inlay_hints.into_iter().filter_map(|hint| hint.text_edit).collect(); + + assert!(edits.is_empty(), "unexpected edits: {edits:?}"); + } + #[test] fn hints_disabled() { check_with_config( |