mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-29 19:17:12 +00:00
Merge pull request #18991 from Veykril/push-rmqmnrymwmoz
Keep already computed inlay hint properties instead of late resolving them
This commit is contained in:
commit
a62e2f513a
11 changed files with 433 additions and 322 deletions
|
|
@ -45,7 +45,7 @@ use hir_def::{
|
||||||
body::BodyDiagnostic,
|
body::BodyDiagnostic,
|
||||||
data::{adt::VariantData, TraitFlags},
|
data::{adt::VariantData, TraitFlags},
|
||||||
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
||||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
|
hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat},
|
||||||
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
|
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
|
||||||
lang_item::LangItemTarget,
|
lang_item::LangItemTarget,
|
||||||
layout::{self, ReprOptions, TargetDataLayout},
|
layout::{self, ReprOptions, TargetDataLayout},
|
||||||
|
|
@ -2470,20 +2470,31 @@ impl Param {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
|
pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
|
||||||
let parent = match self.func {
|
match self.func {
|
||||||
Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it),
|
Callee::Def(CallableDefId::FunctionId(it)) => {
|
||||||
Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0,
|
let parent = DefWithBodyId::FunctionId(it);
|
||||||
_ => return None,
|
let body = db.body(parent);
|
||||||
};
|
if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
|
||||||
let body = db.body(parent);
|
Some(Local { parent, binding_id: self_param })
|
||||||
if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
|
} else if let Pat::Bind { id, .. } =
|
||||||
Some(Local { parent, binding_id: self_param })
|
&body[body.params[self.idx - body.self_param.is_some() as usize]]
|
||||||
} else if let Pat::Bind { id, .. } =
|
{
|
||||||
&body[body.params[self.idx - body.self_param.is_some() as usize]]
|
Some(Local { parent, binding_id: *id })
|
||||||
{
|
} else {
|
||||||
Some(Local { parent, binding_id: *id })
|
None
|
||||||
} else {
|
}
|
||||||
None
|
}
|
||||||
|
Callee::Closure(closure, _) => {
|
||||||
|
let c = db.lookup_intern_closure(closure.into());
|
||||||
|
let body = db.body(c.0);
|
||||||
|
if let Expr::Closure { args, .. } = &body[c.1] {
|
||||||
|
if let Pat::Bind { id, .. } = &body[args[self.idx]] {
|
||||||
|
return Some(Local { parent: c.0, binding_id: *id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ fn hints(
|
||||||
) {
|
) {
|
||||||
closing_brace::hints(hints, sema, config, file_id, node.clone());
|
closing_brace::hints(hints, sema, config, file_id, node.clone());
|
||||||
if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
|
if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
|
||||||
generic_param::hints(hints, sema, config, any_has_generic_args);
|
generic_param::hints(hints, famous_defs, config, any_has_generic_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
match_ast! {
|
match_ast! {
|
||||||
|
|
@ -300,22 +300,23 @@ pub struct InlayHintsConfig {
|
||||||
pub closing_brace_hints_min_lines: Option<usize>,
|
pub closing_brace_hints_min_lines: Option<usize>,
|
||||||
pub fields_to_resolve: InlayFieldsToResolve,
|
pub fields_to_resolve: InlayFieldsToResolve,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlayHintsConfig {
|
impl InlayHintsConfig {
|
||||||
fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> Lazy<TextEdit> {
|
fn lazy_text_edit(&self, finish: impl FnOnce() -> TextEdit) -> LazyProperty<TextEdit> {
|
||||||
if self.fields_to_resolve.resolve_text_edits {
|
if self.fields_to_resolve.resolve_text_edits {
|
||||||
Lazy::Lazy
|
LazyProperty::Lazy
|
||||||
} else {
|
} else {
|
||||||
let edit = finish();
|
let edit = finish();
|
||||||
never!(edit.is_empty(), "inlay hint produced an empty text edit");
|
never!(edit.is_empty(), "inlay hint produced an empty text edit");
|
||||||
Lazy::Computed(edit)
|
LazyProperty::Computed(edit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> Lazy<InlayTooltip> {
|
fn lazy_tooltip(&self, finish: impl FnOnce() -> InlayTooltip) -> LazyProperty<InlayTooltip> {
|
||||||
if self.fields_to_resolve.resolve_hint_tooltip
|
if self.fields_to_resolve.resolve_hint_tooltip
|
||||||
&& self.fields_to_resolve.resolve_label_tooltip
|
&& self.fields_to_resolve.resolve_label_tooltip
|
||||||
{
|
{
|
||||||
Lazy::Lazy
|
LazyProperty::Lazy
|
||||||
} else {
|
} else {
|
||||||
let tooltip = finish();
|
let tooltip = finish();
|
||||||
never!(
|
never!(
|
||||||
|
|
@ -326,7 +327,20 @@ impl InlayHintsConfig {
|
||||||
.is_empty(),
|
.is_empty(),
|
||||||
"inlay hint produced an empty tooltip"
|
"inlay hint produced an empty tooltip"
|
||||||
);
|
);
|
||||||
Lazy::Computed(tooltip)
|
LazyProperty::Computed(tooltip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This always reports a resolvable location, so only use this when it is very likely for a
|
||||||
|
/// location link to actually resolve but where computing `finish` would be costly.
|
||||||
|
fn lazy_location_opt(
|
||||||
|
&self,
|
||||||
|
finish: impl FnOnce() -> Option<FileRange>,
|
||||||
|
) -> Option<LazyProperty<FileRange>> {
|
||||||
|
if self.fields_to_resolve.resolve_label_location {
|
||||||
|
Some(LazyProperty::Lazy)
|
||||||
|
} else {
|
||||||
|
finish().map(LazyProperty::Computed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -441,7 +455,7 @@ pub struct InlayHint {
|
||||||
/// The actual label to show in the inlay hint.
|
/// The actual label to show in the inlay hint.
|
||||||
pub label: InlayHintLabel,
|
pub label: InlayHintLabel,
|
||||||
/// Text edit to apply when "accepting" this inlay hint.
|
/// Text edit to apply when "accepting" this inlay hint.
|
||||||
pub text_edit: Option<Lazy<TextEdit>>,
|
pub text_edit: Option<LazyProperty<TextEdit>>,
|
||||||
/// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
|
/// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
|
||||||
/// hint does not support resolving.
|
/// hint does not support resolving.
|
||||||
pub resolve_parent: Option<TextRange>,
|
pub resolve_parent: Option<TextRange>,
|
||||||
|
|
@ -449,15 +463,15 @@ pub struct InlayHint {
|
||||||
|
|
||||||
/// A type signaling that a value is either computed, or is available for computation.
|
/// A type signaling that a value is either computed, or is available for computation.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Lazy<T> {
|
pub enum LazyProperty<T> {
|
||||||
Computed(T),
|
Computed(T),
|
||||||
Lazy,
|
Lazy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Lazy<T> {
|
impl<T> LazyProperty<T> {
|
||||||
pub fn computed(self) -> Option<T> {
|
pub fn computed(self) -> Option<T> {
|
||||||
match self {
|
match self {
|
||||||
Lazy::Computed(it) => Some(it),
|
LazyProperty::Computed(it) => Some(it),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -508,8 +522,8 @@ pub struct InlayHintLabel {
|
||||||
impl InlayHintLabel {
|
impl InlayHintLabel {
|
||||||
pub fn simple(
|
pub fn simple(
|
||||||
s: impl Into<String>,
|
s: impl Into<String>,
|
||||||
tooltip: Option<Lazy<InlayTooltip>>,
|
tooltip: Option<LazyProperty<InlayTooltip>>,
|
||||||
linked_location: Option<FileRange>,
|
linked_location: Option<LazyProperty<FileRange>>,
|
||||||
) -> InlayHintLabel {
|
) -> InlayHintLabel {
|
||||||
InlayHintLabel {
|
InlayHintLabel {
|
||||||
parts: smallvec![InlayHintLabelPart { text: s.into(), linked_location, tooltip }],
|
parts: smallvec![InlayHintLabelPart { text: s.into(), linked_location, tooltip }],
|
||||||
|
|
@ -593,16 +607,16 @@ pub struct InlayHintLabelPart {
|
||||||
/// refers to (not necessarily the location itself).
|
/// refers to (not necessarily the location itself).
|
||||||
/// When setting this, no tooltip must be set on the containing hint, or VS Code will display
|
/// When setting this, no tooltip must be set on the containing hint, or VS Code will display
|
||||||
/// them both.
|
/// them both.
|
||||||
pub linked_location: Option<FileRange>,
|
pub linked_location: Option<LazyProperty<FileRange>>,
|
||||||
/// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
|
/// The tooltip to show when hovering over the inlay hint, this may invoke other actions like
|
||||||
/// hover requests to show.
|
/// hover requests to show.
|
||||||
pub tooltip: Option<Lazy<InlayTooltip>>,
|
pub tooltip: Option<LazyProperty<InlayTooltip>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::hash::Hash for InlayHintLabelPart {
|
impl std::hash::Hash for InlayHintLabelPart {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.text.hash(state);
|
self.text.hash(state);
|
||||||
self.linked_location.hash(state);
|
self.linked_location.is_some().hash(state);
|
||||||
self.tooltip.is_some().hash(state);
|
self.tooltip.is_some().hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +624,9 @@ impl std::hash::Hash for InlayHintLabelPart {
|
||||||
impl fmt::Debug for InlayHintLabelPart {
|
impl fmt::Debug for InlayHintLabelPart {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self { text, linked_location: None, tooltip: None | Some(Lazy::Lazy) } => text.fmt(f),
|
Self { text, linked_location: None, tooltip: None | Some(LazyProperty::Lazy) } => {
|
||||||
|
text.fmt(f)
|
||||||
|
}
|
||||||
Self { text, linked_location, tooltip } => f
|
Self { text, linked_location, tooltip } => f
|
||||||
.debug_struct("InlayHintLabelPart")
|
.debug_struct("InlayHintLabelPart")
|
||||||
.field("text", text)
|
.field("text", text)
|
||||||
|
|
@ -618,8 +634,10 @@ impl fmt::Debug for InlayHintLabelPart {
|
||||||
.field(
|
.field(
|
||||||
"tooltip",
|
"tooltip",
|
||||||
&tooltip.as_ref().map_or("", |it| match it {
|
&tooltip.as_ref().map_or("", |it| match it {
|
||||||
Lazy::Computed(InlayTooltip::String(it) | InlayTooltip::Markdown(it)) => it,
|
LazyProperty::Computed(
|
||||||
Lazy::Lazy => "",
|
InlayTooltip::String(it) | InlayTooltip::Markdown(it),
|
||||||
|
) => it,
|
||||||
|
LazyProperty::Lazy => "",
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.finish(),
|
.finish(),
|
||||||
|
|
@ -632,7 +650,8 @@ struct InlayHintLabelBuilder<'a> {
|
||||||
db: &'a RootDatabase,
|
db: &'a RootDatabase,
|
||||||
result: InlayHintLabel,
|
result: InlayHintLabel,
|
||||||
last_part: String,
|
last_part: String,
|
||||||
location: Option<FileRange>,
|
resolve: bool,
|
||||||
|
location: Option<LazyProperty<FileRange>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Write for InlayHintLabelBuilder<'_> {
|
impl fmt::Write for InlayHintLabelBuilder<'_> {
|
||||||
|
|
@ -645,11 +664,16 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
|
||||||
fn start_location_link(&mut self, def: ModuleDefId) {
|
fn start_location_link(&mut self, def: ModuleDefId) {
|
||||||
never!(self.location.is_some(), "location link is already started");
|
never!(self.location.is_some(), "location link is already started");
|
||||||
self.make_new_part();
|
self.make_new_part();
|
||||||
let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
|
|
||||||
let location = location.call_site();
|
self.location = Some(if self.resolve {
|
||||||
let location =
|
LazyProperty::Lazy
|
||||||
FileRange { file_id: location.file_id, range: location.focus_or_full_range() };
|
} else {
|
||||||
self.location = Some(location);
|
LazyProperty::Computed({
|
||||||
|
let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
|
||||||
|
let location = location.call_site();
|
||||||
|
FileRange { file_id: location.file_id, range: location.focus_or_full_range() }
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_location_link(&mut self) {
|
fn end_location_link(&mut self) {
|
||||||
|
|
@ -735,6 +759,7 @@ fn label_of_ty(
|
||||||
last_part: String::new(),
|
last_part: String::new(),
|
||||||
location: None,
|
location: None,
|
||||||
result: InlayHintLabel::default(),
|
result: InlayHintLabel::default(),
|
||||||
|
resolve: config.fields_to_resolve.resolve_label_location,
|
||||||
};
|
};
|
||||||
let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config, edition);
|
let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config, edition);
|
||||||
let r = label_builder.finish();
|
let r = label_builder.finish();
|
||||||
|
|
@ -783,7 +808,7 @@ fn ty_to_text_edit(
|
||||||
ty: &hir::Type,
|
ty: &hir::Type,
|
||||||
offset_to_insert: TextSize,
|
offset_to_insert: TextSize,
|
||||||
prefix: impl Into<String>,
|
prefix: impl Into<String>,
|
||||||
) -> Option<Lazy<TextEdit>> {
|
) -> Option<LazyProperty<TextEdit>> {
|
||||||
// FIXME: Limit the length and bail out on excess somehow?
|
// FIXME: Limit the length and bail out on excess somehow?
|
||||||
let rendered = sema
|
let rendered = sema
|
||||||
.scope(node_for_hint)
|
.scope(node_for_hint)
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,7 @@ pub(super) fn hints(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let linked_location =
|
let sized_trait = famous_defs.core_marker_Sized();
|
||||||
famous_defs.core_marker_Sized().and_then(|it| it.try_to_nav(sema.db)).map(|it| {
|
|
||||||
let n = it.call_site();
|
|
||||||
FileRange { file_id: n.file_id, range: n.focus_or_full_range() }
|
|
||||||
});
|
|
||||||
|
|
||||||
for param in params.type_or_const_params() {
|
for param in params.type_or_const_params() {
|
||||||
match param {
|
match param {
|
||||||
|
|
@ -48,7 +44,17 @@ pub(super) fn hints(
|
||||||
}
|
}
|
||||||
hint.parts.push(InlayHintLabelPart {
|
hint.parts.push(InlayHintLabelPart {
|
||||||
text: "Sized".to_owned(),
|
text: "Sized".to_owned(),
|
||||||
linked_location,
|
linked_location: sized_trait.and_then(|it| {
|
||||||
|
config.lazy_location_opt(|| {
|
||||||
|
it.try_to_nav(sema.db).map(|it| {
|
||||||
|
let n = it.call_site();
|
||||||
|
FileRange {
|
||||||
|
file_id: n.file_id,
|
||||||
|
range: n.focus_or_full_range(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}),
|
||||||
tooltip: None,
|
tooltip: None,
|
||||||
});
|
});
|
||||||
if has_bounds {
|
if has_bounds {
|
||||||
|
|
@ -134,12 +140,14 @@ fn foo<T>() {}
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Sized",
|
text: "Sized",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 135..140,
|
),
|
||||||
},
|
range: 135..140,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,10 @@ mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fixture,
|
fixture,
|
||||||
inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
|
inlay_hints::{
|
||||||
|
tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
|
||||||
|
LazyProperty,
|
||||||
|
},
|
||||||
InlayHintsConfig,
|
InlayHintsConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -99,7 +102,7 @@ mod tests {
|
||||||
let (analysis, file_id) = fixture::file(ra_fixture);
|
let (analysis, file_id) = fixture::file(ra_fixture);
|
||||||
let mut inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
|
let mut inlay_hints = analysis.inlay_hints(&config, file_id, None).unwrap();
|
||||||
inlay_hints.iter_mut().flat_map(|hint| &mut hint.label.parts).for_each(|hint| {
|
inlay_hints.iter_mut().flat_map(|hint| &mut hint.label.parts).for_each(|hint| {
|
||||||
if let Some(loc) = &mut hint.linked_location {
|
if let Some(LazyProperty::Computed(loc)) = &mut hint.linked_location {
|
||||||
loc.range = TextRange::empty(TextSize::from(0));
|
loc.range = TextRange::empty(TextSize::from(0));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -134,12 +137,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "B",
|
text: "B",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 63..64,
|
),
|
||||||
},
|
range: 63..64,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -151,12 +156,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "A",
|
text: "A",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 7..8,
|
),
|
||||||
},
|
range: 7..8,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -213,12 +220,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "C",
|
text: "C",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 51..52,
|
),
|
||||||
},
|
range: 51..52,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -230,12 +239,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "B",
|
text: "B",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 29..30,
|
),
|
||||||
},
|
range: 29..30,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -276,12 +287,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "C",
|
text: "C",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 51..52,
|
),
|
||||||
},
|
range: 51..52,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -293,12 +306,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "B",
|
text: "B",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 29..30,
|
),
|
||||||
},
|
range: 29..30,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -340,12 +355,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "B",
|
text: "B",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 23..24,
|
),
|
||||||
},
|
range: 23..24,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -353,12 +370,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "X",
|
text: "X",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 55..56,
|
),
|
||||||
},
|
range: 55..56,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -371,12 +390,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "A",
|
text: "A",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 7..8,
|
),
|
||||||
},
|
range: 7..8,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -384,12 +405,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "X",
|
text: "X",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 55..56,
|
),
|
||||||
},
|
range: 55..56,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -435,12 +458,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Iterator",
|
text: "Iterator",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -448,12 +473,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Item",
|
text: "Item",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -467,12 +494,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Iterator",
|
text: "Iterator",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -480,12 +509,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Item",
|
text: "Item",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -499,12 +530,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Iterator",
|
text: "Iterator",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -512,12 +545,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Item",
|
text: "Item",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
1,
|
file_id: FileId(
|
||||||
),
|
1,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -531,12 +566,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "MyIter",
|
text: "MyIter",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 0..0,
|
),
|
||||||
},
|
range: 0..0,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -577,12 +614,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Struct",
|
text: "Struct",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 7..13,
|
),
|
||||||
},
|
range: 7..13,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -594,12 +633,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Struct",
|
text: "Struct",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 7..13,
|
),
|
||||||
},
|
range: 7..13,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -611,12 +652,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "Struct",
|
text: "Struct",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 7..13,
|
),
|
||||||
},
|
range: 7..13,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
@ -628,12 +671,14 @@ fn main() {
|
||||||
InlayHintLabelPart {
|
InlayHintLabelPart {
|
||||||
text: "self",
|
text: "self",
|
||||||
linked_location: Some(
|
linked_location: Some(
|
||||||
FileRangeWrapper {
|
Computed(
|
||||||
file_id: FileId(
|
FileRangeWrapper {
|
||||||
0,
|
file_id: FileId(
|
||||||
),
|
0,
|
||||||
range: 42..46,
|
),
|
||||||
},
|
range: 42..46,
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
tooltip: "",
|
tooltip: "",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ use syntax::{
|
||||||
match_ast, SyntaxKind, SyntaxNode, T,
|
match_ast, SyntaxKind, SyntaxNode, T,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind};
|
use crate::{
|
||||||
|
inlay_hints::LazyProperty, InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig,
|
||||||
|
InlayKind,
|
||||||
|
};
|
||||||
|
|
||||||
pub(super) fn hints(
|
pub(super) fn hints(
|
||||||
acc: &mut Vec<InlayHint>,
|
acc: &mut Vec<InlayHint>,
|
||||||
|
|
@ -141,7 +144,7 @@ pub(super) fn hints(
|
||||||
acc.push(InlayHint {
|
acc.push(InlayHint {
|
||||||
range: closing_token.text_range(),
|
range: closing_token.text_range(),
|
||||||
kind: InlayKind::ClosingBrace,
|
kind: InlayKind::ClosingBrace,
|
||||||
label: InlayHintLabel::simple(label, None, linked_location),
|
label: InlayHintLabel::simple(label, None, linked_location.map(LazyProperty::Computed)),
|
||||||
text_edit: None,
|
text_edit: None,
|
||||||
position: InlayHintPosition::After,
|
position: InlayHintPosition::After,
|
||||||
pad_left: true,
|
pad_left: true,
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,6 @@ pub(super) fn hints(
|
||||||
let last = captures.len() - 1;
|
let last = captures.len() - 1;
|
||||||
for (idx, capture) in captures.into_iter().enumerate() {
|
for (idx, capture) in captures.into_iter().enumerate() {
|
||||||
let local = capture.local();
|
let local = capture.local();
|
||||||
let source = local.primary_source(sema.db);
|
|
||||||
|
|
||||||
// force cache the source file, otherwise sema lookup will potentially panic
|
|
||||||
_ = sema.parse_or_expand(source.file());
|
|
||||||
|
|
||||||
let label = format!(
|
let label = format!(
|
||||||
"{}{}",
|
"{}{}",
|
||||||
|
|
@ -73,8 +69,17 @@ pub(super) fn hints(
|
||||||
}
|
}
|
||||||
hint.label.append_part(InlayHintLabelPart {
|
hint.label.append_part(InlayHintLabelPart {
|
||||||
text: label,
|
text: label,
|
||||||
linked_location: source.name().and_then(|name| {
|
linked_location: config.lazy_location_opt(|| {
|
||||||
name.syntax().original_file_range_opt(sema.db).map(TupleExt::head).map(Into::into)
|
let source = local.primary_source(sema.db);
|
||||||
|
|
||||||
|
// force cache the source file, otherwise sema lookup will potentially panic
|
||||||
|
_ = sema.parse_or_expand(source.file());
|
||||||
|
source.name().and_then(|name| {
|
||||||
|
name.syntax()
|
||||||
|
.original_file_range_opt(sema.db)
|
||||||
|
.map(TupleExt::head)
|
||||||
|
.map(Into::into)
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
tooltip: None,
|
tooltip: None,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
//! Implementation of inlay hints for generic parameters.
|
//! Implementation of inlay hints for generic parameters.
|
||||||
use ide_db::{active_parameter::generic_def_for_node, RootDatabase};
|
use ide_db::{active_parameter::generic_def_for_node, famous_defs::FamousDefs};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName},
|
ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName},
|
||||||
AstNode,
|
AstNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{inlay_hints::GenericParameterHints, InlayHint, InlayHintsConfig, InlayKind};
|
use crate::{
|
||||||
|
inlay_hints::GenericParameterHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
|
||||||
|
};
|
||||||
|
|
||||||
use super::param_name::{is_argument_similar_to_param_name, render_label};
|
use super::param_name::is_argument_similar_to_param_name;
|
||||||
|
|
||||||
pub(crate) fn hints(
|
pub(crate) fn hints(
|
||||||
acc: &mut Vec<InlayHint>,
|
acc: &mut Vec<InlayHint>,
|
||||||
sema: &hir::Semantics<'_, RootDatabase>,
|
FamousDefs(sema, krate): &FamousDefs<'_, '_>,
|
||||||
config: &InlayHintsConfig,
|
config: &InlayHintsConfig,
|
||||||
node: AnyHasGenericArgs,
|
node: AnyHasGenericArgs,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
|
|
@ -45,12 +47,23 @@ pub(crate) fn hints(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = param.name(sema.db);
|
let allowed = match (param, &arg) {
|
||||||
let param_name = name.as_str();
|
(hir::GenericParam::TypeParam(_), ast::GenericArg::TypeArg(_)) => type_hints,
|
||||||
|
(hir::GenericParam::ConstParam(_), ast::GenericArg::ConstArg(_)) => const_hints,
|
||||||
|
(hir::GenericParam::LifetimeParam(_), ast::GenericArg::LifetimeArg(_)) => {
|
||||||
|
lifetime_hints
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if !allowed {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let param_name = param.name(sema.db);
|
||||||
|
|
||||||
let should_hide = {
|
let should_hide = {
|
||||||
let argument = get_string_representation(&arg)?;
|
let argument = get_string_representation(&arg)?;
|
||||||
is_argument_similar_to_param_name(&argument, param_name)
|
is_argument_similar_to_param_name(&argument, param_name.as_str())
|
||||||
};
|
};
|
||||||
|
|
||||||
if should_hide {
|
if should_hide {
|
||||||
|
|
@ -59,30 +72,28 @@ pub(crate) fn hints(
|
||||||
|
|
||||||
let range = sema.original_range_opt(arg.syntax())?.range;
|
let range = sema.original_range_opt(arg.syntax())?.range;
|
||||||
|
|
||||||
let source_syntax = match param {
|
let colon = if config.render_colons { ":" } else { "" };
|
||||||
hir::GenericParam::TypeParam(it) => {
|
let label = InlayHintLabel::simple(
|
||||||
if !type_hints || !matches!(arg, ast::GenericArg::TypeArg(_)) {
|
format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
|
||||||
return None;
|
None,
|
||||||
}
|
config.lazy_location_opt(|| {
|
||||||
sema.source(it.merge())?.value.syntax().clone()
|
let source_syntax = match param {
|
||||||
}
|
hir::GenericParam::TypeParam(it) => {
|
||||||
hir::GenericParam::ConstParam(it) => {
|
sema.source(it.merge()).map(|it| it.value.syntax().clone())
|
||||||
if !const_hints || !matches!(arg, ast::GenericArg::ConstArg(_)) {
|
}
|
||||||
return None;
|
hir::GenericParam::ConstParam(it) => {
|
||||||
}
|
let syntax = sema.source(it.merge())?.value.syntax().clone();
|
||||||
let syntax = sema.source(it.merge())?.value.syntax().clone();
|
let const_param = ast::ConstParam::cast(syntax)?;
|
||||||
let const_param = ast::ConstParam::cast(syntax)?;
|
const_param.name().map(|it| it.syntax().clone())
|
||||||
const_param.name()?.syntax().clone()
|
}
|
||||||
}
|
hir::GenericParam::LifetimeParam(it) => {
|
||||||
hir::GenericParam::LifetimeParam(it) => {
|
sema.source(it).map(|it| it.value.syntax().clone())
|
||||||
if !lifetime_hints || !matches!(arg, ast::GenericArg::LifetimeArg(_)) {
|
}
|
||||||
return None;
|
};
|
||||||
}
|
let linked_location = source_syntax.and_then(|it| sema.original_range_opt(&it));
|
||||||
sema.source(it)?.value.syntax().clone()
|
linked_location.map(Into::into)
|
||||||
}
|
}),
|
||||||
};
|
);
|
||||||
let linked_location = sema.original_range_opt(&source_syntax);
|
|
||||||
let label = render_label(param_name, config, linked_location);
|
|
||||||
|
|
||||||
Some(InlayHint {
|
Some(InlayHint {
|
||||||
range,
|
range,
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ pub(super) fn hints(
|
||||||
if mir.locals[place.local].ty.adt_id(ChalkTyInterner).is_none() {
|
if mir.locals[place.local].ty.adt_id(ChalkTyInterner).is_none() {
|
||||||
continue; // Arguably only ADTs have significant drop impls
|
continue; // Arguably only ADTs have significant drop impls
|
||||||
}
|
}
|
||||||
let Some(binding) = local_to_binding.get(place.local) else {
|
let Some(&binding_idx) = local_to_binding.get(place.local) else {
|
||||||
continue; // Ignore temporary values
|
continue; // Ignore temporary values
|
||||||
};
|
};
|
||||||
let range = match terminator.span {
|
let range = match terminator.span {
|
||||||
|
|
@ -91,25 +91,26 @@ pub(super) fn hints(
|
||||||
},
|
},
|
||||||
MirSpan::Unknown => continue,
|
MirSpan::Unknown => continue,
|
||||||
};
|
};
|
||||||
let binding_source = source_map
|
let binding = &hir.bindings[binding_idx];
|
||||||
.patterns_for_binding(*binding)
|
|
||||||
.first()
|
|
||||||
.and_then(|d| source_map.pat_syntax(*d).ok())
|
|
||||||
.and_then(|d| {
|
|
||||||
Some(FileRange {
|
|
||||||
file_id: d.file_id.file_id()?.into(),
|
|
||||||
range: d.value.text_range(),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
let binding = &hir.bindings[*binding];
|
|
||||||
let name = binding.name.display_no_db(file_id.edition()).to_smolstr();
|
let name = binding.name.display_no_db(file_id.edition()).to_smolstr();
|
||||||
if name.starts_with("<ra@") {
|
if name.starts_with("<ra@") {
|
||||||
continue; // Ignore desugared variables
|
continue; // Ignore desugared variables
|
||||||
}
|
}
|
||||||
let mut label = InlayHintLabel::simple(
|
let mut label = InlayHintLabel::simple(
|
||||||
name,
|
name,
|
||||||
Some(config.lazy_tooltip(|| crate::InlayTooltip::String("moz".into()))),
|
None,
|
||||||
binding_source,
|
config.lazy_location_opt(|| {
|
||||||
|
source_map
|
||||||
|
.patterns_for_binding(binding_idx)
|
||||||
|
.first()
|
||||||
|
.and_then(|d| source_map.pat_syntax(*d).ok())
|
||||||
|
.and_then(|d| {
|
||||||
|
Some(FileRange {
|
||||||
|
file_id: d.file_id.file_id()?.into(),
|
||||||
|
range: d.value.text_range(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
label.prepend_str("drop(");
|
label.prepend_str("drop(");
|
||||||
label.append_str(")");
|
label.append_str(")");
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
//! fn max(x: i32, y: i32) -> i32 { x + y }
|
//! fn max(x: i32, y: i32) -> i32 { x + y }
|
||||||
//! _ = max(/*x*/4, /*y*/4);
|
//! _ = max(/*x*/4, /*y*/4);
|
||||||
//! ```
|
//! ```
|
||||||
use std::fmt::Display;
|
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{Callable, Semantics};
|
use hir::{Callable, Semantics};
|
||||||
|
|
@ -20,7 +19,7 @@ use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, Inla
|
||||||
|
|
||||||
pub(super) fn hints(
|
pub(super) fn hints(
|
||||||
acc: &mut Vec<InlayHint>,
|
acc: &mut Vec<InlayHint>,
|
||||||
FamousDefs(sema, _): &FamousDefs<'_, '_>,
|
FamousDefs(sema, krate): &FamousDefs<'_, '_>,
|
||||||
config: &InlayHintsConfig,
|
config: &InlayHintsConfig,
|
||||||
_file_id: EditionedFileId,
|
_file_id: EditionedFileId,
|
||||||
expr: ast::Expr,
|
expr: ast::Expr,
|
||||||
|
|
@ -37,23 +36,29 @@ pub(super) fn hints(
|
||||||
.filter_map(|(p, arg)| {
|
.filter_map(|(p, arg)| {
|
||||||
// Only annotate hints for expressions that exist in the original file
|
// Only annotate hints for expressions that exist in the original file
|
||||||
let range = sema.original_range_opt(arg.syntax())?;
|
let range = sema.original_range_opt(arg.syntax())?;
|
||||||
let source = sema.source(p)?;
|
let param_name = p.name(sema.db)?;
|
||||||
let (param_name, name_syntax) = match source.value.as_ref() {
|
Some((p, param_name, arg, range))
|
||||||
Either::Left(pat) => (pat.name()?, pat.name()),
|
|
||||||
Either::Right(param) => match param.pat()? {
|
|
||||||
ast::Pat::IdentPat(it) => (it.name()?, it.name()),
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Some((name_syntax, param_name, arg, range))
|
|
||||||
})
|
})
|
||||||
.filter(|(_, param_name, arg, _)| {
|
.filter(|(_, param_name, arg, _)| {
|
||||||
!should_hide_param_name_hint(sema, &callable, ¶m_name.text(), arg)
|
!should_hide_param_name_hint(sema, &callable, param_name.as_str(), arg)
|
||||||
})
|
})
|
||||||
.map(|(param, param_name, _, hir::FileRange { range, .. })| {
|
.map(|(param, param_name, _, hir::FileRange { range, .. })| {
|
||||||
let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax()));
|
let colon = if config.render_colons { ":" } else { "" };
|
||||||
|
let label = InlayHintLabel::simple(
|
||||||
let label = render_label(¶m_name, config, linked_location);
|
format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
|
||||||
|
None,
|
||||||
|
config.lazy_location_opt(|| {
|
||||||
|
let source = sema.source(param)?;
|
||||||
|
let name_syntax = match source.value.as_ref() {
|
||||||
|
Either::Left(pat) => pat.name(),
|
||||||
|
Either::Right(param) => match param.pat()? {
|
||||||
|
ast::Pat::IdentPat(it) => it.name(),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
}?;
|
||||||
|
sema.original_range_opt(name_syntax.syntax()).map(Into::into)
|
||||||
|
}),
|
||||||
|
);
|
||||||
InlayHint {
|
InlayHint {
|
||||||
range,
|
range,
|
||||||
kind: InlayKind::Parameter,
|
kind: InlayKind::Parameter,
|
||||||
|
|
@ -70,16 +75,6 @@ pub(super) fn hints(
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn render_label(
|
|
||||||
param_name: impl Display,
|
|
||||||
config: &InlayHintsConfig,
|
|
||||||
linked_location: Option<hir::FileRange>,
|
|
||||||
) -> InlayHintLabel {
|
|
||||||
let colon = if config.render_colons { ":" } else { "" };
|
|
||||||
|
|
||||||
InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location.map(Into::into))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_callable(
|
fn get_callable(
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
expr: &ast::Expr,
|
expr: &ast::Expr,
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,8 @@ pub use crate::{
|
||||||
inlay_hints::{
|
inlay_hints::{
|
||||||
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
|
AdjustmentHints, AdjustmentHintsMode, ClosureReturnTypeHints, DiscriminantHints,
|
||||||
GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
|
GenericParameterHints, InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart,
|
||||||
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LifetimeElisionHints,
|
InlayHintPosition, InlayHintsConfig, InlayKind, InlayTooltip, LazyProperty,
|
||||||
|
LifetimeElisionHints,
|
||||||
},
|
},
|
||||||
join_lines::JoinLinesConfig,
|
join_lines::JoinLinesConfig,
|
||||||
markup::Markup,
|
markup::Markup,
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ use ide::{
|
||||||
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve,
|
Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionFieldsToResolve,
|
||||||
CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange,
|
CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange,
|
||||||
FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel,
|
FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel,
|
||||||
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, Markup,
|
InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty,
|
||||||
NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
|
Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
|
||||||
SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
|
SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use ide_db::{assists, rust_doc::format_docs, FxHasher};
|
use ide_db::{assists, rust_doc::format_docs, FxHasher};
|
||||||
|
|
@ -549,12 +549,11 @@ pub(crate) fn inlay_hint(
|
||||||
) -> Cancellable<lsp_types::InlayHint> {
|
) -> Cancellable<lsp_types::InlayHint> {
|
||||||
let hint_needs_resolve = |hint: &InlayHint| -> Option<TextRange> {
|
let hint_needs_resolve = |hint: &InlayHint| -> Option<TextRange> {
|
||||||
hint.resolve_parent.filter(|_| {
|
hint.resolve_parent.filter(|_| {
|
||||||
hint.text_edit.is_some()
|
hint.text_edit.as_ref().is_some_and(LazyProperty::is_lazy)
|
||||||
|| hint
|
|| hint.label.parts.iter().any(|part| {
|
||||||
.label
|
part.linked_location.as_ref().is_some_and(LazyProperty::is_lazy)
|
||||||
.parts
|
|| part.tooltip.as_ref().is_some_and(LazyProperty::is_lazy)
|
||||||
.iter()
|
})
|
||||||
.any(|part| part.linked_location.is_some() || part.tooltip.is_some())
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -569,22 +568,21 @@ pub(crate) fn inlay_hint(
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut something_to_resolve = false;
|
let mut something_to_resolve = false;
|
||||||
let text_edits = if snap
|
let text_edits = inlay_hint
|
||||||
.config
|
.text_edit
|
||||||
.visual_studio_code_version()
|
.take()
|
||||||
.is_none_or(|version| VersionReq::parse(">=1.86.0").unwrap().matches(version))
|
.and_then(|it| match it {
|
||||||
&& resolve_range_and_hash.is_some()
|
LazyProperty::Computed(it) => Some(it),
|
||||||
&& fields_to_resolve.resolve_text_edits
|
LazyProperty::Lazy => {
|
||||||
{
|
something_to_resolve |=
|
||||||
something_to_resolve |= inlay_hint.text_edit.is_some();
|
snap.config.visual_studio_code_version().is_none_or(|version| {
|
||||||
None
|
VersionReq::parse(">=1.86.0").unwrap().matches(version)
|
||||||
} else {
|
}) && resolve_range_and_hash.is_some()
|
||||||
inlay_hint
|
&& fields_to_resolve.resolve_text_edits;
|
||||||
.text_edit
|
None
|
||||||
.take()
|
}
|
||||||
.and_then(|it| it.computed())
|
})
|
||||||
.map(|it| text_edit_vec(line_index, it))
|
.map(|it| text_edit_vec(line_index, it));
|
||||||
};
|
|
||||||
let (label, tooltip) = inlay_hint_label(
|
let (label, tooltip) = inlay_hint_label(
|
||||||
snap,
|
snap,
|
||||||
fields_to_resolve,
|
fields_to_resolve,
|
||||||
|
|
@ -637,22 +635,23 @@ fn inlay_hint_label(
|
||||||
let (label, tooltip) = match &*label.parts {
|
let (label, tooltip) = match &*label.parts {
|
||||||
[InlayHintLabelPart { linked_location: None, .. }] => {
|
[InlayHintLabelPart { linked_location: None, .. }] => {
|
||||||
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
|
let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap();
|
||||||
let hint_tooltip = if needs_resolve && fields_to_resolve.resolve_hint_tooltip {
|
let tooltip = tooltip.and_then(|it| match it {
|
||||||
*something_to_resolve |= tooltip.is_some();
|
LazyProperty::Computed(it) => Some(it),
|
||||||
None
|
LazyProperty::Lazy => {
|
||||||
} else {
|
*something_to_resolve |=
|
||||||
match tooltip.and_then(|it| it.computed()) {
|
needs_resolve && fields_to_resolve.resolve_hint_tooltip;
|
||||||
Some(ide::InlayTooltip::String(s)) => {
|
None
|
||||||
Some(lsp_types::InlayHintTooltip::String(s))
|
|
||||||
}
|
|
||||||
Some(ide::InlayTooltip::Markdown(s)) => {
|
|
||||||
Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
|
|
||||||
kind: lsp_types::MarkupKind::Markdown,
|
|
||||||
value: s,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
let hint_tooltip = match tooltip {
|
||||||
|
Some(ide::InlayTooltip::String(s)) => Some(lsp_types::InlayHintTooltip::String(s)),
|
||||||
|
Some(ide::InlayTooltip::Markdown(s)) => {
|
||||||
|
Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent {
|
||||||
|
kind: lsp_types::MarkupKind::Markdown,
|
||||||
|
value: s,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
};
|
};
|
||||||
(lsp_types::InlayHintLabel::String(text), hint_tooltip)
|
(lsp_types::InlayHintLabel::String(text), hint_tooltip)
|
||||||
}
|
}
|
||||||
|
|
@ -661,31 +660,38 @@ fn inlay_hint_label(
|
||||||
.parts
|
.parts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|part| {
|
.map(|part| {
|
||||||
let tooltip = if needs_resolve && fields_to_resolve.resolve_label_tooltip {
|
let tooltip = part.tooltip.and_then(|it| match it {
|
||||||
*something_to_resolve |= part.tooltip.is_some();
|
LazyProperty::Computed(it) => Some(it),
|
||||||
None
|
LazyProperty::Lazy => {
|
||||||
} else {
|
*something_to_resolve |= fields_to_resolve.resolve_label_tooltip;
|
||||||
match part.tooltip.and_then(|it| it.computed()) {
|
None
|
||||||
Some(ide::InlayTooltip::String(s)) => {
|
|
||||||
Some(lsp_types::InlayHintLabelPartTooltip::String(s))
|
|
||||||
}
|
|
||||||
Some(ide::InlayTooltip::Markdown(s)) => {
|
|
||||||
Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
|
|
||||||
lsp_types::MarkupContent {
|
|
||||||
kind: lsp_types::MarkupKind::Markdown,
|
|
||||||
value: s,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
let tooltip = match tooltip {
|
||||||
|
Some(ide::InlayTooltip::String(s)) => {
|
||||||
|
Some(lsp_types::InlayHintLabelPartTooltip::String(s))
|
||||||
|
}
|
||||||
|
Some(ide::InlayTooltip::Markdown(s)) => {
|
||||||
|
Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent(
|
||||||
|
lsp_types::MarkupContent {
|
||||||
|
kind: lsp_types::MarkupKind::Markdown,
|
||||||
|
value: s,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
};
|
};
|
||||||
let location = if needs_resolve && fields_to_resolve.resolve_label_location {
|
let location = part
|
||||||
*something_to_resolve |= part.linked_location.is_some();
|
.linked_location
|
||||||
None
|
.and_then(|it| match it {
|
||||||
} else {
|
LazyProperty::Computed(it) => Some(it),
|
||||||
part.linked_location.map(|range| location(snap, range)).transpose()?
|
LazyProperty::Lazy => {
|
||||||
};
|
*something_to_resolve |= fields_to_resolve.resolve_label_location;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|range| location(snap, range))
|
||||||
|
.transpose()?;
|
||||||
Ok(lsp_types::InlayHintLabelPart {
|
Ok(lsp_types::InlayHintLabelPart {
|
||||||
value: part.text,
|
value: part.text,
|
||||||
tooltip,
|
tooltip,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue