Skip to content

Commit 085f207

Browse files
committed
Add Trivia.commentValues from @adammcarter
- Copied changes from PR #2578 (#2578) - Original work by @adammcarter - Manual copy due to inaccessible original branch
1 parent 1c0e46a commit 085f207

File tree

3 files changed

+429
-0
lines changed

3 files changed

+429
-0
lines changed

Diff for: Sources/SwiftSyntax/Trivia.swift

+62
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,68 @@ public struct Trivia: Sendable {
4242
pieces.isEmpty
4343
}
4444

45+
/// The string contents of all the comment pieces with any comments tokens trimmed.
46+
///
47+
/// Each element in the array is the trimmed contents of a line comment, or, in the case of a multi-line comment a trimmed, concatenated single string.
48+
public var commentValues: [String] {
49+
var comments = [String]()
50+
var partialComments = [String]()
51+
52+
var foundStartOfCodeBlock = false
53+
var foundEndOfCodeBlock = false
54+
var isInCodeBlock: Bool { foundStartOfCodeBlock && !foundEndOfCodeBlock }
55+
56+
for piece in pieces {
57+
switch piece {
58+
case .blockComment(let text), .docBlockComment(let text):
59+
let text = text.trimmingCharacters(in: "\n")
60+
61+
foundStartOfCodeBlock = text.hasPrefix("/*")
62+
foundEndOfCodeBlock = text.hasSuffix("*/")
63+
64+
let sanitized =
65+
text
66+
.split(separator: "\n")
67+
.map { $0.trimmingAnyCharacters(in: "/*").trimmingAnyCharacters(in: " ") }
68+
.filter { !$0.isEmpty }
69+
.joined(separator: " ")
70+
71+
appendPartialCommentIfPossible(sanitized)
72+
73+
case .lineComment(let text), .docLineComment(let text):
74+
if isInCodeBlock {
75+
appendPartialCommentIfPossible(text)
76+
} else {
77+
comments.append(String(text.trimmingPrefix("/ ")))
78+
}
79+
80+
default:
81+
break
82+
}
83+
84+
if foundEndOfCodeBlock, !partialComments.isEmpty {
85+
appendSubstringsToLines()
86+
partialComments.removeAll()
87+
}
88+
}
89+
90+
if !partialComments.isEmpty {
91+
appendSubstringsToLines()
92+
}
93+
94+
func appendPartialCommentIfPossible(_ text: String) {
95+
guard partialComments.isEmpty || !text.isEmpty else { return }
96+
97+
partialComments.append(text)
98+
}
99+
100+
func appendSubstringsToLines() {
101+
comments.append(partialComments.joined(separator: " "))
102+
}
103+
104+
return comments
105+
}
106+
45107
/// The length of all the pieces in this ``Trivia``.
46108
public var sourceLength: SourceLength {
47109
return pieces.map({ $0.sourceLength }).reduce(.zero, +)

Diff for: Sources/SwiftSyntax/Utils.swift

+46
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,49 @@ extension RawUnexpectedNodesSyntax {
102102
self.init(raw: raw)
103103
}
104104
}
105+
106+
extension String {
107+
func trimmingCharacters(in charactersToTrim: any BidirectionalCollection<Character>) -> Substring {
108+
// TODO: adammcarter - this feels a bit dirty
109+
self[startIndex...].trimmingAnyCharacters(in: charactersToTrim)
110+
}
111+
112+
func trimmingPrefix(_ charactersToTrim: any BidirectionalCollection<Character>) -> Substring {
113+
self[startIndex...].trimmingAnyCharactersFromPrefix(in: charactersToTrim)
114+
}
115+
116+
func trimmingSuffix(_ charactersToTrim: any BidirectionalCollection<Character>) -> Substring {
117+
self[startIndex...].trimmingAnyCharactersFromSuffix(in: charactersToTrim)
118+
}
119+
}
120+
121+
extension Substring {
122+
func trimmingAnyCharacters(in charactersToTrim: any BidirectionalCollection<Character>) -> Substring {
123+
trimmingAnyCharactersFromPrefix(in: charactersToTrim).trimmingAnyCharactersFromSuffix(in: charactersToTrim)
124+
}
125+
126+
func trimmingAnyCharactersFromPrefix(in charactersToTrim: any BidirectionalCollection<Character>) -> Self {
127+
dropFirst(countOfSequentialCharacters(charactersToTrim, in: self))
128+
}
129+
130+
func trimmingAnyCharactersFromSuffix(in charactersToTrim: any BidirectionalCollection<Character>) -> Self {
131+
dropLast(countOfSequentialCharacters(charactersToTrim, in: reversed()))
132+
}
133+
}
134+
135+
private func countOfSequentialCharacters(
136+
_ charactersToCount: any BidirectionalCollection<Character>,
137+
in characters: any BidirectionalCollection<Character>
138+
) -> Int {
139+
var count = 0
140+
141+
for character in characters {
142+
if charactersToCount.contains(character) {
143+
count += 1
144+
} else {
145+
break
146+
}
147+
}
148+
149+
return count
150+
}

0 commit comments

Comments
 (0)