Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
cchantep opened this issue Dec 12, 2021 · 3 comments
Closed

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

cchantep opened this issue Dec 12, 2021 · 3 comments

Comments

@cchantep
Copy link
Contributor

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.

@odersky
Copy link
Contributor

odersky commented Dec 12, 2021

Default values are stored in default getter functions. These have to be looked up explicitly at the moment. We plan an overhaul of default values at some point in the future where we would not rely on default getters anymore. At that point, we should make sure that default arguments can be accessed from reflection.

@cchantep
Copy link
Contributor Author

@Atry
Copy link
Contributor

Atry commented Dec 24, 2021

Is it possible to evaluate the default parameters with scala.quoted.staging?

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

No branches or pull requests

3 participants