-
Notifications
You must be signed in to change notification settings - Fork 410
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-its for misplaced typed throws could be improved #2391
Comments
Tracked in Apple’s issue tracker as rdar://119341656 |
@ahoppen hey can I work on this? |
@vj-codes yes, please! |
I looked into this briefly and it looks like when the following syntax is parsed and the first throws clause has no type - wonder if that's the reason why the type is later omitted and is thought to be part of the return clause? Also wondering what the difference is between
|
Yes, if I remember correctly parsing the type in a misspelled Parsed tokens are a version of materialized tokens that are optimized for parsing speed. The main difference is that a |
Pardon for my lack of understanding of SwiftSyntax, I've experimented with the following code in while self.hasProgressed(&loopProgress) {
if let (spec, handle, matchedSubset) = self.at(
anyIn: S.MisspelledAsyncTokenKinds.self,
or: S.CorrectAsyncTokenKinds.self
) {
...
previousIsThrow = false
} else if let (spec, handle, matchedSubset) = self.at(
anyIn: S.MisspelledThrowsTokenKinds.self,
or: S.CorrectThrowsTokenKinds.self
) {
...
previousIsThrow = true
} else {
if previousIsThrow {
previousIsThrow = false
guard self.at(prefix: "(") else {
break
}
let rawLeftParen = consumeAnyToken()
leftParen = missingToken(.leftParen)
rawType = parseType()
guard self.at(prefix: ")") else {
leftParen = nil
rawType = nil
break
}
let rawRightParen = consumeAnyToken()
rightParen = missingToken(.rightParen)
unexpected.append(rawLeftParen)
unexpected += RawSyntax(rawType!).allTokens()
unexpected.append(rawRightParen)
}
break
}
if synthesizedAsync != nil || synthesizedThrows != nil {
let synthesizedThrowsClause = synthesizedThrows.map {
RawThrowsClauseSyntax(throwsSpecifier: $0, leftParen: leftParen, type: rawType, rightParen: rightParen, arena: self.arena)
}
... and in private func handleMisplacedEffectSpecifiersAfterArrow(
effectSpecifiers: (some EffectSpecifiersSyntax)?,
misplacedSpecifiers: UnexpectedNodesSyntax?
) {
var correctTokens = [effectSpecifiers?.asyncSpecifier, effectSpecifiers?.throwsClause?.throwsSpecifier, effectSpecifiers?.throwsClause?.leftParen]
if let throwingType = effectSpecifiers?.throwsClause?.type {
correctTokens += Array(throwingType.tokens(viewMode: .all))
correctTokens.append(effectSpecifiers?.throwsClause?.rightParen)
}
exchangeTokens(
unexpected: misplacedSpecifiers,
unexpectedTokenCondition: { _ in true },
... Given the source text DiagnosticSpec(message: "'throws (any Error)' must precede '->'", fixIts: ["move 'throws (any Error)' in front of '->'"]) and the almost-correct fixedSource Also, the mutated test cases in |
Issue Kind
Bad Diagnostic Produced
Source Code
Description
Applying the Fix-It for the parser diagnostics here produces malformed code, because the thrown error type gets lost. The "fixed" code is:
It should be
The text was updated successfully, but these errors were encountered: