Skip to content

Commit b99faf8

Browse files
Add defaultParams method to Tasty Reflect Symbol API
1 parent 0b388a6 commit b99faf8

File tree

6 files changed

+47
-0
lines changed

6 files changed

+47
-0
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,22 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
17791779
case sym if sym.is(Flags.CaseAccessor) => sym.asTerm
17801780
}
17811781

1782+
def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref] =
1783+
assert(self.isClass && self.flags.is(Flags.Case))
1784+
val comp: Symbol = self.companionClass
1785+
val names: List[String] =
1786+
for p <- Symbol_caseFields(self) if p.flags.is(Flags.HasDefault)
1787+
yield Symbol_name(p)
1788+
1789+
val body = ClassDef_body(Symbol_tree(comp).asInstanceOf[ClassDef])
1790+
val idents: List[Ref] =
1791+
for case deff @ DefDef(name, _, _, _, tree) <- body
1792+
if name.toString.startsWith("$lessinit$greater$default")
1793+
yield Ref_apply(deff.symbol)
1794+
1795+
names.zip(idents).toMap
1796+
end Symbol_defaultParams
1797+
17821798
def Symbol_children(self: Symbol)(using ctx: Context): List[Symbol] =
17831799
self.children
17841800

library/src/scala/tasty/Reflection.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,14 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>
22842284
def caseFields(using ctx: Context): List[Symbol] =
22852285
internal.Symbol_caseFields(sym)
22862286

2287+
/** Default parameters of a case class. Keys are names of the parameters and values –
2288+
* symbols of the definitions sites of the default values.
2289+
* Implementation restriction: only the default parameters in the first parameter group
2290+
* are returned.
2291+
*/
2292+
def defaultParams(using ctx: Context): Map[String, Ref] =
2293+
internal.Symbol_defaultParams(sym)
2294+
22872295
def isTypeParam(using ctx: Context): Boolean =
22882296
internal.Symbol_isTypeParam(sym)
22892297

library/src/scala/tasty/reflect/CompilerInterface.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,13 @@ trait CompilerInterface {
13321332
/** Fields of a case class type -- only the ones declared in primary constructor */
13331333
def Symbol_caseFields(self: Symbol)(using ctx: Context): List[Symbol]
13341334

1335+
/** Default parameters of a case class. Keys are names of the parameters and values –
1336+
* symbols of the definitions sites of the default values.
1337+
* Implementation restriction: only the default parameters in the first parameter group
1338+
* are returned.
1339+
*/
1340+
def Symbol_defaultParams(self: Symbol)(using ctx: Context): Map[String, Ref]
1341+
13351342
def Symbol_of(fullName: String)(using ctx: Context): Symbol
13361343

13371344
def Symbol_newMethod(parent: Symbol, name: String, flags: Flags, tpe: Type, privateWithin: Symbol)(using ctx: Context): Symbol
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Map(address -> Home, age -> 1)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.quoted._
2+
3+
inline def defaultParams[T]: Map[String, Any] = ${ defaultParamsImpl[T] }
4+
private def defaultParamsImpl[T](
5+
using tpe: Type[T], qctx: QuoteContext): Expr[Map[String, Any]] =
6+
import qctx.tasty._
7+
val sym = tpe.unseal.symbol
8+
val exprs: Map[String, Expr[Any]] =
9+
sym.defaultParams.view.mapValues(_.seal.cast[Any]).toMap
10+
Expr.ofMapValues(exprs)
11+
end defaultParamsImpl
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
case class Cat(name: String, address: String = "Home", age: Int = 1)
2+
3+
@main def Test =
4+
println(defaultParams[Cat])

0 commit comments

Comments
 (0)