scala.meta.internal.trees.quasiquote.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of common_2.11 Show documentation
Show all versions of common_2.11 Show documentation
Bag of private and public helpers used in scala.meta's APIs and implementations
The newest version!
package scala.meta
package internal
package trees
import org.scalameta.internal.MacroHelpers
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
// Generates quasiquote definition boilerplate for a given interpolator
// and then injects it into the annottee.
// See usage examples in the `quasiquotes` project.
class quasiquote[T](qname: String) extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro QuasiquoteMacros.impl
}
class QuasiquoteMacros(val c: Context) extends MacroHelpers {
import c.universe._
val ReificationMacros = q"_root_.scala.meta.internal.quasiquotes.ReificationMacros"
def impl(annottees: c.Tree*): c.Tree = annottees.transformAnnottees(new ImplTransformer {
val q"new $_[..$qtypes](${qname: String}).macroTransform(..$_)" = c.macroApplication
override def transformClass(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
val mmods1 = Modifiers(mmods.flags, TypeName("meta"), mmods.annotations)
if (stats.nonEmpty) c.abort(cdef.pos, "@quasiquote classes must have empty bodies")
val qmodule = {
val qtypesLub = lub(qtypes.map(_.duplicate).map { qtype =>
try c.typecheck(qtype, c.TYPEmode).tpe
catch {
case c.TypecheckException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg)
}
})
q"""
object ${TermName(qname)} {
import scala.language.experimental.macros
def apply[T >: Any](args: T*)(implicit dialect: _root_.scala.meta.Dialect): $qtypesLub = macro $ReificationMacros.apply
def unapply(scrutinee: Any)(implicit dialect: _root_.scala.meta.Dialect): Any = macro $ReificationMacros.unapply
}
"""
}
val qparser = {
val qmonadicResults = qtypes.map(qtype =>
q"""
type Parse[T] = _root_.scala.meta.parsers.Parse[T]
val parse = _root_.scala.Predef.implicitly[Parse[$qtype]]
parse(input, dialect)
"""
)
val qmonadicResult = qmonadicResults.reduce((acc, curr) => q"$acc.orElse($curr)")
val qresult = q"""
$qmonadicResult match {
case x: _root_.scala.meta.parsers.Parsed.Success[_] => x.tree
case x: _root_.scala.meta.parsers.Parsed.Error => throw x.details
}
"""
q"private[meta] def parse(input: _root_.scala.meta.inputs.Input, dialect: _root_.scala.meta.Dialect) = $qresult"
}
val stats1 = stats :+ qmodule
val mstats1 = mstats :+ qparser
val cdef1 =
q"$mods class $name[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats1 }"
val mdef1 =
q"$mmods1 object $mname extends { ..$mearlydefns } with ..$mparents { $mself => ..$mstats1 }"
List(cdef1, mdef1)
}
})
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy