mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-15 22:54:00 +00:00
feat: suggest name in let_stmt and fn_param
This commit is contained in:
parent
b207e5781e
commit
492e66ceab
5 changed files with 53 additions and 2 deletions
|
@ -617,6 +617,16 @@ impl Completions {
|
||||||
}
|
}
|
||||||
self.add_opt(render_struct_pat(RenderContext::new(ctx), pattern_ctx, strukt, local_name));
|
self.add_opt(render_struct_pat(RenderContext::new(ctx), pattern_ctx, strukt, local_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn suggest_name(&mut self, ctx: &CompletionContext<'_>, name: &str) {
|
||||||
|
let item = CompletionItem::new(
|
||||||
|
CompletionItemKind::Binding,
|
||||||
|
ctx.source_range(),
|
||||||
|
SmolStr::from(name),
|
||||||
|
ctx.edition,
|
||||||
|
);
|
||||||
|
item.add_to(self, ctx.db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls the callback for each variant of the provided enum with the path to the variant.
|
/// Calls the callback for each variant of the provided enum with the path to the variant.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Completes constants and paths in unqualified patterns.
|
//! Completes constants and paths in unqualified patterns.
|
||||||
|
|
||||||
use hir::{db::DefDatabase, AssocItem, ScopeDef};
|
use hir::{db::DefDatabase, AssocItem, ScopeDef};
|
||||||
|
use ide_db::syntax_helpers::suggest_name;
|
||||||
use syntax::ast::Pat;
|
use syntax::ast::Pat;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -45,6 +46,18 @@ pub(crate) fn complete_pattern(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suggest name only in let-stmt and fn param
|
||||||
|
if pattern_ctx.should_suggest_name {
|
||||||
|
if let Some(suggested) = ctx
|
||||||
|
.expected_type
|
||||||
|
.as_ref()
|
||||||
|
.map(|ty| ty.strip_references())
|
||||||
|
.and_then(|ty| suggest_name::for_type(&ty, ctx.db, ctx.edition))
|
||||||
|
{
|
||||||
|
acc.suggest_name(ctx, &suggested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let refutable = pattern_ctx.refutability == PatternRefutability::Refutable;
|
let refutable = pattern_ctx.refutability == PatternRefutability::Refutable;
|
||||||
let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1;
|
let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1;
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,7 @@ pub(crate) struct PatternContext {
|
||||||
pub(crate) refutability: PatternRefutability,
|
pub(crate) refutability: PatternRefutability,
|
||||||
pub(crate) param_ctx: Option<ParamContext>,
|
pub(crate) param_ctx: Option<ParamContext>,
|
||||||
pub(crate) has_type_ascription: bool,
|
pub(crate) has_type_ascription: bool,
|
||||||
|
pub(crate) should_suggest_name: bool,
|
||||||
pub(crate) parent_pat: Option<ast::Pat>,
|
pub(crate) parent_pat: Option<ast::Pat>,
|
||||||
pub(crate) ref_token: Option<SyntaxToken>,
|
pub(crate) ref_token: Option<SyntaxToken>,
|
||||||
pub(crate) mut_token: Option<SyntaxToken>,
|
pub(crate) mut_token: Option<SyntaxToken>,
|
||||||
|
|
|
@ -1430,10 +1430,23 @@ fn pattern_context_for(
|
||||||
_ => (None, None),
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only suggest name in let-stmt or fn param
|
||||||
|
let should_suggest_name = matches!(
|
||||||
|
&pat,
|
||||||
|
ast::Pat::IdentPat(it)
|
||||||
|
if it.syntax()
|
||||||
|
.parent()
|
||||||
|
.map_or(false, |node| {
|
||||||
|
let kind = node.kind();
|
||||||
|
ast::LetStmt::can_cast(kind) || ast::Param::can_cast(kind)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
PatternContext {
|
PatternContext {
|
||||||
refutability,
|
refutability,
|
||||||
param_ctx,
|
param_ctx,
|
||||||
has_type_ascription,
|
has_type_ascription,
|
||||||
|
should_suggest_name,
|
||||||
parent_pat: pat.syntax().parent().and_then(ast::Pat::cast),
|
parent_pat: pat.syntax().parent().and_then(ast::Pat::cast),
|
||||||
mut_token,
|
mut_token,
|
||||||
ref_token,
|
ref_token,
|
||||||
|
|
|
@ -60,6 +60,21 @@ const USELESS_METHODS: &[&str] = &[
|
||||||
"into_future",
|
"into_future",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Suggest a name for given type.
|
||||||
|
///
|
||||||
|
/// The function will strip references first, and suggest name from the inner type.
|
||||||
|
///
|
||||||
|
/// - If `ty` is an ADT, it will suggest the name of the ADT.
|
||||||
|
/// + If `ty` is wrapped in `Box`, `Option` or `Result`, it will suggest the name from the inner type.
|
||||||
|
/// - If `ty` is a trait, it will suggest the name of the trait.
|
||||||
|
/// - If `ty` is an `impl Trait`, it will suggest the name of the first trait.
|
||||||
|
///
|
||||||
|
/// If the suggested name conflicts with reserved keywords, it will return `None`.
|
||||||
|
pub fn for_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<String> {
|
||||||
|
let ty = ty.strip_references();
|
||||||
|
name_of_type(&ty, db, edition)
|
||||||
|
}
|
||||||
|
|
||||||
/// Suggest a unique name for generic parameter.
|
/// Suggest a unique name for generic parameter.
|
||||||
///
|
///
|
||||||
/// `existing_params` is used to check if the name conflicts with existing
|
/// `existing_params` is used to check if the name conflicts with existing
|
||||||
|
@ -269,10 +284,9 @@ fn var_name_from_pat(pat: &ast::Pat) -> Option<ast::Name> {
|
||||||
|
|
||||||
fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<String> {
|
fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<String> {
|
||||||
let ty = sema.type_of_expr(expr)?.adjusted();
|
let ty = sema.type_of_expr(expr)?.adjusted();
|
||||||
let ty = ty.remove_ref().unwrap_or(ty);
|
|
||||||
let edition = sema.scope(expr.syntax())?.krate().edition(sema.db);
|
let edition = sema.scope(expr.syntax())?.krate().edition(sema.db);
|
||||||
|
|
||||||
name_of_type(&ty, sema.db, edition)
|
for_type(&ty, sema.db, edition)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<String> {
|
fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<String> {
|
||||||
|
|
Loading…
Reference in a new issue