Skip to content

Render Java symbols as Java, and fix constructor signature rendering #134

Description

@rochala

Java symbols are currently rendered through the Scala printer, so cellar get on a Java type produces signatures that are neither valid Java nor useful Scala.

Current output

cellar get-external cellar.test:cellar-fixture-java:0.1.0-SNAPSHOT cellar.fixture.java.CellarJavaClass

class CellarJavaClass[T >: NothingType <: Comparable[T]] extends CellarJavaInterface[T]
def repeat(x$0: T, x$1: Int): List[T]
def format(x$0: Int, x$1: Boolean): String
def <init>[T >: NothingType <: Comparable[T]](x$0: T): Unit
def getDefault(): T

The fixture source (fixtureJava/src/cellar/fixture/java/CellarJavaClass.java):

public class CellarJavaClass<T extends Comparable<T>> implements CellarJavaInterface<T> {
    public CellarJavaClass(T defaultValue) { ... }
    public List<T> repeat(T value, int times) { ... }
    public String format(int value, boolean verbose) { ... }
    public T getDefault() { ... }
}

Distinct defects

  1. Constructors print as <init>. A constructor should render under the class name, e.g. CellarJavaClass(T defaultValue), not def <init>(...).
  2. Constructors print : Unit. A constructor yields the instance; the return type is noise at best and wrong at worst.
  3. Parameter names are erased placeholders (x$0, x$1). Real names are only in the class file when it was compiled with -parameters (the MethodParameters attribute); otherwise there is nothing to recover and the fallback should probably be type-only (format(int, boolean)) rather than a fake name.
  4. NothingType leaks into Java type-parameter bounds. <T extends Comparable<T>> should print as that, not as [T >: NothingType <: Comparable[T]] — a Java type parameter has no lower bound to show.

The broader question

Beyond the four defects: should Java symbols print as Java at all?

public List<T> repeat(T value, int times)     // instead of
def repeat(x$0: T, x$1: Int): List[T]

The seam already exists — TypePrinter.detectLanguage returns DetectedLanguage.Java (lib/src/cellar/TypePrinter.scala:17), printSymbolSignatureSafe already branches on the detected language to append the Scala 2 caveat (TypePrinter.scala:93), and get-source already emits a ```java fence for Java sources (lib/src/cellar/handlers/GetSourceHandler.scala:88). What is missing is a Java-mode signature printer alongside the Scala one.

That is not a small change: it means a second rendering path over the whole type surface — generics and wildcards (? extends T vs _ <: T), arrays (T[] vs Array[T]), varargs (T... vs T*), primitives (int vs Int), plus modifiers Scala has no keyword for (static, final, synchronized, transient). It also changes output that GetFormatterTest and TypePrinterTest currently assert.

Notes

Fixing defects 1–4 is worthwhile on its own and much cheaper than the full Java printer; they could land first.

Context: raised while reviewing #87, which narrowed the <init> filter so Java constructors are listed at all (an object or trait has no user-callable constructor; a concrete class does). That made the rendering problem visible but deliberately did not address it.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions