Skip to content

Commit e5b9f2e

Browse files
committed
Add a doc comment section mentioning which nodes a node occurs as a child in
Fixes #1920 rdar://112433203
1 parent 680942e commit e5b9f2e

File tree

7 files changed

+1909
-10
lines changed

7 files changed

+1909
-10
lines changed

CodeGeneration/Sources/SyntaxSupport/Node.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,50 @@ public class Node {
149149
self.data = .layout(children: childrenWithUnexpected, traits: traits)
150150
}
151151

152+
/// A doc comment that lists all the nodes in which this node occurs as a child in.
153+
public var containedIn: SwiftSyntax.Trivia {
154+
var childIn: [(node: SyntaxNodeKind, child: Child?)] = []
155+
for node in SYNTAX_NODES {
156+
if let layout = node.layoutNode {
157+
for child in layout.children {
158+
if child.kinds.contains(self.kind) {
159+
childIn.append((node.kind, child))
160+
}
161+
}
162+
} else if let collection = node.collectionNode {
163+
if collection.elementChoices.contains(self.kind) {
164+
childIn.append((node.kind, nil))
165+
}
166+
}
167+
}
168+
169+
guard !childIn.isEmpty else {
170+
return []
171+
}
172+
173+
let list =
174+
childIn
175+
.map {
176+
if let childName = $0.child?.varName {
177+
// This will repeat the syntax type before and after the dot, which is
178+
// a little unfortunate, but it's the only way I found to get docc to
179+
// generate a fully-qualified type + member.
180+
return " - ``\($0.node.syntaxType)``.``\($0.node.syntaxType)/\(childName)``"
181+
} else {
182+
return " - ``\($0.node.syntaxType)``"
183+
}
184+
}
185+
.joined(separator: "\n")
186+
187+
return docCommentTrivia(
188+
from: """
189+
### Contained in
190+
191+
\(list)
192+
"""
193+
)
194+
}
195+
152196
/// Construct the specification for a collection syntax node.
153197
///
154198
/// `base` must be `.syntaxCollection`.
@@ -288,3 +332,22 @@ public struct CollectionNode {
288332
)
289333
}
290334
}
335+
336+
fileprivate extension Child {
337+
var kinds: [SyntaxNodeKind] {
338+
switch kind {
339+
case .node(let kind):
340+
return [kind]
341+
case .nodeChoices(let choices):
342+
return choices.flatMap(\.kinds)
343+
case .collection(let kind, _, _):
344+
return [kind]
345+
case .token:
346+
return [.token]
347+
}
348+
}
349+
}
350+
351+
fileprivate extension Node {
352+
353+
}

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ import Utils
1717

1818
let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
1919
for node in SYNTAX_NODES.compactMap(\.collectionNode) {
20-
let documentation = """
21-
\(node.documentation)
22-
\(node.documentation.isEmpty ? "" : "///")
23-
\(node.grammar)
24-
""".removingEmptyLines
20+
let documentationSections = [
21+
node.documentation,
22+
node.grammar,
23+
node.containedIn,
24+
]
25+
26+
let documentation =
27+
documentationSections
28+
.filter { !$0.isEmpty }
29+
.map { [$0] }
30+
.joined(separator: [Trivia.newline, Trivia.docLineComment("///"), Trivia.newline])
31+
.reduce(Trivia(), +)
2532

2633
try! StructDeclSyntax(
2734
"""

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ extension Child {
3333
func syntaxNode(emitKind: SyntaxNodeKind) -> SourceFileSyntax {
3434
SourceFileSyntax(leadingTrivia: copyrightHeader) {
3535
for node in SYNTAX_NODES.compactMap(\.layoutNode) where node.base == emitKind {
36-
let documentation = """
37-
\(node.documentation)
38-
\(node.documentation.isEmpty ? "" : "///")
39-
\(node.grammar)
40-
""".removingEmptyLines
36+
let documentationSections = [
37+
node.documentation,
38+
node.grammar,
39+
node.containedIn,
40+
]
41+
let documentation =
42+
documentationSections
43+
.filter { !$0.isEmpty }
44+
.map { [$0] }
45+
.joined(separator: [Trivia.newline, Trivia.docLineComment("///"), Trivia.newline])
46+
.reduce(Trivia(), +)
4147

4248
// We are actually handling this node now
4349
try! StructDeclSyntax(

0 commit comments

Comments
 (0)