Skip to content

Commit c22124e

Browse files
committed
Make all Syntax non-optional in OperatorError cases.
Always provide syntax nodes, even if they are synthesized, when forming an OperatorError. This eliminates the need for clients to do this synthesis.
1 parent b67fdaa commit c22124e

File tree

6 files changed

+48
-39
lines changed

6 files changed

+48
-39
lines changed

Sources/SwiftOperators/OperatorError+Diagnostics.swift

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,23 @@ extension OperatorError : DiagnosticMessage {
4848
}
4949

5050
extension OperatorError {
51-
private func fixupDiagnosticDisplayNode<Node: SyntaxProtocol>(
52-
_ node: Node?
53-
) -> Syntax {
54-
if let node = node {
55-
return Syntax(node)
56-
}
57-
58-
return Syntax(MissingDeclSyntax(attributes: nil, modifiers: nil))
59-
}
60-
6151
/// Produce the syntax node at which a diagnostic should be displayed.
6252
var diagnosticDisplayNode: Syntax {
6353
switch self {
6454
case .incomparableOperators(let leftOperator, _, _, _):
6555
return Syntax(leftOperator)
6656

6757
case .missingOperator(_, let node):
68-
return fixupDiagnosticDisplayNode(node)
58+
return node
6959

7060
case .operatorAlreadyExists(_, let newOperator):
71-
return fixupDiagnosticDisplayNode(newOperator.syntax)
61+
return Syntax(newOperator.syntax ?? newOperator.synthesizedSyntax())
7262

7363
case .missingGroup(_, let node):
74-
return fixupDiagnosticDisplayNode(node)
64+
return node
7565

7666
case .groupAlreadyExists(_, let newGroup):
77-
return fixupDiagnosticDisplayNode(newGroup.syntax)
67+
return Syntax(newGroup.syntax ?? newGroup.synthesizedSyntax())
7868
}
7969
}
8070

Sources/SwiftOperators/OperatorError.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ public enum OperatorError: Error {
1818
case groupAlreadyExists(existing: PrecedenceGroup, new: PrecedenceGroup)
1919

2020
/// The named precedence group is missing from the precedence graph.
21-
case missingGroup(PrecedenceGroupName, referencedFrom: Syntax?)
21+
case missingGroup(PrecedenceGroupName, referencedFrom: Syntax)
2222

2323
/// Error produced when a given operator already exists.
2424
case operatorAlreadyExists(existing: Operator, new: Operator)
2525

2626
/// The named operator is missing from the precedence graph.
27-
case missingOperator(OperatorName, referencedFrom: Syntax?)
27+
case missingOperator(OperatorName, referencedFrom: Syntax)
2828

2929
/// No associativity relationship between operators.
3030
case incomparableOperators(

Sources/SwiftOperators/OperatorTable+Folding.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extension OperatorTable {
4747

4848
return try precedenceGraph.precedence(
4949
relating: groupName, to: boundGroupName,
50-
startSyntax: operatorSyntax, endSyntax: bound.syntax,
50+
startSyntax: operatorSyntax, endSyntax: bound.syntax!,
5151
errorHandler: errorHandler
5252
) != .lowerThan
5353
}
@@ -177,9 +177,9 @@ extension OperatorTable {
177177
/// Determine the associativity between two precedence groups.
178178
private func associativity(
179179
firstGroup: PrecedenceGroupName?,
180-
firstOperatorSyntax: Syntax?,
180+
firstOperatorSyntax: Syntax,
181181
secondGroup: PrecedenceGroupName?,
182-
secondOperatorSyntax: Syntax?,
182+
secondOperatorSyntax: Syntax,
183183
errorHandler: OperatorErrorHandler = { throw $0 }
184184
) rethrows -> Associativity {
185185
guard let firstGroup = firstGroup, let secondGroup = secondGroup else {

Sources/SwiftOperators/OperatorTable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ extension OperatorTable {
8585
/// Look for the precedence group corresponding to the given operator.
8686
func lookupOperatorPrecedenceGroupName(
8787
_ operatorName: OperatorName,
88-
referencedFrom syntax: Syntax?,
88+
referencedFrom syntax: Syntax,
8989
errorHandler: OperatorErrorHandler = { throw $0 }
9090
) rethrows -> PrecedenceGroupName? {
9191
guard let op = infixOperators[operatorName] else {

Sources/SwiftOperators/PrecedenceGraph.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct PrecedenceGraph {
6161
/// (fromGroup, fromSyntax) and following precedence groups in the
6262
/// specified direction.
6363
private func searchRelationships(
64-
initialGroupName: PrecedenceGroupName, initialSyntax: Syntax?,
64+
initialGroupName: PrecedenceGroupName, initialSyntax: Syntax,
6565
targetGroupName: PrecedenceGroupName,
6666
direction: PrecedenceRelation.Kind,
6767
errorHandler: OperatorErrorHandler
@@ -70,7 +70,7 @@ struct PrecedenceGraph {
7070
// the graph. This detects cycles and prevents extraneous work.
7171
var groupsSeen: Set<PrecedenceGroupName> = []
7272

73-
var stack: [(PrecedenceGroupName, Syntax?)] =
73+
var stack: [(PrecedenceGroupName, Syntax)] =
7474
[(initialGroupName, initialSyntax)]
7575
while let (currentGroupName, currentOperatorSyntax) = stack.popLast() {
7676
guard let currentGroup = lookupGroup(currentGroupName) else {
@@ -94,7 +94,14 @@ struct PrecedenceGraph {
9494
}
9595

9696
if groupsSeen.insert(otherGroupName).inserted {
97-
stack.append((otherGroupName, relation.syntax.map { Syntax($0) }))
97+
let relationSyntax: Syntax
98+
if let knownSyntax = relation.syntax {
99+
relationSyntax = Syntax(knownSyntax)
100+
} else {
101+
relationSyntax =
102+
Syntax(relation.synthesizedSyntax().otherNames.first!.name)
103+
}
104+
stack.append((otherGroupName, relationSyntax))
98105
}
99106
}
100107
}
@@ -114,8 +121,8 @@ struct PrecedenceGraph {
114121
func precedence(
115122
relating startGroupName: PrecedenceGroupName,
116123
to endGroupName: PrecedenceGroupName,
117-
startSyntax: Syntax?,
118-
endSyntax: Syntax?,
124+
startSyntax: Syntax,
125+
endSyntax: Syntax,
119126
errorHandler: OperatorErrorHandler = { throw $0 }
120127
) rethrows -> Precedence {
121128
if startGroupName == endGroupName {

Sources/SwiftOperators/SyntaxSynthesis.swift

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,31 @@ extension Operator {
3939
}
4040
}
4141

42+
extension PrecedenceRelation {
43+
/// Synthesize a syntactic representation of this precedence relation based on
44+
/// its semantic definition.
45+
///
46+
/// We only use this internally to synthesize syntactic locations.
47+
func synthesizedSyntax(
48+
indentation: Int = 4
49+
) -> PrecedenceGroupRelationSyntax {
50+
PrecedenceGroupRelationSyntax(
51+
higherThanOrLowerThan: .contextualKeyword(
52+
"\(kind)",
53+
leadingTrivia: [ .newlines(1), .spaces(indentation) ]
54+
),
55+
colon: .colonToken(),
56+
otherNames: PrecedenceGroupNameListSyntax(
57+
[
58+
PrecedenceGroupNameElementSyntax(
59+
name: .identifier(groupName, leadingTrivia: .space),
60+
trailingComma: nil)
61+
]
62+
)
63+
)
64+
}
65+
}
66+
4267
extension PrecedenceGroup {
4368
/// Synthesize a syntactic representation of this precedence group based on
4469
/// its semantic definition.
@@ -92,20 +117,7 @@ extension PrecedenceGroup {
92117
for relation in relations {
93118
groupAttributes.append(
94119
Syntax(
95-
PrecedenceGroupRelationSyntax(
96-
higherThanOrLowerThan: .contextualKeyword(
97-
"\(relation.kind)",
98-
leadingTrivia: [ .newlines(1), .spaces(indentation) ]
99-
),
100-
colon: .colonToken(),
101-
otherNames: PrecedenceGroupNameListSyntax(
102-
[
103-
PrecedenceGroupNameElementSyntax(
104-
name: .identifier(relation.groupName, leadingTrivia: .space),
105-
trailingComma: nil)
106-
]
107-
)
108-
)
120+
relation.synthesizedSyntax()
109121
)
110122
)
111123
}

0 commit comments

Comments
 (0)