Skip to content

Do not report CRLF sequences in Layout/TrailingWhitespace rule#627

Merged
Sija merged 3 commits intomasterfrom
fix-issue-622
Jun 9, 2025
Merged

Do not report CRLF sequences in Layout/TrailingWhitespace rule#627
Sija merged 3 commits intomasterfrom
fix-issue-622

Conversation

@Sija
Copy link
Member

@Sija Sija commented Jun 6, 2025

Resolves #622

@Sija Sija added this to the 1.7.0 milestone Jun 6, 2025
@Sija Sija requested a review from veelenga June 6, 2025 23:09
@Sija Sija self-assigned this Jun 6, 2025
Copy link
Member

@veelenga veelenga left a comment

Choose a reason for hiding this comment

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

LGTM

@Sija Sija merged commit b2292de into master Jun 9, 2025
2 of 4 checks passed
@Sija Sija deleted the fix-issue-622 branch June 9, 2025 17:46
# source.lines # => ["a = 1", "b = 2"]
# ```
getter lines : Array(String) { code.split('\n') }
getter lines : Array(String) { code.split(/\r?\n/) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason not to use String#lines? Should be much more efficient.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, String#lines eats the final newline:

str = <<-TEXT
  foo  
  bar\t
  
  TEXT
 
str.lines          # => ["foo  ", "bar\t", ""]
str.split(/\r?\n/) # => ["foo  ", "bar\t", "", ""]

Copy link
Contributor

Choose a reason for hiding this comment

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

Is that really relevant, though?
I believe this should only matter for Lint/TrailingBlankLines which could do a simpler, string-based test.

Copy link
Contributor

Choose a reason for hiding this comment

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

         (\n) lines   5.58k (179.32µs) (± 5.45%)  527kB/op        fastest
   (\n) regex split   2.12k (471.77µs) (± 4.67%)  729kB/op   2.63× slower
  (\n) gsub + split   2.28k (438.07µs) (± 3.47%)  527kB/op   2.44× slower
       (\r\n) lines   5.47k (182.86µs) (± 2.04%)  527kB/op   1.02× slower
 (\r\n) regex split   2.05k (487.75µs) (± 0.91%)  729kB/op   2.72× slower
(\r\n) gsub + split   1.74k (573.81µs) (± 1.94%)  721kB/op   3.20× slower

Copy link
Member Author

Choose a reason for hiding this comment

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

Source#lines is expected to return accurate representation of the underlying data, without any modifications, so I'd prefer to stick to correctness over efficiency here.

On a related note, why the String#lines is eating the final newline? It seems to me that's either a bug, or an undocumented behavior at least.

Copy link
Contributor

@straight-shoota straight-shoota Jun 11, 2025

Choose a reason for hiding this comment

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

I think both interpretations are valid. There's no clear answer whether \n is one or two lines. We have to live with the ambiguity.
The reasoning for one is: The line feed character \n marks the end of a line. That does not necessarily imply the start of a new line. At the end of the file/string there's no content afterwards. So it's reasonable to not counting a trailing newline as an additional empty line.

The documentation is certainly sparse on this, though. String#lines has no docs whatsoever. String#each_line says it "splits the string after each newline", which matches the observed behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree. Having a keep_trailing_newline = false named parameter added to String#lines would help to achieve both behaviors.

Copy link
Contributor

Choose a reason for hiding this comment

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

PR to improve docs: crystal-lang/crystal#15894

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layout/TrailingWhitespace incorrectly reporting \r\n as excess whitespace on Windows

4 participants