如何使用scala 3宏在编译时生成无参数构造函数?

xdyibdwo  于 2023-03-23  发布在  Scala
关注(0)|答案(1)|浏览(155)

如何在一个类上生成一个私有的无参数构造函数(在编译时),当它用@entity注解时-在scala 3宏中
class entity extends scala.annotation.StaticAnnotation

@entity
class Student(val id: Long, val name: String) {
  //??? at compile time generates: private def this() = this(0, null)
}
qco9c6ql

qco9c6ql1#

从Scala 3.3.0-RC 2开始,出现了宏注解(由Nicolas Stucki实现)。

添加辅助构造函数的宏注解应如下:

  • build.sbt*
scalaVersion := "3.3.0-RC3"
import scala.annotation.{MacroAnnotation, experimental}
import scala.quoted.*

object Macros:
  @experimental
  class entity extends MacroAnnotation:
    def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
      import quotes.reflect.*

      tree match
        case ClassDef(name, constr, parents, selfOpt, body) =>
          val constrSym = Symbol.newMethod(tree.symbol, "<init>", MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Unit]))
          val constrDef = DefDef(constrSym, _ => Some(
            Apply(Select.unique(New(Inferred(tree.symbol.typeRef)), "<init>"), List('{0}.asTerm, '{null}.asTerm))
          ))

          val res = List(ClassDef.copy(tree)(name, constr, parents, selfOpt, body :+ constrDef))
          println(res.map(_.show))
          res

        case _ => report.errorAndAbort("@entity can annotate only classes")
import Macros.entity
import scala.annotation.experimental

object App:
  @entity @experimental
  class Student(val id: Long, val name: String)

//scalac: List(@scala.annotation.experimental @Macros.entity class Student(val id: scala.Long, val name: scala.Predef.String) {
//  def this() = new App.Student(0, null)
//})

Macro Annotations in Scala 3
How to generate a class in Dotty with macro?
Scala 3 macro to create enum

相关问题