Skip to content

Commit 5d6ca8c

Browse files
authored
Merge pull request swiftlang#135 from dabelknap/block-comments
Add support for block comments
2 parents 57054f7 + 465ff41 commit 5d6ca8c

File tree

3 files changed

+196
-18
lines changed

3 files changed

+196
-18
lines changed

Sources/SwiftFormatPrettyPrint/Comment.swift

+26-18
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,53 @@ struct Comment {
2121
/// The length of the characters starting the comment.
2222
var prefixLength: Int {
2323
switch self {
24-
// `//`, `/*`, and `/**` all will have their continued lines prefixed with 3 characters.
25-
case .line, .block, .docBlock: return 2
26-
27-
// `/// ` is 4 characters.
28-
case .docLine: return 3
24+
// `//`, `/*`
25+
case .line, .block: return 2
26+
// `///`, `/**`
27+
case .docLine, .docBlock: return 3
2928
}
3029
}
3130

3231
var prefix: String {
3332
switch self {
3433
case .line: return "//"
35-
case .block, .docBlock: return " "
34+
case .block: return "/*"
35+
case .docBlock: return "/**"
3636
case .docLine: return "///"
3737
}
3838
}
3939
}
40+
4041
let kind: Kind
4142
var text: [String]
4243
public var length: Int
4344

4445
init(kind: Kind, text: String) {
45-
self.text = [text]
4646
self.kind = kind
47-
self.length = text.count + kind.prefixLength + 1
48-
49-
self.text[0].removeFirst(kind.prefixLength)
50-
5147
switch kind {
52-
case .docBlock:
53-
self.text.removeLast(2)
54-
case .block:
55-
self.text.removeLast(2)
56-
default: break
48+
case .line, .docLine:
49+
self.text = [text]
50+
self.text[0].removeFirst(kind.prefixLength)
51+
self.length = self.text.reduce(0, { $0 + $1.count + kind.prefixLength + 1 })
52+
53+
case .block, .docBlock:
54+
var fulltext: String = text
55+
fulltext.removeFirst(kind.prefixLength)
56+
fulltext.removeLast(2)
57+
self.text = fulltext.split(separator: "\n", omittingEmptySubsequences: false).map{ String($0) }
58+
self.length = self.text.reduce(0, { $0 + $1.count }) + kind.prefixLength + 3
5759
}
5860
}
5961

6062
func print(indent: Int) -> String {
61-
let separator = "\n" + String(repeating: " ", count: indent) + kind.prefix
62-
return kind.prefix + self.text.joined(separator: separator)
63+
switch self.kind {
64+
case .line, .docLine:
65+
let separator = "\n" + String(repeating: " ", count: indent) + kind.prefix
66+
return kind.prefix + self.text.joined(separator: separator)
67+
case .block, .docBlock:
68+
let separator = "\n" + String(repeating: " ", count: indent)
69+
return kind.prefix + self.text.joined(separator: separator) + "*/"
70+
}
6371
}
6472

6573
mutating func addText(_ text: [String]) {

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

+27
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,17 @@ private final class TokenStreamCreator: SyntaxVisitor {
12621262
}
12631263
return
12641264
}
1265+
case .blockComment(let text):
1266+
if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1267+
return
1268+
} else {
1269+
appendToken(.break(size: 2, offset: 2))
1270+
appendToken(.comment(Comment(kind: .block, text: text)))
1271+
if let parent = nextToken.parent?.parent, !(parent is CodeBlockItemSyntax) {
1272+
appendToken(.newline)
1273+
}
1274+
return
1275+
}
12651276
default:
12661277
break
12671278
}
@@ -1279,6 +1290,14 @@ private final class TokenStreamCreator: SyntaxVisitor {
12791290
appendToken(.comment(Comment(kind: .line, text: text)))
12801291
appendToken(.newline)
12811292
}
1293+
case .blockComment(let text):
1294+
if fileStart {
1295+
appendToken(.comment(Comment(kind: .block, text: text)))
1296+
appendToken(.newline)
1297+
} else if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1298+
appendToken(.comment(Comment(kind: .block, text: text)))
1299+
appendToken(.newline)
1300+
}
12821301
case .docLineComment(let text):
12831302
appendToken(.comment(Comment(kind: .docLine, text: text)))
12841303
if case .newlines? = trivia[safe: offset + 1],
@@ -1287,6 +1306,14 @@ private final class TokenStreamCreator: SyntaxVisitor {
12871306
} else {
12881307
appendToken(.newline)
12891308
}
1309+
case .docBlockComment(let text):
1310+
appendToken(.comment(Comment(kind: .docBlock, text: text)))
1311+
if case .newlines? = trivia[safe: offset + 1],
1312+
case .docLineComment? = trivia[safe: offset + 2] {
1313+
/* do nothing */
1314+
} else {
1315+
appendToken(.newline)
1316+
}
12901317
case .newlines(let n), .carriageReturns(let n), .carriageReturnLineFeeds(let n):
12911318
if n > 1 {
12921319
appendToken(.newlines(min(n - 1, config.maximumBlankLines), offset: 0))

Tests/SwiftFormatPrettyPrintTests/CommentTests.swift

+143
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ public class CommentTests: PrettyPrintTestCase {
128128
// Dictionary comment
129129
let b = ["abc": 456, // small comment
130130
"def": 789]
131+
132+
/* Array comment */
133+
let a = [456, /* small comment */
134+
789]
135+
136+
/* Dictionary comment */
137+
let b = ["abc": 456, /* small comment */
138+
"def": 789]
131139
"""
132140

133141
let expected =
@@ -144,8 +152,143 @@ public class CommentTests: PrettyPrintTestCase {
144152
"def": 789
145153
]
146154
155+
/* Array comment */
156+
let a = [
157+
456, /* small comment */
158+
789
159+
]
160+
161+
/* Dictionary comment */
162+
let b = [
163+
"abc": 456, /* small comment */
164+
"def": 789
165+
]
166+
147167
"""
148168

149169
assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
150170
}
171+
172+
public func testDocumentationBlockComments() {
173+
let input =
174+
"""
175+
/** This is a documentation comment
176+
*
177+
* - Parameters:
178+
* - param1: Param1 comment
179+
* - param2: Param2 comment
180+
* - Returns: The output
181+
**/
182+
func myfun(param1: Int, param2: Double) -> String {
183+
let out = "123"
184+
return out
185+
}
186+
187+
/** A brief doc comment **/
188+
func myfun() {
189+
let a = 123
190+
let b = "456"
191+
}
192+
193+
public class MyClass {
194+
/** Doc comment **/
195+
var myVariable: Int
196+
197+
/** Method doc comment
198+
*
199+
* - Parameters:
200+
* - param1: Param1 comment
201+
* - param2: Param2 comment
202+
* - Returns: The output
203+
**/
204+
func myFun(param1: Int, param2: Int) -> String {
205+
let a = 123
206+
let b = "456"
207+
return b
208+
}
209+
}
210+
"""
211+
212+
let expected =
213+
"""
214+
/** This is a documentation comment
215+
*
216+
* - Parameters:
217+
* - param1: Param1 comment
218+
* - param2: Param2 comment
219+
* - Returns: The output
220+
**/
221+
func myfun(param1: Int, param2: Double) -> String {
222+
let out = "123"
223+
return out
224+
}
225+
226+
/** A brief doc comment **/
227+
func myfun() {
228+
let a = 123
229+
let b = "456"
230+
}
231+
232+
public class MyClass {
233+
/** Doc comment **/
234+
var myVariable: Int
235+
236+
/** Method doc comment
237+
*
238+
* - Parameters:
239+
* - param1: Param1 comment
240+
* - param2: Param2 comment
241+
* - Returns: The output
242+
**/
243+
func myFun(param1: Int, param2: Int) -> String {
244+
let a = 123
245+
let b = "456"
246+
return b
247+
}
248+
}
249+
250+
"""
251+
252+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 55)
253+
}
254+
255+
public func testBlockComments() {
256+
let input =
257+
"""
258+
/* Line Comment1 */
259+
/* Line Comment2 */
260+
let a = 123
261+
let b = "456" /* End of line comment */
262+
let c = "More content"
263+
264+
/* Comment 3
265+
Comment 4 */
266+
267+
let reallyLongVariableName = 123 /* This comment should wrap */
268+
269+
let d = 123
270+
/* Trailing Comment */
271+
"""
272+
273+
let expected =
274+
"""
275+
/* Line Comment1 */
276+
/* Line Comment2 */
277+
let a = 123
278+
let b = "456" /* End of line comment */
279+
let c = "More content"
280+
281+
/* Comment 3
282+
Comment 4 */
283+
284+
let reallyLongVariableName = 123
285+
/* This comment should wrap */
286+
287+
let d = 123
288+
/* Trailing Comment */
289+
290+
"""
291+
292+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
293+
}
151294
}

0 commit comments

Comments
 (0)