Skip to content

Fix more postfix pound if scenarios #402

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 8 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
38 changes: 30 additions & 8 deletions Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
before(tokenToOpenWith.nextToken(viewMode: .all), tokens: .break(breakKindClose, newlines: .soft), .close)
}

if isNestedInPostfixIfConfig(node: Syntax(node)) {
if node.parent?.parent?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
before(
node.firstToken,
tokens: [
Expand Down Expand Up @@ -3481,7 +3481,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

if let calledMemberAccessExpr = calledExpression.as(MemberAccessExprSyntax.self) {
if calledMemberAccessExpr.base != nil {
if isNestedInPostfixIfConfig(node: Syntax(calledMemberAccessExpr)) {
if isNestedInPostfixIfConfig(node: calledMemberAccessExpr) {
before(calledMemberAccessExpr.dot, tokens: [.break(.same, size: 0)])
} else {
before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)])
Expand Down Expand Up @@ -3510,18 +3510,40 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
}
}

private func isNestedInPostfixIfConfig(node: Syntax) -> Bool {
var this: Syntax? = node
private func isNestedInPostfixIfConfig(node: MemberAccessExprSyntax) -> Bool {
func containsDescendent(ancestor: Syntax, node: MemberAccessExprSyntax) -> Bool {
if ancestor.children(viewMode: .sourceAccurate).contains(Syntax(node)) {
return true
}

while this?.parent != nil {
if this?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
for child in ancestor.children(viewMode: .sourceAccurate) {
if containsDescendent(ancestor: child, node: node) {
return true
}

this = this?.parent
}

return false
}

var this: Syntax? = Syntax(node)

while this?.parent != nil {
if this?.is(TupleExprElementSyntax.self) == true {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This handles the scenario in this test

Copy link
Contributor Author

@DavidBrunow DavidBrunow Sep 17, 2022

Choose a reason for hiding this comment

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

This is the fragile part which I dislike. It handles the scenario in that test fine, but what other scenarios are there that this does not handle, or that this breaks?

return false
}

if let postfixIfConfig = this?.as(PostfixIfConfigExprSyntax.self) {
if let ifConfigListSyntax = postfixIfConfig.config.children(viewMode: .sourceAccurate).first?.as(IfConfigClauseListSyntax.self) {
if containsDescendent(ancestor: Syntax(ifConfigListSyntax), node: node) {
return true
}
}
}

this = this?.parent
}

return false
}

extension Syntax {
Expand Down
64 changes: 64 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/IfConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,68 @@ final class IfConfigTests: PrettyPrintTestCase {

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

func testPostfixPoundIfBetweenOtherModifiers() {
let input =
"""
EmptyView()
.padding([.vertical])
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
"""

let expected =
"""
EmptyView()
.padding([.vertical])
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not handled properly by these changes because I didn't think to try adding this until I was creating this pull request. Will look into how to solve this but wanted to have it in this pull request so I didn't forget to mention it.

Copy link
Member

Choose a reason for hiding this comment

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

Have you had any luck with this one? For consistency we'd definitely like if the #if aligns with the preceding . and then the contents are indented one more level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have not yet, things at work got really busy soon after I created this. I'll take another look at it soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Took me a bit longer than I expected to get back to this. I think this latest commit works as intended. Let me know if I misunderstood.

I don't love the implementation I landed on so I'l be looking to improve it if I can.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm happier where this is now. Would appreciate any and all feedback :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@allevato Friendly ping for awareness, not urgency, here since it took me so long to get back to this. I think it is behaving how you described now.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the delay; I lost track of this one. These results look great, thanks for getting all these cases working so well!


"""

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

func testPostfixPoundIfWithTypeInModifier() {
let input =
"""
EmptyView()
.padding([.vertical])
#if os(iOS)
.iOSSpecificModifier(
SpecificType()
.onChanged { _ in
// do things
}
.onEnded { _ in
// do things
}
)
#endif
"""

let expected =
"""
EmptyView()
.padding([.vertical])
#if os(iOS)
.iOSSpecificModifier(
SpecificType()
.onChanged { _ in
// do things
}
.onEnded { _ in
// do things
}
)
#endif

"""

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