Skip to content

Ignore discretionary newlines in a number of new locations. #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
after(node.inKeyword, tokens: .space)

if let typeAnnotation = node.typeAnnotation {
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
after(
typeAnnotation.colon,
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
}

Expand Down Expand Up @@ -695,7 +697,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
/// - Parameter node: The tuple expression element to be arranged.
private func arrangeAsTupleExprElement(_ node: TupleExprElementSyntax) {
before(node.firstToken, tokens: .open)
after(node.colon, tokens: .break)
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
after(node.lastToken, tokens: .close)
}

Expand Down Expand Up @@ -756,13 +758,13 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
}

override func visit(_ node: DictionaryTypeSyntax) -> SyntaxVisitorContinueKind {
after(node.colon, tokens: .break)
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
return .visitChildren
}

override func visit(_ node: DictionaryElementSyntax) -> SyntaxVisitorContinueKind {
before(node.firstToken, tokens: .open)
after(node.colon, tokens: .break)
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
after(node.lastToken, tokens: .close)
return .visitChildren
}
Expand Down Expand Up @@ -855,7 +857,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
// If we have an open delimiter following the colon, use a space instead of a continuation
// break so that we don't awkwardly shift the delimiter down and indent it further if it
// wraps.
let tokenAfterColon: Token = startsWithOpenDelimiter(Syntax(node.expression)) ? .space : .break
let tokenAfterColon: Token =
startsWithOpenDelimiter(Syntax(node.expression))
? .space
: .break(.continue, newlines: .elective(ignoresDiscretionary: true))

after(node.colon, tokens: tokenAfterColon)

if let trailingComma = node.trailingComma {
Expand Down Expand Up @@ -1028,8 +1034,10 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
override func visit(_ node: FunctionParameterSyntax) -> SyntaxVisitorContinueKind {
before(node.firstToken, tokens: .open)
arrangeAttributeList(node.attributes)
after(node.colon, tokens: .break)
before(node.secondName, tokens: .break)
before(
node.secondName,
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))

if let trailingComma = node.trailingComma {
after(trailingComma, tokens: .close, .break(.same))
Expand Down Expand Up @@ -1240,9 +1248,10 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

override func visit(_ node: TupleTypeElementSyntax) -> SyntaxVisitorContinueKind {
before(node.firstToken, tokens: .open)
after(node.colon, tokens: .break)
after(node.inOut, tokens: .break)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this break after the inOut token?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inOut token here is legacy, I believe, from when the attribute used to come before the variable name instead of the type (e.g., inout foo: Bar instead of foo: inout Bar). The parser doesn't accept that syntax anymore (I tried it in the syntax explorer), so I don't think this will ever be non-nil. When using the new syntax (foo: inout Bar), the type comes across as an AttributedTypeSyntax, and we add a break after the specifier (which might be inout, __shared, etc.).

before(node.secondName, tokens: .break)
before(
node.secondName,
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))

if let trailingComma = node.trailingComma {
after(trailingComma, tokens: .close, .break(.same))
Expand Down Expand Up @@ -1303,7 +1312,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

override func visit(_ node: AvailabilityLabeledArgumentSyntax) -> SyntaxVisitorContinueKind {
before(node.label, tokens: .open)
after(node.colon, tokens: .break(.continue, size: 1))
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This break had a size of 1 before, to create a space. Do we still want that space when it doesn't fire?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default size for a break is 1 (https://github.com/apple/swift-format/blob/master/Sources/SwiftFormatPrettyPrint/Token.swift#L210), so I was cleaning up the unnecessary specification while editing here.

We probably ought to do that throughout at some point. I also think we ought to make the break kind be explicit instead of defaulting to .continue.

after(node.value.lastToken, tokens: .close)
return .visitChildren
}
Expand Down Expand Up @@ -1578,7 +1587,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
var closeAfterToken: TokenSyntax? = nil

if let typeAnnotation = node.typeAnnotation {
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
after(
typeAnnotation.colon,
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
closesNeeded += 1
closeAfterToken = typeAnnotation.lastToken
}
Expand Down Expand Up @@ -1664,7 +1675,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

override func visit(_ node: AttributedTypeSyntax) -> SyntaxVisitorContinueKind {
arrangeAttributeList(node.attributes)
after(node.specifier, tokens: .break)
after(
node.specifier,
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
return .visitChildren
}

Expand Down Expand Up @@ -1751,7 +1764,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

override func visit(_ node: GenericParameterSyntax) -> SyntaxVisitorContinueKind {
before(node.firstToken, tokens: .open)
after(node.colon, tokens: .break)
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
if let trailingComma = node.trailingComma {
after(trailingComma, tokens: .close, .break(.same))
} else {
Expand Down Expand Up @@ -1958,7 +1971,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
after(node.letOrVarKeyword, tokens: .break)

if let typeAnnotation = node.typeAnnotation {
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
after(
typeAnnotation.colon,
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
}

Expand Down
24 changes: 24 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/AttributeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,28 @@ final class AttributeTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
}

func testIgnoresDiscretionaryLineBreakAfterColon() {
let input =
"""
@available(
*, unavailable,
renamed:
"MyRenamedFunction"
)
func f() {}
"""

let expected =
"""
@available(
*, unavailable,
renamed: "MyRenamedFunction"
)
func f() {}

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 30)
}
}
39 changes: 39 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/DictionaryDeclTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,43 @@ final class DictionaryDeclTests: PrettyPrintTestCase {
XCTAssertDiagnosed(.removeTrailingComma, line: 1, column: 32)
XCTAssertDiagnosed(.addTrailingComma, line: 4, column: 17)
}

func testIgnoresDiscretionaryNewlineAfterColon() {
let input =
"""
let a = [
"reallyLongKeySoTheValueWillWrap":
value
]
let a = [
"shortKey":
value
]
let a:
[ReallyLongKeySoTheValueWillWrap:
Value]
let a:
[ShortKey:
Value]
"""

let expected =
"""
let a = [
"reallyLongKeySoTheValueWillWrap":
value
]
let a = [
"shortKey": value
]
let a:
[ReallyLongKeySoTheValueWillWrap:
Value]
let a:
[ShortKey: Value]

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 20)
}
}
23 changes: 23 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/ForInStmtTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,27 @@ final class ForInStmtTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
}

func testTypeAnnotationIgnoresDiscretionaryNewlineAfterColon() {
let input =
"""
for i:
ExplicitType in mycontainer
{
let a = 123
let b = i
}
"""

let expected =
"""
for i: ExplicitType in mycontainer {
let a = 123
let b = i
}

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
}
}
24 changes: 24 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/FunctionCallTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,28 @@ final class FunctionCallTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
}

func testIgnoresDiscretionaryLineBreakAfterColon() {
let input =
"""
myFunc(
a:
foo,
b:
bar + baz + quux
)
"""

let expected =
"""
myFunc(
a: foo,
b: bar + baz
+ quux
)

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 20)
}
}
47 changes: 47 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/FunctionDeclTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1038,4 +1038,51 @@ final class FunctionDeclTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 14)
}

func testIgnoresDiscretionaryLineBreakAfterColonAndInout() {
let input =
"""
func foo(
a:
ReallyLongTypeName,
b:
ShortType,
c:
inout
C,
labeled
d:
D,
reallyLongLabel
reallyLongArg: E
) {}
func foo<
A:
ReallyLongType,
B:
ShortType
>(a: A, b: B) {}

"""

let expected =
"""
func foo(
a:
ReallyLongTypeName,
b: ShortType,
c: inout C,
labeled d: D,
reallyLongLabel
reallyLongArg: E
) {}
func foo<
A: ReallyLongType,
B: ShortType
>(a: A, b: B) {}

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 23)
}
}
20 changes: 20 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/PatternBindingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,24 @@ final class PatternBindingTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
}

func testIgnoresDiscretionaryNewlineAfterColon() {
let input =
"""
let someObject:
Foo = object
let someObject:
Foo = longerObjectName
"""

let expected =
"""
let someObject: Foo = object
let someObject: Foo =
longerObjectName

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 28)
}
}
33 changes: 33 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/TupleDeclTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,37 @@ final class TupleDeclTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 30)
}

func testIgnoresDiscretionaryNewlineAfterColon() {
let input =
"""
let a = (
reallyLongKeySoTheValueWillWrap:
value,
b: c
)
let a = (
shortKey:
value,
b:
c
)
"""

let expected =
"""
let a = (
reallyLongKeySoTheValueWillWrap:
value,
b: c
)
let a = (
shortKey: value,
b: c
)

"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 25)
}
}
Loading