From 6feb52c12accbf0ef54475cf66a03e035b922749 Mon Sep 17 00:00:00 2001 From: Mikhail Rakhmanov Date: Sat, 13 Jun 2020 00:55:21 +0200 Subject: Add more patterns, tests and fix keywords --- crates/ra_ide/src/completion/complete_keyword.rs | 690 +++++++-------------- crates/ra_ide/src/completion/completion_context.rs | 19 +- crates/ra_ide/src/completion/patterns.rs | 61 +- 3 files changed, 297 insertions(+), 473 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index 432793de2..79432113c 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs @@ -60,32 +60,104 @@ fn add_keyword( } pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { + let has_trait_or_impl_parent = ctx.has_impl_parent || ctx.has_trait_parent; + if ctx.trait_as_prev_sibling || ctx.impl_as_prev_sibling { + add_keyword(ctx, acc, "where", "where ", true); + return; + } + if ctx.unsafe_is_prev { + add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent); + add_keyword( + ctx, + acc, + "trait", + "trait $0 {}", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword( + ctx, + acc, + "impl", + "impl $0 {}", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + return; + } add_keyword(ctx, acc, "fn", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent); - add_keyword(ctx, acc, "use", "fn $0() {}", ctx.is_new_item || ctx.block_expr_parent); - add_keyword(ctx, acc, "impl", "impl $0 {}", ctx.is_new_item); - add_keyword(ctx, acc, "trait", "impl $0 {}", ctx.is_new_item); - add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev); - add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev); - add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !ctx.unsafe_is_prev); - add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent); - add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent); + add_keyword( + ctx, + acc, + "use", + "use ", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword( + ctx, + acc, + "impl", + "impl $0 {}", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword( + ctx, + acc, + "trait", + "trait $0 {}", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword(ctx, acc, "enum", "enum $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); + add_keyword(ctx, acc, "struct", "struct $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); + add_keyword(ctx, acc, "union", "union $0 {}", ctx.is_new_item && !has_trait_or_impl_parent); + add_keyword(ctx, acc, "match", "match $0 {}", ctx.block_expr_parent || ctx.is_match_arm); + add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent || ctx.is_match_arm); add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent); add_keyword(ctx, acc, "let", "let ", ctx.if_is_prev || ctx.block_expr_parent); + add_keyword(ctx, acc, "if", "if ", ctx.if_is_prev || ctx.block_expr_parent || ctx.is_match_arm); + add_keyword( + ctx, + acc, + "if let", + "if let ", + ctx.if_is_prev || ctx.block_expr_parent || ctx.is_match_arm, + ); add_keyword(ctx, acc, "else", "else {$0}", ctx.after_if); add_keyword(ctx, acc, "else if", "else if $0 {}", ctx.after_if); - add_keyword(ctx, acc, "mod", "mod $0 {}", ctx.is_new_item || ctx.block_expr_parent); + add_keyword( + ctx, + acc, + "mod", + "mod $0 {}", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); add_keyword(ctx, acc, "mut", "mut ", ctx.bind_pat_parent || ctx.ref_pat_parent); add_keyword(ctx, acc, "const", "const ", ctx.is_new_item || ctx.block_expr_parent); add_keyword(ctx, acc, "type", "type ", ctx.is_new_item || ctx.block_expr_parent); - add_keyword(ctx, acc, "static", "static ", ctx.is_new_item || ctx.block_expr_parent); - add_keyword(ctx, acc, "extern", "extern ", ctx.is_new_item || ctx.block_expr_parent); - add_keyword(ctx, acc, "unsafe", "unsafe ", ctx.is_new_item || ctx.block_expr_parent); + add_keyword( + ctx, + acc, + "static", + "static ", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword( + ctx, + acc, + "extern", + "extern ", + (ctx.is_new_item && !has_trait_or_impl_parent) || ctx.block_expr_parent, + ); + add_keyword( + ctx, + acc, + "unsafe", + "unsafe ", + ctx.is_new_item || ctx.block_expr_parent || ctx.is_match_arm, + ); add_keyword(ctx, acc, "continue", "continue;", ctx.in_loop_body && ctx.can_be_stmt); add_keyword(ctx, acc, "break", "break;", ctx.in_loop_body && ctx.can_be_stmt); add_keyword(ctx, acc, "continue", "continue", ctx.in_loop_body && !ctx.can_be_stmt); add_keyword(ctx, acc, "break", "break", ctx.in_loop_body && !ctx.can_be_stmt); - add_keyword(ctx, acc, "pub", "pub ", ctx.is_new_item && !ctx.inside_trait); - add_keyword(ctx, acc, "where", "where ", ctx.trait_as_prev_sibling || ctx.impl_as_prev_sibling); + add_keyword(ctx, acc, "pub", "pub ", ctx.is_new_item && !ctx.has_trait_parent); let fn_def = match &ctx.function_syntax { Some(it) => it, @@ -111,21 +183,17 @@ fn complete_return( #[cfg(test)] mod tests { use crate::completion::{ - test_utils::{do_completion, get_completions}, - CompletionItem, CompletionKind, + test_utils::get_completions, + CompletionKind, }; use insta::assert_debug_snapshot; - fn do_keyword_completion(code: &str) -> Vec { - do_completion(code, CompletionKind::Keyword) - } - fn get_keyword_completions(code: &str) -> Vec { get_completions(code, CompletionKind::Keyword) } #[test] - fn completes_keywords_in_use_stmt() { + fn test_keywords_in_use_stmt() { assert_debug_snapshot!( get_keyword_completions(r"use <|>"), @r###" @@ -159,7 +227,7 @@ mod tests { } #[test] - fn completes_various_keywords_in_function() { + fn test_keywords_in_function() { assert_debug_snapshot!( get_keyword_completions(r"fn quux() { <|> }"), @r###" @@ -167,12 +235,16 @@ mod tests { "kw const", "kw extern", "kw fn", + "kw if", + "kw if let", + "kw impl", "kw let", "kw loop", "kw match", "kw mod", "kw return", "kw static", + "kw trait", "kw type", "kw unsafe", "kw use", @@ -183,9 +255,37 @@ mod tests { } #[test] - fn completes_else_after_if() { + fn test_keywords_inside_block() { assert_debug_snapshot!( - do_keyword_completion( + get_keyword_completions(r"fn quux() { if true { <|> } }"), + @r###" + [ + "kw const", + "kw extern", + "kw fn", + "kw if", + "kw if let", + "kw impl", + "kw let", + "kw loop", + "kw match", + "kw mod", + "kw return", + "kw static", + "kw trait", + "kw type", + "kw unsafe", + "kw use", + "kw while", + ] + "### + ); + } + + #[test] + fn test_keywords_after_if() { + assert_debug_snapshot!( + get_keyword_completions( r" fn quux() { if true { @@ -196,505 +296,189 @@ mod tests { ), @r###" [ - CompletionItem { - label: "else", - source_range: 108..108, - delete: 108..108, - insert: "else {$0}", - kind: Keyword, - }, - CompletionItem { - label: "else if", - source_range: 108..108, - delete: 108..108, - insert: "else if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "if", - source_range: 108..108, - delete: 108..108, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 108..108, - delete: 108..108, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 108..108, - delete: 108..108, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 108..108, - delete: 108..108, - insert: "return;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 108..108, - delete: 108..108, - insert: "while $0 {}", - kind: Keyword, - }, + "kw const", + "kw else", + "kw else if", + "kw extern", + "kw fn", + "kw if", + "kw if let", + "kw impl", + "kw let", + "kw loop", + "kw match", + "kw mod", + "kw return", + "kw static", + "kw trait", + "kw type", + "kw unsafe", + "kw use", + "kw while", ] "### ); } #[test] - fn test_completion_return_value() { + fn test_keywords_in_match_arm() { assert_debug_snapshot!( - do_keyword_completion( + get_keyword_completions( r" fn quux() -> i32 { - <|> - 92 + match () { + () => <|> + } } ", ), @r###" [ - CompletionItem { - label: "if", - source_range: 56..56, - delete: 56..56, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 56..56, - delete: 56..56, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 56..56, - delete: 56..56, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 56..56, - delete: 56..56, - insert: "return $0;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 56..56, - delete: 56..56, - insert: "while $0 {}", - kind: Keyword, - }, + "kw if", + "kw if let", + "kw loop", + "kw match", + "kw return", + "kw unsafe", ] "### ); + } + + #[test] + fn test_keywords_in_trait_def() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() { - <|> - 92 - } - ", - ), + get_keyword_completions(r"trait My { <|> }"), @r###" [ - CompletionItem { - label: "if", - source_range: 49..49, - delete: 49..49, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 49..49, - delete: 49..49, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 49..49, - delete: 49..49, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 49..49, - delete: 49..49, - insert: "return;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 49..49, - delete: 49..49, - insert: "while $0 {}", - kind: Keyword, - }, + "kw const", + "kw fn", + "kw type", + "kw unsafe", ] "### ); } #[test] - fn dont_add_semi_after_return_if_not_a_statement() { + fn test_keywords_in_impl_def() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() -> i32 { - match () { - () => <|> - } - } - ", - ), + get_keyword_completions(r"impl My { <|> }"), @r###" [ - CompletionItem { - label: "if", - source_range: 97..97, - delete: 97..97, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 97..97, - delete: 97..97, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 97..97, - delete: 97..97, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 97..97, - delete: 97..97, - insert: "return $0", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 97..97, - delete: 97..97, - insert: "while $0 {}", - kind: Keyword, - }, + "kw const", + "kw fn", + "kw pub", + "kw type", + "kw unsafe", ] "### ); } #[test] - fn last_return_in_block_has_semi() { + fn test_keywords_in_loop() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() -> i32 { - if condition { - <|> - } - } - ", - ), + get_keyword_completions(r"fn my() { loop { <|> } }"), @r###" [ - CompletionItem { - label: "if", - source_range: 95..95, - delete: 95..95, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 95..95, - delete: 95..95, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 95..95, - delete: 95..95, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 95..95, - delete: 95..95, - insert: "return $0;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 95..95, - delete: 95..95, - insert: "while $0 {}", - kind: Keyword, - }, + "kw break", + "kw const", + "kw continue", + "kw extern", + "kw fn", + "kw if", + "kw if let", + "kw impl", + "kw let", + "kw loop", + "kw match", + "kw mod", + "kw return", + "kw static", + "kw trait", + "kw type", + "kw unsafe", + "kw use", + "kw while", ] "### ); + } + + #[test] + fn test_keywords_after_unsafe_in_item_list() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() -> i32 { - if condition { - <|> - } - let x = 92; - x - } - ", - ), + get_keyword_completions(r"unsafe <|>"), @r###" [ - CompletionItem { - label: "if", - source_range: 95..95, - delete: 95..95, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 95..95, - delete: 95..95, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 95..95, - delete: 95..95, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 95..95, - delete: 95..95, - insert: "return $0;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 95..95, - delete: 95..95, - insert: "while $0 {}", - kind: Keyword, - }, + "kw fn", + "kw impl", + "kw trait", ] "### ); } #[test] - fn completes_break_and_continue_in_loops() { + fn test_keywords_after_unsafe_in_block_expr() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() -> i32 { - loop { <|> } - } - ", - ), + get_keyword_completions(r"fn my_fn() { unsafe <|> }"), @r###" [ - CompletionItem { - label: "break", - source_range: 63..63, - delete: 63..63, - insert: "break;", - kind: Keyword, - }, - CompletionItem { - label: "continue", - source_range: 63..63, - delete: 63..63, - insert: "continue;", - kind: Keyword, - }, - CompletionItem { - label: "if", - source_range: 63..63, - delete: 63..63, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 63..63, - delete: 63..63, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 63..63, - delete: 63..63, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 63..63, - delete: 63..63, - insert: "return $0;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 63..63, - delete: 63..63, - insert: "while $0 {}", - kind: Keyword, - }, + "kw fn", + "kw impl", + "kw trait", ] "### ); + } - // No completion: lambda isolates control flow + #[test] + fn test_mut_in_ref_and_in_fn_parameters_list() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn quux() -> i32 { - loop { || { <|> } } - } - ", - ), + get_keyword_completions(r"fn my_fn(&<|>) {}"), + @r###" + [ + "kw mut", + ] + "### + ); + assert_debug_snapshot!( + get_keyword_completions(r"fn my_fn(<|>) {}"), + @r###" + [ + "kw mut", + ] + "### + ); + assert_debug_snapshot!( + get_keyword_completions(r"fn my_fn() { let &<|> }"), @r###" [ - CompletionItem { - label: "if", - source_range: 68..68, - delete: 68..68, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 68..68, - delete: 68..68, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 68..68, - delete: 68..68, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 68..68, - delete: 68..68, - insert: "return $0;", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 68..68, - delete: 68..68, - insert: "while $0 {}", - kind: Keyword, - }, + "kw mut", ] "### ); } #[test] - fn no_semi_after_break_continue_in_expr() { + fn test_where_keyword() { assert_debug_snapshot!( - do_keyword_completion( - r" - fn f() { - loop { - match () { - () => br<|> - } - } - } - ", - ), + get_keyword_completions(r"trait A <|>"), + @r###" + [ + "kw where", + ] + "### + ); + assert_debug_snapshot!( + get_keyword_completions(r"impl A <|>"), @r###" [ - CompletionItem { - label: "break", - source_range: 122..124, - delete: 122..124, - insert: "break", - kind: Keyword, - }, - CompletionItem { - label: "continue", - source_range: 122..124, - delete: 122..124, - insert: "continue", - kind: Keyword, - }, - CompletionItem { - label: "if", - source_range: 122..124, - delete: 122..124, - insert: "if $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "loop", - source_range: 122..124, - delete: 122..124, - insert: "loop {$0}", - kind: Keyword, - }, - CompletionItem { - label: "match", - source_range: 122..124, - delete: 122..124, - insert: "match $0 {}", - kind: Keyword, - }, - CompletionItem { - label: "return", - source_range: 122..124, - delete: 122..124, - insert: "return", - kind: Keyword, - }, - CompletionItem { - label: "while", - source_range: 122..124, - delete: 122..124, - insert: "while $0 {}", - kind: Keyword, - }, + "kw where", ] "### - ) + ); } } diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 41aec5686..2f96861ca 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -12,8 +12,9 @@ use ra_syntax::{ use ra_text_edit::Indel; use super::patterns::{ - has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_ref_pat_parent, - has_trait_as_prev_sibling, if_is_prev, inside_trait, is_in_loop_body, unsafe_is_prev, + has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, + has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_in_loop_body, + is_match_arm, unsafe_is_prev, }; use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition}; use test_utils::mark; @@ -70,9 +71,11 @@ pub(crate) struct CompletionContext<'a> { pub(super) bind_pat_parent: bool, pub(super) ref_pat_parent: bool, pub(super) in_loop_body: bool, - pub(super) inside_trait: bool, + pub(super) has_trait_parent: bool, + pub(super) has_impl_parent: bool, pub(super) trait_as_prev_sibling: bool, pub(super) impl_as_prev_sibling: bool, + pub(super) is_match_arm: bool, } impl<'a> CompletionContext<'a> { @@ -136,10 +139,12 @@ impl<'a> CompletionContext<'a> { ref_pat_parent: false, bind_pat_parent: false, block_expr_parent: false, - inside_trait: false, + has_trait_parent: false, + has_impl_parent: false, trait_as_prev_sibling: false, impl_as_prev_sibling: false, if_is_prev: false, + is_match_arm: false, }; let mut original_file = original_file.syntax().clone(); @@ -217,11 +222,13 @@ impl<'a> CompletionContext<'a> { self.unsafe_is_prev = unsafe_is_prev(syntax_element.clone()); self.if_is_prev = if_is_prev(syntax_element.clone()); self.bind_pat_parent = has_bind_pat_parent(syntax_element.clone()); - self.ref_pat_parent = has_ref_pat_parent(syntax_element.clone()); + self.ref_pat_parent = has_ref_parent(syntax_element.clone()); self.in_loop_body = is_in_loop_body(syntax_element.clone()); - self.inside_trait = inside_trait(syntax_element.clone()); + self.has_trait_parent = has_trait_parent(syntax_element.clone()); + self.has_impl_parent = has_impl_parent(syntax_element.clone()); self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); + self.is_match_arm = is_match_arm(syntax_element.clone()); } fn fill( diff --git a/crates/ra_ide/src/completion/patterns.rs b/crates/ra_ide/src/completion/patterns.rs index bc39689ab..bc37196d5 100644 --- a/crates/ra_ide/src/completion/patterns.rs +++ b/crates/ra_ide/src/completion/patterns.rs @@ -6,16 +6,42 @@ use ra_syntax::{ SyntaxNode, SyntaxToken, }; -pub(crate) fn inside_trait(element: SyntaxElement) -> bool { - element.ancestors().find(|it| it.kind() == TRAIT_DEF).is_some() +pub(crate) fn has_trait_parent(element: SyntaxElement) -> bool { + not_same_range_ancestor(element) + .filter(|it| it.kind() == ITEM_LIST) + .and_then(|it| it.parent()) + .filter(|it| it.kind() == TRAIT_DEF) + .is_some() +} + +pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { + not_same_range_ancestor(element) + .filter(|it| it.kind() == ITEM_LIST) + .and_then(|it| it.parent()) + .filter(|it| it.kind() == IMPL_DEF) + .is_some() +} + +pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { + not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some() } pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { element.ancestors().find(|it| it.kind() == BIND_PAT).is_some() } -pub(crate) fn has_ref_pat_parent(element: SyntaxElement) -> bool { - element.ancestors().find(|it| it.kind() == REF_PAT).is_some() +pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { + not_same_range_ancestor(element) + .filter(|it| it.kind() == REF_PAT || it.kind() == REF_EXPR) + .is_some() +} + +pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { + not_same_range_ancestor(element.clone()).filter(|it| it.kind() == MATCH_ARM).is_some() + && previous_sibling_or_ancestor_sibling(element) + .and_then(|it| it.into_token()) + .filter(|it| it.kind() == FAT_ARROW) + .is_some() } pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { @@ -34,10 +60,6 @@ pub(crate) fn if_is_prev(element: SyntaxElement) -> bool { .is_some() } -pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { - not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some() -} - pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == TRAIT_DEF).is_some() } @@ -114,8 +136,9 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option }", inside_trait); + fn test_has_trait_parent() { + check_pattern_is_applicable(r"trait A { f<|> }", has_trait_parent); + } + + #[test] + fn test_has_impl_parent() { + check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); } #[test] @@ -151,12 +179,12 @@ mod tests { #[test] fn test_has_ref_pat_parent_in_func_parameters() { - check_pattern_is_applicable(r"fn my_fn(&<|>) {}", has_ref_pat_parent); + check_pattern_is_applicable(r"fn my_fn(&m<|>) {}", has_ref_parent); } #[test] fn test_has_ref_pat_parent_in_let_statement() { - check_pattern_is_applicable(r"fn my_fn() { let &<|> }", has_ref_pat_parent); + check_pattern_is_applicable(r"fn my() { let &m<|> }", has_ref_parent); } #[test] @@ -168,4 +196,9 @@ mod tests { fn test_has_bind_pat_parent_in_let_statement() { check_pattern_is_applicable(r"fn my_fn() { let m<|> }", has_bind_pat_parent); } + + #[test] + fn test_is_match_arm() { + check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm); + } } -- cgit v1.2.3