Skip to content

Commit 278fe58

Browse files
authored
Merge pull request swiftlang#104 from dabelknap/cleanup-v2
Fix `newline` token length calculation
2 parents 6b7cf01 + 67e1ced commit 278fe58

File tree

4 files changed

+59
-52
lines changed

4 files changed

+59
-52
lines changed

Sources/PrettyPrint/PrettyPrint.swift

+25-22
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,15 @@ public class PrettyPrinter {
4747
// Did the previous token trigger a newline?
4848
private var lastBreak = false
4949

50+
// What is the offset value of the last triggering break?
51+
private var lastBreakOffset = 0
52+
53+
// What is the total number of spaces we need to indent from the last break?
54+
private var lastBreakValue = 0
55+
5056
// Keep track of the indentation level of the current group as the number of blank spaces.
5157
private var indentStack = [0]
5258

53-
// The first token of a group must be indented according to it's outer group. Use this stack when
54-
// printing the indent of the first token in a group. Subsequent tokens will use the indent of the
55-
// current group.
56-
private var breakStack = [0]
57-
5859
// Do we force breaks (for consistent breaking) within the current group?
5960
private var forceBreakStack = [false]
6061

@@ -110,17 +111,15 @@ public class PrettyPrinter {
110111
}
111112

112113
let indentValue = indentStack.last ?? 0
113-
let breakValue = breakStack.last ?? 0
114-
indentStack.append(indentValue + offset)
115-
breakStack.append(breakValue)
114+
indentStack.append(indentValue + offset + lastBreakOffset)
115+
lastBreakOffset = 0
116116

117117
case .close:
118118
if isDebugMode {
119119
writeCloseGroupDebugMarker()
120120
}
121121
forceBreakStack.removeLast()
122122
indentStack.removeLast()
123-
breakStack.removeLast()
124123

125124
case .break(let size, let offset):
126125
if isDebugMode {
@@ -135,35 +134,41 @@ public class PrettyPrinter {
135134
if length > spaceRemaining || forcebreak {
136135
// Update the top of the breakStack to reflect the indentation level of the current group.
137136
let indentValue = indentStack.last ?? 0
138-
breakStack.removeLast()
139-
breakStack.append(indentValue + offset)
140137

141138
spaceRemaining = maxLineLength - indentValue - offset
142139
write("\n")
140+
143141
lastBreak = true
142+
lastBreakOffset = offset
143+
lastBreakValue = indentValue + offset
144144
} else {
145145
writeSpaces(size)
146146
spaceRemaining -= size
147+
147148
lastBreak = false
149+
lastBreakOffset = 0
150+
lastBreakValue = 0
148151
}
149152

150-
case .newlines(let N):
153+
case .newlines(let N, let offset):
151154
// Newlines are treated as forced `breaks` with a size of zero.
152155
let indentValue = indentStack.last ?? 0
153-
breakStack.removeLast()
154-
breakStack.append(indentValue)
155156

156-
spaceRemaining = maxLineLength - indentValue
157+
spaceRemaining = maxLineLength - indentValue - offset
157158
write(String(repeating: "\n", count: N))
158-
lastBreak = true
159159

160+
lastBreak = true
161+
lastBreakOffset = offset
162+
lastBreakValue = indentValue + offset
160163

161164
case .syntax(let syntaxToken):
162165
if lastBreak {
163-
// If the last token created a newline, we need to apply indentation.
164-
let indentValue = breakStack.last ?? 0
165-
writeSpaces(indentValue)
166+
// If the last token created a new line, we need to apply indentation.
167+
writeSpaces(lastBreakValue)
168+
166169
lastBreak = false
170+
lastBreakOffset = 0
171+
lastBreakValue = 0
167172
}
168173
write(syntaxToken.text)
169174
spaceRemaining -= syntaxToken.text.count
@@ -223,9 +228,7 @@ public class PrettyPrinter {
223228
delimIndexStack.removeLast()
224229
}
225230

226-
lengths.append(-total)
227-
delimIndexStack.append(i)
228-
total += 1
231+
lengths.append(0)
229232

230233
case .syntax(let syntaxToken):
231234
lengths.append(syntaxToken.text.count)

Sources/PrettyPrint/Token.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ enum BreakStyle {
2828

2929
enum Token {
3030
case comment(Comment, hasTrailingSpace: Bool)
31-
case newlines(Int)
31+
case newlines(Int, offset: Int)
3232
case `break`(size: Int, offset: Int)
3333
case open(BreakStyle, Int)
3434
case close
3535
case syntax(TokenSyntax)
3636

37-
static let newline = Token.newlines(1)
37+
static let newline = Token.newlines(1, offset: 0)
38+
static func newline(offset: Int) -> Token {
39+
return Token.newlines(1, offset: offset)
40+
}
41+
3842
static let open = Token.open(.inconsistent, 0)
3943

4044
static let `break` = Token.break(size: 1, offset: 0)

Sources/PrettyPrint/TokenStreamCreator.swift

+26-26
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,15 @@ private final class TokenStreamCreator: SyntaxVisitor {
169169
}
170170

171171
override func visit(_ node: ParameterClauseSyntax) {
172-
after(node.leftParen, tokens: .break(size: 0), .open(.consistent, 0))
173-
before(node.rightParen, tokens: .close)
172+
after(node.leftParen, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
173+
before(node.rightParen, tokens: .break(size: 0, offset: -2), .close)
174174
super.visit(node)
175175
}
176176

177177
override func visit(_ node: ReturnClauseSyntax) {
178+
before(node.firstToken, tokens: .open)
179+
before(node.returnType.firstToken, tokens: .break)
180+
after(node.lastToken, tokens: .close)
178181
super.visit(node)
179182
}
180183

@@ -260,6 +263,16 @@ private final class TokenStreamCreator: SyntaxVisitor {
260263
}
261264

262265
override func visit(_ node: CodeBlockSyntax) {
266+
for i in 0..<(node.statements.count - 1) {
267+
after(node.statements[i].lastToken, tokens: .newline)
268+
}
269+
super.visit(node)
270+
}
271+
272+
override func visit(_ node: CodeBlockItemSyntax) {
273+
if !(node.parent?.parent is CodeBlockSyntax) {
274+
after(node.lastToken, tokens: .newline)
275+
}
263276
super.visit(node)
264277
}
265278

@@ -315,17 +328,17 @@ private final class TokenStreamCreator: SyntaxVisitor {
315328
override func visit(_ node: IfStmtSyntax) {
316329
before(node.ifKeyword, tokens: .open(.inconsistent, 3))
317330
after(node.ifKeyword, tokens: .break)
318-
before(node.body.leftBrace, tokens: .break, .close)
331+
before(node.body.leftBrace, tokens: .break(offset: -3), .close)
319332

320-
after(node.body.leftBrace, tokens: .open(.consistent, 2), .newline)
321-
before(node.body.rightBrace, tokens: .close)
333+
after(node.body.leftBrace, tokens: .newline(offset: 2), .open(.consistent, 0))
334+
before(node.body.rightBrace, tokens: .newline(offset: -2), .close)
322335

323336
before(node.elseKeyword, tokens: .break)
324337
after(node.elseKeyword, tokens: .break)
325338

326339
if let elseBody = node.elseBody as? CodeBlockSyntax {
327-
after(elseBody.leftBrace, tokens: .open(.consistent, 2), .newline)
328-
before(elseBody.rightBrace, tokens: .close)
340+
after(elseBody.leftBrace, tokens: .newline(offset: 2), .open(.consistent, 0))
341+
before(elseBody.rightBrace, tokens: .newline(offset: -2), .close)
329342
}
330343
super.visit(node)
331344
}
@@ -395,7 +408,9 @@ private final class TokenStreamCreator: SyntaxVisitor {
395408
}
396409

397410
override func visit(_ node: ReturnStmtSyntax) {
411+
before(node.firstToken, tokens: .open)
398412
after(node.returnKeyword, tokens: .break)
413+
after(node.lastToken, tokens: .close)
399414
super.visit(node)
400415
}
401416

@@ -448,30 +463,20 @@ private final class TokenStreamCreator: SyntaxVisitor {
448463
}
449464

450465
override func visit(_ node: FunctionDeclSyntax) {
451-
if let token = node.firstToken {
452-
before(token, tokens: .open(.inconsistent, 2))
453-
}
454-
before(node.signature.input.rightParen, tokens: .break(size: 0), .close)
455466
after(node.modifiers?.lastToken, tokens: .break)
456467
after(node.funcKeyword, tokens: .break)
457468

458469
if let body = node.body {
459470
before(body.leftBrace, tokens: .break)
460-
after(body.leftBrace, tokens: .open(.consistent, 2), .newline)
461-
before(body.rightBrace, tokens: .close)
471+
after(body.leftBrace, tokens: .newline(offset: 2), .open(.consistent, 0))
472+
before(body.rightBrace, tokens: .newline(offset: -2), .close)
462473
}
463474

464475
super.visit(node)
465476
}
466477

467478
override func visit(_ node: FunctionSignatureSyntax) {
468-
if node.output != nil {
469-
after(node.input.rightParen, tokens: .break)
470-
}
471-
before(node.output?.arrow, tokens: .open(.consistent, 2))
472-
after(node.output?.arrow, tokens: .break)
473-
after(node.output?.returnType.lastToken, tokens: .close)
474-
479+
before(node.output?.firstToken, tokens: .break)
475480
super.visit(node)
476481
}
477482

@@ -513,11 +518,6 @@ private final class TokenStreamCreator: SyntaxVisitor {
513518
super.visit(node)
514519
}
515520

516-
override func visit(_ node: CodeBlockItemSyntax) {
517-
after(node.lastToken, tokens: .newline)
518-
super.visit(node)
519-
}
520-
521521
override func visit(_ node: ExtensionDeclSyntax) {
522522
super.visit(node)
523523
}
@@ -905,7 +905,7 @@ private final class TokenStreamCreator: SyntaxVisitor {
905905
}
906906
case .newlines(let n), .carriageReturns(let n), .carriageReturnLineFeeds(let n):
907907
if n > 1 {
908-
appendToken(.newlines(min(n - 1, config.maximumBlankLines)))
908+
appendToken(.newlines(min(n - 1, config.maximumBlankLines), offset: 0))
909909
}
910910
default:
911911
break

Tests/PrettyPrinterTests/IfStmtTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ public class IfStmtTests: PrettyPrintTestCase {
8888
8989
if var1 < var2 {
9090
let a = 23
91-
} else if var3 <
92-
var4 {
91+
} else
92+
if var3 < var4 {
9393
var b = 123
9494
}
9595

0 commit comments

Comments
 (0)