mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Add few smoke tests for patterns and refactoring
This commit is contained in:
parent
f46bc12199
commit
a2b4385f16
@ -65,13 +65,13 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||||||
add_keyword(ctx, acc, "use", "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, "impl", "impl $0 {}", ctx.is_new_item);
|
||||||
add_keyword(ctx, acc, "trait", "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.after_unsafe);
|
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.after_unsafe);
|
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.after_unsafe);
|
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, "match", "match $0 {}", ctx.block_expr_parent);
|
||||||
add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent);
|
add_keyword(ctx, acc, "loop", "loop {$0}", ctx.block_expr_parent);
|
||||||
add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent);
|
add_keyword(ctx, acc, "while", "while $0 {}", ctx.block_expr_parent);
|
||||||
add_keyword(ctx, acc, "let", "let ", ctx.after_if || ctx.block_expr_parent);
|
add_keyword(ctx, acc, "let", "let ", ctx.if_is_prev || ctx.block_expr_parent);
|
||||||
add_keyword(ctx, acc, "else", "else {$0}", ctx.after_if);
|
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, "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 || ctx.block_expr_parent);
|
||||||
|
@ -12,8 +12,8 @@ use ra_syntax::{
|
|||||||
use ra_text_edit::Indel;
|
use ra_text_edit::Indel;
|
||||||
|
|
||||||
use super::patterns::{
|
use super::patterns::{
|
||||||
goes_after_unsafe, has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling,
|
has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_ref_pat_parent,
|
||||||
has_ref_pat_parent, has_trait_as_prev_sibling, inside_trait, is_in_loop_body,
|
has_trait_as_prev_sibling, if_is_prev, inside_trait, is_in_loop_body, unsafe_is_prev,
|
||||||
};
|
};
|
||||||
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
|
use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
|
||||||
use test_utils::mark;
|
use test_utils::mark;
|
||||||
@ -64,7 +64,8 @@ pub(crate) struct CompletionContext<'a> {
|
|||||||
pub(super) is_path_type: bool,
|
pub(super) is_path_type: bool,
|
||||||
pub(super) has_type_args: bool,
|
pub(super) has_type_args: bool,
|
||||||
pub(super) attribute_under_caret: Option<ast::Attr>,
|
pub(super) attribute_under_caret: Option<ast::Attr>,
|
||||||
pub(super) after_unsafe: bool,
|
pub(super) unsafe_is_prev: bool,
|
||||||
|
pub(super) if_is_prev: bool,
|
||||||
pub(super) block_expr_parent: bool,
|
pub(super) block_expr_parent: bool,
|
||||||
pub(super) bind_pat_parent: bool,
|
pub(super) bind_pat_parent: bool,
|
||||||
pub(super) ref_pat_parent: bool,
|
pub(super) ref_pat_parent: bool,
|
||||||
@ -130,7 +131,7 @@ impl<'a> CompletionContext<'a> {
|
|||||||
has_type_args: false,
|
has_type_args: false,
|
||||||
dot_receiver_is_ambiguous_float_literal: false,
|
dot_receiver_is_ambiguous_float_literal: false,
|
||||||
attribute_under_caret: None,
|
attribute_under_caret: None,
|
||||||
after_unsafe: false,
|
unsafe_is_prev: false,
|
||||||
in_loop_body: false,
|
in_loop_body: false,
|
||||||
ref_pat_parent: false,
|
ref_pat_parent: false,
|
||||||
bind_pat_parent: false,
|
bind_pat_parent: false,
|
||||||
@ -138,6 +139,7 @@ impl<'a> CompletionContext<'a> {
|
|||||||
inside_trait: false,
|
inside_trait: false,
|
||||||
trait_as_prev_sibling: false,
|
trait_as_prev_sibling: false,
|
||||||
impl_as_prev_sibling: false,
|
impl_as_prev_sibling: false,
|
||||||
|
if_is_prev: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut original_file = original_file.syntax().clone();
|
let mut original_file = original_file.syntax().clone();
|
||||||
@ -212,7 +214,8 @@ impl<'a> CompletionContext<'a> {
|
|||||||
let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
|
let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
|
||||||
let syntax_element = NodeOrToken::Token(fake_ident_token.clone());
|
let syntax_element = NodeOrToken::Token(fake_ident_token.clone());
|
||||||
self.block_expr_parent = has_block_expr_parent(syntax_element.clone());
|
self.block_expr_parent = has_block_expr_parent(syntax_element.clone());
|
||||||
self.after_unsafe = goes_after_unsafe(syntax_element.clone());
|
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.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_pat_parent(syntax_element.clone());
|
||||||
self.in_loop_body = is_in_loop_body(syntax_element.clone());
|
self.in_loop_body = is_in_loop_body(syntax_element.clone());
|
||||||
|
@ -22,7 +22,7 @@ pub(crate) fn has_ref_pat_parent(element: SyntaxElement) -> bool {
|
|||||||
element.ancestors().find(|it| it.kind() == REF_PAT).is_some()
|
element.ancestors().find(|it| it.kind() == REF_PAT).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn goes_after_unsafe(element: SyntaxElement) -> bool {
|
pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool {
|
||||||
element
|
element
|
||||||
.into_token()
|
.into_token()
|
||||||
.and_then(|it| previous_non_trivia_token(it))
|
.and_then(|it| previous_non_trivia_token(it))
|
||||||
@ -30,6 +30,14 @@ pub(crate) fn goes_after_unsafe(element: SyntaxElement) -> bool {
|
|||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn if_is_prev(element: SyntaxElement) -> bool {
|
||||||
|
element
|
||||||
|
.into_token()
|
||||||
|
.and_then(|it| previous_non_trivia_token(it))
|
||||||
|
.filter(|it| it.kind() == IF_KW)
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool {
|
pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool {
|
||||||
not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some()
|
not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some()
|
||||||
}
|
}
|
||||||
@ -110,3 +118,79 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
|
|||||||
non_trivia_sibling(NodeOrToken::Node(prev_sibling_node), Direction::Prev)
|
non_trivia_sibling(NodeOrToken::Node(prev_sibling_node), Direction::Prev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{
|
||||||
|
has_block_expr_parent, has_impl_as_prev_sibling, has_trait_as_prev_sibling, if_is_prev,
|
||||||
|
inside_trait, unsafe_is_prev,
|
||||||
|
};
|
||||||
|
use crate::completion::test_utils::check_pattern_is_applicable;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unsafe_is_prev() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
unsafe i<|>
|
||||||
|
",
|
||||||
|
unsafe_is_prev,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_if_is_prev() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
if l<|>
|
||||||
|
",
|
||||||
|
if_is_prev,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_inside_trait() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
trait A {
|
||||||
|
fn<|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
inside_trait,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_has_trait_as_prev_sibling() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
trait A w<|> {
|
||||||
|
}
|
||||||
|
",
|
||||||
|
has_trait_as_prev_sibling,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_has_impl_as_prev_sibling() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
impl A w<|> {
|
||||||
|
}
|
||||||
|
",
|
||||||
|
has_impl_as_prev_sibling,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parent_block_expr() {
|
||||||
|
check_pattern_is_applicable(
|
||||||
|
r"
|
||||||
|
fn my_fn() {
|
||||||
|
let a = 2;
|
||||||
|
f<|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
has_block_expr_parent,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@ use crate::{
|
|||||||
mock_analysis::{analysis_and_position, single_file_with_position},
|
mock_analysis::{analysis_and_position, single_file_with_position},
|
||||||
CompletionItem,
|
CompletionItem,
|
||||||
};
|
};
|
||||||
|
use hir::Semantics;
|
||||||
|
use ra_syntax::{AstNode, NodeOrToken, SyntaxElement, SyntaxToken};
|
||||||
|
|
||||||
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
|
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
|
||||||
do_completion_with_options(code, kind, &CompletionConfig::default())
|
do_completion_with_options(code, kind, &CompletionConfig::default())
|
||||||
@ -27,3 +29,15 @@ pub(crate) fn do_completion_with_options(
|
|||||||
kind_completions.sort_by_key(|c| c.label().to_owned());
|
kind_completions.sort_by_key(|c| c.label().to_owned());
|
||||||
kind_completions
|
kind_completions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn check_pattern_is_applicable(code: &str, check: fn(SyntaxElement) -> bool) {
|
||||||
|
let (analysis, pos) = single_file_with_position(code);
|
||||||
|
analysis
|
||||||
|
.with_db(|db| {
|
||||||
|
let sema = Semantics::new(db);
|
||||||
|
let original_file = sema.parse(pos.file_id);
|
||||||
|
let token = original_file.syntax().token_at_offset(pos.offset).left_biased().unwrap();
|
||||||
|
assert!(check(NodeOrToken::Token(token)));
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user