-
Notifications
You must be signed in to change notification settings - Fork 433
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
Add commentValue
property to Trivia
for cleaned comments
#2966
base: main
Are you sure you want to change the base?
Conversation
- Copied changes from PR swiftlang#2578 (swiftlang#2578) - Original work by @adammcarter - Manual copy due to inaccessible original branch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing the issue, @zyadtaha. I think the PR still needs some polishing regarding indentation handling. I left a few comments inline.
3ad450f
to
c23e3dc
Compare
Thanks for the feedback, @ahoppen! I've addressed the comments—let me know if anything else needs attention. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the adjustments. I left a few more edge cases to consider as comments.
Add release note for Trivia.commentValue Address PR review Address second review
c23e3dc
to
04f700e
Compare
Hey @ahoppen, just wanted to check if there's anything else needed from my side on this PR. Let me know if you have any concerns. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. I think there are still a few more issues that need to be addressed.
|
||
// Helper function to trim leading and trailing newlines | ||
func trimNewlines(_ text: String) -> String { | ||
let trimmed = text.drop(while: { $0 == "\n" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should also cover \r\n
(Windows-style newlines) here as well.
func processBlockComment(_ text: String, prefix: String, suffix: String) -> String { | ||
var text = text | ||
text.removeFirst(prefix.count) | ||
text.removeLast(suffix.count) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can’t generally assume that the comment will end with */
. For example, if you have a source file with an unterminated block comment, the end of file token will have the block comment as trivia but that trivia doesn’t end with */
.
|
||
// Helper function to process multiline block comments | ||
func processMultilineBlockComment(_ text: String) -> String { | ||
var lines = text.split(separator: "\n", omittingEmptySubsequences: false).map(String.init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you avoid constructing String
here and instead work on Substring
. Substring
avoids memory allocations and is thus more performant.
let minIndentation = | ||
lines | ||
.filter { !$0.isEmpty } | ||
.map { $0.prefix { $0 == " " }.count } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we should also handle tabs as indentation.
return text | ||
} | ||
|
||
// Helper function to process multiline block comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you be a little more specific in the comment what this function does? As it stands right now, the comment doesn’t really add any value, it just rephrases the function name.
lines.removeLast() | ||
} else { | ||
lines[lines.count - 1].removeLast(2) | ||
lines[lines.count - 1] = trimWhitespace(lines[lines.count - 1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This removes all whitespace from the last line, not just minIndentation
, right?
Actually, on second reading, does their trim whitespace and then drop the prefix again in the map
below, potentially removing contents of the comment?
text.hasPrefix("/*\n") | ||
? processMultilineBlockComment(text) | ||
: processBlockComment(text, prefix: "/*", suffix: "*/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think we need a general distinction here. Say if you have
/* abc
def
ghi
*/
We should still be able to strip the indentation. We just need to exclude the first line from the indentation stripping.
@@ -42,6 +42,112 @@ public struct Trivia: Sendable { | |||
pieces.isEmpty | |||
} | |||
|
|||
/// The string contents of all the comment pieces with any comments tokens trimmed. | |||
public var commentValue: String { | |||
var comments = [String]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be an array of Substring
instead of String
to avoid intermediate memory allocations for the comment value pieces?
This PR continues the work from #2578, addressing the review comments and refining the behavior of
Trivia.commentValue
.