![JAR search and dependency download from the Maven repository](/logo.png)
org.scalameta.annotations.quasiquote.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalameta-foundation_2.11 Show documentation
Show all versions of scalameta-foundation_2.11 Show documentation
Metaprogramming and hosting APIs of scala.meta
The newest version!
package org.scalameta.annotations
import scala.language.experimental.macros
import scala.annotation.StaticAnnotation
import scala.reflect.macros.whitebox.Context
class quasiquote[T](qname: scala.Symbol) extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro QuasiquoteMacros.impl
}
class QuasiquoteMacros(val c: Context) {
import c.universe._
import Flag._
def impl(annottees: c.Tree*): c.Tree = {
val q"new $_[$qtype](scala.Symbol(${qname: String})).macroTransform(..$_)" = c.macroApplication
def transform(cdef: ClassDef, mdef: ModuleDef): List[ImplDef] = {
val q"$mods class $name[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" = cdef
val q"$mmods object $mname extends { ..$mearlydefns } with ..$mparents { $mself => ..$mstats }" = mdef
if (stats.nonEmpty) c.abort(cdef.pos, "@quasiquote classes must have empty bodies")
val qmodule = q"""
object ${TermName(qname)} {
import scala.language.experimental.macros
def apply[T](args: T*): _root_.scala.meta.Tree = macro $mname.applyImpl
def unapply(scrutinee: Any): $qtype = macro ???
}
"""
val qparser = TermName("parse" + qname.capitalize)
val q"..$applyimpls" = q"""
import scala.reflect.macros.whitebox.Context
def applyImpl(c: Context)(args: c.Tree*): c.Tree = {
import _root_.scala.meta.syntactic.parsers.RichOrigin
val helper = new _root_.scala.meta.syntactic.quasiquotes.Macros[c.type](c)
helper.apply(c.macroApplication, (s: String) => s.parse[$qtype])
}
"""
val cdef1 = q"$mods class $name[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..${qmodule +: stats} }"
val mdef1 = q"$mmods object $mname extends { ..$mearlydefns } with ..$mparents { $mself => ..${mstats ++ applyimpls} }"
List(cdef1, mdef1)
}
val expanded = annottees match {
case (cdef: ClassDef) :: (mdef: ModuleDef) :: rest if cdef.mods.hasFlag(IMPLICIT) => transform(cdef, mdef) ++ rest
case (cdef: ClassDef) :: rest if cdef.mods.hasFlag(IMPLICIT) => transform(cdef, q"object ${cdef.name.toTermName}") ++ rest
case annottee :: rest => c.abort(annottee.pos, "only implicit classes can be @quasiquote")
}
q"{ ..$expanded; () }"
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy