-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Parse] Improve diagnostic and add fixit to correct '#else if' to '#elseif' #25008
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
Conversation
lib/Parse/ParseIfConfig.cpp
Outdated
diagnose(Tok.getLoc(), | ||
diag::unexpected_if_following_else_compilation_directive) | ||
.fixItReplace( | ||
SourceRange(ClauseLoc, Tok.getLoc().getAdvancedLoc(1)), |
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.
Maybe you can extract this into a separate line otherwise it makes the indentation looks a bit weird IMO.
auto diag = diag::unexpected_if_following_else_compilation_directive;
auto rangeToReplace = SourceRange(ClauseLoc, Tok.getLoc().getAdvancedLoc(1));
diagnose(Tok.getLoc(), diag).fixItReplace(rangeToReplace, "#elseif");
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.
Turns out this was a little more complicated then it needed to be, it reads much better now that I've simplified it a bit
|
||
#if FOO | ||
#else if BAR | ||
// expected-error@-1 {{unexpected 'if' keyword following '#else' conditional compilation directive; did you mean '#elseif?'}} |
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 think this is supposed to be just expected-error
. Also, you can also check whether the fix-it is correctly applied by using this syntax:
{{column_start-column_end=<text>}}
so for example:
// expected-error {{unexpected 'if' keyword following '#else' conditional compilation directive; did you mean '#elseif?'}}{{0-9=#elseif}}
(wrote this without running, so you might have to tweak the range).
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.
expected-error@-1
is correct; it says the error should appear on the line before the comment.
You're correct that this needs to test the fix-it, though. Columns are 1-based (this confuses me all the time), so I think the range is 1-9.
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.
Sorry, I meant we could use expected-error
and put it on the same line as #else if BAR
? I suppose it's fine otherwise because the line would become even longer 😅
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.
Good catch, thanks!
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.
Thank you for fixing this! I make this mistake all the time; it'll be nice to have the compiler point me to the right code. My suggestions are pretty minor—you've done a good job here.
lib/Parse/ParseIfConfig.cpp
Outdated
diagnose(Tok.getLoc(), | ||
diag::unexpected_if_following_else_compilation_directive) | ||
.fixItReplace( | ||
SourceRange(ClauseLoc, Tok.getLoc().getAdvancedLoc(1)), |
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.
.getAdvancedLoc(1)
shouldn't be needed.
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.
fixed
lib/Parse/ParseIfConfig.cpp
Outdated
@@ -623,8 +623,18 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig( | |||
foundActive |= isActive; | |||
|
|||
if (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) { | |||
diagnose(Tok.getLoc(), | |||
diag::extra_tokens_conditional_compilation_directive); | |||
if (isElse && Tok.is(tok::kw_if)) { |
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.
To maximize the recovery, I think you should do this before line 599. Like:
bool isElse = Tok.is(tok::pound_else);
SourceLoc ClauseLoc = consumeToken();
+ if (isElse && Tok.is(tok::kw_if) && !Tok.isAtStartOfLine()) {
+ .. Emit error and fix-it ..
+ consumeToken(tok::kw_if);
+ isElse = false;
+ }
+
Expr *Condition = nullptr;
bool isActive = false;
// Parse the condition. Evaluate it to determine the active
// clause unless we're doing a parse-only pass.
if (isElse) {
This way, the parser automatically parse and possibly diagnose the condition after #else if
.
For example, given
#else if SOME == THING
In this case, we want to diagnose both:
#else if
for fix-it#elseif
==
forerror: expected '&&' or '||' expression
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.
Yeah, recovering here seems to work well and catch parse errors in the condition. Thanks!
lib/Parse/ParseIfConfig.cpp
Outdated
@@ -623,8 +623,18 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig( | |||
foundActive |= isActive; | |||
|
|||
if (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) { | |||
diagnose(Tok.getLoc(), |
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.
Small tips: Parser
has diagnose(Token Tok, Diagnostic Diag)
function. You don't need .getLoc()
here.
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.
fixed
Resolves SR-10581
326271d
to
901d947
Compare
Thanks for the feedback @theblixguy @rintaro @brentdax . I think I've addressed all the issues raised |
@swift-ci please smoke test |
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.
Thank you!
Resolves SR-10581