Skip to content

Commit 91c5978

Browse files
committed
Add diagnostics for wrong modifiers for operator declarations & update test cases
1 parent 0a98797 commit 91c5978

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ extension Parser {
18881888
_ attrs: DeclAttributes,
18891889
_ handle: RecoveryConsumptionHandle
18901890
) -> RawOperatorDeclSyntax {
1891-
let (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.eat(handle)
1891+
var (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.eat(handle)
18921892
let unexpectedBeforeName: RawUnexpectedNodesSyntax?
18931893
let name: RawTokenSyntax
18941894
switch self.canRecoverTo(anyIn: OperatorLike.self) {
@@ -1964,15 +1964,32 @@ extension Parser {
19641964
} else {
19651965
unexpectedAtEnd = nil
19661966
}
1967-
1967+
1968+
var unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax?
19681969
var modifiers: RawModifierListSyntax? = attrs.modifiers
1970+
1971+
let expectedModifiers = [Keyword.prefix.defaultText, Keyword.postfix.defaultText, Keyword.infix.defaultText]
1972+
1973+
if let firstModifier = modifiers?.elements.first {
1974+
if !expectedModifiers.contains(firstModifier.name.tokenText) {
1975+
unexpectedBetweenAttributesAndModifiers = RawUnexpectedNodesSyntax([modifiers], arena: self.arena)
1976+
modifiers = nil
1977+
} else {
1978+
unexpectedBeforeOperatorKeyword = RawUnexpectedNodesSyntax(Array(modifiers!.elements.dropFirst()), arena: self.arena)
1979+
modifiers = RawModifierListSyntax(elements: [firstModifier], arena: self.arena)
1980+
}
1981+
}
1982+
1983+
1984+
19691985
if modifiers == nil, unexpectedBeforeOperatorKeyword == nil {
19701986
let missedModifier = RawDeclModifierSyntax(name: self.missingToken(.prefix), detail: nil, arena: self.arena)
19711987
modifiers = RawModifierListSyntax(elements: [missedModifier], arena: self.arena)
19721988
}
19731989

19741990
return RawOperatorDeclSyntax(
19751991
attributes: attrs.attributes,
1992+
unexpectedBetweenAttributesAndModifiers,
19761993
modifiers: modifiers,
19771994
unexpectedBeforeOperatorKeyword,
19781995
operatorKeyword: operatorKeyword,

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,15 @@ public struct NegatedAvailabilityCondition: ParserError {
369369
}
370370
}
371371

372+
public struct OperatorContradictingModifier: ParserError {
373+
public let contradictingModifier: TokenSyntax
374+
public let previousModifier: TokenSyntax
375+
376+
public var message: String {
377+
return "'\(contradictingModifier)' contradicts previous modifier '\(previousModifier)'"
378+
}
379+
}
380+
372381
public struct SpaceSeparatedIdentifiersError: ParserError {
373382
public let firstToken: TokenSyntax
374383
public let additionalTokens: [TokenSyntax]

Tests/SwiftParserTest/translated/OperatorDeclTests.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,41 @@ final class OperatorDeclTests: XCTestCase {
480480
)
481481
}
482482

483+
484+
func testOperatorDecl124() {
485+
assertParse(
486+
"""
487+
prefix 1️⃣mutating operator ?? : UndeclaredPrecedenceGroup
488+
""",
489+
diagnostics: [
490+
DiagnosticSpec(message: "unexpected code 'mutating' in operator declaration")
491+
]
492+
)
493+
}
494+
495+
func testOperatorDecl125() {
496+
assertParse(
497+
"""
498+
prefix 1️⃣postfix operator ** : PrecedenceGroup
499+
""",
500+
diagnostics: [
501+
DiagnosticSpec(message: "unexpected code 'postfix' in operator declaration")
502+
]
503+
)
504+
}
505+
506+
func testOperatorDecl126() {
507+
assertParse(
508+
"""
509+
1️⃣mutating 2️⃣operator ?? : PrecedenceGroup
510+
""",
511+
diagnostics: [
512+
DiagnosticSpec(message: "unexpected code 'mutating' before operator declaration"),
513+
DiagnosticSpec(locationMarker: "2️⃣", message: "operator must be declared as 'prefix', 'postfix', or 'infix'")
514+
]
515+
)
516+
}
517+
483518
func testIdentifierAsOperatorName() {
484519
assertParse(
485520
"postfix operator 1️⃣aa",

0 commit comments

Comments
 (0)