Skip to content

Commit b91218c

Browse files
authored
Merge pull request swiftlang#122 from dabelknap/attributes
Add support for attributes
2 parents d4be124 + 14cfd37 commit b91218c

File tree

9 files changed

+398
-11
lines changed

9 files changed

+398
-11
lines changed

Sources/PrettyPrint/PrettyPrint.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,12 @@ public class PrettyPrinter {
177177
// Print out the number of spaces according to the size, and adjust spaceRemaining.
178178
case .space(let size):
179179
spaceRemaining -= size
180-
writeSpaces(size)
180+
writeSpaces(size + lastBreakValue)
181+
182+
lastBreak = false
183+
lastBreakConsecutive = false
184+
lastBreakOffset = 0
185+
lastBreakValue = 0
181186

182187
// Apply N line breaks, calculate the indentation required, and adjust spaceRemaining.
183188
case .newlines(let N, let offset):

Sources/PrettyPrint/TokenStreamCreator.swift

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
213213
}
214214

215215
override func visit(_ node: EnumDeclSyntax) {
216+
if let attributes = node.attributes {
217+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
218+
after(attributes.lastToken, tokens: .open)
219+
} else {
220+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
221+
}
222+
216223
after(node.enumKeyword, tokens: .break)
217224

218225
before(
@@ -224,7 +231,10 @@ private final class TokenStreamCreator: SyntaxVisitor {
224231
if node.genericWhereClause == nil {
225232
before(node.members.leftBrace, tokens: .break)
226233
}
227-
after(node.members.leftBrace, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
234+
after(
235+
node.members.leftBrace,
236+
tokens: .close, .close, .break(size: 0, offset: 2), .open(.consistent, 0)
237+
)
228238
before(node.members.rightBrace, tokens: .break(size: 0, offset: -2), .close)
229239

230240
super.visit(node)
@@ -429,6 +439,26 @@ private final class TokenStreamCreator: SyntaxVisitor {
429439
}
430440

431441
override func visit(_ node: AttributeSyntax) {
442+
if node.balancedTokens.count > 0 {
443+
for i in 0..<(node.balancedTokens.count - 1) {
444+
let tokens = node.balancedTokens
445+
switch (tokens[i].tokenKind, tokens[i+1].tokenKind) {
446+
case (.leftParen, _): ()
447+
case (_, .rightParen): ()
448+
case (_, .comma): ()
449+
case (_, .colon): ()
450+
default:
451+
after(tokens[i], tokens: .space)
452+
}
453+
}
454+
after(node.balancedTokens.lastToken, tokens: .newline)
455+
} else {
456+
if node.parent?.parent is ImportDeclSyntax {
457+
after(node.lastToken, tokens: .space)
458+
} else {
459+
after(node.lastToken, tokens: .break)
460+
}
461+
}
432462
super.visit(node)
433463
}
434464

@@ -437,6 +467,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
437467
}
438468

439469
override func visit(_ node: ClassDeclSyntax) {
470+
if let attributes = node.attributes {
471+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
472+
after(attributes.lastToken, tokens: .open)
473+
} else {
474+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
475+
}
476+
440477
after(node.classKeyword, tokens: .break)
441478

442479
before(
@@ -448,7 +485,10 @@ private final class TokenStreamCreator: SyntaxVisitor {
448485
if node.genericWhereClause == nil {
449486
before(node.members.leftBrace, tokens: .break)
450487
}
451-
after(node.members.leftBrace, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
488+
after(
489+
node.members.leftBrace,
490+
tokens: .close, .close, .break(size: 0, offset: 2), .open(.consistent, 0)
491+
)
452492
before(node.members.rightBrace, tokens: .break(size: 0, offset: -2), .close)
453493

454494
super.visit(node)
@@ -522,7 +562,6 @@ private final class TokenStreamCreator: SyntaxVisitor {
522562
}
523563

524564
override func visit(_ node: ImportDeclSyntax) {
525-
after(node.attributes?.lastToken, tokens: .space)
526565
after(node.importTok, tokens: .space)
527566
after(node.importKind, tokens: .space)
528567
super.visit(node)
@@ -536,6 +575,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
536575
}
537576

538577
override func visit(_ node: StructDeclSyntax) {
578+
if let attributes = node.attributes {
579+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
580+
after(attributes.lastToken, tokens: .open)
581+
} else {
582+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
583+
}
584+
539585
after(node.structKeyword, tokens: .break)
540586

541587
before(
@@ -548,7 +594,10 @@ private final class TokenStreamCreator: SyntaxVisitor {
548594
if node.genericWhereClause == nil {
549595
before(node.members.leftBrace, tokens: .break)
550596
}
551-
after(node.members.leftBrace, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
597+
after(
598+
node.members.leftBrace,
599+
tokens: .close, .close, .break(size: 0, offset: 2), .open(.consistent, 0)
600+
)
552601
before(node.members.rightBrace, tokens: .break(size: 0, offset: -2), .close)
553602

554603
super.visit(node)
@@ -605,6 +654,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
605654
}
606655

607656
override func visit(_ node: FunctionDeclSyntax) {
657+
if let attributes = node.attributes {
658+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
659+
after(attributes.lastToken, tokens: .open)
660+
} else {
661+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
662+
}
663+
608664
after(node.funcKeyword, tokens: .break)
609665

610666
before(
@@ -617,7 +673,7 @@ private final class TokenStreamCreator: SyntaxVisitor {
617673
if node.genericWhereClause == nil {
618674
before(body.leftBrace, tokens: .break)
619675
}
620-
after(body.leftBrace, tokens: .break(offset: 2), .open(.consistent, 0))
676+
after(body.leftBrace, tokens: .close, .close, .break(offset: 2), .open(.consistent, 0))
621677
before(body.rightBrace, tokens: .break(offset: -2), .close)
622678
}
623679

@@ -657,8 +713,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
657713
}
658714

659715
override func visit(_ node: VariableDeclSyntax) {
660-
before(node.firstToken, tokens: .open(.inconsistent, 0))
661-
after(node.lastToken, tokens: .close)
716+
if let attributes = node.attributes {
717+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
718+
after(attributes.lastToken, tokens: .open)
719+
} else {
720+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
721+
}
722+
after(node.lastToken, tokens: .close, .close)
662723
after(node.letOrVarKeyword, tokens: .break)
663724
super.visit(node)
664725
}
@@ -668,6 +729,13 @@ private final class TokenStreamCreator: SyntaxVisitor {
668729
}
669730

670731
override func visit(_ node: ExtensionDeclSyntax) {
732+
if let attributes = node.attributes {
733+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0))
734+
after(attributes.lastToken, tokens: .open)
735+
} else {
736+
before(node.firstToken, tokens: .space(size: 0), .open(.consistent, 0), .open)
737+
}
738+
671739
after(node.extensionKeyword, tokens: .break)
672740

673741
before(
@@ -679,7 +747,10 @@ private final class TokenStreamCreator: SyntaxVisitor {
679747
if node.genericWhereClause == nil {
680748
before(node.members.leftBrace, tokens: .break)
681749
}
682-
after(node.members.leftBrace, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
750+
after(
751+
node.members.leftBrace,
752+
tokens: .close, .close, .break(size: 0, offset: 2), .open(.consistent, 0)
753+
)
683754
before(node.members.rightBrace, tokens: .break(size: 0, offset: -2), .close)
684755

685756
super.visit(node)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
public class AttributeTests: PrettyPrintTestCase {
2+
public func testAttributeParamSpacing() {
3+
let input =
4+
"""
5+
@available
6+
@available(iOS 9.0, *)
7+
@available(*, unavailable, renamed: "MyRenamedProtocol")
8+
@available(iOS 10.0, macOS 10.12, *)
9+
"""
10+
11+
let expected =
12+
"""
13+
@available
14+
@available(iOS 9.0, *)
15+
@available(*, unavailable, renamed: "MyRenamedProtocol")
16+
@available(iOS 10.0, macOS 10.12, *)
17+
18+
19+
"""
20+
21+
// Do not wrap attributes
22+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 5)
23+
}
24+
}

Tests/PrettyPrinterTests/ClassDeclTests.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,58 @@ public class ClassDeclTests: PrettyPrintTestCase {
193193
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
194194
}
195195

196+
public func testClassAttributes() {
197+
let input =
198+
"""
199+
@dynamicMemberLookup public class MyClass {
200+
let A: Int
201+
let B: Double
202+
}
203+
@dynamicMemberLookup @objc public class MyClass {
204+
let A: Int
205+
let B: Double
206+
}
207+
@dynamicMemberLookup @objc @objcMembers public class MyClass {
208+
let A: Int
209+
let B: Double
210+
}
211+
@dynamicMemberLookup
212+
@available(swift 4.0)
213+
public class MyClass {
214+
let A: Int
215+
let B: Double
216+
}
217+
"""
218+
219+
let expected =
220+
"""
221+
@dynamicMemberLookup public class MyClass {
222+
let A: Int
223+
let B: Double
224+
}
225+
@dynamicMemberLookup @objc public class MyClass {
226+
let A: Int
227+
let B: Double
228+
}
229+
@dynamicMemberLookup
230+
@objc
231+
@objcMembers
232+
public class MyClass {
233+
let A: Int
234+
let B: Double
235+
}
236+
@dynamicMemberLookup
237+
@available(swift 4.0)
238+
public class MyClass {
239+
let A: Int
240+
let B: Double
241+
}
242+
243+
"""
244+
245+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
246+
}
247+
196248
public func testClassFullWrap() {
197249
let input =
198250
"""

Tests/PrettyPrinterTests/EnumDeclTests.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,58 @@ public class EnumDeclTests: PrettyPrintTestCase {
272272
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
273273
}
274274

275+
public func testEnumAttributes() {
276+
let input =
277+
"""
278+
@dynamicMemberLookup public enum MyEnum {
279+
case firstCase
280+
let B: Double
281+
}
282+
@dynamicMemberLookup @objc public enum MyEnum {
283+
case firstCase
284+
let B: Double
285+
}
286+
@dynamicMemberLookup @objc @objcMembers public enum MyEnum {
287+
case firstCase
288+
let B: Double
289+
}
290+
@dynamicMemberLookup
291+
@available(swift 4.0)
292+
public enum MyEnum {
293+
case firstCase
294+
let B: Double
295+
}
296+
"""
297+
298+
let expected =
299+
"""
300+
@dynamicMemberLookup public enum MyEnum {
301+
case firstCase
302+
let B: Double
303+
}
304+
@dynamicMemberLookup @objc public enum MyEnum {
305+
case firstCase
306+
let B: Double
307+
}
308+
@dynamicMemberLookup
309+
@objc
310+
@objcMembers
311+
public enum MyEnum {
312+
case firstCase
313+
let B: Double
314+
}
315+
@dynamicMemberLookup
316+
@available(swift 4.0)
317+
public enum MyEnum {
318+
case firstCase
319+
let B: Double
320+
}
321+
322+
"""
323+
324+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 55)
325+
}
326+
275327
public func testEnumFullWrap() {
276328
let input =
277329
"""

Tests/PrettyPrinterTests/ExtensionDeclTests.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,58 @@ public class ExtensionDeclTests: PrettyPrintTestCase {
151151
assertPrettyPrintEqual(input: input, expected: expected, linelength: 70)
152152
}
153153

154+
public func testExtensionAttributes() {
155+
let input =
156+
"""
157+
@dynamicMemberLookup public extension MyExtension {
158+
let A: Int
159+
let B: Double
160+
}
161+
@dynamicMemberLookup @objc public extension MyExtension {
162+
let A: Int
163+
let B: Double
164+
}
165+
@dynamicMemberLookup @objc @objcMembers public extension MyExtension {
166+
let A: Int
167+
let B: Double
168+
}
169+
@dynamicMemberLookup
170+
@available(swift 4.0)
171+
public extension MyExtension {
172+
let A: Int
173+
let B: Double
174+
}
175+
"""
176+
177+
let expected =
178+
"""
179+
@dynamicMemberLookup public extension MyExtension {
180+
let A: Int
181+
let B: Double
182+
}
183+
@dynamicMemberLookup @objc public extension MyExtension {
184+
let A: Int
185+
let B: Double
186+
}
187+
@dynamicMemberLookup
188+
@objc
189+
@objcMembers
190+
public extension MyExtension {
191+
let A: Int
192+
let B: Double
193+
}
194+
@dynamicMemberLookup
195+
@available(swift 4.0)
196+
public extension MyExtension {
197+
let A: Int
198+
let B: Double
199+
}
200+
201+
"""
202+
203+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
204+
}
205+
154206
public func testExtensionFullWrap() {
155207
let input =
156208
"""

0 commit comments

Comments
 (0)