From 34e06f2d1772a0237260caae37dedf5dc6ad716f Mon Sep 17 00:00:00 2001 From: InSync Date: Tue, 8 Apr 2025 14:05:51 +0700 Subject: [PATCH] [red-knot] Do not show types for literal expressions on hover (#17290) ## Summary Resolves #17289. After this change, Red Knot will no longer show types on hover for `None`, `...`, `True`, `False`, numbers, strings (but not f-strings), and bytes literals. ## Test Plan Unit tests. --- crates/red_knot_ide/src/hover.rs | 59 ++++++++++++++++++++++++++++- crates/ruff_python_ast/src/nodes.rs | 13 +++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/crates/red_knot_ide/src/hover.rs b/crates/red_knot_ide/src/hover.rs index 967b23d6e7..e8f5e17b6b 100644 --- a/crates/red_knot_ide/src/hover.rs +++ b/crates/red_knot_ide/src/hover.rs @@ -1,4 +1,4 @@ -use crate::goto::find_goto_target; +use crate::goto::{find_goto_target, GotoTarget}; use crate::{Db, MarkupKind, RangedValue}; use red_knot_python_semantic::types::Type; use red_knot_python_semantic::SemanticModel; @@ -12,6 +12,12 @@ pub fn hover(db: &dyn Db, file: File, offset: TextSize) -> Option + foo: str = 'bar' + "#, + ); + + assert_snapshot!(test.hover(), @"Hover provided no content"); + } + + #[test] + fn hover_literal_int() { + let test = cursor_test( + r#" + print( + 0 + 1 + ) + "#, + ); + + assert_snapshot!(test.hover(), @"Hover provided no content"); + } + + #[test] + fn hover_literal_ellipsis() { + let test = cursor_test( + r#" + print( + ... + ) + "#, + ); + + assert_snapshot!(test.hover(), @"Hover provided no content"); + } + + #[test] + fn hover_docstring() { + let test = cursor_test( + r#" + def f(): + """Lorem ipsum dolor sit amet.""" + "#, + ); + + assert_snapshot!(test.hover(), @"Hover provided no content"); + } + impl CursorTest { fn hover(&self) -> String { use std::fmt::Write; diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index 0146903c6c..fea704f613 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -102,6 +102,19 @@ impl Expr { } impl ExprRef<'_> { + /// See [`Expr::is_literal_expr`]. + pub fn is_literal_expr(&self) -> bool { + matches!( + self, + ExprRef::StringLiteral(_) + | ExprRef::BytesLiteral(_) + | ExprRef::NumberLiteral(_) + | ExprRef::BooleanLiteral(_) + | ExprRef::NoneLiteral(_) + | ExprRef::EllipsisLiteral(_) + ) + } + pub fn precedence(&self) -> OperatorPrecedence { OperatorPrecedence::from(self) }