Skip to content

Commit f6d3649

Browse files
authored
Merge pull request swiftlang#141 from dabelknap/comment-fixes
Fixes to comment behavior
2 parents 1e07785 + f2f085c commit f6d3649

File tree

2 files changed

+132
-74
lines changed

2 files changed

+132
-74
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 98 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,10 @@ private final class TokenStreamCreator: SyntaxVisitor {
398398
}
399399

400400
override func visit(_ node: CodeBlockSyntax) {
401-
for i in 0..<(node.statements.count - 1) {
402-
after(node.statements[i].lastToken, tokens: .newline)
401+
if node.statements.count > 0 {
402+
for i in 0..<(node.statements.count - 1) {
403+
after(node.statements[i].lastToken, tokens: .newline)
404+
}
403405
}
404406
super.visit(node)
405407
}
@@ -1233,123 +1235,145 @@ private final class TokenStreamCreator: SyntaxVisitor {
12331235
}
12341236

12351237
override func visit(_ token: TokenSyntax) {
1236-
let fileStart = token.previousToken == nil
1237-
extractTrivia(token.leadingTrivia, fileStart: fileStart)
1238+
extractLeadingTrivia(token)
12381239
if let before = beforeMap[token] {
12391240
tokens += before
12401241
}
12411242
appendToken(.syntax(token))
1242-
extractTrailingLineComment(token)
1243+
extractTrailingComment(token)
12431244
if let afterGroups = afterMap[token] {
12441245
for after in afterGroups.reversed() {
12451246
tokens += after
12461247
}
12471248
}
1248-
extractTrivia(token.trailingTrivia)
12491249
}
12501250

1251-
func appendToken(_ token: Token) {
1252-
if let last = tokens.last {
1253-
switch (last, token) {
1254-
case (.comment(let c1), .comment(let c2))
1255-
where c1.kind == .docLine && c2.kind == .docLine:
1256-
var newComment = c1
1257-
newComment.addText(c2.text)
1258-
tokens[tokens.count - 1] = .comment(newComment)
1259-
return
1260-
default:
1261-
break
1251+
private func extractTrailingComment(_ token: TokenSyntax) {
1252+
let nextToken = token.nextToken
1253+
guard let trivia = nextToken?.leadingTrivia,
1254+
let firstPiece = trivia[safe: 0] else {
1255+
return
1256+
}
1257+
1258+
switch firstPiece {
1259+
case .lineComment(let text):
1260+
appendToken(.break(size: 2, offset: 2))
1261+
appendToken(.comment(Comment(kind: .line, text: text)))
1262+
if isInContainer(token) {
1263+
appendToken(.newline)
12621264
}
1265+
1266+
case .blockComment(let text):
1267+
appendToken(.break(size: 2, offset: 2))
1268+
appendToken(.comment(Comment(kind: .block, text: text)))
1269+
if isInContainer(token) {
1270+
appendToken(.newline)
1271+
}
1272+
1273+
default:
1274+
return
12631275
}
1264-
tokens.append(token)
12651276
}
12661277

1267-
private func shouldAddNewlineBefore(_ token: TokenSyntax?) -> Bool {
1268-
guard let token = token, let before = beforeMap[token] else { return false }
1269-
for item in before {
1270-
if case .newlines = item { return false }
1278+
private func isInContainer(_ token: TokenSyntax) -> Bool {
1279+
if token.parent is ArrayElementSyntax || token.parent is DictionaryElementSyntax || token.parent is TupleElementSyntax {
1280+
return true
12711281
}
1272-
return true
1282+
return false
12731283
}
12741284

1275-
private func extractTrailingLineComment(_ token: TokenSyntax) {
1276-
guard let nextToken = token.nextToken else {
1277-
return
1278-
}
1279-
let trivia = nextToken.leadingTrivia
1280-
for (offset, piece) in trivia.enumerated() {
1285+
private func extractLeadingTrivia(_ token: TokenSyntax) {
1286+
let isStartOfFile = token.previousToken == nil
1287+
let trivia = token.leadingTrivia
1288+
1289+
for (index, piece) in trivia.enumerated() {
12811290
switch piece {
12821291
case .lineComment(let text):
1283-
if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1284-
return
1285-
} else {
1286-
appendToken(.break(size: 2, offset: 2))
1292+
if index > 0 || isStartOfFile {
1293+
if token.withoutTrivia().text == "}" {
1294+
if let previousToken = token.previousToken,
1295+
previousToken.withoutTrivia().text == "{" {
1296+
// do nothing
1297+
} else {
1298+
appendToken(.newline)
1299+
}
1300+
}
1301+
12871302
appendToken(.comment(Comment(kind: .line, text: text)))
1288-
if let parent = nextToken.parent?.parent, !(parent is CodeBlockItemSyntax) {
1303+
1304+
if token.withoutTrivia().text == "}" {
1305+
appendToken(.newline(offset: -2))
1306+
} else {
12891307
appendToken(.newline)
12901308
}
1291-
return
12921309
}
1310+
12931311
case .blockComment(let text):
1294-
if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1295-
return
1296-
} else {
1297-
appendToken(.break(size: 2, offset: 2))
1312+
if index > 0 || isStartOfFile {
1313+
if token.withoutTrivia().text == "}" {
1314+
if let previousToken = token.previousToken,
1315+
previousToken.withoutTrivia().text == "{" {
1316+
// do nothing
1317+
} else {
1318+
appendToken(.newline)
1319+
}
1320+
}
1321+
12981322
appendToken(.comment(Comment(kind: .block, text: text)))
1299-
if let parent = nextToken.parent?.parent, !(parent is CodeBlockItemSyntax) {
1323+
1324+
if token.withoutTrivia().text == "}" {
1325+
appendToken(.newline(offset: -2))
1326+
} else {
13001327
appendToken(.newline)
13011328
}
1302-
return
13031329
}
1304-
default:
1305-
break
1306-
}
1307-
}
1308-
}
13091330

1310-
private func extractTrivia(_ trivia: Trivia, fileStart: Bool = false) {
1311-
for (offset, piece) in trivia.enumerated() {
1312-
switch piece {
1313-
case .lineComment(let text):
1314-
if fileStart {
1315-
appendToken(.comment(Comment(kind: .line, text: text)))
1316-
appendToken(.newline)
1317-
} else if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1318-
appendToken(.comment(Comment(kind: .line, text: text)))
1319-
appendToken(.newline)
1320-
}
1321-
case .blockComment(let text):
1322-
if fileStart {
1323-
appendToken(.comment(Comment(kind: .block, text: text)))
1324-
appendToken(.newline)
1325-
} else if offset > 0, case .newlines? = trivia[safe: offset - 1] {
1326-
appendToken(.comment(Comment(kind: .block, text: text)))
1327-
appendToken(.newline)
1328-
}
13291331
case .docLineComment(let text):
13301332
appendToken(.comment(Comment(kind: .docLine, text: text)))
1331-
if case .newlines? = trivia[safe: offset + 1],
1332-
case .docLineComment? = trivia[safe: offset + 2] {
1333-
/* do nothing */
1333+
if case .newlines? = trivia[safe: index + 1],
1334+
case .docLineComment? = trivia[safe: index + 2] {
1335+
// do nothing
13341336
} else {
13351337
appendToken(.newline)
13361338
}
1339+
13371340
case .docBlockComment(let text):
13381341
appendToken(.comment(Comment(kind: .docBlock, text: text)))
1339-
if case .newlines? = trivia[safe: offset + 1],
1340-
case .docLineComment? = trivia[safe: offset + 2] {
1341-
/* do nothing */
1342-
} else {
1343-
appendToken(.newline)
1344-
}
1342+
appendToken(.newline)
1343+
13451344
case .newlines(let n), .carriageReturns(let n), .carriageReturnLineFeeds(let n):
13461345
if n > 1 {
13471346
appendToken(.newlines(min(n - 1, config.maximumBlankLines), offset: 0))
13481347
}
1348+
1349+
default:
1350+
break
1351+
}
1352+
}
1353+
}
1354+
1355+
func appendToken(_ token: Token) {
1356+
if let last = tokens.last {
1357+
switch (last, token) {
1358+
case (.comment(let c1), .comment(let c2))
1359+
where c1.kind == .docLine && c2.kind == .docLine:
1360+
var newComment = c1
1361+
newComment.addText(c2.text)
1362+
tokens[tokens.count - 1] = .comment(newComment)
1363+
return
13491364
default:
13501365
break
13511366
}
13521367
}
1368+
tokens.append(token)
1369+
}
1370+
1371+
private func shouldAddNewlineBefore(_ token: TokenSyntax?) -> Bool {
1372+
guard let token = token, let before = beforeMap[token] else { return false }
1373+
for item in before {
1374+
if case .newlines = item { return false }
1375+
}
1376+
return true
13531377
}
13541378
}
13551379

Tests/SwiftFormatPrettyPrintTests/CommentTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ public class CommentTests: PrettyPrintTestCase {
9292
9393
let reallyLongVariableName = 123 // This comment should wrap
9494
95+
func MyFun() {
96+
// just a comment
97+
}
98+
99+
func MyFun() {
100+
// Comment 1
101+
// Comment 2
102+
let a = 123
103+
104+
let b = 456 // Comment 3
105+
}
106+
107+
func MyFun() {
108+
let c = 789 // Comment 4
109+
// Comment 5
110+
}
111+
95112
let d = 123
96113
// Trailing Comment
97114
"""
@@ -110,6 +127,23 @@ public class CommentTests: PrettyPrintTestCase {
110127
let reallyLongVariableName = 123
111128
// This comment should wrap
112129
130+
func MyFun() {
131+
// just a comment
132+
}
133+
134+
func MyFun() {
135+
// Comment 1
136+
// Comment 2
137+
let a = 123
138+
139+
let b = 456 // Comment 3
140+
}
141+
142+
func MyFun() {
143+
let c = 789 // Comment 4
144+
// Comment 5
145+
}
146+
113147
let d = 123
114148
// Trailing Comment
115149

0 commit comments

Comments
 (0)