Skip to content

Commit db21e49

Browse files
committed
Fold operators using the standard operator table in MacroSystem
The compiler folds operators in attributes and freestanding macro nodes but `MacroSystem` wasn’t doing that. But it should to match the compiler behavior. rdar://114786803 Fixes #2128
1 parent 23be62c commit db21e49

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

Sources/SwiftCompilerPluginMessageHandling/PluginMacroExpansionContext.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class SourceManager {
8585
case .attribute:
8686
node = Syntax(AttributeSyntax.parse(from: &parser))
8787
}
88-
if let operatorTable = operatorTable {
88+
if let operatorTable {
8989
node = operatorTable.foldAll(node, errorHandler: { _ in /*ignore*/ })
9090
}
9191

Sources/SwiftSyntaxMacroExpansion/BasicMacroExpansionContext.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SwiftDiagnostics
14+
import SwiftOperators
1415
import SwiftSyntax
1516
import SwiftSyntaxMacros
1617

@@ -77,6 +78,20 @@ extension BasicMacroExpansionContext {
7778
detachedNodes[Syntax(detached)] = Syntax(node)
7879
return detached
7980
}
81+
82+
/// Fold all operators in `node` and associated the ``KnownSourceFile``
83+
/// information of `node` with the original new, folded tree.
84+
func foldAllOperators(of node: some SyntaxProtocol, with operatorTable: OperatorTable) -> Syntax {
85+
let folded = operatorTable.foldAll(node, errorHandler: { _ in /*ignore*/ })
86+
if let originalSourceFile = node.root.as(SourceFileSyntax.self),
87+
let newSourceFile = folded.root.as(SourceFileSyntax.self)
88+
{
89+
// Folding operators doesn't change the source file and its associated locations
90+
// Record the `KnownSourceFile` information for the folded tree.
91+
sourceFiles[newSourceFile] = sourceFiles[originalSourceFile]
92+
}
93+
return folded
94+
}
8095
}
8196

8297
extension String {

Sources/SwiftSyntaxMacroExpansion/MacroSystem.swift

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SwiftDiagnostics
14+
import SwiftOperators
1415
import SwiftSyntax
1516
import SwiftSyntaxBuilder
1617
@_spi(MacroExpansion) import SwiftParser
@@ -55,7 +56,7 @@ private func expandFreestandingMemberDeclList(
5556
let expanded = try expandFreestandingMacro(
5657
definition: definition,
5758
macroRole: inferFreestandingMacroRole(definition: definition),
58-
node: node.detach(in: context),
59+
node: node.detach(in: context, foldingWith: .standardOperators),
5960
in: context,
6061
indentationWidth: indentationWidth
6162
)
@@ -80,7 +81,7 @@ private func expandFreestandingCodeItemList(
8081
let expanded = try expandFreestandingMacro(
8182
definition: definition,
8283
macroRole: inferFreestandingMacroRole(definition: definition),
83-
node: node.detach(in: context),
84+
node: node.detach(in: context, foldingWith: .standardOperators),
8485
in: context,
8586
indentationWidth: indentationWidth
8687
)
@@ -108,7 +109,7 @@ private func expandFreestandingExpr(
108109
let expanded = expandFreestandingMacro(
109110
definition: definition,
110111
macroRole: .expression,
111-
node: node.detach(in: context),
112+
node: node.detach(in: context, foldingWith: .standardOperators),
112113
in: context,
113114
indentationWidth: indentationWidth
114115
)
@@ -134,7 +135,7 @@ private func expandMemberMacro(
134135
let expanded = expandAttachedMacro(
135136
definition: definition,
136137
macroRole: .member,
137-
attributeNode: attributeNode.detach(in: context),
138+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
138139
declarationNode: attachedTo.detach(in: context),
139140
parentDeclNode: nil,
140141
extendedType: nil,
@@ -163,7 +164,7 @@ private func expandMemberAttributeMacro(
163164
let expanded = expandAttachedMacro(
164165
definition: definition,
165166
macroRole: .memberAttribute,
166-
attributeNode: attributeNode.detach(in: context),
167+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
167168
declarationNode: member.detach(in: context),
168169
parentDeclNode: declaration.detach(in: context),
169170
extendedType: nil,
@@ -191,7 +192,7 @@ private func expandPeerMacroMember(
191192
let expanded = expandAttachedMacro(
192193
definition: definition,
193194
macroRole: .peer,
194-
attributeNode: attributeNode.detach(in: context),
195+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
195196
declarationNode: attachedTo.detach(in: context),
196197
parentDeclNode: nil,
197198
extendedType: nil,
@@ -219,7 +220,7 @@ private func expandPeerMacroCodeItem(
219220
let expanded = expandAttachedMacro(
220221
definition: definition,
221222
macroRole: .peer,
222-
attributeNode: attributeNode.detach(in: context),
223+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
223224
declarationNode: attachedTo.detach(in: context),
224225
parentDeclNode: nil,
225226
extendedType: nil,
@@ -251,7 +252,7 @@ private func expandAccessorMacroWithoutExistingAccessors(
251252
let expanded = expandAttachedMacro(
252253
definition: definition,
253254
macroRole: .accessor,
254-
attributeNode: attributeNode.detach(in: context),
255+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
255256
declarationNode: attachedTo.detach(in: context),
256257
parentDeclNode: nil,
257258
extendedType: nil,
@@ -285,7 +286,7 @@ private func expandAccessorMacroWithExistingAccessors(
285286
let expanded = expandAttachedMacro(
286287
definition: definition,
287288
macroRole: .accessor,
288-
attributeNode: attributeNode.detach(in: context),
289+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
289290
declarationNode: attachedTo.detach(in: context),
290291
parentDeclNode: nil,
291292
extendedType: nil,
@@ -322,7 +323,7 @@ private func expandExtensionMacro(
322323
let expanded = expandAttachedMacro(
323324
definition: definition,
324325
macroRole: .extension,
325-
attributeNode: attributeNode.detach(in: context),
326+
attributeNode: attributeNode.detach(in: context, foldingWith: .standardOperators),
326327
declarationNode: attachedTo.detach(in: context),
327328
parentDeclNode: nil,
328329
extendedType: extendedType.detach(in: context),
@@ -1007,4 +1008,47 @@ private extension SyntaxProtocol {
10071008

10081009
return self.detached
10091010
}
1011+
1012+
/// Fold operators in this node using the given operator table, detach the
1013+
/// node and inform the macro expansion context, if it needs to know.
1014+
func detach(
1015+
in context: MacroExpansionContext,
1016+
foldingWith operatorTable: OperatorTable?
1017+
) -> Syntax {
1018+
let folded: Syntax
1019+
if let operatorTable {
1020+
if let basicContext = context as? BasicMacroExpansionContext {
1021+
folded = basicContext.foldAllOperators(of: self, with: operatorTable)
1022+
} else {
1023+
folded = operatorTable.foldAll(self, errorHandler: { _ in /*ignore*/ })
1024+
}
1025+
} else {
1026+
folded = Syntax(self)
1027+
}
1028+
return folded.detach(in: context)
1029+
}
1030+
}
1031+
1032+
private extension FreestandingMacroExpansionSyntax {
1033+
/// Same as `SyntaxProtocol.detach(in:foldingWith:)` but returns a node of type
1034+
/// `Self` since we know that operator folding doesn't change the type of any
1035+
/// `FreestandingMacroExpansionSyntax`.
1036+
func detach(
1037+
in context: MacroExpansionContext,
1038+
foldingWith operatorTable: OperatorTable?
1039+
) -> Self {
1040+
return (detach(in: context, foldingWith: operatorTable) as Syntax).cast(Self.self)
1041+
}
1042+
}
1043+
1044+
private extension AttributeSyntax {
1045+
/// Same as `SyntaxProtocol.detach(in:foldingWith:)` but returns a node of type
1046+
/// `Self` since we know that operator folding doesn't change the type of any
1047+
/// `AttributeSyntax`.
1048+
func detach(
1049+
in context: MacroExpansionContext,
1050+
foldingWith operatorTable: OperatorTable?
1051+
) -> Self {
1052+
return (detach(in: context, foldingWith: operatorTable) as Syntax).cast(Self.self)
1053+
}
10101054
}

0 commit comments

Comments
 (0)