mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 20:43:21 +00:00
Merge #9171
9171: internal: simplify r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
590472607c
5 changed files with 33 additions and 36 deletions
|
@ -5,8 +5,8 @@ use std::iter;
|
||||||
use syntax::{SyntaxKind, T};
|
use syntax::{SyntaxKind, T};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
|
context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, CompletionItem,
|
||||||
CompletionKind, Completions,
|
CompletionItemKind, CompletionKind, Completions,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
|
@ -128,8 +128,15 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
||||||
add_keyword("mut", "mut ");
|
add_keyword("mut", "mut ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.in_loop_body {
|
let (can_be_stmt, in_loop_body) = match ctx.path_context {
|
||||||
if ctx.can_be_stmt() {
|
Some(PathCompletionContext {
|
||||||
|
is_trivial_path: true, can_be_stmt, in_loop_body, ..
|
||||||
|
}) => (can_be_stmt, in_loop_body),
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
if in_loop_body {
|
||||||
|
if can_be_stmt {
|
||||||
add_keyword("continue", "continue;");
|
add_keyword("continue", "continue;");
|
||||||
add_keyword("break", "break;");
|
add_keyword("break", "break;");
|
||||||
} else {
|
} else {
|
||||||
|
@ -138,9 +145,6 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.is_trivial_path() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let fn_def = match &ctx.function_def {
|
let fn_def = match &ctx.function_def {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
|
@ -148,7 +152,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
||||||
|
|
||||||
add_keyword(
|
add_keyword(
|
||||||
"return",
|
"return",
|
||||||
match (ctx.can_be_stmt(), fn_def.ret_type().is_some()) {
|
match (can_be_stmt, fn_def.ret_type().is_some()) {
|
||||||
(true, true) => "return $0;",
|
(true, true) => "return $0;",
|
||||||
(true, false) => "return;",
|
(true, false) => "return;",
|
||||||
(false, true) => "return $0",
|
(false, true) => "return $0",
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
use ide_db::helpers::SnippetCap;
|
use ide_db::helpers::SnippetCap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
|
context::PathCompletionContext, item::Builder, CompletionContext, CompletionItem,
|
||||||
Completions,
|
CompletionItemKind, CompletionKind, Completions,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder {
|
fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder {
|
||||||
|
@ -14,15 +14,21 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if !(ctx.is_trivial_path() && ctx.function_def.is_some()) {
|
if ctx.function_def.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let can_be_stmt = match ctx.path_context {
|
||||||
|
Some(PathCompletionContext { is_trivial_path: true, can_be_stmt, .. }) => can_be_stmt,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
let cap = match ctx.config.snippet_cap {
|
let cap = match ctx.config.snippet_cap {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ctx.can_be_stmt() {
|
if can_be_stmt {
|
||||||
snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
|
snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
|
||||||
snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
|
snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,20 +34,13 @@
|
||||||
use hir::{self, HasAttrs, HasSource};
|
use hir::{self, HasAttrs, HasSource};
|
||||||
use ide_db::{traits::get_missing_assoc_items, SymbolKind};
|
use ide_db::{traits::get_missing_assoc_items, SymbolKind};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, edit, Impl},
|
ast::{self, edit},
|
||||||
display::function_declaration,
|
display::function_declaration,
|
||||||
AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T,
|
AstNode, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, T,
|
||||||
};
|
};
|
||||||
use text_edit::TextEdit;
|
use text_edit::TextEdit;
|
||||||
|
|
||||||
use crate::{
|
use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
|
||||||
CompletionContext,
|
|
||||||
CompletionItem,
|
|
||||||
CompletionItemKind,
|
|
||||||
CompletionKind,
|
|
||||||
Completions,
|
|
||||||
// display::function_declaration,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
enum ImplCompletionKind {
|
enum ImplCompletionKind {
|
||||||
|
@ -58,7 +51,7 @@ enum ImplCompletionKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if let Some((kind, trigger, impl_def)) = completion_match(ctx) {
|
if let Some((kind, trigger, impl_def)) = completion_match(ctx.token.clone()) {
|
||||||
get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item {
|
get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item {
|
||||||
hir::AssocItem::Function(fn_item)
|
hir::AssocItem::Function(fn_item)
|
||||||
if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn =>
|
if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn =>
|
||||||
|
@ -80,8 +73,7 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> {
|
fn completion_match(mut token: SyntaxToken) -> Option<(ImplCompletionKind, SyntaxNode, ast::Impl)> {
|
||||||
let mut token = ctx.token.clone();
|
|
||||||
// For keyword without name like `impl .. { fn $0 }`, the current position is inside
|
// For keyword without name like `impl .. { fn $0 }`, the current position is inside
|
||||||
// the whitespace token, which is outside `FN` syntax node.
|
// the whitespace token, which is outside `FN` syntax node.
|
||||||
// We need to follow the previous token in this case.
|
// We need to follow the previous token in this case.
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub(crate) struct PathCompletionContext {
|
||||||
pub(super) can_be_stmt: bool,
|
pub(super) can_be_stmt: bool,
|
||||||
/// `true` if we expect an expression at the cursor position.
|
/// `true` if we expect an expression at the cursor position.
|
||||||
pub(super) is_expr: bool,
|
pub(super) is_expr: bool,
|
||||||
|
pub(super) in_loop_body: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -94,7 +95,6 @@ pub(crate) struct CompletionContext<'a> {
|
||||||
pub(super) active_parameter: Option<ActiveParameter>,
|
pub(super) active_parameter: Option<ActiveParameter>,
|
||||||
pub(super) locals: Vec<(String, Local)>,
|
pub(super) locals: Vec<(String, Local)>,
|
||||||
|
|
||||||
pub(super) in_loop_body: bool,
|
|
||||||
pub(super) incomplete_let: bool,
|
pub(super) incomplete_let: bool,
|
||||||
|
|
||||||
no_completion_required: bool,
|
no_completion_required: bool,
|
||||||
|
@ -160,7 +160,6 @@ impl<'a> CompletionContext<'a> {
|
||||||
path_context: None,
|
path_context: None,
|
||||||
active_parameter: ActiveParameter::at(db, position),
|
active_parameter: ActiveParameter::at(db, position),
|
||||||
locals,
|
locals,
|
||||||
in_loop_body: false,
|
|
||||||
incomplete_let: false,
|
incomplete_let: false,
|
||||||
no_completion_required: false,
|
no_completion_required: false,
|
||||||
};
|
};
|
||||||
|
@ -324,10 +323,6 @@ impl<'a> CompletionContext<'a> {
|
||||||
self.path_context.as_ref().and_then(|it| it.path_qual.as_ref())
|
self.path_context.as_ref().and_then(|it| it.path_qual.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn can_be_stmt(&self) -> bool {
|
|
||||||
self.path_context.as_ref().map_or(false, |it| it.can_be_stmt)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_impl_def(&mut self) {
|
fn fill_impl_def(&mut self) {
|
||||||
self.impl_def = self
|
self.impl_def = self
|
||||||
.sema
|
.sema
|
||||||
|
@ -453,7 +448,6 @@ impl<'a> CompletionContext<'a> {
|
||||||
let for_is_prev2 = for_is_prev2(syntax_element.clone());
|
let for_is_prev2 = for_is_prev2(syntax_element.clone());
|
||||||
(fn_is_prev && !inside_impl_trait_block) || for_is_prev2
|
(fn_is_prev && !inside_impl_trait_block) || for_is_prev2
|
||||||
};
|
};
|
||||||
self.in_loop_body = is_in_loop_body(syntax_element.clone());
|
|
||||||
|
|
||||||
self.incomplete_let =
|
self.incomplete_let =
|
||||||
syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
|
syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
|
||||||
|
@ -584,7 +578,9 @@ impl<'a> CompletionContext<'a> {
|
||||||
is_path_type: false,
|
is_path_type: false,
|
||||||
can_be_stmt: false,
|
can_be_stmt: false,
|
||||||
is_expr: false,
|
is_expr: false,
|
||||||
|
in_loop_body: false,
|
||||||
});
|
});
|
||||||
|
path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
|
||||||
let path = segment.parent_path();
|
let path = segment.parent_path();
|
||||||
|
|
||||||
if let Some(p) = path.syntax().parent() {
|
if let Some(p) = path.syntax().parent() {
|
||||||
|
|
|
@ -272,9 +272,8 @@ fn test_for_is_prev2() {
|
||||||
check_pattern_is_applicable(r"for i i$0", for_is_prev2);
|
check_pattern_is_applicable(r"for i i$0", for_is_prev2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
|
pub(crate) fn is_in_loop_body(node: &SyntaxNode) -> bool {
|
||||||
element
|
node.ancestors()
|
||||||
.ancestors()
|
|
||||||
.take_while(|it| it.kind() != FN && it.kind() != CLOSURE_EXPR)
|
.take_while(|it| it.kind() != FN && it.kind() != CLOSURE_EXPR)
|
||||||
.find_map(|it| {
|
.find_map(|it| {
|
||||||
let loop_body = match_ast! {
|
let loop_body = match_ast! {
|
||||||
|
@ -285,7 +284,7 @@ pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loop_body.filter(|it| it.syntax().text_range().contains_range(element.text_range()))
|
loop_body.filter(|it| it.syntax().text_range().contains_range(node.text_range()))
|
||||||
})
|
})
|
||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue