scala.reflect.macros.whitebox.Context Scala Examples
The following examples show how to use scala.reflect.macros.whitebox.Context.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Macro.scala From zio-macros with Apache License 2.0 | 5 votes |
package zio.macros.accessible import com.github.ghik.silencer.silent import zio.macros.core.ModulePattern import scala.reflect.macros.whitebox.Context private[macros] class Macro(val c: Context) extends ModulePattern { import c.universe._ case class Config(name: Option[String]) def apply(annottees: c.Tree*): c.Tree = { @silent("pattern var [^\\s]+ in method unapply is never used") val config: Config = c.prefix.tree match { case Apply(_, args) => val name = args.collectFirst { case q"$cfg" => c.eval(c.Expr[String](cfg)) }.map { ident => util.Try(c.typecheck(c.parse(s"object $ident {}"))) match { case util.Failure(_) => c.abort(c.enclosingPosition, s"""Invalid identifier "$ident". Cannot generate accessors object.""") case util.Success(_) => ident } } Config(name) case other => c.abort(c.enclosingPosition, s"Invalid accessible macro call ${showRaw(other)}") } val trees = extractTrees(annottees) val module = extractModule(trees.module) val companion = extractCompanion(trees.companion) val service = extractService(companion.body) val capabilites = extractCapabilities(service) val accessors = generateCapabilityAccessors(module.name, module.serviceName, capabilites) val updatedCompanion = generateUpdatedCompanion(config, module, companion, accessors) q""" ${trees.module} $updatedCompanion """ } private def generateCapabilityAccessors( moduleType: TypeName, serviceName: TermName, capabilities: List[Capability] ): List[Tree] = capabilities.map { capability => val (name, e, a) = (capability.name, capability.error, capability.value) val mods = if (capability.impl == EmptyTree) Modifiers() else Modifiers(Flag.OVERRIDE) val returnType = tq"_root_.zio.ZIO[$moduleType, $e, $a]" val returnValue = capability.argLists match { case Some(argLists) if argLists.flatten.nonEmpty => val argNames = argLists.map(_.map(_.name)) q"_root_.zio.ZIO.accessM(_.$serviceName.$name(...$argNames))" case _ => q"_root_.zio.ZIO.accessM(_.$serviceName.$name)" } capability.argLists match { case None => q"$mods val $name: $returnType = $returnValue" case Some(Nil) => q"$mods def $name: $returnType = $returnValue" case Some(List(Nil)) => q"$mods def $name(): $returnType = $returnValue" case Some(argLists) => q"$mods def $name(...$argLists): $returnType = $returnValue" } } private def generateUpdatedCompanion( config: Config, module: ModuleSummary, companion: CompanionSummary, capabilityAccessors: List[Tree] ): Tree = { val accessor: Tree = config.name match { case Some(name) => c.parse(s"object $name extends Accessors") case None => EmptyTree } q""" object ${companion.name} { ..${companion.body} trait Accessors extends Service[${module.name}] { ..$capabilityAccessors } $accessor } """ } }
Example 2
Source File: package.scala From logging with Apache License 2.0 | 5 votes |
package com.persist import scala.language.experimental.macros import scala.reflect.macros.whitebox.Context import com.persist.JsonOps._ def richToString(m: RichMsg): String = { m match { case s: String => s case x => Compact(x, safe = true) } } implicit def sourceLocation: () => SourceLocation = macro sourceLocationMacro def sourceLocationMacro(c: Context): c.Expr[() => SourceLocation] = { import c.universe._ val p = c.macroApplication.pos val file = p.source.file.name val line = p.line def allOwners(s: c.Symbol): Seq[c.Symbol] = { if (s == `NoSymbol`) { Seq() } else { s +: allOwners(s.owner) } } val owners = allOwners(c.internal.enclosingOwner) val className = owners .filter(s => s.toString.startsWith("class") || s.toString.startsWith("object")) .map(s => s.asClass.name.toString()) .reverse .mkString("$") val packageName = owners .filter(_.isPackage) .map(_.name.toString()) .filter(_ != "<root>") .reverse .mkString(".") c.Expr[() => SourceLocation](q"() => SourceLocation($file,$packageName,$className,$line)") } }
Example 3
Source File: singletons.scala From iota with Apache License 2.0 | 5 votes |
package iota //#=cats package iotaz //#=scalaz package test import scala.language.dynamics import scala.reflect.macros.whitebox.Context import scala.Predef.augmentString trait Literal { type T } object Literal { type Bound[A] = Literal { type T <: A } } object LiteralInt extends Dynamic { def selectDynamic(selector: String): Literal.Bound[Int] = macro MacrosLiterally.literalIntSelectDynamic } object LiteralString extends Dynamic { def selectDynamic(selector: String): Literal.Bound[String] = macro MacrosLiterally.literalStringSelectDynamic } final class MacrosLiterally(val c: Context) { import c.universe.{ Literal => ASTLiteral, _ } import internal.decorators._ private[this] final val iotaPackage: Tree = q"_root_.iota" //#=cats q"_root_.iotaz" //#=scalaz def literalIntSelectDynamic(selector: Tree): Tree = { val q"${value: String}" = selector val tpe = c.internal.constantType(Constant(value.toInt)) val tree = tq"$iotaPackage.test.Literal { type T = $tpe }" ASTLiteral(Constant(())).setType(c.typecheck(tree, mode = c.TYPEmode).tpe) } def literalStringSelectDynamic(selector: Tree): Tree = { val q"${value: String}" = selector val tpe = c.internal.constantType(Constant(value)) val tree = tq"$iotaPackage.test.Literal { type T = $tpe }" ASTLiteral(Constant(())).setType(c.typecheck(tree, mode = c.TYPEmode).tpe) } }
Example 4
Source File: typeclass.scala From typeclassic with Apache License 2.0 | 5 votes |
package typeclassic import scala.annotation.{ compileTimeOnly, StaticAnnotation } import scala.language.experimental.macros import scala.reflect.macros.whitebox.Context import macrocompat._ @compileTimeOnly("typeclass annotation should have been automatically removed but was not") class typeclass(excludeParents: List[String] = Nil, generateAllOps: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro TypeClassMacros.generateTypeClass } @bundle class TypeClassMacros(val c: Context) { import c.universe._ def generateTypeClass(annottees: c.Expr[Any]*): c.Expr[Any] = { annottees.map(_.tree) match { case (typeClass: ClassDef) :: Nil => modify(typeClass, None) case (typeClass: ClassDef) :: (companion: ModuleDef) :: Nil => modify(typeClass, Some(companion)) case other :: Nil => c.abort(c.enclosingPosition, "@typeclass can only be applied to traits or abstract classes that take 1 type parameter which is either a proper type or a type constructor") } } private def modify(typeClass: ClassDef, companion: Option[ModuleDef]) = { val (tparam, proper) = typeClass.tparams match { case hd :: Nil => hd.tparams.size match { case 0 => (hd, true) case 1 => (hd, false) case n => c.abort(c.enclosingPosition, "@typeclass may only be applied to types that take a single proper type or type constructor") } case other => c.abort(c.enclosingPosition, "@typeclass may only be applied to types that take a single type parameter") } val modifiedTypeClass = typeClass // TODO val modifiedCompanion = generateCompanion(typeClass, tparam, proper, companion match { case Some(c) => c case None => q"object ${typeClass.name.toTermName} {}" }) val result = c.Expr(q""" $modifiedTypeClass $modifiedCompanion """) trace(s"Generated type class ${typeClass.name}:\n" + showCode(result.tree)) result } private def generateCompanion(typeClass: ClassDef, tparam0: TypeDef, proper: Boolean, comp: Tree): Tree = { val tparam = eliminateVariance(tparam0) val q"$mods object $name extends ..$bases { ..$body }" = comp q""" $mods object $name extends ..$bases { import scala.language.experimental.macros ..$body ${generateInstanceSummoner(typeClass, tparam)} } """ } private def generateInstanceSummoner(typeClass: ClassDef, tparam: TypeDef): Tree = { q""" @_root_.typeclassic.op("$$y {$$x}") def apply[$tparam](implicit x1: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] = macro _root_.typeclassic.OpsMacros.op10 """ } // This method is from simulacrum, contributed by paulp, and is licensed under 3-Clause BSD private def eliminateVariance(tparam: TypeDef): TypeDef = { // If there's another way to do this I'm afraid I don't know it. val u = c.universe.asInstanceOf[c.universe.type with scala.reflect.internal.SymbolTable] val tparam0 = tparam.asInstanceOf[u.TypeDef] val badFlags = (Flag.COVARIANT | Flag.CONTRAVARIANT).asInstanceOf[Long] val fixedMods = tparam0.mods & ~badFlags TypeDef(fixedMods.asInstanceOf[c.universe.Modifiers], tparam.name, tparam.tparams, tparam.rhs) } private def trace(s: => String) = { // Macro paradise seems to always output info statements, even without -verbose if (sys.props.get("typeclassic.trace").isDefined) c.info(c.enclosingPosition, s, false) } }
Example 5
Source File: AnnotationMacros.scala From scalajs-angulate with MIT License | 5 votes |
// - Project: scalajs-angulate (https://github.com/jokade/scalajs-angulate) // Description: Macro implementations for AnnotatedFunction // // Distributed under the MIT License (see included file LICENSE) package biz.enef.angulate.impl import scala.reflect.macros.whitebox.Context protected[angulate] class AnnotationMacros(val c: Context) extends MacroBase { import c.universe._ // print generated code to console during compilation private lazy val logCode = c.settings.exists( _ == "biz.enef.angulate.AnnotationMacros.debug" ) def functionDIArray(f: c.Tree) = { val diArray = createFunctionDIArray(f) val tree = q"""{import scalajs.js import biz.enef.angulate.AnnotatedFunction new AnnotatedFunction($diArray) }""" if(logCode) printCode( tree ) tree } }
Example 6
Source File: QuotationDsl.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.dsl import scala.language.experimental.macros import scala.language.implicitConversions import scala.reflect.macros.whitebox.Context import io.getquill.ast.Ast import io.getquill.quotation.NonQuotedException import io.getquill.quotation.Quotation import scala.annotation.compileTimeOnly private[dsl] trait QuotationDsl { this: CoreDsl => trait Quoted[+T] { def ast: Ast override def toString = ast.toString } def quote[T](body: Quoted[T]): Quoted[T] = macro QuotationMacro.doubleQuote[T] def quote[T1, R](func: T1 => Quoted[R]): Quoted[T1 => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, R](func: (T1, T2) => Quoted[R]): Quoted[(T1, T2) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, R](func: (T1, T2, T3) => Quoted[R]): Quoted[(T1, T2, T3) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, R](func: (T1, T2, T3, T4) => Quoted[R]): Quoted[(T1, T2, T3, T4) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, R](func: (T1, T2, T3, T4, T5) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, T6, R](func: (T1, T2, T3, T4, T5, T6) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, T6, T7, R](func: (T1, T2, T3, T4, T5, T6, T7) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, T6, T7, T8, R](func: (T1, T2, T3, T4, T5, T6, T7, T8) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](func: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R] = macro QuotationMacro.quotedFunctionBody def quote[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](func: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R] = macro QuotationMacro.quotedFunctionBody implicit def quote[T](body: T): Quoted[T] = macro QuotationMacro.quote[T] @compileTimeOnly(NonQuotedException.message) implicit def unquote[T](quoted: Quoted[T]): T = NonQuotedException() } private[dsl] class QuotationMacro(val c: Context) extends Quotation
Example 7
Source File: LoadNaming.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.idiom import scala.reflect.macros.whitebox.Context import scala.util.Try import io.getquill.NamingStrategy import io.getquill.util.CollectTry import io.getquill.util.LoadObject import io.getquill.CompositeNamingStrategy object LoadNaming { def static(c: Context)(tpe: c.Type): Try[NamingStrategy] = CollectTry { strategies(c)(tpe).map(LoadObject[NamingStrategy](c)(_)) }.map(NamingStrategy(_)) private def strategies(c: Context)(tpe: c.Type) = tpe <:< c.typeOf[CompositeNamingStrategy] match { case true => tpe.typeArgs .filterNot(_ =:= c.weakTypeOf[NamingStrategy]) .filterNot(_ =:= c.weakTypeOf[scala.Nothing]) case false => List(tpe) } }
Example 8
Source File: Rebind.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.quotation import scala.reflect.macros.whitebox.Context import io.getquill.ast.Ast import io.getquill.ast.Function import io.getquill.ast.FunctionApply import io.getquill.ast.Ident import io.getquill.ast.QuotedReference object Rebind { def apply(c: Context)(tree: c.Tree, ast: Ast, astParser: c.Tree => Ast): Option[Ast] = { import c.universe.{ Function => _, Ident => _, _ } def toIdent(s: Symbol) = Ident(s.name.decodedName.toString) def paramIdents(method: MethodSymbol) = method.paramLists.flatten.map(toIdent) def placeholder(t: Tree): Tree = q"null.asInstanceOf[${t.tpe}]" tree match { case q"$conv($orig).$m[..$t](...$params)" => val convMethod = conv.symbol.asMethod val origIdent = paramIdents(convMethod).head val paramsIdents = paramIdents(convMethod.returnType.member(m).asMethod) val paramsAsts = params.flatten.map(astParser) val reifiedTree = q"$conv(${placeholder(orig)}).$m[..$t](...${params.map(_.map(placeholder(_)))})" val function = QuotedReference(reifiedTree, Function(origIdent :: paramsIdents, ast)) val apply = FunctionApply(function, astParser(orig) :: paramsAsts) Some(apply) case _ => None } } }
Example 9
Source File: Bindings.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.quotation import scala.reflect.macros.whitebox.Context object Bindings { def apply(c: Context)(quoted: c.Tree, tpe: c.Type): Map[c.Symbol, c.Tree] = { import c.universe._ tpe .member(TermName("bindings")) .typeSignature.decls.collect { case m: MethodSymbol if (m.isGetter) => m -> q""" { import _root_.scala.language.reflectiveCalls $quoted.bindings.$m } """ }.toMap } }
Example 10
Source File: Quotation.scala From quill with Apache License 2.0 | 5 votes |
package io.getquill.quotation import scala.annotation.StaticAnnotation import scala.reflect.ClassTag import scala.reflect.macros.whitebox.Context import io.getquill.ast._ import io.getquill.util.MacroContextExt._ import io.getquill.norm.BetaReduction import io.getquill.util.EnableReflectiveCalls case class QuotedAst(ast: Ast) extends StaticAnnotation trait Quotation extends Liftables with Unliftables with Parsing with ReifyLiftings { val c: Context import c.universe._ private val quoted = TermName("quoted") def quote[T](body: Tree)(implicit t: WeakTypeTag[T]) = { val ast = BetaReduction(astParser(body)) val id = TermName(s"id${ast.hashCode.abs}") val (reifiedAst, liftings) = reifyLiftings(ast) val quotation = c.untypecheck { q""" new ${c.prefix}.Quoted[$t] { ..${EnableReflectiveCalls(c)} @${c.weakTypeOf[QuotedAst]}($reifiedAst) def $quoted = ast override def ast = $reifiedAst def $id() = () $liftings } """ } if (IsDynamic(ast)) { q"$quotation: ${c.prefix}.Quoted[$t]" } else { quotation } } def doubleQuote[T: WeakTypeTag](body: Expr[Any]) = body.tree match { case q"null" => c.fail("Can't quote null") case tree => q"${c.prefix}.unquote($tree)" } def quotedFunctionBody(func: Expr[Any]) = func.tree match { case q"(..$p) => $b" => q"${c.prefix}.quote((..$p) => ${c.prefix}.unquote($b))" } protected def unquote[T](tree: Tree)(implicit ct: ClassTag[T]) = astTree(tree).flatMap(astUnliftable.unapply).map { case ast: T => ast } private def astTree(tree: Tree) = for { method <- tree.tpe.decls.find(_.name == quoted) annotation <- method.annotations.headOption astTree <- annotation.tree.children.lastOption } yield astTree }
Example 11
Source File: ByTreeTyper.scala From coroutines with BSD 3-Clause "New" or "Revised" License | 5 votes |
package org.coroutines.common import scala.collection._ import scala.language.experimental.macros import scala.reflect.macros.whitebox.Context private[coroutines] class ByTreeTyper[C <: Context](val c: C)(val treeValue: Any) { import c.universe._ private val tree = treeValue.asInstanceOf[Tree] private val treeMapping = mutable.Map[Tree, Tree]() private val traverser = new TraverserUtil[c.type](c) val untypedTree = c.untypecheck(tree) traverser.traverseByShape(untypedTree, tree)((t, pt) => treeMapping(t) = pt) object typeOf { private val augmentedTypes = mutable.Map[Tree, Type]() def apply(t: Tree) = { if (augmentedTypes.contains(t)) augmentedTypes(t) else if (treeMapping.contains(t)) treeMapping(t).tpe else t.tpe } def update(t: Tree, tpe: Type) = augmentedTypes(t) = tpe } }
Example 12
Source File: macro_impl.scala From lms-clean with BSD 3-Clause "New" or "Revised" License | 5 votes |
package lms.experimental //import language.experimental.macros import scala.annotation.StaticAnnotation import scala.reflect.macros.whitebox.Context import scala.util.matching.Regex import scala.collection.mutable object ir_impl { def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ println("YOUPI") println(c.prefix) val List(a) = annottees println(a) a.tree match { case q"def $name[..$t](..$args): $tpe" => val args1 = args map { case ValDef(_,x,_,_) => q"ref($x)" } return c.Expr(q"def $name[..$t](..$args): $tpe = reflect[$tpe](${name.toString},..$args1)") case q"def $name[..$t](..$args): $tpe = $body" => // TODO: strip by-name type val args0 = args map { case ValDef(_,x,_,_) => q"$x" } val args1 = args map { case ValDef(_,x,_,_) => q"ref($x)" } val name_next = TermName(name.toString + "_next") // TODO: what if we have type parameters? just disallow? return c.Expr(q""" lower((..$args) => Rewrite[$tpe]($name(..$args0), $name_next(..$args0))) def $name[..$t](..$args): $tpe = reflect[$tpe](${name.toString},..$args1) def $name_next[..$t](..$args): $tpe = $body """) // TODO class def //case t@ClassDef(_,_,_,_) => } } }