Skip to content

Commit da075e2

Browse files
authored
Merge pull request swiftlang#1733 from kimdv/kimdv/fix-parsing-of-attribute-labels
Fix parsing `=` instead of `:`
2 parents 2f61f77 + 6800937 commit da075e2

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,12 +1065,21 @@ extension Parser {
10651065
mutating func parseUnavailableFromAsyncArguments() -> RawUnavailableFromAsyncArgumentsSyntax {
10661066
let (unexpectedBeforeLabel, label) = self.expect(.keyword(.message))
10671067
let (unexpectedBeforeColon, colon) = self.expect(.colon)
1068+
1069+
let unexpectedBetweenColonAndMessage: RawUnexpectedNodesSyntax?
1070+
if let equalToken = self.consume(if: .equal) {
1071+
unexpectedBetweenColonAndMessage = RawUnexpectedNodesSyntax([equalToken], arena: self.arena)
1072+
} else {
1073+
unexpectedBetweenColonAndMessage = nil
1074+
}
1075+
10681076
let message = self.parseStringLiteral()
10691077
return RawUnavailableFromAsyncArgumentsSyntax(
10701078
unexpectedBeforeLabel,
10711079
messageLabel: label,
10721080
unexpectedBeforeColon,
10731081
colon: colon,
1082+
unexpectedBetweenColonAndMessage,
10741083
message: message,
10751084
arena: self.arena
10761085
)

Sources/SwiftParser/TokenPrecedence.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ enum TokenPrecedence: Comparable {
2727
case weakBracketed(closingDelimiter: RawTokenKind)
2828
/// A punctuator that can occur inside a statement
2929
case weakPunctuator
30+
/// A punctuator that is a fairly strong indicator of separating two distinct parts of a statement.
31+
case mediumPunctuator
3032
/// The closing delimiter of `weakBracketed`
3133
case weakBracketClose
3234
/// Keywords that start a new statement.
@@ -71,22 +73,24 @@ enum TokenPrecedence: Comparable {
7173
return 3
7274
case .weakPunctuator:
7375
return 4
74-
case .weakBracketClose:
76+
case .mediumPunctuator:
7577
return 5
76-
case .stmtKeyword:
78+
case .weakBracketClose:
7779
return 6
78-
case .strongPunctuator:
80+
case .stmtKeyword:
7981
return 7
80-
case .openingBrace:
82+
case .strongPunctuator:
8183
return 8
82-
case .closingBrace:
84+
case .openingBrace:
8385
return 9
84-
case .declKeyword:
86+
case .closingBrace:
8587
return 10
86-
case .openingPoundIf:
88+
case .declKeyword:
8789
return 11
88-
case .closingPoundIf:
90+
case .openingPoundIf:
8991
return 12
92+
case .closingPoundIf:
93+
return 13
9094
}
9195
}
9296

@@ -143,9 +147,12 @@ enum TokenPrecedence: Comparable {
143147
case // Chaining punctuators
144148
.infixQuestionMark, .period, .postfixQuestionMark, .exclamationMark,
145149
// Misc
146-
.atSign, .backslash, .backtick, .colon, .comma, .ellipsis, .equal, .prefixAmpersand:
150+
.backslash, .backtick, .ellipsis, .equal, .prefixAmpersand:
147151
self = .weakPunctuator
148152

153+
case .atSign, .colon, .comma:
154+
self = .mediumPunctuator
155+
149156
// MARK: Weak bracket close
150157
case // Weak brackets
151158
.rightAngle, .rightParen, .rightSquare:

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,26 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
16251625
return .skipChildren
16261626
}
16271627

1628+
if let equalToken = node.unexpectedBetweenColonAndMessage?.onlyPresentToken(where: { $0.tokenKind == .equal }) {
1629+
addDiagnostic(
1630+
equalToken,
1631+
MissingNodesError(missingNodes: [Syntax(node.colon)]),
1632+
fixIts: [
1633+
FixIt(
1634+
message: ReplaceTokensFixIt(
1635+
replaceTokens: [equalToken],
1636+
replacements: [node.colon]
1637+
),
1638+
changes: [
1639+
FixIt.MultiNodeChange.makeMissing(equalToken),
1640+
FixIt.MultiNodeChange.makePresent(node.colon),
1641+
]
1642+
)
1643+
],
1644+
handledNodes: [equalToken.id, node.colon.id]
1645+
)
1646+
}
1647+
16281648
if let token = node.unexpectedBetweenMessageLabelAndColon?.onlyPresentToken(where: { $0.tokenKind.isIdentifier }),
16291649
token.isPresent,
16301650
node.messageLabel.isMissing

Tests/SwiftParserTest/AttributeTests.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,10 @@ final class AttributeTests: XCTestCase {
536536
func foo() {}
537537
""",
538538
diagnostics: [
539-
DiagnosticSpec(message: "expected ':' and string literal in @_unavailableFromAsync argument", fixIts: ["insert ':' and string literal"]),
540-
DiagnosticSpec(message: #"unexpected code '= "abc"' in attribute"#),
539+
DiagnosticSpec(message: "expected ':' in @_unavailableFromAsync argument", fixIts: ["replace '=' with ':'"])
541540
],
542541
fixedSource: """
543-
@_unavailableFromAsync(message: ""= "abc")
542+
@_unavailableFromAsync(message: "abc")
544543
func foo() {}
545544
"""
546545
)

0 commit comments

Comments
 (0)