Skip to content

No way to resolve the parameters & fields default values #14093

@cchantep

Description

@cchantep

Compiler version

3.1.2-RC1-bin-20211205-94f4118-NIGHTLY

Minimized code

Considering the following class:

final class Foo(val lorem: String = "default")

There is no function provided by SymbolMethods that can be used to resolve the "default" value for the lorem field (or constructor argument).

Debugging the trees, it seems the default value isn't represented anywhere:

inline def test[T]: Unit = ${ testImpl[T] }

private def testImpl[T: Type](using q: Quotes): Expr[Unit] = {
  import q.reflect.*

  val ts = TypeRepr.of[T]
  val ctor = ts.typeSymbol.primaryConstructor

  println(ts.typeSymbol.tree.show)
  // => final class Foo(val lorem: scala.Predef.String) extends java.lang.Object

  println(ts.typeSymbol.tree.toString)
  // => TypeDef(Foo,Template(DefDef(<init>,List(List(ValDef(lorem,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],EmptyTree))),TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class repl$)),module class rs$line$1$)),class Foo)],EmptyTree),List(TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)]),ValDef(_,EmptyTree,EmptyTree),List(ValDef(lorem,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],EmptyTree))))

  println(ctor.tree.show)
  // => def this(val lorem: scala.Predef.String)

  println(ctor.tree.toString)
    // def this(val lorem: scala.Predef.String)
    // DefDef(<init>,List(List(ValDef(lorem,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],EmptyTree))),TypeTree[TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class repl$)),module class rs$line$1$)),class Foo)],EmptyTree)

  ctor.paramSymss.flatMap(identity).foreach { arg =>
    println(s"${arg.name} ?hasDefault:${arg.flags.is(Flags.HasDefault)} = ${arg.tree.show} / ${arg.tree}")
  }
  // => lorem ?hasDefault:true = val lorem: java.lang.String / ValDef(lorem,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String)],EmptyTree)

  ts.typeSymbol.fieldMembers.foreach { field =>
    println(s"${field.name} ?hasDefault:${field.flags.is(Flags.HasDefault)} = ${field.tree.show} / ${field.tree}")
  }
  // => lorem ?hasDefault:true = val lorem: scala.Predef.String / ValDef(lorem,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scala)),object Predef),type String)],EmptyTree)

  '{ () }
}

Expectation

Be able to resolve the default value, either directly through SymbolMethods or using the trees.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions