Skip to content

Commit 7f83979

Browse files
authored
Merge pull request #1323 from kimdv/kimdv/add-custom-format-to-code-gen
Add custom format to code gen for `TupleExprElementListSyntax`, `FunctionParameterListSyntax`, `ArrayElementListSyntax` and `DictionaryElementListSyntax `
2 parents 1c0bccd + 59801d4 commit 7f83979

File tree

9 files changed

+2189
-913
lines changed

9 files changed

+2189
-913
lines changed

CodeGeneration/Sources/Utils/CodeGenerationFormat.swift

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,42 @@ import SwiftSyntax
1717
public class CodeGenerationFormat: BasicFormat {
1818
public override var indentation: TriviaPiece { .spaces(indentationLevel * 2) }
1919

20-
public func ensuringTwoLeadingNewlines<NodeType: SyntaxProtocol>(node: NodeType) -> NodeType {
21-
if node.leadingTrivia?.first?.isNewline ?? false {
22-
return node.with(\.leadingTrivia, indentedNewline + (node.leadingTrivia ?? []))
20+
public override func visit(_ node: ArrayElementListSyntax) -> ArrayElementListSyntax {
21+
let children = node.children(viewMode: .all)
22+
// Short array literals are presented on one line, list each element on a different line.
23+
if children.count > 3 {
24+
return ArrayElementListSyntax(formatChildrenSeparatedByNewline(children: children, elementType: ArrayElementSyntax.self))
2325
} else {
24-
return node.with(\.leadingTrivia, indentedNewline + indentedNewline + (node.leadingTrivia ?? []))
26+
return super.visit(node)
27+
}
28+
}
29+
30+
public override func visit(_ node: CodeBlockItemSyntax) -> CodeBlockItemSyntax {
31+
if node.parent?.parent?.is(SourceFileSyntax.self) == true, !node.item.is(ImportDeclSyntax.self) {
32+
let formatted = super.visit(node)
33+
return ensuringTwoLeadingNewlines(node: formatted)
34+
} else {
35+
return super.visit(node)
36+
}
37+
}
38+
39+
public override func visit(_ node: DictionaryElementListSyntax) -> DictionaryElementListSyntax {
40+
let children = node.children(viewMode: .all)
41+
// Short dictionary literals are presented on one line, list each element on a different line.
42+
if children.count > 3 {
43+
return DictionaryElementListSyntax(formatChildrenSeparatedByNewline(children: children, elementType: DictionaryElementSyntax.self))
44+
} else {
45+
return super.visit(node)
46+
}
47+
}
48+
49+
public override func visit(_ node: FunctionParameterListSyntax) -> FunctionParameterListSyntax {
50+
let children = node.children(viewMode: .all)
51+
// Short function parameter literals are presented on one line, list each element on a different line.
52+
if children.count > 3 {
53+
return FunctionParameterListSyntax(formatChildrenSeparatedByNewline(children: children, elementType: FunctionParameterSyntax.self))
54+
} else {
55+
return super.visit(node)
2556
}
2657
}
2758

@@ -34,12 +65,42 @@ public class CodeGenerationFormat: BasicFormat {
3465
}
3566
}
3667

37-
public override func visit(_ node: CodeBlockItemSyntax) -> CodeBlockItemSyntax {
38-
if node.parent?.parent?.is(SourceFileSyntax.self) == true, !node.item.is(ImportDeclSyntax.self) {
39-
let formatted = super.visit(node)
40-
return ensuringTwoLeadingNewlines(node: formatted)
68+
public override func visit(_ node: TupleExprElementListSyntax) -> TupleExprElementListSyntax {
69+
let children = node.children(viewMode: .all)
70+
// Short tuple element list literals are presented on one line, list each element on a different line.
71+
if children.count > 3 {
72+
return TupleExprElementListSyntax(formatChildrenSeparatedByNewline(children: children, elementType: TupleExprElementSyntax.self))
4173
} else {
4274
return super.visit(node)
4375
}
4476
}
77+
78+
// MARK: - Private
79+
80+
private func ensuringTwoLeadingNewlines<NodeType: SyntaxProtocol>(node: NodeType) -> NodeType {
81+
if node.leadingTrivia?.first?.isNewline ?? false {
82+
return node.with(\.leadingTrivia, indentedNewline + (node.leadingTrivia ?? []))
83+
} else {
84+
return node.with(\.leadingTrivia, indentedNewline + indentedNewline + (node.leadingTrivia ?? []))
85+
}
86+
}
87+
88+
private func formatChildrenSeparatedByNewline<SyntaxType: SyntaxProtocol>(children: SyntaxChildren, elementType: SyntaxType.Type) -> [SyntaxType] {
89+
indentationLevel += 1
90+
var formattedChildren = children.map {
91+
self.visit($0).as(SyntaxType.self)!
92+
}
93+
formattedChildren = formattedChildren.map {
94+
if $0.leadingTrivia?.first?.isNewline == true {
95+
return $0
96+
} else {
97+
return $0.with(\.leadingTrivia, indentedNewline + ($0.leadingTrivia ?? []))
98+
}
99+
}
100+
indentationLevel -= 1
101+
if !formattedChildren.isEmpty {
102+
formattedChildren[formattedChildren.count - 1] = formattedChildren[formattedChildren.count - 1].with(\.trailingTrivia, indentedNewline)
103+
}
104+
return formattedChildren
105+
}
45106
}

CodeGeneration/Sources/generate-swiftsyntax/KeywordFile.swift renamed to CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/KeywordFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Utils
1717

1818
let lookupTable = ArrayExprSyntax(leftSquare: .leftSquareBracketToken(trailingTrivia: .newline)) {
1919
for keyword in KEYWORDS {
20-
ArrayElementSyntax(expression: ExprSyntax("\(literal: keyword.name)"), trailingComma: .commaToken(), trailingTrivia: .newline)
20+
ArrayElementSyntax(expression: ExprSyntax("\(literal: keyword.name)"), trailingComma: .commaToken())
2121
}
2222
}
2323

Sources/SwiftBasicFormat/generated/BasicFormat.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ open class BasicFormat: SyntaxRewriter {
6161
leadingTrivia = leadingTrivia.indented(indentation: indentation)
6262
trailingTrivia = trailingTrivia.indented(indentation: indentation)
6363
let rewritten = TokenSyntax(
64-
node.tokenKind,
65-
leadingTrivia: leadingTrivia,
66-
trailingTrivia: trailingTrivia,
67-
presence: node.presence
64+
node.tokenKind,
65+
leadingTrivia: leadingTrivia,
66+
trailingTrivia: trailingTrivia,
67+
presence: node.presence
68+
6869
)
6970
lastRewrittenToken = rewritten
7071
putNextTokenOnNewLine = false

0 commit comments

Comments
 (0)