Skip to content

Commit 869eafb

Browse files
committed
Make unowned parsing accept RecoveryConsumptionHandle
Mark modifiers after fixity unexpected
1 parent dab15c3 commit 869eafb

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,26 +1717,27 @@ extension Parser {
17171717
var unexpectedBeforeFixity = RawUnexpectedNodesSyntax(attrs.attributes?.elements ?? [], arena: self.arena)
17181718

17191719
var fixity: RawTokenSyntax?
1720-
var leftInFixityModifier: RawUnexpectedNodesSyntax?
1720+
var unexpectedAfterFixity: RawUnexpectedNodesSyntax?
17211721

17221722
if let modifiers = attrs.modifiers?.elements {
17231723
if let firstFixityIndex = modifiers.firstIndex(where: { isFixity($0) }) {
17241724
let fixityModifier = modifiers[firstFixityIndex]
17251725
fixity = fixityModifier.name
17261726

1727-
leftInFixityModifier = RawUnexpectedNodesSyntax(combining: fixityModifier.unexpectedBetweenNameAndDetail, RawUnexpectedNodesSyntax([fixityModifier.detail], arena: self.arena), fixityModifier.unexpectedAfterDetail, arena: self.arena)
1728-
17291727
let beforeFixity = Array(modifiers[0..<firstFixityIndex])
17301728

17311729
unexpectedBeforeFixity = RawUnexpectedNodesSyntax(combining: unexpectedBeforeFixity, RawUnexpectedNodesSyntax(beforeFixity, arena: self.arena), fixityModifier.unexpectedBeforeName, arena: self.arena)
1730+
1731+
unexpectedAfterFixity = RawUnexpectedNodesSyntax(combining: RawUnexpectedNodesSyntax(combining: fixityModifier.unexpectedBetweenNameAndDetail, RawUnexpectedNodesSyntax([fixityModifier.detail], arena: self.arena), fixityModifier.unexpectedAfterDetail, arena: self.arena), RawUnexpectedNodesSyntax(Array(modifiers[modifiers.index(after: firstFixityIndex)...]), arena: self.arena), arena: self.arena)
1732+
17321733
} else {
17331734
unexpectedBeforeFixity = RawUnexpectedNodesSyntax(combining: unexpectedBeforeFixity, RawUnexpectedNodesSyntax(modifiers, arena: self.arena), arena: self.arena)
17341735
}
17351736
}
17361737

17371738
var (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.expect(.keyword(.operator))
17381739

1739-
unexpectedBeforeOperatorKeyword = RawUnexpectedNodesSyntax(combining: leftInFixityModifier, unexpectedBeforeOperatorKeyword, arena: self.arena)
1740+
unexpectedBeforeOperatorKeyword = RawUnexpectedNodesSyntax(combining: unexpectedAfterFixity, unexpectedBeforeOperatorKeyword, arena: self.arena)
17401741

17411742
return OperatorDeclIntroducer(
17421743
unexpectedBeforeFixity: unexpectedBeforeFixity,

Sources/SwiftParser/Modifiers.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ extension Parser {
5858
} else {
5959
break MODIFIER_LOOP
6060
}
61-
case (.declarationModifier(.unowned), _)?:
62-
elements.append(self.parseUnownedModifier())
61+
case (.declarationModifier(.unowned), let handle)?:
62+
elements.append(self.parseUnownedModifier(handle))
6363
case (.declarationModifier(.final), let handle)?,
6464
(.declarationModifier(.required), let handle)?,
6565
(.declarationModifier(.optional), let handle)?,
@@ -113,8 +113,8 @@ extension Parser {
113113
)
114114
}
115115

116-
mutating func parseUnownedModifier() -> RawDeclModifierSyntax {
117-
let (unexpectedBeforeKeyword, keyword) = self.expect(.keyword(.unowned))
116+
mutating func parseUnownedModifier(_ handle: RecoveryConsumptionHandle) -> RawDeclModifierSyntax {
117+
let (unexpectedBeforeKeyword, keyword) = self.eat(handle)
118118

119119
let detail: RawDeclModifierDetailSyntax?
120120
if self.at(.leftParen) {

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,4 +2163,31 @@ final class DeclarationTests: XCTestCase {
21632163
]
21642164
)
21652165
}
2166+
2167+
func testUnexpectedTokenInClassFollowedByUnownedModifier() {
2168+
assertParse(
2169+
"""
2170+
class A 5️⃣{
2171+
1️⃣^
2172+
}
2173+
unowned 2️⃣B 3️⃣{
2174+
}4️⃣
2175+
""",
2176+
diagnostics: [
2177+
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code before modifier"),
2178+
DiagnosticSpec(locationMarker: "2️⃣", message: "expected 'func' in function", fixIts: ["insert 'func'"]),
2179+
DiagnosticSpec(locationMarker: "3️⃣", message: "expected parameter clause in function signature", fixIts: ["insert parameter clause"]),
2180+
DiagnosticSpec(locationMarker: "4️⃣", message: "expected '}' to end class", notes: [NoteSpec(locationMarker: "5️⃣", message: "to match this opening '{'")], fixIts: ["insert '}'"]),
2181+
],
2182+
fixedSource:
2183+
"""
2184+
class A {
2185+
^
2186+
}
2187+
unowned func B() {
2188+
}
2189+
}
2190+
"""
2191+
)
2192+
}
21662193
}

Tests/SwiftParserTest/translated/OperatorDeclTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,17 @@ final class OperatorDeclTests: XCTestCase {
598598
)
599599
}
600600

601+
func testMultipleFixity() {
602+
assertParse(
603+
"""
604+
prefix 1️⃣infix operator &+&
605+
""",
606+
diagnostics: [
607+
DiagnosticSpec(message: "unexpected code 'infix' in operator declaration")
608+
]
609+
)
610+
}
611+
601612
func testIdentifierAsOperatorName() {
602613
assertParse(
603614
"postfix operator 1️⃣aa",

0 commit comments

Comments
 (0)