Skip to content

test(organizeimports): add failing IO tests for inline comment behavior (issue #2267)#2324

Draft
arnavsharma990 wants to merge 8 commits intoscalacenter:mainfrom
arnavsharma990:fix-organizeimports-comments
Draft

test(organizeimports): add failing IO tests for inline comment behavior (issue #2267)#2324
arnavsharma990 wants to merge 8 commits intoscalacenter:mainfrom
arnavsharma990:fix-organizeimports-comments

Conversation

@arnavsharma990
Copy link
Contributor

@arnavsharma990 arnavsharma990 commented Nov 28, 2025

Fixes #2267

This PR adds new IO test cases for OrganizeImports to capture the incorrect handling of inline comments (e.g., comments to the right of imports being lost, reordered incorrectly, or not associated with the correct import). These test
s encode the expected behavior so the underlying rule can later be updated to preserve inline comments consistently.

Locally, the new tests pass, but some unrelated expect*/testOnly suites occasionally behave inconsistently on my machine (sometimes showing passed, canceled, or failed). I’ve attached a screenshot in the discussion, but this inconsistency does not involve the new OrganizeImports tests themselves.

Please review the added test cases and confirm whether this structure matches what the maintainers expect before I proceed to implement the actual fix to OrganizeImports.
Screenshot 2025-11-28 at 4 17 07 PM
Screenshot 2025-11-28 at 4 04 01 PM

@arnavsharma990
Copy link
Contributor Author

Test cases included

I added failing test cases in the following files:

InlineCommentMultiple.scala

InlineCommentMoves.scala

InlineCommentRemoved.scala

These tests capture scenarios where inline comments are not preserved, shifted incorrectly, or dropped during import organization.

@arnavsharma990
Copy link
Contributor Author

arnavsharma990 commented Nov 28, 2025

@bjaglin The failing CI is expected as the new IO tests intentionally fail because they capture the inline comment issue described in #2267.
These failing tests demonstrate the bug before implementing the fix.

@tgodzik
Copy link
Contributor

tgodzik commented Dec 2, 2025

I think the test cases look fine, we might not need that many though.

@arnavsharma990
Copy link
Contributor Author

Thanks for the clarification and for reviewing the tests!
I’ll trim the test cases as suggested.

Also, should I start working on the actual fix for the issue now?

@tgodzik
Copy link
Contributor

tgodzik commented Dec 2, 2025

Sure, just make sure that if you use AI that you properly vet the output and try to minimize the changes.

Copy link
Collaborator

@bjaglin bjaglin left a comment

Choose a reason for hiding this comment

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

That's a great start 👍 I think we could add heading/trailing examples, as well as multi-line /* */ comments to have a better coverage.

Feel free to start working on implementation.

import c.C

object InlineCommentMultiple {
val keep = 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: we can remove that if removeUnused is not tested

…aloneComment.scala

Co-authored-by: Brice Jaglin <bjaglin@gmail.com>
Copilot AI review requested due to automatic review settings December 3, 2025 15:51
Removed unused import 'c.C' to clean up code.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds new IO test cases to capture the current (incorrect) behavior of the OrganizeImports rule when handling inline comments. The tests document scenarios where inline comments are lost, reordered incorrectly, or not properly associated with their imports, establishing a baseline for future fixes to issue #2267.

  • Adds fixture file InlineCommentFixtures.scala with test packages and classes
  • Creates 4 test scenarios covering standalone comments, inline comment preservation during sorting, inline comment behavior with unused import removal, and inline comment movement
  • Establishes expected behavior patterns for subsequent OrganizeImports rule improvements

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scalafix-tests/shared/src/main/scala/test/organizeImports/InlineCommentFixtures.scala Provides fixture classes in packages a, b, c, z, my.pkg, other, x, y for testing import organization with inline comments
scalafix-tests/input/src/main/scala/test/organizeImports/StandaloneComment.scala Tests that standalone comments (not inline) are preserved when imports are sorted
scalafix-tests/output/src/main/scala/test/organizeImports/StandaloneComment.scala Expected output showing standalone comment preserved with sorted imports
scalafix-tests/input/src/main/scala/test/organizeImports/InlineCommentRemoved.scala Tests inline comment behavior when associated import is removed as unused
scalafix-tests/output/src/main/scala/test/organizeImports/InlineCommentRemoved.scala Expected output showing unused import and its inline comment are both removed
scalafix-tests/input/src/main/scala/test/organizeImports/InlineCommentMultiple.scala Tests preservation of multiple inline comments during import sorting
scalafix-tests/output/src/main/scala/test/organizeImports/InlineCommentMultiple.scala Expected output showing inline comments move with their associated imports when sorted
scalafix-tests/input/src/main/scala/test/organizeImports/InlineCommentMoves.scala Tests inline comment staying with its import when imports are reordered
scalafix-tests/output/src/main/scala/test/organizeImports/InlineCommentMoves.scala Expected output showing inline comment moved with its import during sorting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@arnavsharma990
Copy link
Contributor Author

I’ve addressed the inline comment preservation issue and expanded test coverage to include:

trailing // and /* */ comments

leading (heading) comments

mixed line and block comments

correct removal of unused imports along with their comments

Formatting has been applied with scalafmt, and the PR should be ready for review / merge.
Happy to make any further adjustments if needed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
.lastOption
.collect { case c: Token.Comment =>
allTokens.indexOf(c) + 1
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

The allTokens.indexOf(c) call performs a linear search through all tokens which is inefficient. Since tokensAfter is already derived from allTokens, the index can be calculated more efficiently using lastImportTokenEnd + tokensAfter.indexOf(c).

Suggested change
allTokens.indexOf(c) + 1
lastImportTokenEnd + tokensAfter.indexOf(c) + 1

Copilot uses AI. Check for mistakes.
Comment on lines +119 to +127
// Collect trailing comments for each importer before reordering
val trailingComments: Map[Int, String] = {
val comments = doc.comments
(for {
imp <- imports
importer <- imp.importers
comment <- comments.trailing(importer).headOption
} yield importer.pos.start -> (" " + comment.syntax)).toMap
}
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

This implementation only collects trailing comments (comments on the same line after an import) but does not handle leading comments (comments on the line before an import). The test case InlineCommentLeading.scala demonstrates this gap - leading comments should move with their associated imports but this implementation doesn't support that.

Copilot uses AI. Check for mistakes.
imp <- imports
importer <- imp.importers
comment <- comments.trailing(importer).headOption
} yield importer.pos.start -> (" " + comment.syntax)).toMap
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Using importer.pos.start as the key could lead to collisions if multiple importers have the same start position. While unlikely in normal code, using a more unique identifier or the importer itself as a key would be more robust.

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +126
(for {
imp <- imports
importer <- imp.importers
comment <- comments.trailing(importer).headOption
} yield importer.pos.start -> (" " + comment.syntax)).toMap
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

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

Prepending a space character to the comment syntax is a formatting decision that should be parameterized or documented. Different comment styles (block vs line) may require different spacing.

Suggested change
(for {
imp <- imports
importer <- imp.importers
comment <- comments.trailing(importer).headOption
} yield importer.pos.start -> (" " + comment.syntax)).toMap
// Separator between an import and its trailing comment (single space by default)
val trailingCommentSeparator = " "
(for {
imp <- imports
importer <- imp.importers
comment <- comments.trailing(importer).headOption
} yield importer.pos.start -> (trailingCommentSeparator + comment.syntax)).toMap

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@bjaglin bjaglin left a comment

Choose a reason for hiding this comment

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

Thanks for the taking a stab at the implementation @arnavsharma990 !

  • Could you have a look at the remaining comments? I find them all relevant. As noted here, there is a new scalameta feature available on main that should make the implementation much simpler
  • Could you update the title and the description now that this PR is actually an implementation?

arnavsharma990 and others added 3 commits February 17, 2026 00:15
…neCommentLeading.scala

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mports.scala

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mports.scala

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@arnavsharma990 arnavsharma990 marked this pull request as draft February 16, 2026 18:46
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.

OrganizeImports does not retain inline comments

4 participants