Skip to content

classSymbol fullname not consistent with class name for inner classes #10933

@gaeljw

Description

@gaeljw

Minimized code

Consider the following macro:

import scala.quoted._

object Macros {

  inline def parameterTypes[T1](): String = {
    ${ getTypes[T1]() }
  }

  private def getTypes[T1]()(using Type[T1], Quotes): Expr[String] = {
    import quotes.reflect._
    Expr(TypeRepr.of[T1].classSymbol.get.fullName)
  }

}

And the following usage (as a test but doesn't matter) :

case class TopLevelClass(c: String)

object TestObject {

  case class ObjectInnerClass(b: String)

}

class Test1 {

  case class InnerClass(a: String)

  @Test def t1(): Unit = {
    val foundTypes = Macros.parameterTypes[InnerClass]()
    val foundTypesObj = Macros.parameterTypes[TestObject.ObjectInnerClass]()
    val foundTypesTL = Macros.parameterTypes[TopLevelClass]()

    val expectedTypes = classOf[InnerClass].getName()
    val expectedTypesObj = classOf[TestObject.ObjectInnerClass].getName()
    val expectedTypesTL = classOf[TopLevelClass].getName()

    println(foundTypes)
    println(expectedTypes)

    println(foundTypesObj)
    println(expectedTypesObj)

    println(foundTypesTL)
    println(expectedTypesTL)
  }

}

Output

Test1.InnerClass
Test1$InnerClass
TestObject$.ObjectInnerClass
TestObject$ObjectInnerClass
TopLevelClass
TopLevelClass

// Or with a package
my.project.Test1.InnerClass
my.project.Test1$InnerClass
my.project.TestObject$.ObjectInnerClass
my.project.TestObject$ObjectInnerClass
my.project.TopLevelClass
my.project.TopLevelClass

For inner classes, the name given by the macro is different of the actual class name.

Expectation

I expected the TypeRepr.of[T1].classSymbol.get.fullName to give the same name as would classOf[T1].getName.

To give some background, I'm later using the class name with Class.forName(name) and it fails for Class.forName("TestObject$.ObjectInnerClass") for instance.

If that's an expected behavior, what would be the way from TypeRepr.of[T1] to get the class name that can later be used to retrieve the actual class?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions