Skip to content

Commit 93aade8

Browse files
committed
Merge pull request #546 from allevato/macro-decls
Format `macro` declarations.
1 parent 9ab8329 commit 93aade8

File tree

2 files changed

+443
-0
lines changed

2 files changed

+443
-0
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,52 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
240240
return .visitChildren
241241
}
242242

243+
override func visit(_ node: MacroDeclSyntax) -> SyntaxVisitorContinueKind {
244+
// Macro declarations have a syntax that combines the best parts of types and functions while
245+
// adding their own unique flavor, so we have to copy and adapt the relevant parts of those
246+
// `arrange*` functions here.
247+
before(node.firstToken(viewMode: .sourceAccurate), tokens: .open)
248+
249+
arrangeAttributeList(node.attributes)
250+
251+
let hasArguments = !node.signature.input.parameterList.isEmpty
252+
253+
// Prioritize keeping ") -> <return_type>" together. We can only do this if the macro has
254+
// arguments.
255+
if hasArguments && config.prioritizeKeepingFunctionOutputTogether {
256+
// Due to visitation order, the matching .open break is added in ParameterClauseSyntax.
257+
after(node.signature.lastToken(viewMode: .sourceAccurate), tokens: .close)
258+
}
259+
260+
let mustBreak = node.signature.output != nil || node.definition != nil
261+
arrangeParameterClause(node.signature.input, forcesBreakBeforeRightParen: mustBreak)
262+
263+
// Prioritize keeping "<modifiers> macro <name>(" together. Also include the ")" if the
264+
// parameter list is empty.
265+
let firstTokenAfterAttributes =
266+
node.modifiers?.firstToken(viewMode: .sourceAccurate) ?? node.macroKeyword
267+
before(firstTokenAfterAttributes, tokens: .open)
268+
after(node.macroKeyword, tokens: .break)
269+
if hasArguments || node.genericParameterClause != nil {
270+
after(node.signature.input.leftParen, tokens: .close)
271+
} else {
272+
after(node.signature.input.rightParen, tokens: .close)
273+
}
274+
275+
if let genericWhereClause = node.genericWhereClause {
276+
before(genericWhereClause.firstToken(viewMode: .sourceAccurate), tokens: .break(.same), .open)
277+
after(genericWhereClause.lastToken(viewMode: .sourceAccurate), tokens: .close)
278+
}
279+
if let definition = node.definition {
280+
// Start the group *after* the `=` so that it all wraps onto its own line if it doesn't fit.
281+
after(definition.equal, tokens: .open)
282+
after(definition.lastToken(viewMode: .sourceAccurate), tokens: .close)
283+
}
284+
285+
after(node.lastToken(viewMode: .sourceAccurate), tokens: .close)
286+
return .visitChildren
287+
}
288+
243289
/// Applies formatting tokens to the tokens in the given type declaration node (i.e., a class,
244290
/// struct, enum, protocol, or extension).
245291
private func arrangeTypeDeclBlock(

0 commit comments

Comments
 (0)