Skip to content

Commit 5340511

Browse files
committed
Change how OperatorDecl is presented and parsed & Update test cases
1 parent d8dee5c commit 5340511

File tree

16 files changed

+158
-217
lines changed

16 files changed

+158
-217
lines changed

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,24 +1283,14 @@ public let DECL_NODES: [Node] = [
12831283
description: "A Swift `operator` declaration.",
12841284
kind: "Decl",
12851285
traits: [
1286-
"IdentifiedDecl",
1287-
"Attributed",
1286+
"IdentifiedDecl"
12881287
],
12891288
children: [
12901289
Child(
1291-
name: "Attributes",
1292-
kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"),
1293-
nameForDiagnostics: "attributes",
1294-
description: "The attributes applied to the 'operator' declaration.",
1295-
isOptional: true
1296-
),
1297-
Child(
1298-
name: "Modifiers",
1299-
kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"),
1300-
nameForDiagnostics: "modifiers",
1301-
description: "The declaration modifiers applied to the 'operator' declaration.",
1302-
isOptional: true,
1303-
classification: "Attribute"
1290+
name: "OperatorModifier",
1291+
kind: .token(choices: [.keyword(text: "prefix"), .keyword(text: "postfix"), .keyword(text: "infix")]),
1292+
nameForDiagnostics: "modifier",
1293+
description: "The declaration modifier applied to the 'operator' declaration."
13041294
),
13051295
Child(
13061296
name: "OperatorKeyword",

Sources/IDEUtils/generated/SyntaxClassification.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ extension SyntaxClassification {
8787
return (.buildConfigId, false)
8888
case (.memberTypeIdentifier, 5):
8989
return (.typeIdentifier, false)
90-
case (.operatorDecl, 7):
90+
case (.operatorDecl, 5):
9191
return (.operatorIdentifier, false)
9292
case (.precedenceGroupAssociativity, 1):
9393
return (.keyword, false)
@@ -106,8 +106,6 @@ extension SyntaxClassification {
106106
return (.keyword, false)
107107
case (.ifConfigClause, 3):
108108
return (.buildConfigId, false)
109-
case (.operatorDecl, 3):
110-
return (.attribute, false)
111109
default:
112110
return nil
113111
}

Sources/SwiftOperators/OperatorTable+Semantics.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,7 @@ extension Operator {
6868
/// TODO: This ignores all semantic errors.
6969
init(from syntax: OperatorDeclSyntax) {
7070
self.syntax = syntax
71-
72-
kind =
73-
syntax.modifiers?.compactMap {
74-
OperatorKind(rawValue: $0.name.text)
75-
}.first ?? .infix
71+
kind = OperatorKind(rawValue: syntax.operatorModifier.text) ?? .infix
7672

7773
name = syntax.identifier.text
7874

Sources/SwiftOperators/SyntaxSynthesis.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ extension Operator {
2626
/// Synthesize a syntactic representation of this operator based on its
2727
/// semantic definition.
2828
public func synthesizedSyntax() -> OperatorDeclSyntax {
29-
let modifiers = ModifierListSyntax(
30-
[DeclModifierSyntax(name: .keyword(kind.keyword))]
31-
)
29+
let modifier = TokenSyntax.keyword(kind.keyword)
3230
let operatorKeyword = TokenSyntax.keyword(.operator, leadingTrivia: .space)
3331
let identifierSyntax =
3432
TokenSyntax.binaryOperator(name, leadingTrivia: .space)
@@ -41,7 +39,7 @@ extension Operator {
4139
}
4240

4341
return OperatorDeclSyntax(
44-
modifiers: modifiers,
42+
operatorModifier: modifier,
4543
operatorKeyword: operatorKeyword,
4644
identifier: identifierSyntax,
4745
operatorPrecedenceAndTypes: precedenceGroupSyntax

Sources/SwiftParser/Declarations.swift

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,22 @@ extension Parser {
211211
break
212212
}
213213

214+
// If we are inside a memberDecl list, we don't want to eat closing braces (which most likely close the outer context)
215+
// while recoverying to the declaration start.
216+
let recoveryPrecedence = inMemberDeclList ? TokenPrecedence.closingBrace : nil
217+
218+
switch self.canRecoverTo(anyIn: DeclarationStart.self, overrideRecoveryPrecedence: recoveryPrecedence) {
219+
case (.operatorKeyword, _)?:
220+
return RawDeclSyntax(parseOperatorDeclaration())
221+
default:
222+
break
223+
}
224+
214225
let attrs = DeclAttributes(
215226
attributes: self.parseAttributeList(),
216227
modifiers: self.parseModifierList()
217228
)
218229

219-
// If we are inside a memberDecl list, we don't want to eat closing braces (which most likely close the outer context)
220-
// while recoverying to the declaration start.
221-
let recoveryPrecedence = inMemberDeclList ? TokenPrecedence.closingBrace : nil
222-
223230
switch self.canRecoverTo(anyIn: DeclarationStart.self, overrideRecoveryPrecedence: recoveryPrecedence) {
224231
case (.importKeyword, let handle)?:
225232
return RawDeclSyntax(self.parseImportDeclaration(attrs, handle))
@@ -250,8 +257,8 @@ extension Parser {
250257
return RawDeclSyntax(self.parseInitializerDeclaration(attrs, handle))
251258
case (.deinitKeyword, let handle)?:
252259
return RawDeclSyntax(self.parseDeinitializerDeclaration(attrs, handle))
253-
case (.operatorKeyword, let handle)?:
254-
return RawDeclSyntax(self.parseOperatorDeclaration(attrs, handle))
260+
case (.operatorKeyword, _)?:
261+
return RawDeclSyntax(self.parseOperatorDeclaration())
255262
case (.precedencegroupKeyword, let handle)?:
256263
return RawDeclSyntax(self.parsePrecedenceGroupDeclaration(attrs, handle))
257264
case (.actorKeyword, let handle)?:
@@ -1686,11 +1693,12 @@ extension Parser {
16861693
/// infix-operator-declaration → 'infix' 'operator' operator infix-operator-group?
16871694
/// infix-operator-group → ':' precedence-group-name
16881695
@_spi(RawSyntax)
1689-
public mutating func parseOperatorDeclaration(
1690-
_ attrs: DeclAttributes,
1691-
_ handle: RecoveryConsumptionHandle
1692-
) -> RawOperatorDeclSyntax {
1693-
let (unexpectedBeforeOperatorKeyword, operatorKeyword) = self.eat(handle)
1696+
public mutating func parseOperatorDeclaration() -> RawOperatorDeclSyntax {
1697+
1698+
let (unexpectedBeforeModifier, modifier) = self.expect(.keyword(.infix), .keyword(.postfix), .keyword(.prefix), default: .keyword(.prefix))
1699+
1700+
let (unexpectedBeforeOperator, operatorKeyword) = self.expect(.keyword(.operator))
1701+
16941702
let unexpectedBeforeName: RawUnexpectedNodesSyntax?
16951703
let name: RawTokenSyntax
16961704
switch self.canRecoverTo(anyIn: OperatorLike.self) {
@@ -1767,9 +1775,9 @@ extension Parser {
17671775
unexpectedAtEnd = nil
17681776
}
17691777
return RawOperatorDeclSyntax(
1770-
attributes: attrs.attributes,
1771-
modifiers: attrs.modifiers,
1772-
unexpectedBeforeOperatorKeyword,
1778+
unexpectedBeforeModifier,
1779+
operatorModifier: modifier,
1780+
unexpectedBeforeOperator,
17731781
operatorKeyword: operatorKeyword,
17741782
unexpectedBeforeName,
17751783
identifier: name,

Sources/SwiftParser/Lookahead.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ extension Parser.Lookahead {
179179
}
180180

181181
extension Parser.Lookahead {
182+
mutating func consumeModifierList() -> Bool {
183+
guard self.at(anyIn: DeclarationModifier.self) != nil else {
184+
return false
185+
}
186+
while self.consume(ifAnyIn: DeclarationModifier.self) != nil {
187+
self.skipSingle()
188+
}
189+
190+
return true
191+
}
192+
182193
mutating func consumeAttributeList() -> Bool {
183194
guard self.at(.atSign) else {
184195
return false

Sources/SwiftParser/SyntaxUtils.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ extension RawUnexpectedNodesSyntax {
4141
init?<SyntaxType: RawSyntaxNodeProtocol>(_ nodes: [SyntaxType?], arena: __shared SyntaxArena) {
4242
self.init(nodes.compactMap({ $0 }), arena: arena)
4343
}
44+
45+
init?<SyntaxType: RawSyntaxNodeProtocol>(_ nodes: [SyntaxType]?, arena: __shared SyntaxArena) {
46+
guard let nodes = nodes else {
47+
return nil
48+
}
49+
self.init(nodes, arena: arena)
50+
}
4451
}
4552

4653
// MARK: Combining unexpected nodes

Sources/SwiftParser/TokenPrecedence.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public enum TokenPrecedence: Comparable {
220220
// Variables
221221
.let, .var,
222222
// Operator stuff
223-
.operator, .precedencegroup,
223+
.operator, .precedencegroup, .infix, .prefix, .postfix,
224224
// Misc
225225
.import:
226226
self = .declKeyword

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,15 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
893893
if shouldSkip(node) {
894894
return .skipChildren
895895
}
896+
897+
if node.operatorModifier.presence == .missing {
898+
addDiagnostic(
899+
node.operatorModifier,
900+
.missingModifierInOperatorDeclaration,
901+
handledNodes: [node.operatorModifier.id]
902+
)
903+
}
904+
896905
if let unexpected = node.unexpectedAfterOperatorPrecedenceAndTypes,
897906
unexpected.contains(where: { $0.is(PrecedenceGroupAttributeListSyntax.self) }) == true
898907
{

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ extension DiagnosticMessage where Self == StaticParserError {
179179
public static var misspelledThrows: Self {
180180
.init("expected throwing specifier; did you mean 'throws'?")
181181
}
182+
public static var missingModifierInOperatorDeclaration: Self {
183+
.init("operator must be declared as 'prefix', 'postfix', or 'infix'")
184+
}
182185
public static var multiLineStringLiteralMustBeginOnNewLine: Self {
183186
.init("multi-line string literal content must begin on a new line")
184187
}

Sources/SwiftSyntax/generated/SyntaxTraits.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ extension MemberDeclBlockSyntax: BracedSyntax {}
553553

554554
extension MissingDeclSyntax: AttributedSyntax {}
555555

556-
extension OperatorDeclSyntax: IdentifiedDeclSyntax, AttributedSyntax {}
556+
extension OperatorDeclSyntax: IdentifiedDeclSyntax {}
557557

558558
extension ParameterClauseSyntax: ParenthesizedSyntax {}
559559

Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14781,11 +14781,9 @@ public struct RawOperatorDeclSyntax: RawDeclSyntaxNodeProtocol {
1478114781
}
1478214782

1478314783
public init(
14784-
_ unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? = nil,
14785-
attributes: RawAttributeListSyntax?,
14786-
_ unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? = nil,
14787-
modifiers: RawModifierListSyntax?,
14788-
_ unexpectedBetweenModifiersAndOperatorKeyword: RawUnexpectedNodesSyntax? = nil,
14784+
_ unexpectedBeforeOperatorModifier: RawUnexpectedNodesSyntax? = nil,
14785+
operatorModifier: RawTokenSyntax,
14786+
_ unexpectedBetweenOperatorModifierAndOperatorKeyword: RawUnexpectedNodesSyntax? = nil,
1478914787
operatorKeyword: RawTokenSyntax,
1479014788
_ unexpectedBetweenOperatorKeywordAndIdentifier: RawUnexpectedNodesSyntax? = nil,
1479114789
identifier: RawTokenSyntax,
@@ -14795,65 +14793,55 @@ public struct RawOperatorDeclSyntax: RawDeclSyntaxNodeProtocol {
1479514793
arena: __shared SyntaxArena
1479614794
) {
1479714795
let raw = RawSyntax.makeLayout(
14798-
kind: .operatorDecl, uninitializedCount: 11, arena: arena) { layout in
14796+
kind: .operatorDecl, uninitializedCount: 9, arena: arena) { layout in
1479914797
layout.initialize(repeating: nil)
14800-
layout[0] = unexpectedBeforeAttributes?.raw
14801-
layout[1] = attributes?.raw
14802-
layout[2] = unexpectedBetweenAttributesAndModifiers?.raw
14803-
layout[3] = modifiers?.raw
14804-
layout[4] = unexpectedBetweenModifiersAndOperatorKeyword?.raw
14805-
layout[5] = operatorKeyword.raw
14806-
layout[6] = unexpectedBetweenOperatorKeywordAndIdentifier?.raw
14807-
layout[7] = identifier.raw
14808-
layout[8] = unexpectedBetweenIdentifierAndOperatorPrecedenceAndTypes?.raw
14809-
layout[9] = operatorPrecedenceAndTypes?.raw
14810-
layout[10] = unexpectedAfterOperatorPrecedenceAndTypes?.raw
14798+
layout[0] = unexpectedBeforeOperatorModifier?.raw
14799+
layout[1] = operatorModifier.raw
14800+
layout[2] = unexpectedBetweenOperatorModifierAndOperatorKeyword?.raw
14801+
layout[3] = operatorKeyword.raw
14802+
layout[4] = unexpectedBetweenOperatorKeywordAndIdentifier?.raw
14803+
layout[5] = identifier.raw
14804+
layout[6] = unexpectedBetweenIdentifierAndOperatorPrecedenceAndTypes?.raw
14805+
layout[7] = operatorPrecedenceAndTypes?.raw
14806+
layout[8] = unexpectedAfterOperatorPrecedenceAndTypes?.raw
1481114807
}
1481214808
self.init(unchecked: raw)
1481314809
}
1481414810

14815-
public var unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? {
14811+
public var unexpectedBeforeOperatorModifier: RawUnexpectedNodesSyntax? {
1481614812
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
1481714813
}
1481814814

14819-
public var attributes: RawAttributeListSyntax? {
14820-
layoutView.children[1].map(RawAttributeListSyntax.init(raw:))
14815+
public var operatorModifier: RawTokenSyntax {
14816+
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
1482114817
}
1482214818

14823-
public var unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? {
14819+
public var unexpectedBetweenOperatorModifierAndOperatorKeyword: RawUnexpectedNodesSyntax? {
1482414820
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
1482514821
}
1482614822

14827-
public var modifiers: RawModifierListSyntax? {
14828-
layoutView.children[3].map(RawModifierListSyntax.init(raw:))
14829-
}
14830-
14831-
public var unexpectedBetweenModifiersAndOperatorKeyword: RawUnexpectedNodesSyntax? {
14832-
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
14833-
}
14834-
1483514823
public var operatorKeyword: RawTokenSyntax {
14836-
layoutView.children[5].map(RawTokenSyntax.init(raw:))!
14824+
layoutView.children[3].map(RawTokenSyntax.init(raw:))!
1483714825
}
1483814826

1483914827
public var unexpectedBetweenOperatorKeywordAndIdentifier: RawUnexpectedNodesSyntax? {
14840-
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
14828+
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
1484114829
}
1484214830

1484314831
public var identifier: RawTokenSyntax {
14844-
layoutView.children[7].map(RawTokenSyntax.init(raw:))!
14832+
layoutView.children[5].map(RawTokenSyntax.init(raw:))!
1484514833
}
1484614834

1484714835
public var unexpectedBetweenIdentifierAndOperatorPrecedenceAndTypes: RawUnexpectedNodesSyntax? {
14848-
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
14836+
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
1484914837
}
1485014838

1485114839
public var operatorPrecedenceAndTypes: RawOperatorPrecedenceAndTypesSyntax? {
14852-
layoutView.children[9].map(RawOperatorPrecedenceAndTypesSyntax.init(raw:))
14840+
layoutView.children[7].map(RawOperatorPrecedenceAndTypesSyntax.init(raw:))
1485314841
}
1485414842

1485514843
public var unexpectedAfterOperatorPrecedenceAndTypes: RawUnexpectedNodesSyntax? {
14856-
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
14844+
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
1485714845
}
1485814846
}
1485914847

0 commit comments

Comments
 (0)