-
Notifications
You must be signed in to change notification settings - Fork 1.8k
fix: Don't trigger postfix completion in if
block which has an else
block
#14123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Don't trigger postfix completion in if
block which has an else
block
#14123
Conversation
Discard postfix completion if the next_non_trivia_sibling of dot_token is an ELSE_KW.
Some(ast::Expr::IfExpr(_)) => { | ||
let next_sibling = field.dot_token().and_then(|token| { | ||
let dot_token = original_file.covering_element(token.text_range()); | ||
let next_sibling = dot_token.as_token().and_then(|t| t.next_token()).and_then(|t| next_non_trivia_sibling(t.into())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to find the next sibling by calling next_non_trivia_sibling
on dot_token
, but this return None
.
dot_token.as_token().and_then(|t| next_non_trivia_sibling(t.into()))
So I find the next_non_trivia_sibling
on dot_token.next_token()
instead. I'm not sure if this is 100% correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to fetch the dot token from the original file, this logic here can be done fully with the fake syntax tree. The reason why next_non_trivia_sibling
fails is because the else keyword is wrapped in an error node that is the sibling of the parent of the field expression.
If we use the fake file instead I think it should be enough to just check for the next non trivia token (next from the fake NameRef
that we get passed in this function. Then we also don't need those next_sibling branches that check for a node that contains else
, we can just check the else
token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated it, but I found no method to find next_non_trivia_token
, so I wrote one based on previous_non_triva_token
.
rust-analyzer/crates/ide-completion/src/context/analysis.rs
Lines 1304 to 1306 in 646f973
fn previous_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> { | |
let mut token = match e.into() { | |
SyntaxElement::Node(n) => n.first_token()?, |
I'm not sure if I should reuse next_non_trivia_sibling
in this case.
rust-analyzer/crates/ide-completion/src/context/analysis.rs
Lines 1320 to 1322 in 646f973
fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> { | |
let mut e = ele.next_sibling_or_token(); | |
while let Some(inner) = e { |
By the way, I think next_non_trivia_sibling
is duplicated with syntax::algo::next_non_trivia_sibling
.
if
block which has an else
blockif
block which has an else
block
@bors r=Veykril |
☀️ Test successful - checks-actions |
Can fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> {
let token = match e.into() {
SyntaxElement::Node(n) => n.last_token()?,
SyntaxElement::Token(t) => t,
}.next_token();
iter::successors(token, Token::next_token)
.find(|token| !token.kind().is_trivia())
}
|
@Masynchin it can, but we don't necessarily prefer the functional style, and the function is pretty similar to the one below ( |
Fix #14096