-
Notifications
You must be signed in to change notification settings - Fork 440
Produce a meaningful diagnostic for "#elif" typo #1358
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
Produce a meaningful diagnostic for "#elif" typo #1358
Conversation
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. I think you are going in the right direction but macros are making this harder because #elif
could be a macro invocation. See my comment inline.
36abdd5
to
a92e8e0
Compare
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 for the delay. I started a review but forgot to submit the comments 😬
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.
This is looking good now. I’ve got a couple stylistic comments inline, otherwise this is ready to be merged.
517d776
to
0c10750
Compare
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. Let’s 🚢it
@swift-ci Please test |
@ahoppen I'm not sure why this is failing. Here's what I'm seeing from the pipeline: I'm also seeing some tests fail on main: I'm using Xcode 14.0.1, and MacOS 13.0 |
Those other test cases look odd. I can’t reproduce them on my machine. Can you expand the test failures and send me the difference between the expected and generated source? |
Hey @ahoppen, I've performed the steps you suggested above, and I've created some issues as a result. The failing tests on main are being described by issue #1410 Regarding the parsing error on Any ideas on how to proceed? |
Hey @TiagoMaiaL, swift-parser-cli dump-parse path/to/swift/Parse/ConditionalCompilation/language_version.swift |
0c10750
to
6a7fd46
Compare
@swift-ci Please test |
Hey @ahoppen, (unexpectedBeforePound, pound) = self.eat(poundIfHandle)
firstIteration = false
switch pound.tokenKind {
case .poundIfKeyword, .poundElseifKeyword:
// ...
case .poundElseKeyword:
// ...
default:
// pound.tokenKind is simply `#`.
preconditionFailure("The loop condition should guarantee that we are at one of these tokens")
} This is happening when we parse the following source from that file: let x: @#$()%&*)@#$(%&* The parser interprets the On
|
Yes, that makes sense to me. I think it’s fine that the parser parsers the The problem here is that you have loosened the loop condition by adding So, I think you would need to add a label case .pound:
break LOOP I haven’t tested it though. |
6a7fd46
to
c08859a
Compare
Hey @ahoppen, thank you for the help. I did as you suggested, and tests are passing. I noted, however, that the As opposed to After investigating a little bit, if I assign switch pound.tokenKind {
case .poundIfKeyword, .poundElseifKeyword:
// ...
case .poundElseKeyword:
// ...
case .pound:
condition = nil
default:
preconditionFailure("The loop condition should guarantee that we are at one of these tokens")
} I'm not sure if this is ideal, though. Any guidance on how to fix this is appreciated. |
What you are describing sounds as expected.
With your branch, it created the reduced |
c08859a
to
c8f99f0
Compare
Oh, I see now. The real problem here is that the condition of the Could you try the following?
|
adb5290
to
6a3eefe
Compare
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.
Thanks. That looks a lot cleaner to me now. I’ve got a few minor comments inline. If tests are passing, I think we’re getting close to merging this now.
6a3eefe
to
633f8cb
Compare
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.
Two minor comments, then this will be ready to go 🚀
633f8cb
to
7778544
Compare
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.
Let’s run it through CI again 🤞🏽
@swift-ci Please test |
I was checking the causes for the pipeline failures:
I've rebased my branch on top of latest main, and tests are still passing. @ahoppen Do you know what might be happening? |
CI is running a few additional tests that are disabled locally by default because they have significant performance impact on the parser. Essentially what these tests do, is to modify the source passed to --- a/Package.swift
+++ b/Package.swift
@@ -22,14 +22,14 @@ if ProcessInfo.processInfo.environment["SWIFT_BUILD_SCRIPT_ENVIRONMENT"] != nil
]),
]
}
-if ProcessInfo.processInfo.environment["SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION"] != nil {
+if ProcessInfo.processInfo.environment["SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION"] != nil || true {
swiftSyntaxSwiftSettings += [
.define("SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION")
]
}
var swiftParserSwiftSettings: [SwiftSetting] = []
-if ProcessInfo.processInfo.environment["SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION"] != nil {
+if ProcessInfo.processInfo.environment["SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION"] != nil || true {
swiftParserSwiftSettings += [
.define("SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION")
] If you then run switch x {
#()
#if true
bar()
#endif
case .A, .B:
break
} |
Thanks for the information, @ahoppen. I did some comparisons between
If I try to recover by parsing
My understanding is limited, so I would like to see if you have some suggestions, if possible. I'll try to run the tests the way you suggested. When you say "running without |
Oh, I see what’s going wrong. My suggestion of how to unify the loop condition was simply wrong. I’m sorry for that. But I’m making up suggestions of how to fix this as we go as well and don’t know the final outcome myself… Your analysis was correct, in I did some testing myself now and am fairly confident that the following should now really work (it does in my little prototype implementation I did locally at least). The idea is to just handle all the parsing of the initial
https://github.com/apple/swift-syntax/blob/main/CONTRIBUTING.md#xctests under |
7778544
to
e41b861
Compare
I did as you suggested. I've extracted that new elements parsing method to be out of the Tests are passing, at least locally (including running them with the |
e41b861
to
5aa69cf
Compare
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.
Nice. This reads so much better better with the #if
parsing extracted than what we currently have in main
. 😍
@swift-ci Please test |
@swift-ci Please test Windows |
@ahoppen If I'm not mistaken, the CI failures don't seem related to the changes in this PR. Is there anything I can do? |
Oh, yes. I think we just hit bad timing where CI picked up one of the PRs related to #1496 but not the other one. I’ll just trigger CI again. |
@swift-ci Please test macOS |
@swift-ci Please test Windows |
Purpose
To fix the second part of issue #1221: emit a proper diagnostic and fixit for the common
#elif
typo.Implementation details
I've considered two approaches:
elif
case to theTokenKind
enums, and later on use it to generate the proper diagnosticpound
TokenKind
to determine if the user has a typo in the code and generate the diagnosticI chose the second option because it didn't require changes to the
TokenKind
enums. I'm now adding unexpected tokens for the.pound
+.identifier
cases. If the identifier text iselif
, I synthesize apoundElseIf
token. I don't know how we could also check for.pound
+.keywords
, or if this would be needed.For the diagnostic generations, I'm adding the proper fixit for the
elif
case, and if the identifier is any other word, I just add a generic diagnostic for it.Any tip or help to get this right is really appreciated. Thank you in advance.