2020-10-18 13:09:00 +03:00
|
|
|
//! Completes keywords.
|
2019-09-30 11:58:53 +03:00
|
|
|
|
2020-08-12 18:26:51 +02:00
|
|
|
use syntax::{ast, SyntaxKind};
|
2020-07-03 23:46:36 +02:00
|
|
|
use test_utils::mark;
|
2019-01-08 22:33:36 +03:00
|
|
|
|
2020-10-18 13:09:00 +03:00
|
|
|
use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
|
2019-01-08 22:33:36 +03:00
|
|
|
|
2020-10-25 10:59:15 +03:00
|
|
|
pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
2019-01-08 22:33:36 +03:00
|
|
|
// complete keyword "crate" in use stmt
|
2019-01-20 12:02:00 +08:00
|
|
|
let source_range = ctx.source_range();
|
2020-08-13 22:41:55 +02:00
|
|
|
|
|
|
|
if ctx.use_item_syntax.is_some() {
|
|
|
|
if ctx.path_qual.is_none() {
|
2020-06-27 12:25:08 +02:00
|
|
|
CompletionItem::new(CompletionKind::Keyword, source_range, "crate::")
|
2019-01-08 22:33:36 +03:00
|
|
|
.kind(CompletionItemKind::Keyword)
|
2019-01-19 22:02:50 +08:00
|
|
|
.insert_text("crate::")
|
2019-01-08 22:33:36 +03:00
|
|
|
.add_to(acc);
|
|
|
|
}
|
2020-08-13 22:41:55 +02:00
|
|
|
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
|
|
|
|
.kind(CompletionItemKind::Keyword)
|
|
|
|
.add_to(acc);
|
|
|
|
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
|
|
|
|
.kind(CompletionItemKind::Keyword)
|
|
|
|
.insert_text("super::")
|
|
|
|
.add_to(acc);
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
2020-07-04 10:36:12 +02:00
|
|
|
|
|
|
|
// Suggest .await syntax for types that implement Future trait
|
|
|
|
if let Some(receiver) = &ctx.dot_receiver {
|
|
|
|
if let Some(ty) = ctx.sema.type_of_expr(receiver) {
|
|
|
|
if ty.impls_future(ctx.db) {
|
|
|
|
CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await")
|
|
|
|
.kind(CompletionItemKind::Keyword)
|
|
|
|
.detail("expr.await")
|
|
|
|
.insert_text("await")
|
|
|
|
.add_to(acc);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
2020-10-25 10:59:15 +03:00
|
|
|
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
2020-06-26 20:09:11 -06:00
|
|
|
if ctx.token.kind() == SyntaxKind::COMMENT {
|
2020-07-03 23:46:36 +02:00
|
|
|
mark::hit!(no_keyword_completion_in_comments);
|
2020-06-26 20:09:11 -06:00
|
|
|
return;
|
|
|
|
}
|
2020-11-16 12:18:01 +01:00
|
|
|
if ctx.record_lit_syntax.is_some() {
|
|
|
|
mark::hit!(no_keyword_completion_in_record_lit);
|
|
|
|
return;
|
|
|
|
}
|
2020-06-26 20:09:11 -06:00
|
|
|
|
2020-06-13 00:55:21 +02:00
|
|
|
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 {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "where", "where ");
|
2020-06-13 00:55:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ctx.unsafe_is_prev {
|
2020-06-13 13:47:30 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent {
|
|
|
|
add_keyword(ctx, acc, "fn", "fn $0() {}")
|
|
|
|
}
|
|
|
|
|
2020-07-30 11:42:51 +02:00
|
|
|
if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "trait", "trait $0 {}");
|
|
|
|
add_keyword(ctx, acc, "impl", "impl $0 {}");
|
|
|
|
}
|
|
|
|
|
2020-06-13 00:55:21 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent
|
|
|
|
{
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "fn", "fn $0() {}");
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "use", "use ");
|
|
|
|
add_keyword(ctx, acc, "impl", "impl $0 {}");
|
|
|
|
add_keyword(ctx, acc, "trait", "trait $0 {}");
|
|
|
|
}
|
|
|
|
|
2020-07-30 11:42:51 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "enum", "enum $0 {}");
|
2020-07-10 17:42:18 +02:00
|
|
|
add_keyword(ctx, acc, "struct", "struct $0");
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "union", "union $0 {}");
|
|
|
|
}
|
|
|
|
|
2020-07-10 17:56:55 +02:00
|
|
|
if ctx.is_expr {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "match", "match $0 {}");
|
|
|
|
add_keyword(ctx, acc, "while", "while $0 {}");
|
2020-07-10 17:41:43 +02:00
|
|
|
add_keyword(ctx, acc, "loop", "loop {$0}");
|
2021-01-15 15:01:32 +03:00
|
|
|
add_keyword(ctx, acc, "if", "if $0 {}");
|
|
|
|
add_keyword(ctx, acc, "if let", "if let $1 = $0 {}");
|
2020-06-13 13:47:30 +02:00
|
|
|
}
|
2020-07-10 17:41:43 +02:00
|
|
|
|
2020-06-13 13:47:30 +02:00
|
|
|
if ctx.if_is_prev || ctx.block_expr_parent {
|
|
|
|
add_keyword(ctx, acc, "let", "let ");
|
|
|
|
}
|
2020-07-10 17:41:43 +02:00
|
|
|
|
2020-06-13 13:47:30 +02:00
|
|
|
if ctx.after_if {
|
|
|
|
add_keyword(ctx, acc, "else", "else {$0}");
|
|
|
|
add_keyword(ctx, acc, "else if", "else if $0 {}");
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "mod", "mod $0 {}");
|
|
|
|
}
|
|
|
|
if ctx.bind_pat_parent || ctx.ref_pat_parent {
|
|
|
|
add_keyword(ctx, acc, "mut", "mut ");
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent
|
|
|
|
{
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "const", "const ");
|
|
|
|
add_keyword(ctx, acc, "type", "type ");
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "static", "static ");
|
|
|
|
};
|
2020-07-30 11:42:51 +02:00
|
|
|
if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent {
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "extern", "extern ");
|
|
|
|
}
|
2020-07-30 11:42:51 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent
|
|
|
|
|| has_trait_or_impl_parent
|
|
|
|
|| ctx.block_expr_parent
|
|
|
|
|| ctx.is_match_arm
|
|
|
|
{
|
2020-06-13 13:47:30 +02:00
|
|
|
add_keyword(ctx, acc, "unsafe", "unsafe ");
|
|
|
|
}
|
|
|
|
if ctx.in_loop_body {
|
|
|
|
if ctx.can_be_stmt {
|
|
|
|
add_keyword(ctx, acc, "continue", "continue;");
|
|
|
|
add_keyword(ctx, acc, "break", "break;");
|
|
|
|
} else {
|
|
|
|
add_keyword(ctx, acc, "continue", "continue");
|
|
|
|
add_keyword(ctx, acc, "break", "break");
|
|
|
|
}
|
|
|
|
}
|
2020-08-25 17:20:29 +02:00
|
|
|
if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent | ctx.has_field_list_parent {
|
|
|
|
add_keyword(ctx, acc, "pub(crate)", "pub(crate) ");
|
|
|
|
add_keyword(ctx, acc, "pub", "pub ");
|
2020-06-13 13:47:30 +02:00
|
|
|
}
|
2019-01-08 22:33:36 +03:00
|
|
|
|
2020-06-13 01:21:48 +02:00
|
|
|
if !ctx.is_trivial_path {
|
|
|
|
return;
|
|
|
|
}
|
2019-07-19 12:56:47 +03:00
|
|
|
let fn_def = match &ctx.function_syntax {
|
2019-01-08 22:33:36 +03:00
|
|
|
Some(it) => it,
|
|
|
|
None => return,
|
|
|
|
};
|
2019-07-19 12:56:47 +03:00
|
|
|
acc.add_all(complete_return(ctx, &fn_def, ctx.can_be_stmt));
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
2020-06-13 13:47:30 +02:00
|
|
|
fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem {
|
|
|
|
let res = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw)
|
|
|
|
.kind(CompletionItemKind::Keyword);
|
|
|
|
|
|
|
|
match ctx.config.snippet_cap {
|
|
|
|
Some(cap) => res.insert_snippet(cap, snippet),
|
|
|
|
_ => res.insert_text(if snippet.contains('$') { kw } else { snippet }),
|
|
|
|
}
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) {
|
|
|
|
acc.add(keyword(ctx, kw, snippet));
|
|
|
|
}
|
|
|
|
|
2019-01-19 22:02:50 +08:00
|
|
|
fn complete_return(
|
|
|
|
ctx: &CompletionContext,
|
2020-07-30 14:51:08 +02:00
|
|
|
fn_def: &ast::Fn,
|
2019-01-19 22:02:50 +08:00
|
|
|
can_be_stmt: bool,
|
|
|
|
) -> Option<CompletionItem> {
|
2019-01-08 22:33:36 +03:00
|
|
|
let snip = match (can_be_stmt, fn_def.ret_type().is_some()) {
|
|
|
|
(true, true) => "return $0;",
|
|
|
|
(true, false) => "return;",
|
|
|
|
(false, true) => "return $0",
|
|
|
|
(false, false) => "return",
|
|
|
|
};
|
2019-01-19 22:02:50 +08:00
|
|
|
Some(keyword(ctx, "return", snip))
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2020-08-21 13:19:31 +02:00
|
|
|
use expect_test::{expect, Expect};
|
2020-07-03 12:51:18 +02:00
|
|
|
|
2020-10-18 13:09:00 +03:00
|
|
|
use crate::{
|
2020-07-03 13:21:14 +02:00
|
|
|
test_utils::{check_edit, completion_list},
|
|
|
|
CompletionKind,
|
|
|
|
};
|
2020-07-03 23:46:36 +02:00
|
|
|
use test_utils::mark;
|
2019-01-19 22:02:50 +08:00
|
|
|
|
2020-07-03 12:51:18 +02:00
|
|
|
fn check(ra_fixture: &str, expect: Expect) {
|
|
|
|
let actual = completion_list(ra_fixture, CompletionKind::Keyword);
|
|
|
|
expect.assert_eq(&actual)
|
2020-06-12 08:49:12 +02:00
|
|
|
}
|
|
|
|
|
2019-01-08 22:33:36 +03:00
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_in_use_stmt() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"use $0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw crate::
|
|
|
|
kw self
|
|
|
|
kw super::
|
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"use a::$0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
2020-07-04 19:03:58 +02:00
|
|
|
kw self
|
|
|
|
kw super::
|
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"use a::{b, $0}",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
2020-07-04 19:03:58 +02:00
|
|
|
kw self
|
|
|
|
kw super::
|
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-13 10:43:39 +02:00
|
|
|
#[test]
|
|
|
|
fn test_keywords_at_source_file_level() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"m$0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw use
|
2020-07-03 12:51:18 +02:00
|
|
|
kw impl
|
|
|
|
kw trait
|
2020-12-19 13:18:40 +02:00
|
|
|
kw enum
|
|
|
|
kw struct
|
2020-07-03 12:51:18 +02:00
|
|
|
kw union
|
2020-12-19 13:18:40 +02:00
|
|
|
kw mod
|
|
|
|
kw const
|
|
|
|
kw type
|
|
|
|
kw static
|
|
|
|
kw extern
|
2020-07-03 12:51:18 +02:00
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw pub(crate)
|
|
|
|
kw pub
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2020-06-13 10:43:39 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-01-08 22:33:36 +03:00
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_in_function() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn quux() { $0 }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw use
|
|
|
|
kw impl
|
|
|
|
kw trait
|
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-03 12:51:18 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw let
|
|
|
|
kw mod
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
2020-12-19 13:18:40 +02:00
|
|
|
kw static
|
|
|
|
kw extern
|
2020-07-03 12:51:18 +02:00
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw return
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_inside_block() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn quux() { if true { $0 } }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw use
|
|
|
|
kw impl
|
|
|
|
kw trait
|
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-03 12:51:18 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw let
|
|
|
|
kw mod
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
2020-12-19 13:18:40 +02:00
|
|
|
kw static
|
|
|
|
kw extern
|
2020-07-03 12:51:18 +02:00
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw return
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2020-06-13 00:55:21 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_keywords_after_if() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r#"fn quux() { if true { () } $0 }"#,
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw use
|
|
|
|
kw impl
|
|
|
|
kw trait
|
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-03 12:51:18 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw let
|
2020-12-19 13:18:40 +02:00
|
|
|
kw else
|
|
|
|
kw else if
|
2020-07-03 12:51:18 +02:00
|
|
|
kw mod
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
2020-12-19 13:18:40 +02:00
|
|
|
kw static
|
|
|
|
kw extern
|
2020-07-03 12:51:18 +02:00
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw return
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
2020-07-03 13:21:14 +02:00
|
|
|
check_edit(
|
|
|
|
"else",
|
2021-01-06 20:15:48 +00:00
|
|
|
r#"fn quux() { if true { () } $0 }"#,
|
2020-07-03 13:21:14 +02:00
|
|
|
r#"fn quux() { if true { () } else {$0} }"#,
|
|
|
|
);
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_in_match_arm() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
fn quux() -> i32 {
|
2021-01-06 20:15:48 +00:00
|
|
|
match () { () => $0 }
|
2020-07-03 12:51:18 +02:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2020-12-19 13:18:40 +02:00
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-03 12:51:18 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw return
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
2020-06-13 00:55:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_keywords_in_trait_def() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"trait My { $0 }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
|
|
|
kw unsafe
|
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_in_impl_def() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"impl My { $0 }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw pub(crate)
|
|
|
|
kw pub
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_in_loop() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn my() { loop { $0 } }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
2020-12-19 13:18:40 +02:00
|
|
|
kw use
|
|
|
|
kw impl
|
|
|
|
kw trait
|
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-03 12:51:18 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw let
|
|
|
|
kw mod
|
2020-12-19 13:18:40 +02:00
|
|
|
kw const
|
2020-07-03 12:51:18 +02:00
|
|
|
kw type
|
2020-12-19 13:18:40 +02:00
|
|
|
kw static
|
|
|
|
kw extern
|
2020-07-03 12:51:18 +02:00
|
|
|
kw unsafe
|
2020-12-19 13:18:40 +02:00
|
|
|
kw continue
|
|
|
|
kw break
|
|
|
|
kw return
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
2020-06-13 00:55:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_keywords_after_unsafe_in_item_list() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"unsafe $0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
|
|
|
kw trait
|
2020-12-19 13:18:40 +02:00
|
|
|
kw impl
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_keywords_after_unsafe_in_block_expr() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn my_fn() { unsafe $0 }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw fn
|
|
|
|
kw trait
|
2020-12-19 13:18:40 +02:00
|
|
|
kw impl
|
2020-07-03 12:51:18 +02:00
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
2020-06-13 00:55:21 +02:00
|
|
|
}
|
2019-01-19 22:02:50 +08:00
|
|
|
|
2020-06-13 00:55:21 +02:00
|
|
|
#[test]
|
|
|
|
fn test_mut_in_ref_and_in_fn_parameters_list() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn my_fn(&$0) {}",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw mut
|
|
|
|
"#]],
|
2020-06-13 00:55:21 +02:00
|
|
|
);
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn my_fn($0) {}",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw mut
|
|
|
|
"#]],
|
2020-06-13 00:55:21 +02:00
|
|
|
);
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"fn my_fn() { let &$0 }",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw mut
|
|
|
|
"#]],
|
2019-01-08 22:33:36 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-06-13 00:55:21 +02:00
|
|
|
fn test_where_keyword() {
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"trait A $0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw where
|
|
|
|
"#]],
|
2020-06-13 00:55:21 +02:00
|
|
|
);
|
2020-07-03 12:51:18 +02:00
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r"impl A $0",
|
2020-07-03 12:51:18 +02:00
|
|
|
expect![[r#"
|
|
|
|
kw where
|
|
|
|
"#]],
|
2020-06-13 00:55:21 +02:00
|
|
|
);
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|
2020-07-03 23:46:36 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn no_keyword_completion_in_comments() {
|
|
|
|
mark::check!(no_keyword_completion_in_comments);
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
fn test() {
|
2021-01-06 20:15:48 +00:00
|
|
|
let x = 2; // A comment$0
|
2020-07-03 23:46:36 +02:00
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[""]],
|
|
|
|
);
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
/*
|
2021-01-06 20:15:48 +00:00
|
|
|
Some multi-line comment$0
|
2020-07-03 23:46:36 +02:00
|
|
|
*/
|
|
|
|
"#,
|
|
|
|
expect![[""]],
|
|
|
|
);
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
/// Some doc comment
|
2021-01-06 20:15:48 +00:00
|
|
|
/// let test$0 = 1
|
2020-07-03 23:46:36 +02:00
|
|
|
"#,
|
|
|
|
expect![[""]],
|
|
|
|
);
|
|
|
|
}
|
2020-07-04 10:36:12 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_completion_await_impls_future() {
|
|
|
|
check(
|
|
|
|
r#"
|
2020-10-02 16:13:48 +02:00
|
|
|
//- /main.rs crate:main deps:std
|
2020-07-04 10:36:12 +02:00
|
|
|
use std::future::*;
|
|
|
|
struct A {}
|
|
|
|
impl Future for A {}
|
2021-01-06 20:15:48 +00:00
|
|
|
fn foo(a: A) { a.$0 }
|
2020-07-04 10:36:12 +02:00
|
|
|
|
2020-10-02 16:13:48 +02:00
|
|
|
//- /std/lib.rs crate:std
|
2020-07-04 10:36:12 +02:00
|
|
|
pub mod future {
|
|
|
|
#[lang = "future_trait"]
|
|
|
|
pub trait Future {}
|
|
|
|
}
|
2020-09-10 20:01:23 +08:00
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
kw await expr.await
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
|
|
|
|
check(
|
|
|
|
r#"
|
2020-10-02 16:13:48 +02:00
|
|
|
//- /main.rs crate:main deps:std
|
2020-09-10 20:01:23 +08:00
|
|
|
use std::future::*;
|
|
|
|
fn foo() {
|
|
|
|
let a = async {};
|
2021-01-06 20:15:48 +00:00
|
|
|
a.$0
|
2020-09-10 20:01:23 +08:00
|
|
|
}
|
|
|
|
|
2020-10-02 16:13:48 +02:00
|
|
|
//- /std/lib.rs crate:std
|
2020-09-10 20:01:23 +08:00
|
|
|
pub mod future {
|
|
|
|
#[lang = "future_trait"]
|
|
|
|
pub trait Future {
|
|
|
|
type Output;
|
|
|
|
}
|
|
|
|
}
|
2020-07-04 10:36:12 +02:00
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
kw await expr.await
|
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
2020-07-10 17:41:43 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn after_let() {
|
|
|
|
check(
|
2021-01-06 20:15:48 +00:00
|
|
|
r#"fn main() { let _ = $0 }"#,
|
2020-07-10 17:41:43 +02:00
|
|
|
expect![[r#"
|
2020-12-19 13:18:40 +02:00
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-07-10 17:41:43 +02:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw return
|
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
2020-08-25 17:20:29 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn before_field() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct Foo {
|
2021-01-06 20:15:48 +00:00
|
|
|
$0
|
2020-08-25 17:20:29 +02:00
|
|
|
pub f: i32,
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
|
|
|
kw pub(crate)
|
2020-12-19 13:18:40 +02:00
|
|
|
kw pub
|
2020-08-25 17:20:29 +02:00
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
2020-11-16 12:18:01 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn skip_struct_initializer() {
|
|
|
|
mark::check!(no_keyword_completion_in_record_lit);
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct Foo {
|
|
|
|
pub f: i32,
|
|
|
|
}
|
|
|
|
fn foo() {
|
|
|
|
Foo {
|
2021-01-06 20:15:48 +00:00
|
|
|
$0
|
2020-11-16 12:18:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#""#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn struct_initializer_field_expr() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
struct Foo {
|
|
|
|
pub f: i32,
|
|
|
|
}
|
|
|
|
fn foo() {
|
|
|
|
Foo {
|
2021-01-06 20:15:48 +00:00
|
|
|
f: $0
|
2020-11-16 12:18:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2020-12-19 13:18:40 +02:00
|
|
|
kw match
|
|
|
|
kw while
|
|
|
|
kw loop
|
2020-11-16 12:18:01 +01:00
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw return
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2019-01-08 22:33:36 +03:00
|
|
|
}
|