简体   繁体   中英

How can I use macros for code substitution in Scala?

I have repetitive blocks of code I want to copy, like old C-style macros. I'm trying quasiquotes:

import scala.language.experimental.macros

object CodeBlock {
  val quasi = q"""def foo() = {"bar"}"""
}

case class A() {
// ??? want quasi here
}

case class B() {
// ??? want quasi here
}

Try macro annotation

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

@compileTimeOnly("enable macro paradise")
class codeBlock extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro CodeBlockMacro.impl
}

object CodeBlockMacro {
  def impl(c: whitebox.Context)(annottees: c.Tree*): c.Tree = {
    import c.universe._
    annottees match {
      case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" :: tail =>
        q"""
          $mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self =>
            def foo() = {"bar"}
            ..$stats
          }

          ..$tail
        """
    }
  }
}

@codeBlock
case class A()

@codeBlock
case class B()

//Warning:scalac: {
//  case class A extends scala.Product with scala.Serializable {
//    def <init>() = {
//      super.<init>();
//      ()
//    };
//    def foo() = "bar"
//  };
//  ()
//}
//Warning:scalac: {
//  case class B extends scala.Product with scala.Serializable {
//    def <init>() = {
//      super.<init>();
//      ()
//    };
//    def foo() = "bar"
//  };
//  ()
//}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM