Skip to content

Respect indentation in the line for sub-tree in BasicFormat #1867

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 4 commits into from
Jul 13, 2023

Conversation

gibachan
Copy link
Contributor

The pull request at #1791 emphasizes the need to indent sub-tree nodes while formatting.

I attempted to address another sub-tree indentation based on the comment in #1791 (comment).

@gibachan gibachan requested a review from ahoppen as a code owner June 29, 2023 23:39
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Thanks a lot. I’ve got a couple comments/questions inline. It looks really good overall though.

public extension TokenSyntax {
/// The indentation of this token
///
/// In contrast to `indentation`, this does not walk to previous tokens to
Copy link
Member

Choose a reason for hiding this comment

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

I know that you just copied it, but could you fix this comment while you’re at it?

Suggested change
/// In contrast to `indentation`, this does not walk to previous tokens to
/// In contrast to `indentationOfLine`, this does not walk to previous tokens to

Copy link
Contributor Author

@gibachan gibachan Jul 9, 2023

Choose a reason for hiding this comment

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

Fixed 👍 b1b0e83

Comment on lines 416 to 417
// Add an indentation in the line for the initial token,
// if the token is present and its leadingTrivia does not contain the indentation.
Copy link
Member

Choose a reason for hiding this comment

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

I’m not sure if my formulation of the comment is more helpful than yours but I think some information like the following would have helped me.

// If we are formatting a subtree and the line that the initial token occurs on is indented, use that line indentation for the first token in the subtree to format. For example, when formatting only the code block in the following, then the opening `{` should be indented by four spaces.
// ```
//     func test() {
//         print(1)
//     }
// ```

Copy link
Contributor Author

@gibachan gibachan Jul 9, 2023

Choose a reason for hiding this comment

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

Nice comment! Thank you 88fadc7

Comment on lines 39 to 43
tokens = tokens.enumerated()
.map { index, token in
// We detach the nodes from the second one onwards, considering the line indentation only for the first node
NoNewlinesFormat(viewMode: .all).visit(index == 0 ? token : token.detached)
}
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed? I would expect that we should be able to always do

- tokens = tokens.map({ NoNewlinesFormat(viewMode: .all).visit($0) })
+ tokens = tokens.map({ NoNewlinesFormat(viewMode: .all).visit($0.detached) })

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 seem to have misunderstood, and now I agree with you.

However, this will cause a test to fail for this test case.

https://github.com/apple/swift-syntax/blob/e7068e8eb76542591a189f703f8b62881a520588/Tests/SwiftParserTest/AttributeTests.swift#L99-L113

The error message appears in this line of the DiagnosticSpec, stating that it outputs :false instead of : false.
https://github.com/apple/swift-syntax/blob/e7068e8eb76542591a189f703f8b62881a520588/Tests/SwiftParserTest/AttributeTests.swift#L106

The whitespace between : and false should be inserted by BasicFormat, and I believe the code responsible for it is here.

But requiresWhitespace(between:and:) returns false because the detached : token will not find false as its next token. As a result, the whitespace is not inserted as expected in the test case.

I am currently investigating this issue.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see what’s going wrong g here: We definitely shouldn’t detach because otherwise we don’t know that : is followed by false in NoNewlinesFormat and thus can’t decide whether to add a space after it.

The issue is that inheriting the line’s indentation only makes sense if the formatted text should contain newlines. NoNewlinesFormat is a bit of an oddity here because it doesn’t do that. What I would do is to add the following property to BasicFormat and only perform your logic if inferInitialTokenIndentaiton is true. NoNewlinesFormat can then override it and set it to false.

/// If we are formatting a subtree and the line that the initial token occurs on is indented,
/// use that line indentation for the first token in the subtree to format.
/// 
/// For example, when formatting only the code block in the following,
/// then the opening `{` should be indented by four spaces.
/// ```
///     func test() {
///         print(1)
///     }
/// ```
open var inferInitialTokenIndentaiton: Bool { true }

And then, I think we also don’t need the inline comment in visit(_: TokenSyntax) anymore because the behavior is documented on inferInitialTokenIndentaiton.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow, thank you for your great support!
I fixed it and squashed those commits into cc9f449

@gibachan gibachan marked this pull request as draft July 9, 2023 11:58
@gibachan gibachan force-pushed the parent-indentation branch 2 times, most recently from dcdda8c to cc9f449 Compare July 10, 2023 12:17
@gibachan gibachan marked this pull request as ready for review July 10, 2023 12:19
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

This looks good. Thanks 👍🏽

@ahoppen
Copy link
Member

ahoppen commented Jul 10, 2023

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge July 10, 2023 14:15
auto-merge was automatically disabled July 10, 2023 23:40

Head branch was pushed to by a user without write access

@gibachan gibachan force-pushed the parent-indentation branch from cc9f449 to 1622dc6 Compare July 10, 2023 23:40
@gibachan
Copy link
Contributor Author

Oh, I forgot to run "./format.py" for my changes, sorry. I fixed it! 1622dc6

@gibachan gibachan requested a review from ahoppen July 10, 2023 23:46
@ahoppen
Copy link
Member

ahoppen commented Jul 11, 2023

@swift-ci Please test

Copy link
Member

Choose a reason for hiding this comment

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

When building swift-syntax for the compiler, we are building it using CMake and you need to add this file to Sources/SwiftBasicFormat/CMakeLists.txt.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added this file to Sources/SwiftBasicFormat/CMakeLists.txt. 73a21a8


import SwiftSyntax

public extension TokenSyntax {
Copy link
Member

Choose a reason for hiding this comment

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

Looking at this file again, is there a reason this extension needs to be public? If not, I’d prefer to keep it internal so we don’t increase our API surface area further.

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 did it to make var indentationOfLine: Trivia accessible from ParseDiagnosticsGenerator.swift which is in SwiftParserDiagnostics package.

I made this extension internal in 30bfccd. Please let me know if this was not your intention 😄

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I meant if we could make indentationOfLine internal but I forgot that we use it from ParseDiagnosticsGenerator. Makes sense to be public 👍🏽

@gibachan gibachan requested a review from ahoppen July 12, 2023 12:04
@ahoppen
Copy link
Member

ahoppen commented Jul 13, 2023

@swift-ci Please test

@ahoppen ahoppen enabled auto-merge July 13, 2023 05:20
@ahoppen ahoppen merged commit 174c1ae into swiftlang:main Jul 13, 2023
@gibachan gibachan deleted the parent-indentation branch July 13, 2023 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants