Improve checks for postfix suggestions

This commit is contained in:
Igor Aleksanov 2020-09-12 17:32:19 +03:00
parent ea320141c6
commit e447b3a4a2
3 changed files with 23 additions and 16 deletions

View File

@ -211,9 +211,7 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
)
.add_to(acc);
if ctx.is_string_literal {
add_format_like_completions(acc, ctx, &dot_receiver, cap, &receiver_text);
}
add_format_like_completions(acc, ctx, &dot_receiver, cap, &receiver_text);
}
fn get_receiver_text(receiver: &ast::Expr, receiver_is_ambiguous_float_literal: bool) -> String {

View File

@ -27,7 +27,11 @@ pub(super) fn add_format_like_completions(
cap: SnippetCap,
receiver_text: &str,
) {
assert!(receiver_text.len() >= 2);
if !is_string_literal(receiver_text) {
// It's not a string literal, do not parse input.
return;
}
let input = &receiver_text[1..receiver_text.len() - 1];
let mut parser = FormatStrParser::new(input);
@ -42,6 +46,20 @@ pub(super) fn add_format_like_completions(
}
}
/// Checks whether provided item is a string literal.
fn is_string_literal(item: &str) -> bool {
if item.len() < 2 {
return false;
}
if item.chars().nth(0) != Some('"') || item.chars().nth(item.len() - 1) != Some('"') {
return false;
}
true
}
/// Parser for a format-like string. It is more allowing in terms of string contents,
/// as we expect variable placeholders to be filled with expressions.
#[derive(Debug)]
pub struct FormatStrParser {
input: String,
@ -127,7 +145,7 @@ impl FormatStrParser {
pub fn parse(&mut self) -> Result<(), ()> {
let mut current_expr = String::new();
let mut placeholders_count = 0;
let mut placeholder_id = 1;
// Count of open braces inside of an expression.
// We assume that user knows what they're doing, thus we treat it like a correct pattern, e.g.
@ -163,8 +181,8 @@ impl FormatStrParser {
(State::MaybeExpr, '}') => {
// This is an empty sequence '{}'. Replace it with placeholder.
self.output.push(chr);
self.extracted_expressions.push(format!("${}", placeholders_count));
placeholders_count += 1;
self.extracted_expressions.push(format!("${}", placeholder_id));
placeholder_id += 1;
self.state = State::NotExpr;
}
(State::MaybeExpr, _) => {

View File

@ -74,8 +74,6 @@ pub(crate) struct CompletionContext<'a> {
pub(super) is_pattern_call: bool,
/// If this is a macro call, i.e. the () are already there.
pub(super) is_macro_call: bool,
/// If this is a string literal, like "lorem ipsum".
pub(super) is_string_literal: bool,
pub(super) is_path_type: bool,
pub(super) has_type_args: bool,
pub(super) attribute_under_caret: Option<ast::Attr>,
@ -158,7 +156,6 @@ impl<'a> CompletionContext<'a> {
is_call: false,
is_pattern_call: false,
is_macro_call: false,
is_string_literal: false,
is_path_type: false,
has_type_args: false,
dot_receiver_is_ambiguous_float_literal: false,
@ -473,12 +470,6 @@ impl<'a> CompletionContext<'a> {
} else {
false
};
self.is_string_literal = if let Some(ast::Expr::Literal(l)) = &self.dot_receiver {
matches!(l.kind(), ast::LiteralKind::String { .. })
} else {
false
};
}
if let Some(method_call_expr) = ast::MethodCallExpr::cast(parent) {
// As above