lampepfl / dotty-feature-requests

Historical feature requests. Please create new feature requests at https://github.com/lampepfl/dotty/discussions/new?category=feature-requests
31 stars 2 forks source link

Scala enums non extending java.lang.Enum should provide a way access their class name in runtime #338

Closed WojciechMazur closed 1 year ago

WojciechMazur commented 1 year ago

Scala enums are implemented as anonymous classes. Class[_].getSimpleName() always returns empty strings for them. Because of that in order to get to the information of the class name we need use toString on matched type. toString can potentially be overridden. In case of non-singleton enum we also need to parse the toString method to strip arguments list.


trait Named {
  def name: String = {
    this match {
      // Singleton: case Foo
      case e: scala.runtime.EnumValue =>e.toString()
      // Non-singleton: case Foo(args)
      case e: scala.reflect.Enum => e.toString.takeWhile(_ != '(')
      // Non enum and not an anonymous class
      case _ => this.getClass().getSimpleName().ensuring(_.nonEmpty)
    }
  }
}

enum Foo extends Named {
  case Bar
  case Other(foo: String)
}
case class NonEnum(arg: String) extends Named

Seq(Foo.Bar, Foo.Other("foo"), NonEnum("foo"))
  .map(_.name)
  .foreach(println)

output

// defined trait Named
// defined class Foo
// defined case class NonEnum

Bar
Other
NonEnum

The compiler has the information about the actual names for all enums, however, they're never used in case of enums non extending java.lang.Enum. I propose to work on establishing the common pattern to accessing the names of the enums. One potential solution I can think of is usage of typeclass scala.runtime.EnumName[T <: scala.reflect.Enum] which instance would be created in the companion class of enum.

plokhotnyuk commented 1 year ago

Using toString for parametrized classes can be quite expensive...

Could some macro be an option?

bishabosha commented 1 year ago

you can use productPrefix