Print companion members one per line - #126
Merged
Merged
Conversation
Companion members were joined with ", " and emitted inline, unlike the Members section which gets a fenced block with one signature per line. For a type with a large companion (cats.effect.IO has ~100) that produced a single unreadable line that could not be grepped. Render them the same way as Members: a scala-fenced block, one signature per line. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rochala
added a commit
that referenced
this pull request
Aug 22, 2026
Problem
-------
Querying a Scala 2 sealed ADT (sealed trait T; object T { case object A
extends T }) produced garbled output: subtype names used JVM $-encoding
(CellarADT$.CellarAA$), the module class appeared as a third duplicate
result block, and <init> constructors leaked into object member lists.
The zero-param-def colon, the PolyType result separator and the Scala 2
package-object prefix are already fixed on main by #117 and #126, so
those parts are dropped from this change.
Changes
-------
SymbolResolver
- findStaticModuleClass returns the raw `Foo$` class while findStaticTerm
returns the `object Foo` val; both denote the same object and produced
a spurious extra result block. Widen the val to its module class, then
`distinct`. The class is the right representative: only it carries the
parents, flags, members, sealed children and source span that the
renderers and get-source need -- keeping the val instead would have
silently emptied `get-source` for every standalone object and dropped
`extends`/flags/companion/subtypes from its `get` output.
GetFormatter
- displayFqn: render `Outer$.Inner` as `Outer.Inner` and drop the trailing
module-class marker, so user-visible names use source-level dotted
notation. Applied to the heading FQN, the Origin field and the subtype
list. The marker is stripped only for an actual module class, so names
that genuinely end in `$` (a `$` member, a Scala 3 `Foo$package`) are
left untouched.
TypePrinter
- Print a module class as `object Foo`, not `object Foo$`.
PublicApiFilter
- Filter `<init>` only for module classes. An object has no user-callable
constructor, but a Java type has no companion `apply` either, so its
constructors are the only listing that shows how it is built.
Tests
-----
- Scala 2 fixture: nested case object/case class resolution, single
companion result, clean subtype names.
- get-source of a standalone object returns the whole object body.
- Java constructors survive the `<init>` filter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion members were joined with
", "and emitted inline, unlike the Members section which gets a fenced block with one signature per line. For a type with a large companion (cats.effect.IOhas ~100) that produced a single unreadable line that could not be grepped.Render them the same way as Members: a
scala-fenced block, one signature per line.Before
After
Sample output in
skills/cellar/SKILL.mdupdated to match.Testing
./mill lib.test— 372/372 pass.Note
Out of scope here:
renderCompanionignores--limit, unlikerenderMembers, so a large companion still dumps in full — now as many lines rather than one long one.🤖 Generated with Claude Code