scala.reflect.macros.whitebox Scala Examples
The following examples show how to use scala.reflect.macros.whitebox.
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: delegate.scala From macro-compat with Apache License 2.0 | 5 votes |
package delegate import scala.language.experimental.macros import scala.reflect.macros.whitebox import macrocompat.bundle class Delegate { def delegate: Unit = macro DelegateMacro.delegate } @bundle class DelegateMacro(val c: whitebox.Context) { outer => import c.universe._ class D(override val c: outer.c.type) extends Delegatee(c) def delegate: Tree = (new D(c)).delegate } @bundle class Delegatee(val c: whitebox.Context) { import c.universe._ def delegate: Tree = { q"()" } }
Example 2
Source File: autoSemigroupalK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoSemigroupalK") class autoSemigroupalK extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoSemigroupalKMacros.semigroupalKInst } private[tagless] class autoSemigroupalKMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateSemigroupalKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("semigroupalKFor" + algebraName), typeParams, tq"_root_.cats.tagless.SemigroupalK[$algebraType]", q"_root_.cats.tagless.Derive.semigroupalK[$algebraType]" ) def semigroupalKInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList) { algebra => algebra.forVaryingEffectType(generateSemigroupalKFor(algebra.name)) :: Nil } }
Example 3
Source File: autoFlatMap.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoFlatMap") class autoFlatMap extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoFlatMapMacros.flatMapInst } private[tagless] class autoFlatMapMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateFlatMapFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("flatMapFor" + algebraName), typeParams, tq"_root_.cats.FlatMap[$algebraType]", q"_root_.cats.tagless.Derive.flatMap[$algebraType]" ) def flatMapInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateFlatMapFor(algebra.name)) :: Nil } }
Example 4
Source File: autoContravariantK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoFunctorK") class autoContravariantK(autoDerivation: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoContravariantKMacros.contravariantKInst } private [tagless] class autoContravariantKMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateContravariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("contravariantKFor" + algebraName), typeParams, tq"_root_.cats.tagless.ContravariantK[$algebraType]", q"_root_.cats.tagless.Derive.contravariantK[$algebraType]" ) def contravariantKInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList) { algebra => algebra.forVaryingEffectType(generateContravariantKFor(algebra.name)) :: Nil } }
Example 5
Source File: autoFunctor.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoFunctor") class autoFunctor extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoFunctorMacros.functorInst } private[tagless] class autoFunctorMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateFunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("functorFor" + algebraName), typeParams, tq"_root_.cats.Functor[$algebraType]", q"_root_.cats.tagless.Derive.functor[$algebraType]" ) def functorInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateFunctorFor(algebra.name)) :: Nil } }
Example 6
Source File: autoInvariant.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoInvariant") class autoInvariant extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoInvariantMacros.invariantInst } private[tagless] class autoInvariantMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateInvariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("invariantFor" + algebraName), typeParams, tq"_root_.cats.Invariant[$algebraType]", q"_root_.cats.tagless.Derive.invariant[$algebraType]" ) def invariantInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateInvariantFor(algebra.name)) :: Nil } }
Example 7
Source File: autoProfunctor.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoProfunctor") class autoProfunctor extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoProfunctorMacros.profunctorInst } private[tagless] class autoProfunctorMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateProfunctorFor( algebraName: String )(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("profunctorFor" + algebraName), typeParams, tq"_root_.cats.arrow.Profunctor[$algebraType]", q"_root_.cats.tagless.Derive.profunctor[$algebraType]" ) def profunctorInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) { algebra => algebra.forVaryingEffectType(generateProfunctorFor(algebra.name)) :: Nil } }
Example 8
Source File: autoBifunctor.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoBifunctor") class autoBifunctor extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoBifunctorMacros.bifunctorInst } private[tagless] class autoBifunctorMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateBifunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("bifunctorFor" + algebraName), typeParams, tq"_root_.cats.Bifunctor[$algebraType]", q"_root_.cats.tagless.Derive.bifunctor[$algebraType]" ) def bifunctorInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) { algebra => algebra.forVaryingEffectType(generateBifunctorFor(algebra.name)) :: Nil } }
Example 9
Source File: autoInstrument.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoInstrument") class autoInstrument extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoInstrumentMacros.instrumentInst } private[tagless] class autoInstrumentMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateInstrumentFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("instrumentFor" + algebraName), typeParams, tq"_root_.cats.tagless.diagnosis.Instrument[$algebraType]", q"_root_.cats.tagless.Derive.instrument[$algebraType]" ) def instrumentInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.FirstHigherKindedTypeParam) { algebra => algebra.forVaryingEffectType(generateInstrumentFor(algebra.name)) :: Nil } }
Example 10
Source File: ExportedMagnolia.scala From pureconfig with Mozilla Public License 2.0 | 5 votes |
package pureconfig.module.magnolia import magnolia.Magnolia import pureconfig.Exported import scala.language.higherKinds import scala.reflect.macros.whitebox // Wrap the output of Magnolia in an Exported to force it to a lower priority. // This seems to work, despite magnolia hardcode checks for `macroApplication` symbol // and relying on getting an diverging implicit expansion error for auto-mode. // Thankfully at least it doesn't check the output type of its `macroApplication` object ExportedMagnolia { def exportedMagnolia[TC[_], A: c.WeakTypeTag](c: whitebox.Context): c.Expr[Exported[TC[A]]] = { val magnoliaTree = c.Expr[TC[A]](Magnolia.gen[A](c)) c.universe.reify(Exported(magnoliaTree.splice)) } }
Example 11
Source File: MacroCompat.scala From pureconfig with Mozilla Public License 2.0 | 5 votes |
package pureconfig.derivation import scala.reflect.macros.{ TypecheckException, whitebox } import pureconfig.Derivation trait MacroCompat { val c: whitebox.Context import c.universe._ // since we are inside a whitebox implicit macro, error messages from `c.abort` as not printed. A trick must be used // to make the compiler print our custom message. That's done by setting a @implicitNotFound annotation on our // `Derivation` class (idea taken from shapeless `Lazy`). def setImplicitNotFound(msg: String): Unit = { import c.internal.decorators._ val infTree = c.typecheck(q"""new _root_.scala.annotation.implicitNotFound($msg)""", silent = false) typeOf[Derivation[_]].typeSymbol.setAnnotations(Annotation(infTree)) } // This should be simply defined as `c.inferImplicitValue(c.weakTypeOf[A])`, but divergent implicits are wrongly // reported up to Scala 2.12.2. See https://github.com/scala/bug/issues/10398 for more information. def inferImplicitValueCompat(typ: Type): Tree = { val cc = c.asInstanceOf[scala.reflect.macros.contexts.Context] val enclosingTree = cc.openImplicits.headOption.map(_.tree) .orElse(cc.enclosingMacros.lastOption.map(_.macroApplication)) .getOrElse(EmptyTree).asInstanceOf[cc.universe.analyzer.global.Tree] val res: cc.Tree = cc.universe.analyzer.inferImplicit( enclosingTree, typ.asInstanceOf[cc.Type], false, cc.callsiteTyper.context, true, false, cc.enclosingPosition, (pos, msg) => throw TypecheckException(pos, msg)) res.asInstanceOf[c.Tree] } }
Example 12
Source File: LazyContextParser.scala From pureconfig with Mozilla Public License 2.0 | 5 votes |
package pureconfig.derivation import scala.reflect.macros.whitebox def unapply(tree: Tree): Option[LazyContext] = tree match { case q"""{ val $outer = { final class $anonClass extends ${ _ } with ${ _ } { ..$lazyDefs } new $anonClassRef().$entrypoint } shapeless.Lazy.apply[${ _ }]($outerRef) }""" if isRefTo(outerRef, outer) && isRefTo(anonClassRef, anonClass) => val lazyDefMap: Map[TermName, Tree] = lazyDefs.collect { case q"lazy val $valName = $valBody" => valName -> valBody }.toMap val entrypointDef = lazyDefMap(entrypoint) Some(LazyContext(anonClass, lazyDefMap - entrypoint, entrypointDef)) case _ => None } private[this] def isRefTo(tree: Tree, name: Name): Boolean = tree match { case Ident(otherName) => name == otherName case _ => false } } }
Example 13
Source File: Sanitiser.scala From sansible with MIT License | 5 votes |
package ansible import scala.language.experimental.macros import scala.reflect.macros.whitebox class Sanitiser(c: whitebox.Context) { private def reSugar(sym: c.universe.Symbol): String = Seq( "\\$eq" -> "=", "\\$hash" -> "#", "\\$bang" -> "!", "\\$asInstanceOf" -> "asInstanceOf", "\\$isInstanceOf" -> "isInstanceOf" ).foldLeft(sym.name.toString) { case (s, (a, b)) => s.replaceAll(a, b) } private val objType = c.weakTypeOf[Object] private val prodType = c.weakTypeOf[Product] private val keywords = c.universe.asInstanceOf[scala.reflect.internal.SymbolTable].nme.keywords.map(_.decoded) private val reservedWords = keywords ++ objType.decls.map(reSugar) ++ prodType.decls.map(reSugar) def safeName(name: String) = if (reservedWords(name)) s"_$name" else name }
Example 14
Source File: Expand.scala From sansible with MIT License | 5 votes |
package ansible import ansible.AnsibleModule._ import argonaut.Argonaut._ import better.files._ import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox @compileTimeOnly("enable macro paradise to expand macro annotations") class expand extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro Expander.expand_impl } object Expander { val tmpDir = System.getProperty("java.io.tmpdir") def expand_impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ val gen = new CodeGen(c) val files = (tmpDir / "parsed_modules").listRecursively.filter(_.extension.contains(".json")).toList val ansibleModules = files.map { f => f.contentAsString.decodeValidation[AnsibleModule].fold(err => throw new Exception(s"Failed reading the json representation of the Ansible module: ${f.path}, error: $err"), identity ) } def generateModule(m: AnsibleModule): (ModuleDef, ClassDef) = { val moduleTypeName = TypeName(camelize(m.name)) val moduleTermName = TermName(camelize(m.name)) val sortedOptions = m.options.sortBy(_.required)(Ordering[Boolean].reverse) val (enumTypes, enumValues, fields) = sortedOptions.foldLeft((List.empty[ClassDef], List.empty[ModuleDef], Vector.empty[ValDef])) { case ((enumTypes, enumValues, fields), option) => option match { case o: BooleanOption => (enumTypes, enumValues, fields :+ gen.boolVal(o).asInstanceOf[ValDef]) case o: StringOption => (enumTypes, enumValues, fields :+ gen.stringVal(o).asInstanceOf[ValDef]) case o: EnumOption => (gen.enumClassDef(o).asInstanceOf[ClassDef] :: enumTypes, gen.enumObjectDef(o).asInstanceOf[ModuleDef] :: enumValues, fields :+ gen.enumVal(o, m.name).asInstanceOf[ValDef]) } } val jsonEncoderVal = gen.moduleObjectJsonEncoder(m).asInstanceOf[ValDef] val enumSetters = m.enumOptions.map(gen.enumSetterDef(m.name)).asInstanceOf[List[DefDef]] val objectDef = q""" object $moduleTermName { $jsonEncoderVal ..$enumTypes ..$enumValues } """.asInstanceOf[ModuleDef] val classDef = q""" case class $moduleTypeName(..$fields) extends ansible.Module { override def call = ModuleCall(this.asJson) ..$enumSetters } """.asInstanceOf[ClassDef] (objectDef, classDef) } annottees.map(_.tree) match { case List(q"trait $_") => val (objectDefs, classDefs) = ansibleModules.map(m => generateModule(m)).unzip c.Expr[Any]( q""" import argonaut._ import Argonaut._ ..$objectDefs ..$classDefs """) case _ => c.abort(c.enclosingPosition, "@expand should annotate a trait") } } private def camelize(str: String): String = str.split('_').map { s => if (s.isEmpty) "" else s.head.toUpper.toString + s.tail.toLowerCase }.mkString }
Example 15
Source File: ShowRenderMacros.scala From Vegas with MIT License | 5 votes |
package vegas.macros import scala.reflect.macros.whitebox import scala.util.Try class ShowRenderMacros(val c: whitebox.Context) { import c.universe.{Try => _, _} private def html(tree: Tree) = Try(c.typecheck(tree)).flatMap { checked => Try(c.typecheck(q"vegas.render.ShowHTML($checked)")) } def materializeDefault: Tree = { val possibilities: Try[Tree] = html(q"""(str: String) => { println(org.apache.zeppelin.spark.utils.DisplayUtils.html(str)) }""") orElse html(q"""(str: String) => { publish.html(str) }""") orElse html(q"""(str: String) => { display.html(str) }""") orElse html(q"""(str: String) => { kernel.display.content("text/html", str) }""") orElse Try(c.typecheck(q"""vegas.render.ShowRender.using(_.window.show)""")) possibilities.getOrElse(c.abort(c.enclosingPosition, "No default Vegas renderer could be materialized")) } }
Example 16
Source File: ConfigurableDeriver.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras import io.circe.generic.extras.codec.{ ConfiguredAsObjectCodec, ReprAsObjectCodec } import io.circe.generic.extras.decoding.{ ConfiguredDecoder, ReprDecoder } import io.circe.generic.extras.encoding.{ ConfiguredAsObjectEncoder, ReprAsObjectEncoder } import io.circe.generic.util.macros.DerivationMacros import scala.reflect.macros.whitebox class ConfigurableDeriver(val c: whitebox.Context) extends DerivationMacros[ ReprDecoder, ReprAsObjectEncoder, ReprAsObjectCodec, ConfiguredDecoder, ConfiguredAsObjectEncoder, ConfiguredAsObjectCodec ] { import c.universe._ def deriveConfiguredDecoder[R: c.WeakTypeTag]: c.Expr[ReprDecoder[R]] = c.Expr[ReprDecoder[R]](constructDecoder[R]) def deriveConfiguredEncoder[R: c.WeakTypeTag]: c.Expr[ReprAsObjectEncoder[R]] = c.Expr[ReprAsObjectEncoder[R]](constructEncoder[R]) def deriveConfiguredCodec[R: c.WeakTypeTag]: c.Expr[ReprAsObjectCodec[R]] = c.Expr[ReprAsObjectCodec[R]](constructCodec[R]) protected[this] val RD: TypeTag[ReprDecoder[_]] = c.typeTag protected[this] val RE: TypeTag[ReprAsObjectEncoder[_]] = c.typeTag protected[this] val RC: TypeTag[ReprAsObjectCodec[_]] = c.typeTag protected[this] val DD: TypeTag[ConfiguredDecoder[_]] = c.typeTag protected[this] val DE: TypeTag[ConfiguredAsObjectEncoder[_]] = c.typeTag protected[this] val DC: TypeTag[ConfiguredAsObjectCodec[_]] = c.typeTag protected[this] val hnilReprDecoder: Tree = q"_root_.io.circe.generic.extras.decoding.ReprDecoder.hnilReprDecoder" protected[this] val hnilReprCodec: Tree = q"_root_.io.circe.generic.extras.codec.ReprAsObjectCodec.hnilReprCodec" protected[this] val decodeMethodName: TermName = TermName("configuredDecode") protected[this] val decodeAccumulatingMethodName: TermName = TermName("configuredDecodeAccumulating") protected[this] override def decodeMethodArgs: List[Tree] = List( q"transformMemberNames: (_root_.java.lang.String => _root_.java.lang.String)", q"transformConstructorNames: (_root_.java.lang.String => _root_.java.lang.String)", q"defaults: _root_.scala.collection.immutable.Map[_root_.java.lang.String, _root_.scala.Any]", q"discriminator: _root_.scala.Option[_root_.java.lang.String]" ) protected[this] def encodeMethodName: TermName = TermName("configuredEncodeObject") protected[this] override def encodeMethodArgs: List[Tree] = List( q"transformMemberNames: (_root_.java.lang.String => _root_.java.lang.String)", q"transformConstructorNames: (_root_.java.lang.String => _root_.java.lang.String)", q"discriminator: _root_.scala.Option[_root_.java.lang.String]" ) protected[this] def decodeField(name: String, decode: TermName): Tree = q""" orDefault( c.downField(transformMemberNames($name)), $decode, $name, defaults ) """ protected[this] def decodeFieldAccumulating(name: String, decode: TermName): Tree = q""" orDefaultAccumulating( c.downField(transformMemberNames($name)), $decode, $name, defaults ) """ protected[this] def decodeSubtype(name: String, decode: TermName): Tree = q""" withDiscriminator( $decode, c, transformConstructorNames($name), discriminator ) """ protected[this] def decodeSubtypeAccumulating(name: String, decode: TermName): Tree = q""" withDiscriminatorAccumulating( $decode, c, transformConstructorNames($name), discriminator ) """ protected[this] def encodeField(name: String, encode: TermName, value: TermName): Tree = q"(transformMemberNames($name), $encode($value))" protected[this] def encodeSubtype(name: String, encode: TermName, value: TermName): Tree = q"addDiscriminator($encode, $value, transformConstructorNames($name), discriminator)" }
Example 17
Source File: autoContravariant.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoContravariant") class autoContravariant extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoContravariantMacros.contravariantInst } private[tagless] class autoContravariantMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateContravariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("contravariantFor" + algebraName), typeParams, tq"_root_.cats.Contravariant[$algebraType]", q"_root_.cats.tagless.Derive.contravariant[$algebraType]" ) def contravariantInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateContravariantFor(algebra.name)) :: Nil } }
Example 18
Source File: reporter.scala From macro-compat with Apache License 2.0 | 5 votes |
package reporters import scala.reflect.macros.whitebox @macrocompat.bundle class ErrorReporterMacro(val c: whitebox.Context) { import c.universe._ def testReporterImplicit(t: Tree): Tree = { val casted = c.asInstanceOf[reflect.macros.runtime.Context] val typer = casted.callsiteTyper val ctx = typer.context val r = ctx.reporter r.errors.map(_.errMsg) t } }
Example 19
Source File: LocationMacros.scala From polynote with Apache License 2.0 | 5 votes |
package polynote.env.macros import polynote.env.ops.Location import scala.annotation.tailrec import scala.reflect.macros.whitebox class LocationMacros(val c: whitebox.Context) { import c.universe._ def materialize: Expr[Location] = { val enclosingPosition = c.enclosingPosition val owner = c.internal.enclosingOwner val name = expr(enclosingPosition.source.file.name) val line = expr(enclosingPosition.line) val method = expr(enclosingMethod(owner).map(_.name.decodedName.toString).getOrElse("<unknown>")) val cls = expr(enclosingClass(owner).map(_.fullName).getOrElse("<unknown>")) reify { Location(name.splice, line.splice, method.splice, cls.splice) } } private def expr[T](const: T): Expr[T] = c.Expr[T](Literal(Constant(const))) @tailrec private def enclosingMethod(sym: Symbol): Option[MethodSymbol] = sym match { case null | NoSymbol => None case m if m.isMethod => Some(m.asMethod) case m => enclosingMethod(sym.owner) } @tailrec private def enclosingClass(sym: Symbol): Option[ClassSymbol] = sym match { case null | NoSymbol => None case m if m.isClass => Some(m.asClass) case m => enclosingClass(sym.owner) } }
Example 20
Source File: ZEnvMacros.scala From polynote with Apache License 2.0 | 5 votes |
package polynote.env.macros import zio.ZIO import polynote.env.ops.Enrich import scala.reflect.macros.whitebox class ZEnvMacros(val c: whitebox.Context) extends RefinementMacros { import c.universe._ private def zio(R: Type, E: Type, A: Type): Type = appliedType( weakTypeOf[ZIO[_, _, _]].typeConstructor, R, E, A) private def delegate(sym: Symbol, in: Type, to: Tree) = q"final val ${sym.name.toTermName}: ${sym.infoIn(in).resultType} = $to" def createDelegate[A : WeakTypeTag, B : WeakTypeTag](a: Tree, b: Tree): Tree = { val A = weakTypeOf[A].dealias val B = weakTypeOf[B].dealias val Result = weakTypeOf[A with B] for { aParts <- refinementParts(A).right bParts <- refinementParts(B).right } yield { val clsName = TypeName(c.freshName("Env")) val aDecls = A.members.collect { case sym if sym.isMethod && sym.asMethod.paramLists == Nil && sym.isAbstract && !B.members.exists(_.name.toString == sym.name.toString) => delegate(sym, A, q"$a.$sym") case sym if sym.isMethod && sym.asMethod.paramLists == List(Nil) && sym.isAbstract && !B.members.exists(_.name.toString == sym.name.toString) => delegate(sym, A, q"$a.$sym()") }.toList val bDecls = B.members.collect { case sym if sym.isMethod && sym.asMethod.paramLists == Nil && sym.isAbstract => delegate(sym, B, q"$b.$sym") case sym if sym.isMethod && sym.asMethod.paramLists == List(Nil) && sym.isAbstract => delegate(sym, B, q"$b.$sym()") }.toList val classDef = ClassDef(Modifiers(), clsName, Nil, Template( TypeTree(weakTypeOf[AnyRef]) :: ((aParts ::: bParts).distinct).map(TypeTree(_)), noSelfType, DefDef(Modifiers(), termNames.CONSTRUCTOR, Nil, Nil :: Nil, TypeTree(), Block(List(Apply(Select(Super(This(typeNames.EMPTY), typeNames.EMPTY), termNames.CONSTRUCTOR), Nil)), Literal(Constant(())))) :: aDecls ::: bDecls )) Block(List(classDef), q"new $clsName: $Result") } }.fold(fail[A, B], identity) def mkEnrich[A : WeakTypeTag, B : WeakTypeTag]: Tree = { val A = weakTypeOf[A].dealias val B = weakTypeOf[B].dealias val ResultType = weakTypeOf[Enrich[A, B]] val result = q""" new $ResultType { def apply(a: $A, b: $B): $A with $B = ${createDelegate[A, B](q"a", q"b")} } """ try { c.typecheck(result) } catch { case err: Throwable => val e = err throw(e) } } def fail[A : WeakTypeTag, B : WeakTypeTag](err: Failure): Nothing = { val str = failureString(err, weakTypeOf[A], weakTypeOf[B]) c.abort(c.enclosingPosition, str) } }
Example 21
Source File: RefinementMacros.scala From polynote with Apache License 2.0 | 5 votes |
package polynote.env.macros import scala.reflect.macros.whitebox trait RefinementMacros { val c: whitebox.Context import c.universe._ sealed trait Failure case object NotRefinement extends Failure case object NoMember extends Failure case class AmbiguousMember(members: List[(Type, Symbol)]) extends Failure def refinementParts(typ: Type): Either[Failure, List[Type]] = typ.dealias match { case RefinedType(parts, _) => parts.foldLeft[Either[Failure, List[Type]]](Right(Nil)) { case (l@Left(_), _) => l case (Right(parts), part) => refinementParts(part).right.map { partParts => partParts ::: parts } } case other if other =:= typeOf[Any] => Right(List(typeOf[Any])) case other => Right(List(other)) } def definingPart(parts: List[Type], member: Type): Either[Failure, (Type, Symbol)] = parts.flatMap { part => part.decls.collect { case sym if member <:< sym.infoIn(part).resultType => part -> sym } } match { case one :: Nil => Right(one) case Nil => Left(NoMember) case many => Left(AmbiguousMember(many)) } def intersection(parts: List[Type]): Type = parts match { case Nil => weakTypeOf[Any] case one :: Nil => one case many => c.internal.refinedType(many, NoSymbol) } def formatMembers(members: List[(Type, Symbol)]): String = members.map { case (typ, sym) => s"${sym.name} in ${typ.typeSymbol.name}" }.mkString(", ") def failureString(failure: Failure, in: Type, member: Type): String = failure match { case NotRefinement => s"Type $in is not an intersection type" case NoMember => s"Type $in does not contain a member of type $member" case AmbiguousMember(members) => s"Ambiguous member; $in declares multiple members of type $member: ${formatMembers(members)}" } }
Example 22
Source File: DummyImplicit.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package transmitter import scala.language.experimental.macros import scala.reflect.macros.whitebox object DummyImplicit { class Resolvable private[DummyImplicit] object Resolvable { implicit def dummy: Resolvable = new Resolvable implicit def noDummy: Resolvable = macro NoDummyImplicit.skip } class Unresolvable private[DummyImplicit] object Unresolvable { implicit def noDummy: Unresolvable = macro NoDummyImplicit.skip } } object NoDummyImplicit { def skip(c: whitebox.Context): c.Tree = c.abort(c.enclosingPosition, "Skipping dummy macro") }
Example 23
Source File: Serializable.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package transmitter import scala.annotation.{compileTimeOnly, implicitNotFound} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.util.Try @implicitNotFound("${T} is not serializable") trait Serializable[T] { def serialize(value: T): MessageBuffer def deserialize(value: MessageBuffer): Try[T] } object Serializable { @inline def apply[T](implicit serializable: Serializable[T]): Serializable[T] = serializable @compileTimeOnly("Value is not serializable") final implicit def resolutionFailure[T](implicit ev: DummyImplicit.Resolvable): Serializable[T] = macro SerializableResolutionFailure[T] @compileTimeOnly("Value is not serializable") final def dummy[T]: Serializable[T] = throw new NotImplementedError } object SerializableResolutionFailure { def apply[T: c.WeakTypeTag](c: whitebox.Context)(ev: c.Tree): c.Tree = { import c.universe._ // the current macro expansion always appears twice // see: http://stackoverflow.com/a/20466423 val recursionCount = c.openMacros.count { other => c.enclosingPosition == other.enclosingPosition && c.macroApplication.toString == other.macroApplication.toString } if (recursionCount > 2) c.abort(c.enclosingPosition, "Skipping serializable resolution failure macro for recursive invocation") val serializableType = weakTypeOf[Serializable[T]] if ((c inferImplicitValue serializableType).nonEmpty) c.abort(c.enclosingPosition, "Skipping serializable resolution failure macro to prioritize other implicit") val tpe = weakTypeOf[T] val message = s"$tpe is not serializable" q"""{ @${termNames.ROOTPKG}.scala.annotation.compileTimeOnly($message) def resolutionFailure() = () resolutionFailure() ${termNames.ROOTPKG}.loci.transmitter.Serializable.dummy[$tpe] }""" } }
Example 24
Source File: TransmittableDummy.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package transmitter import scala.annotation.compileTimeOnly import scala.concurrent.Future import scala.language.experimental.macros import scala.reflect.macros.whitebox trait TransmittableDummy { this: Transmittable.type => @compileTimeOnly("Value is not transmittable") final implicit def resolutionFailure[T](implicit ev: DummyImplicit.Resolvable): Transmittable[T, T, T] { type Proxy = Future[T] type Transmittables = Transmittables.None } = macro TransmittableResolutionFailure[T] @compileTimeOnly("Value is not transmittable") final def dummy[T]: Transmittable[T, T, T] { type Proxy = Future[T] type Transmittables = Transmittables.None } = IdenticallyTransmittable() } object TransmittableResolutionFailure { def apply[T: c.WeakTypeTag](c: whitebox.Context)(ev: c.Tree): c.Tree = { import c.universe._ // the current macro expansion always appears twice // see: http://stackoverflow.com/a/20466423 val recursionCount = c.openMacros.count { other => c.enclosingPosition == other.enclosingPosition && c.macroApplication.toString == other.macroApplication.toString } if (recursionCount > 2) c.abort(c.enclosingPosition, "Skipping transmittable resolution failure macro for recursive invocation") val resolutionType = weakTypeOf[Transmittable.Aux.Resolution[T, _, _, _, _]] if ((c inferImplicitValue resolutionType).nonEmpty) c.abort(c.enclosingPosition, "Skipping transmittable resolution failure macro to prioritize other implicit") val tpe = weakTypeOf[T] val message = s"$tpe is not transmittable" q"""{ @${termNames.ROOTPKG}.scala.annotation.compileTimeOnly($message) def resolutionFailure() = () resolutionFailure() ${termNames.ROOTPKG}.loci.transmitter.Transmittable.dummy[$tpe] }""" } }
Example 25
Source File: TracingExecutionContext.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package logging import scribe.{LoggingExecutionContext, Position} import scala.concurrent.{ExecutionContext, ExecutionContextExecutor} import scala.reflect.macros.whitebox class TracingExecutionContext(context: ExecutionContext, stack: List[Position]) extends LoggingExecutionContext(context, stack) with ExecutionContextExecutor { override def execute(runnable: Runnable) = super.execute(new Runnable { override def run() = tracing run { runnable.run() } }) } object ImplicitTracingExecutionContext { def resolve(c: whitebox.Context): c.Tree = { import c.universe._ if (c.hasErrors) c.abort(c.enclosingPosition, "Skipping tracing execution context macro due to compilation errors") // the current macro expansion always appears twice // see: http://stackoverflow.com/a/20466423 val recursionCount = c.openMacros.count { other => c.enclosingPosition == other.enclosingPosition && c.macroApplication.toString == other.macroApplication.toString } if (recursionCount > 2) c.abort(c.enclosingPosition, "Skipping tracing execution context macro for recursive invocation") val tree = c.inferImplicitValue(typeOf[ExecutionContext]) if (tree.isEmpty) c.abort(c.enclosingPosition, "Skipping tracing execution context macro due to unresolved execution context") // flag symbol of inferred tree as synthetic if it is private or a local variable // to prevent "value is never used" warnings val symbol = tree.symbol.asTerm if (!symbol.isGetter && !symbol.isParamAccessor || symbol.isGetter && symbol.isPrivate) c.internal.setFlag(tree.symbol, Flag.SYNTHETIC) ExplicitTracingExecutionContext.instrument(c)(tree) } } object ExplicitTracingExecutionContext { def instrument(c: whitebox.Context)(context: c.Tree): c.Tree = { import c.universe._ val stack = c.typecheck(q"${termNames.ROOTPKG}.scribe.Execution.custom(null)", silent = true) match { case q"new $_($_, $stack)" => Right(stack) case q"new $_($_, $stack): $_" => Right(stack) case tree => Left(tree) } val tracingContext = tq"${termNames.ROOTPKG}.loci.logging.TracingExecutionContext" stack match { case Right(stack) => q"new $tracingContext($context, $stack)" case Left(tree) => val message = s"scribe logging framework custom execution context macro generated unexpected code: $tree" q"""{ @${termNames.ROOTPKG}.scala.annotation.compileTimeOnly($message) def unexpectedTree() = () unexpectedTree() new $tracingContext(null, null) }""" } } }
Example 26
Source File: ToStringObfuscate.scala From firebase4s with MIT License | 5 votes |
package firebase4s.macros import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.annotation.compileTimeOnly @compileTimeOnly("enable macro paradise to expand macro annotations") class ToStringObfuscate(fieldsToObfuscate: String*) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro ToStringObfuscateImpl.impl } object ToStringObfuscateImpl { def obfuscateValue(value: String) = "*" * value.length def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ def extractAnnotationParameters(tree: Tree): List[c.universe.Tree] = tree match { case q"new $name( ..$params )" => params case _ => throw new Exception("ToStringObfuscate annotation must be have at least one parameter.") } def extractCaseClassesParts(classDecl: ClassDef) = classDecl match { case q"case class $className(..$fields) extends ..$parents { ..$body }" => (className, fields, parents, body) } def replaceCaseClassSensitiveValues(tree: Tree) = tree match { case Literal(Constant(field: String)) => q""" ${TermName(field)} = firebase4s.macros.ToStringObfuscateImpl.obfuscateValue(this.${TermName(field)}) """ case _ => c.abort(c.enclosingPosition, s"[replaceCaseClassSensitiveValues] Match error with $tree") } val sensitiveFields = extractAnnotationParameters(c.prefix.tree) val fieldReplacements = sensitiveFields.map(replaceCaseClassSensitiveValues(_)) def extractNewToString(sensitiveFields: List[Tree]) = q""" override def toString: ${typeOf[String]} = { scala.runtime.ScalaRunTime._toString(this.copy(..$fieldReplacements)) } """ def modifiedDeclaration(classDecl: ClassDef) = { val (className, fields, parents, body) = extractCaseClassesParts(classDecl) val newToString = extractNewToString(sensitiveFields) val params = fields.asInstanceOf[List[ValDef]].map { p => p.duplicate } c.Expr[Any]( q""" case class $className ( ..$params ) extends ..$parents { $newToString ..$body } """ ) } annottees.map(_.tree) toList match { case (classDecl: ClassDef) :: Nil => modifiedDeclaration(classDecl) case _ => c.abort(c.enclosingPosition, "Invalid annottee") } } }
Example 27
Source File: SymbolMacros.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.macros import shapeless.ReprTypes import scala.reflect.macros.{blackbox, whitebox} trait SymbolMacros extends ReprTypes { val c: blackbox.Context import c.universe._ import c.internal.{constantType, refinedType} def taggedType = typeOf[shapeless.tag.Tagged[_]].typeConstructor object KeyName { def apply(name: String): Type = NamedSymbol(appliedType(taggedType, constantType(Constant(name)))) def unapply(tpe: Type): Option[String] = tpe match { case NamedSymbol(ConstantType(Constant(name: String))) => Some(name) case ConstantType(Constant(name: String)) => Some(name) case _ => None } } object NamedSymbol { def apply(tpe: Type): Type = refinedType(List(symbolTpe, tpe), NoSymbol) def unapply(tpe: Type): Option[Type] = tpe.dealias match { case RefinedType(List(sym, tag, _*), _) if sym == symbolTpe => tag.typeArgs.headOption case _ => None } } def freshIdent(name: String): Ident = Ident(freshName(name)) def freshName(name: String): TermName = TermName(c.freshName(name)) }
Example 28
Source File: ParamMaker.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.macros import ru.tinkoff.tschema.macros.ParamMaker.Applyer import ru.tinkoff.tschema.typeDSL import ru.tinkoff.tschema.typeDSL.{Capture, DSLAtom, FormField, Header, QueryParam} import scala.language.{dynamics, higherKinds} import scala.language.experimental.macros import shapeless.Witness import scala.reflect.macros.whitebox class ParamMaker[T[_, _]] extends Dynamic { def params[A]: Applyer = macro ParamMakerMacro.paramsImpl[A, T[_, _]] } object ParamMaker { type Applyer = { def apply[A](x: => A): DSLAtom } def apply[T[_, _]]: ParamMaker[T] = new ParamMaker[T] object query extends ParamMaker[QueryParam] object path extends ParamMaker[Capture] object headers extends ParamMaker[Header] object form extends ParamMaker[FormField] } class ParamMakerMacro(val c: whitebox.Context) extends SymbolMacros { import c.universe._ val consTpe = typeOf[typeDSL.:>[_, _]].typeConstructor def paramsImpl[A: WeakTypeTag, T: WeakTypeTag] = { val const = weakTypeTag[T].tpe.typeConstructor val result = extractNamesTypes(weakTypeOf[A]).map { case (name, tpe) => appliedType(const, KeyName(name), tpe) } .reduce((a, b) => appliedType(consTpe, a, b)) q""" new { import ru.tinkoff.tschema.typeDSL.{:>} def apply[A](x: => A): :>[$result, A] = new :> }""" } def extractNamesTypes(ref: Type): List[(String, Type)] = ref match { case RefinedType(tpes, scope) => info(tpes) scope.collect { case m: MethodSymbol => info(m) m.name.decodedName.toString -> m.returnType }.toList case _ => List.empty } def info[A](mess: A) = c.info(c.enclosingPosition, mess.toString, force = false) }
Example 29
Source File: TypeName.scala From zio-config with Apache License 2.0 | 5 votes |
package zio.config.shapeless import scala.language.experimental.macros import scala.reflect.macros.whitebox trait TypeName[T] { def apply(): String } object TypeName { implicit def materializeTypeName[T]: TypeName[T] = macro typeNameImpl[T] def typeNameImpl[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = { import c.universe._ val T = c.weakTypeOf[T] val name = T.typeSymbol.name.toString q" new _root_.zio.config.shapeless.TypeName[$T]{ def apply(): String = $name } " } }
Example 30
Source File: Macros.scala From libisabelle with Apache License 2.0 | 5 votes |
package info.hupel.isabelle.internal import scala.reflect.macros.whitebox import cats.instances.list._ import cats.syntax.traverse._ import info.hupel.isabelle._ import info.hupel.isabelle.pure._ object Macros { def fuse(terms: List[Program[Term]], parts: List[String]): Program[String] = { val tps: Program[List[String]] = terms.sequence.map { ts => ts zip parts.tail map { case (t, p) => val s = Codec[Term].encode(t).compact s"XML\\<open>$s\\<close>$p" } } tps.map(_.mkString("")).map(parts.head + _) } } class Macros(val c: whitebox.Context) { import c.universe.{Expr => _, _} private val q"""${_}(${_}(..$parts)).term""" = c.prefix.tree private def embed(arg: Tree): Tree = { if (arg.tpe <:< typeOf[Term]) q"""_root_.info.hupel.isabelle.Program.pure($arg)""" else if (arg.tpe <:< typeOf[Expr[_]]) q"""_root_.info.hupel.isabelle.Program.pure($arg.term)""" else { val embeddable = c.inferImplicitValue(appliedType(typeOf[Embeddable[_]], arg.tpe)) if (embeddable == EmptyTree) c.error(c.enclosingPosition, s"Could not find implicit `Embeddable` for type ${arg.tpe}") q"""$embeddable.embed($arg)""" } } def term(args: Tree*): c.Expr[Program[String]] = { val terms = args.map(embed) val termList = c.Expr[List[Program[Term]]](q"""_root_.scala.List(..$terms)""") val partList = c.Expr[List[String]](q"""_root_.scala.List(..$parts)""") reify { Macros.fuse(termList.splice, partList.splice) } } }
Example 31
Source File: TransformerIntoWhiteboxMacros.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.macros import io.scalaland.chimney.internal.utils.MacroUtils import scala.reflect.macros.whitebox class TransformerIntoWhiteboxMacros(val c: whitebox.Context) extends MacroUtils { import c.universe._ def withFieldConstImpl(selector: Tree, value: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldConst($selector, ${trees("value")})", "value" -> value ) } def withFieldConstFImpl[F[+_]]( selector: Tree, value: Tree )( implicit F: WeakTypeTag[F[_]] ): Tree = { q"${c.prefix.tree}.lift[$F].withFieldConstF($selector, $value)" } def withFieldComputedImpl(selector: Tree, map: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldComputed($selector, ${trees("map")})", "map" -> map ) } def withFieldComputedFImpl[F[+_]]( selector: Tree, map: Tree )( implicit F: WeakTypeTag[F[_]] ): Tree = { q"${c.prefix.tree}.lift[$F].withFieldComputedF($selector, $map)" } def withFieldRenamedImpl(selectorFrom: Tree, selectorTo: Tree): Tree = { c.prefix.tree.refineTransformerDefinition(q"_.withFieldRenamed($selectorFrom, $selectorTo)") } def withCoproductInstanceImpl(f: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withCoproductInstance(${trees("f")})", "f" -> f ) } def withCoproductInstanceFImpl[F[+_]](f: Tree)(implicit F: WeakTypeTag[F[_]]): Tree = { q"${c.prefix.tree}.lift[$F].withCoproductInstanceF($f)" } }
Example 32
Source File: TransformerFIntoWhiteboxMacros.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.macros import io.scalaland.chimney.internal.utils.MacroUtils import scala.reflect.macros.whitebox class TransformerFIntoWhiteboxMacros(val c: whitebox.Context) extends MacroUtils { import c.universe._ def withFieldConstImpl(selector: Tree, value: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldConst($selector, ${trees("value")})", "value" -> value ) } def withFieldConstFImpl(selector: Tree, value: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldConstF($selector, ${trees("value")})", "value" -> value ) } def withFieldComputedImpl(selector: Tree, map: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldComputed($selector, ${trees("map")})", "map" -> map ) } def withFieldComputedFImpl(selector: Tree, map: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withFieldComputedF($selector, ${trees("map")})", "map" -> map ) } def withFieldRenamedImpl(selectorFrom: Tree, selectorTo: Tree): Tree = { c.prefix.tree.refineTransformerDefinition(q"_.withFieldRenamed($selectorFrom, $selectorTo)") } def withCoproductInstanceImpl(f: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withCoproductInstance(${trees("f")})", "f" -> f ) } def withCoproductInstanceFImpl(f: Tree): Tree = { c.prefix.tree.refineTransformerDefinition_Hack( trees => q"_.withCoproductInstanceF(${trees("f")})", "f" -> f ) } }
Example 33
Source File: ServiceMacros.scala From scalajs-angulate with MIT License | 5 votes |
// - Project: scalajs-angulate (https://github.com/jokade/scalajs-angulate) // Description: // // Distributed under the MIT License (see included file LICENSE) package biz.enef.angulate.impl import acyclic.file import scala.reflect.macros.whitebox protected [angulate] class ServiceMacros(val c: whitebox.Context) extends MacroBase { import c.universe._ // print generated code to console during compilation private lazy val logCode = c.settings.exists( _ == "biz.enef.angulate.ServiceMacros.debug" ) def serviceOf[T: c.WeakTypeTag] = { val serviceType = weakTypeOf[T] val name = serviceType.toString.split('.').last createService(serviceType, q"${name.head.toLower+name.tail}") } def serviceOfWithName[T: c.WeakTypeTag](name: c.Tree) = { val serviceType = weakTypeOf[T] createService(serviceType, q"${name}") } private def createService(ct: c.Type, name: c.Tree) = { val module = Select(c.prefix.tree, TermName("self")) val constr = ct.members.filter( _.isConstructor ).map( _.asMethod ).head val (params,args) = makeArgsList(constr) val deps = getDINames(constr) // AngularJS service construction array val carray = q"""js.Array[Any](..$deps, ((..$params) => new $ct(..$args)):js.Function) """ val tree = q"""{import scala.scalajs.js import js.Dynamic.{global,literal} $module.self.factory($name,$carray) }""" if (logCode) printCode(tree, "\nserviceOf macro:") tree } }
Example 34
Source File: CoproductMacros.scala From featherbed with Apache License 2.0 | 5 votes |
package featherbed.littlemacros import scala.reflect.macros.whitebox import shapeless.{:+:, CNil} class CoproductMacros(val c: whitebox.Context) { import c.universe._ def callAcceptCoproduct(types: Tree*): Tree = { val lhs = c.prefix.tree val accepts = types map { case Literal(const @ Constant(str: String)) => c.internal.constantType(const) case other => c.abort(c.enclosingPosition, s"$other is not a string constant") } val cnil = weakTypeOf[CNil] val ccons = weakTypeOf[:+:[_, _]].typeConstructor val coproductType = accepts.foldRight(cnil) { case (elemTpe, acc) => appliedType(ccons, List(elemTpe, acc)) } q"$lhs.accept[$coproductType]" } }
Example 35
Source File: GogglesMacros.scala From goggles with MIT License | 5 votes |
package goggles.macros import goggles.macros.interpret.dsl.{GetModeDslImpl, SetModeDslImpl, LensModeDslImpl} import scala.reflect.macros.whitebox object GogglesMacros { def getImpl(ctx: whitebox.Context)(args: ctx.Expr[Any]*): ctx.Tree = { val interpreter = new GetModeDslImpl { override val c: ctx.type = ctx; } interpreter.handleMacroResultOf(_.get(args: _*)) } def setImpl(ctx: whitebox.Context)(args: ctx.Expr[Any]*): ctx.Tree = { val interpreter = new SetModeDslImpl { override val c: ctx.type = ctx; } interpreter.handleMacroResultOf(_.set(args: _*)) } def lensImpl(ctx: whitebox.Context)(args: ctx.Expr[Any]*): ctx.Tree = { val interpreter = new LensModeDslImpl { override val c: ctx.type = ctx; } interpreter.handleMacroResultOf(_.lens(args: _*)) } }
Example 36
Source File: WindowedStreamMacros.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.lang.internal import com.amazon.milan.Id import com.amazon.milan.lang.Stream import com.amazon.milan.program.WindowApply import com.amazon.milan.program.internal.{ConvertExpressionHost, MappedStreamHost} import com.amazon.milan.typeutil.TypeDescriptor import scala.reflect.macros.whitebox class WindowedStreamMacros(val c: whitebox.Context) extends ConvertExpressionHost with MappedStreamHost { import c.universe._ def apply[T: c.WeakTypeTag, TOut: c.WeakTypeTag](f: c.Expr[Iterable[T] => TOut]): c.Expr[Stream[TOut]] = { val applyFunction = getMilanFunction(f.tree) val streamType = getStreamTypeExpr[TOut](applyFunction) val outputNodeId = Id.newId() val sourceExpressionVal = TermName(c.freshName("sourceExpr")) val exprVal = TermName(c.freshName("expr")) val tree = q""" val $sourceExpressionVal = ${c.prefix}.expr val $exprVal = new ${typeOf[WindowApply]}($sourceExpressionVal, $applyFunction, $outputNodeId, $outputNodeId, $streamType) new ${weakTypeOf[Stream[TOut]]}($exprVal, $exprVal.recordType.asInstanceOf[${weakTypeOf[TypeDescriptor[TOut]]}]) """ c.Expr[Stream[TOut]](tree) } }
Example 37
Source File: JoinedStreamMacros.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.lang.internal import com.amazon.milan.Id import com.amazon.milan.lang.{JoinType, JoinedStream, JoinedStreamWithCondition, Stream} import com.amazon.milan.program.internal.ConvertExpressionHost import com.amazon.milan.program.{FullJoin, FunctionDef, LeftInnerJoin, LeftJoin} import com.amazon.milan.typeutil.{JoinedStreamsTypeDescriptor, TypeDescriptor} import scala.reflect.macros.whitebox def select[TLeft: c.WeakTypeTag, TRight: c.WeakTypeTag, TOut: c.WeakTypeTag](f: c.Expr[(TLeft, TRight) => TOut]): c.Expr[Stream[TOut]] = { this.warnIfNoRecordId[TOut]() val exprTree = createMappedToRecordStream2[TLeft, TRight, TOut](f) val exprVal = TermName(c.freshName("expr")) val tree = q""" val $exprVal = $exprTree new ${weakTypeOf[Stream[TOut]]}($exprVal, $exprVal.recordType.asInstanceOf[${weakTypeOf[TypeDescriptor[TOut]]}]) """ c.Expr[Stream[TOut]](tree) } } object JoinedStreamUtil { def where[TLeft, TRight](inputStream: JoinedStream[TLeft, TRight], conditionExpr: FunctionDef): JoinedStreamWithCondition[TLeft, TRight] = { ProgramValidation.validateFunction(conditionExpr, 2) val joinNodeId = Id.newId() val joinedStreamType = new JoinedStreamsTypeDescriptor(inputStream.leftInput.recordType, inputStream.rightInput.recordType) val joinExpr = inputStream.joinType match { case JoinType.LeftEnrichmentJoin => new LeftJoin(inputStream.leftInput, inputStream.rightInput, conditionExpr, joinNodeId, joinNodeId, joinedStreamType) case JoinType.FullEnrichmentJoin => new FullJoin(inputStream.leftInput, inputStream.rightInput, conditionExpr, joinNodeId, joinNodeId, joinedStreamType) case JoinType.LeftInnerJoin => new LeftInnerJoin(inputStream.leftInput, inputStream.rightInput, conditionExpr, joinNodeId, joinNodeId, joinedStreamType) } new JoinedStreamWithCondition[TLeft, TRight](joinExpr) } }
Example 38
Source File: JoinedWindowedStreamMacros.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.lang.internal import com.amazon.milan.Id import com.amazon.milan.lang.{LeftJoinedWindowedStream, Stream} import com.amazon.milan.program.internal.ConvertExpressionHost import com.amazon.milan.program.{FlatMap, FunctionDef, LeftWindowedJoin} import com.amazon.milan.typeutil.{DataStreamTypeDescriptor, TypeDescriptor} import scala.reflect.macros.whitebox class JoinedWindowedStreamMacros(val c: whitebox.Context) extends StreamMacroHost with ConvertExpressionHost { import c.universe._ def leftApply[TLeft: c.WeakTypeTag, TRight: c.WeakTypeTag, TOut: c.WeakTypeTag](applyFunction: c.Expr[(TLeft, Iterable[TRight]) => TOut]): c.Expr[Stream[TOut]] = { this.warnIfNoRecordId[TOut]() val applyFunctionExpr = getMilanFunction(applyFunction.tree) val inputStreamVal = TermName(c.freshName("inputStream")) val outputTypeInfo = getTypeDescriptor[TOut] val tree = q""" _root_.com.amazon.milan.lang.internal.ProgramValidation.validateFunction($applyFunctionExpr, 2) val $inputStreamVal = ${c.prefix} _root_.com.amazon.milan.lang.internal.JoinedWindowedStreamUtil.leftApply[${weakTypeOf[TLeft]}, ${weakTypeOf[TRight]}, ${weakTypeOf[TOut]}]($inputStreamVal, $applyFunctionExpr, $outputTypeInfo) """ c.Expr[Stream[TOut]](tree) } } object JoinedWindowedStreamUtil { def leftApply[TLeft, TRight, TOut](inputStream: LeftJoinedWindowedStream[TLeft, TRight], applyFunction: FunctionDef, outputRecordType: TypeDescriptor[TOut]): Stream[TOut] = { val outNodeId = Id.newId() val leftInputExpr = inputStream.leftInput.expr val rightInputExpr = inputStream.rightInput.expr val joinExpr = LeftWindowedJoin(leftInputExpr, rightInputExpr) val outputStreamType = new DataStreamTypeDescriptor(outputRecordType) val mapExpr = new FlatMap(joinExpr, applyFunction, outNodeId, outNodeId, outputStreamType) new Stream[TOut](mapExpr, outputRecordType) } }
Example 39
Source File: ProgramTypeNamesHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.program.internal import scala.reflect.macros.whitebox trait ProgramTypeNamesHost { val c: whitebox.Context import c.universe._ val FieldTypeName: Tree = q"_root_.com.amazon.milan.program.Field" val FieldComputationExpressionTypeName: Tree = q"_root_.com.amazon.milan.program.FieldComputationExpression" val FilteredStreamTypeName: Tree = q"_root_.com.amazon.milan.program.FilteredStream" val MappedStreamTypeName: Tree = q"_root_.com.amazon.milan.program.MappedStream" val MapToFieldsTypeName: Tree = q"_root_.com.amazon.milan.program.MapToFields" val MapToRecordTypeName: Tree = q"_root_.com.amazon.milan.program.MapToRecord" val ProgramValidationTypeName: Tree = q"_root_.com.amazon.milan.program.ProgramValidation" val FunctionReferenceTypeName: Tree = q"_root_.com.amazon.milan.program.FunctionReference" val TypeDescriptorTypeName: Tree = q"_root_.com.amazon.milan.typeutil.TypeDescriptor[Any]" val FieldDescriptorTypeName: Tree = q"_root_.com.amazon.milan.typeutil.FieldDescriptor[Any]" }
Example 40
Source File: FilteredStreamHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.program.internal import com.amazon.milan.Id import com.amazon.milan.program.Filter import scala.reflect.macros.whitebox def createdFilteredStream[T: c.WeakTypeTag](predicate: c.Expr[T => Boolean]): c.Expr[Filter] = { val outputNodeId = Id.newId() val predicateExpression = getMilanFunction(predicate.tree) val inputExprVal = TermName(c.freshName("inputExpr")) val tree = q""" val $inputExprVal = ${c.prefix}.expr new ${typeOf[Filter]}($inputExprVal, $predicateExpression, $outputNodeId, $outputNodeId, $inputExprVal.tpe) """ c.Expr[Filter](tree) } }
Example 41
Source File: FunctionReferenceHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.program.internal import com.amazon.milan.program.FunctionReference import scala.reflect.macros.whitebox private def getFunctionReferenceFromSelect(objectRef: c.universe.Tree, functionName: c.universe.Name): FunctionReference = { if (!functionName.isTermName) { abort(s"$functionName is not a method name.") } val typeName = this.getTypeName(objectRef) val aggregationTypePrefix = "com.amazon.milan.lang.aggregation." val methodName = functionName.toTermName.toString if (methodName == "apply" && typeName.startsWith(aggregationTypePrefix)) { val actualMethodName = "aggregation." + typeName.substring(aggregationTypePrefix.length) FunctionReference("builtin", actualMethodName) } else { FunctionReference(typeName, methodName) } } }
Example 42
Source File: RecordTypeHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.program.internal import com.amazon.milan.program.{FunctionDef, NamedFields} import com.amazon.milan.typeutil.{DataStreamTypeDescriptor, FieldDescriptor, GroupedStreamTypeDescriptor, StreamTypeDescriptor, TupleTypeDescriptor, TypeDescriptor, TypeDescriptorMacroHost} import scala.reflect.macros.whitebox trait RecordTypeHost extends TypeDescriptorMacroHost { val c: whitebox.Context import c.universe._ def getStreamTypeExpr[T: c.WeakTypeTag](producingFunction: c.Expr[FunctionDef]): c.Expr[StreamTypeDescriptor] = { val recordType = getTypeDescriptor[T] val tree = q"new ${typeOf[DataStreamTypeDescriptor]}(com.amazon.milan.program.internal.RecordTypeUtil.addFieldNames($recordType, $producingFunction))" c.Expr[StreamTypeDescriptor](tree) } def getGroupedStreamTypeExpr[T: c.WeakTypeTag, TKey: c.WeakTypeTag](producingFunction: c.Expr[FunctionDef]): c.Expr[GroupedStreamTypeDescriptor] = { val recordType = getTypeDescriptor[T] val keyType = getTypeDescriptor[TKey] val tree = q"new ${typeOf[GroupedStreamTypeDescriptor]}($keyType, com.amazon.milan.program.internal.RecordTypeUtil.addFieldNames($recordType, $producingFunction))" c.Expr[GroupedStreamTypeDescriptor](tree) } def getRecordTypeExpr[T: c.WeakTypeTag](producingFunction: c.Expr[FunctionDef]): c.Expr[TypeDescriptor[T]] = { this.getRecordTypeExpr[T](getTypeDescriptor[T], producingFunction) } def getRecordTypeExpr[T](recordType: TypeDescriptor[T], producingFunction: c.Expr[FunctionDef]): c.Expr[TypeDescriptor[T]] = { val tree = q"com.amazon.milan.program.internal.RecordTypeUtil.addFieldNames($recordType, $producingFunction)" c.Expr[TypeDescriptor[T]](tree) } } object RecordTypeUtil { def addFieldNames[T](recordType: TypeDescriptor[T], producingFunction: FunctionDef): TypeDescriptor[T] = { if (recordType.fields.nonEmpty || recordType.genericArguments.isEmpty) { recordType } else { producingFunction.body match { case NamedFields(fields) if fields.length == recordType.genericArguments.length => val fieldDescriptors = fields.zip(recordType.genericArguments).map { case (field, ty) => FieldDescriptor(field.fieldName, ty) } new TupleTypeDescriptor[T](fieldDescriptors) case _ => recordType } } } }
Example 43
Source File: MappedStreamHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.program.internal import com.amazon.milan.Id import com.amazon.milan.program._ import scala.reflect.macros.whitebox def createStreamMap[TOut: c.WeakTypeTag](mapFunction: c.Expr[FunctionDef], validationExpression: c.universe.Tree): c.Expr[StreamMap] = { val streamType = getStreamTypeExpr[TOut](mapFunction) val outputNodeId = Id.newId() val sourceExpressionVal = TermName(c.freshName("sourceExpr")) val tree = q""" $validationExpression val $sourceExpressionVal = ${c.prefix}.expr new ${typeOf[StreamMap]}($sourceExpressionVal, $mapFunction, $outputNodeId, $outputNodeId, $streamType) """ c.Expr[StreamMap](tree) } def createAggregate[TOut: c.WeakTypeTag](aggregateFunction: c.Expr[FunctionDef], validationExpression: c.universe.Tree): c.Expr[Aggregate] = { val streamType = getStreamTypeExpr[TOut](aggregateFunction) val outputNodeId = Id.newId() val sourceExpressionVal = TermName(c.freshName("sourceExpr")) val tree = q""" $validationExpression val $sourceExpressionVal = ${c.prefix}.expr new ${typeOf[Aggregate]}($sourceExpressionVal, $aggregateFunction, $outputNodeId, $outputNodeId, $streamType) """ c.Expr[Aggregate](tree) } }
Example 44
Source File: LiftTypeDescriptorHost.scala From milan with Apache License 2.0 | 5 votes |
package com.amazon.milan.typeutil import scala.reflect.macros.whitebox trait LiftTypeDescriptorHost { val c: whitebox.Context import c.universe._ implicit def liftNumericTypeDescriptor[T: c.WeakTypeTag]: Liftable[NumericTypeDescriptor[T]] = { t => q"new ${weakTypeOf[NumericTypeDescriptor[T]]}(${t.typeName})" } implicit def liftBasicTypeDescriptor[T: c.WeakTypeTag]: Liftable[BasicTypeDescriptor[T]] = { tree => tree match { case t: NumericTypeDescriptor[T] => liftNumericTypeDescriptor[T](c.weakTypeTag[T])(t) case t: BasicTypeDescriptor[T] => q"new ${weakTypeOf[BasicTypeDescriptor[T]]}(${t.typeName})" } } implicit def liftTupleTypeDescriptor[T: c.WeakTypeTag]: Liftable[TupleTypeDescriptor[T]] = { t => q"new ${weakTypeOf[TupleTypeDescriptor[T]]}(${t.typeName}, ${t.genericArguments}, ${t.fields})" } implicit def liftObjectTypeDescriptor[T: c.WeakTypeTag]: Liftable[ObjectTypeDescriptor[T]] = { t => q"new ${weakTypeOf[ObjectTypeDescriptor[T]]}(${t.typeName}, ${t.genericArguments}, ${t.fields})" } implicit def liftGeneratedTypeDescriptor[T: c.WeakTypeTag]: Liftable[GeneratedTypeDescriptor[T]] = { t => q"new ${weakTypeOf[GeneratedTypeDescriptor[T]]}(${t.typeName}, ${t.genericArguments}, ${t.fields})" } implicit def liftCollectionTypeDescriptor[T: c.WeakTypeTag]: Liftable[CollectionTypeDescriptor[T]] = { t => q"new ${weakTypeOf[CollectionTypeDescriptor[T]]}(${t.typeName}, ${t.genericArguments})" } implicit val liftDataStreamTypeDescriptor: Liftable[DataStreamTypeDescriptor] = { t => q"new ${typeOf[DataStreamTypeDescriptor]}(${t.recordType})" } implicit val liftJoinedStreamsTypeDescriptor: Liftable[JoinedStreamsTypeDescriptor] = { t => q"new ${typeOf[JoinedStreamsTypeDescriptor]}(${t.leftRecordType}, ${t.rightRecordType})" } implicit val liftGroupedStreamTypeDescriptor: Liftable[GroupedStreamTypeDescriptor] = { t => q"new ${typeOf[GroupedStreamTypeDescriptor]}(${t.keyType}, ${t.recordType})" } implicit def liftStreamTypeDescriptor: Liftable[StreamTypeDescriptor] = { tree => tree match { case t: DataStreamTypeDescriptor => liftDataStreamTypeDescriptor(t) case t: JoinedStreamsTypeDescriptor => liftJoinedStreamsTypeDescriptor(t) case t: GroupedStreamTypeDescriptor => liftGroupedStreamTypeDescriptor(t) } } implicit def liftTypeDescriptor[T: c.WeakTypeTag]: Liftable[TypeDescriptor[T]] = { tree => tree match { case t: BasicTypeDescriptor[T] => liftBasicTypeDescriptor[T](c.weakTypeTag[T])(t) case t: TupleTypeDescriptor[T] => liftTupleTypeDescriptor(c.weakTypeTag[T])(t) case t: ObjectTypeDescriptor[T] => liftObjectTypeDescriptor(c.weakTypeTag[T])(t) case t: GeneratedTypeDescriptor[T] => liftGeneratedTypeDescriptor(c.weakTypeTag[T])(t) case t: CollectionTypeDescriptor[T] => liftCollectionTypeDescriptor(c.weakTypeTag[T])(t) case t: StreamTypeDescriptor => liftStreamTypeDescriptor(t) } } implicit val liftTypeDescriptorAny: Liftable[TypeDescriptor[Any]] = { t => liftTypeDescriptor[Any](c.weakTypeTag[Any])(t) } implicit val liftTypeDescriptorWildcard: Liftable[TypeDescriptor[_]] = { t => liftTypeDescriptor[Any](c.weakTypeTag[Any])(t.asInstanceOf[TypeDescriptor[Any]]) } implicit def liftFieldDescriptor[T: c.WeakTypeTag]: Liftable[FieldDescriptor[T]] = { t => q"new ${weakTypeOf[FieldDescriptor[T]]}(${t.name}, ${t.fieldType})" } implicit val liftFieldDescriptorWildcard: Liftable[FieldDescriptor[_]] = { t => q"new ${weakTypeOf[FieldDescriptor[Any]]}(${t.name}, ${t.fieldType.asInstanceOf[TypeDescriptor[Any]]})" } }
Example 45
Source File: unions.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless import scala.language.dynamics import scala.language.experimental.macros import scala.reflect.macros.whitebox object union { import syntax.UnionOps implicit def unionOps[C <: Coproduct](u : C) : UnionOps[C] = new UnionOps(u) object Union extends Dynamic { def applyDynamicNamed[U <: Coproduct](method: String)(elems: Any*): U = macro UnionMacros.mkUnionNamedImpl[U] def selectDynamic(tpeSelector: String): Any = macro LabelledMacros.unionTypeImpl } } @macrocompat.bundle class UnionMacros(val c: whitebox.Context) { import c.universe._ import internal.constantType import labelled.FieldType val fieldTypeTpe = typeOf[FieldType[_, _]].typeConstructor val SymTpe = typeOf[scala.Symbol] val atatTpe = typeOf[tag.@@[_,_]].typeConstructor def mkUnionNamedImpl[U <: Coproduct : WeakTypeTag](method: Tree)(elems: Tree*): Tree = { def mkSingletonSymbolType(c: Constant): Type = appliedType(atatTpe, List(SymTpe, constantType(c))) def mkFieldTpe(keyTpe: Type, valueTpe: Type): Type = appliedType(fieldTypeTpe, List(keyTpe, valueTpe.widen)) def mkElem(keyTpe: Type, value: Tree): Tree = q"$value.asInstanceOf[${mkFieldTpe(keyTpe, value.tpe)}]" def promoteElem(elem: Tree): Tree = elem match { case q""" $prefix(${Literal(k: Constant)}, $v) """ => mkElem(mkSingletonSymbolType(k), v) case _ => c.abort(c.enclosingPosition, s"$elem has the wrong shape for a record field") } val q"${methodString: String}" = method if(methodString != "apply") c.abort(c.enclosingPosition, s"this method must be called as 'apply' not '$methodString'") val elem = elems match { case Seq(e) => e case _ => c.abort(c.enclosingPosition, s"only one branch of a union may be inhabited") } q""" _root_.shapeless.Coproduct[${weakTypeOf[U]}](${promoteElem(elem)}) """ } }
Example 46
Source File: typechecking.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless.test import scala.language.experimental.macros import java.util.regex.Pattern import scala.reflect.macros.{ whitebox, ParseException, TypecheckException } object illTyped { def apply(code: String): Unit = macro IllTypedMacros.applyImplNoExp def apply(code: String, expected: String): Unit = macro IllTypedMacros.applyImpl } @macrocompat.bundle class IllTypedMacros(val c: whitebox.Context) { import c.universe._ def applyImplNoExp(code: Tree): Tree = applyImpl(code, null) def applyImpl(code: Tree, expected: Tree): Tree = { val Literal(Constant(codeStr: String)) = code val (expPat, expMsg) = expected match { case null => (null, "Expected some error.") case Literal(Constant(s: String)) => (Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.DOTALL), "Expected error matching: "+s) } try { val dummy0 = TermName(c.freshName) val dummy1 = TermName(c.freshName) c.typecheck(c.parse(s"object $dummy0 { val $dummy1 = { $codeStr } }")) c.error(c.enclosingPosition, "Type-checking succeeded unexpectedly.\n"+expMsg) } catch { case e: TypecheckException => val msg = e.getMessage if((expected ne null) && !(expPat.matcher(msg)).matches) c.error(c.enclosingPosition, "Type-checking failed in an unexpected way.\n"+expMsg+"\nActual error: "+msg) case e: ParseException => c.error(c.enclosingPosition, s"Parsing failed.\n${e.getMessage}") } q"()" } }
Example 47
Source File: lazyref.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless import scala.reflect.macros.whitebox class LazyMacrosRef(val c: whitebox.Context) { import c.universe._ def mkLazyImpl[I: WeakTypeTag]: Tree = { val i = new LazyMacros(c) i.mkLazyImpl[I].asInstanceOf[Tree] } def mkStrictImpl[I: WeakTypeTag]: Tree = { val i = new LazyMacros(c) i.mkStrictImpl[I].asInstanceOf[Tree] } }
Example 48
Source File: nat.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless import scala.language.experimental.macros import scala.annotation.tailrec import scala.reflect.macros.whitebox type _0 = shapeless._0 val _0: _0 = new _0 def toInt[N <: Nat](implicit toIntN : ToInt[N]) = toIntN() def toInt(n : Nat)(implicit toIntN : ToInt[n.N]) = toIntN() implicit def natOps[N <: Nat](n : N) : NatOps[N] = new NatOps(n) } @macrocompat.bundle class NatMacros(val c: whitebox.Context) extends NatMacroDefns { import c.universe._ def materializeWidened(i: Tree): Tree = i match { case NatLiteral(n) => mkNatValue(n) case _ => c.abort(c.enclosingPosition, s"Expression $i does not evaluate to a non-negative Int literal") } } @macrocompat.bundle trait NatMacroDefns { val c: whitebox.Context import c.universe._ object NatLiteral { def unapply(i: Tree): Option[Int] = i match { case Literal(Constant(n: Int)) if n >= 0 => Some(n) case _ => None } } def mkNatTpt(i: Int): Tree = { val succSym = typeOf[Succ[_]].typeConstructor.typeSymbol val _0Sym = typeOf[_0].typeSymbol @tailrec def loop(i: Int, acc: Tree): Tree = { if(i == 0) acc else loop(i-1, AppliedTypeTree(Ident(succSym), List(acc))) } loop(i, Ident(_0Sym)) } def mkNatTpe(i: Int): Type = { val succTpe = typeOf[Succ[_]].typeConstructor val _0Tpe = typeOf[_0] @tailrec def loop(i: Int, acc: Type): Type = { if(i == 0) acc else loop(i-1, appliedType(succTpe, acc)) } loop(i, _0Tpe) } def mkNatValue(i: Int): Tree = q""" new ${mkNatTpt(i)} """ }
Example 49
Source File: CaseClassSkipper.scala From singleton-ops with Apache License 2.0 | 5 votes |
package singleton.twoface.impl import singleton.ops.impl.HasOut import singleton.twoface.TwoFace import scala.reflect.macros.whitebox sealed trait CaseClassSkipper[T <: HasOut] extends HasOut { type Out def apply(value : T => Any, fallBack : => Boolean) : Out } object CaseClassSkipper { type Aux[T <: HasOut, Out0] = CaseClassSkipper[T]{type Out = Out0} type TAux[T <: HasOut, Out0] = T {type Out = Out0} //Normal value retrieval implicit def evNormal[T <: HasOut](implicit t : T) : Aux[T, TwoFace.Boolean[t.Out]] = new CaseClassSkipper[T] { type Out = TwoFace.Boolean[t.Out] def apply(value: T => Any, fallBack: => Boolean): Out = value(t).asInstanceOf[Out] } //Fallback value retrieval case class Fail[T <: HasOut]() extends CaseClassSkipper[T] { type Out = Boolean def apply(value: T => Any, fallBack: => Boolean): Boolean = fallBack } implicit def evCC[T <: HasOut](implicit n : shapeless.Refute[T]) : Aux[T, Boolean] = macro evCCMacro[T] def evCCMacro[T <: HasOut](c: whitebox.Context)(n : c.Tree)(implicit wt : c.WeakTypeTag[T]) : c.Tree = { import c.universe._ val t = weakTypeOf[T] if (c.internal.enclosingOwner.owner.asClass.isCaseClass) q"_root_.singleton.twoface.impl.CaseClassSkipper.Fail[$t]()" else c.abort(c.enclosingPosition, "Could not find implicit for...") } }
Example 50
Source File: Injectable.scala From angulate2 with MIT License | 5 votes |
// Project: angulate2 (https://github.com/jokade/angulate2) // Description: Angular2 @Injectable annotation. // Copyright (c) 2016 Johannes.Kastner <[email protected]> // Distributed under the MIT License (see included LICENSE file) package angulate2.core import angulate2.internal.ClassDecorator import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @js.native @JSImport("@angular/core","Injectable") object InjectableFacade extends js.Object { def apply() : js.Object = js.native def apply(options: js.Object) : js.Object = js.native } // NOTE: keep the constructor parameter list and Injectable.Macro.annotationParamNames in sync! @compileTimeOnly("enable macro paradise to expand macro annotations") class Injectable extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro Injectable.Macro.impl } object Injectable { private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator { import c.universe._ override val annotationName: String = "Injectable" override val annotationParamNames: Seq[String] = Seq() override def mainAnnotationObject = q"angulate2.core.InjectableFacade" } }
Example 51
Source File: NgModule.scala From angulate2 with MIT License | 5 votes |
// Project: angulate2 // Description: Angular2 @NgModule macro annotation // Copyright (c) 2016 Johannes.Kastner <[email protected]> // Distributed under the MIT License (see included LICENSE file) package angulate2.core import angulate2.internal.ClassDecorator import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @js.native @JSImport("@angular/core","NgModule") object NgModuleFacade extends js.Object { def apply() : js.Object = js.native def apply(options: js.Object) : js.Object = js.native } // NOTE: keep the constructor parameter list and Component.Macro.annotationParamNames in sync! @compileTimeOnly("enable macro paradise to expand macro annotations") class NgModule(providers: js.Array[js.Any] = null, declarations: js.Array[js.Any] = null, imports: js.Array[js.Any] = null, exports: js.Array[js.Any] = null, entryComponents: js.Array[js.Any] = null, bootstrap: js.Array[js.Any] = null, schemas: js.Array[js.Any] = null, id: String = null) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro NgModule.Macro.impl } object NgModule { private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator { import c.universe._ val annotationParamNames = Seq( "providers", "declarations", "imports", "exports", "entryComponents", "bootstrap", "schemas", "id" ) override val annotationName: String = "NgModule" override def mainAnnotationObject = q"angulate2.core.NgModuleFacade" } }
Example 52
Source File: Pipe.scala From angulate2 with MIT License | 5 votes |
// Project: angulate2 (https://github.com/jokade/angulate2) // Description: // Copyright (c) 2017 Johannes.Kastner <[email protected]> // Distributed under the MIT License (see included LICENSE file) package angulate2.core import angulate2.internal.ClassDecorator import de.surfice.smacrotools.createJS import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @js.native @JSImport("@angular/core","Pipe") object PipeFacade extends js.Object { def apply(options: js.Object) : js.Object = js.native } // NOTE: keep the constructor parameter list and Directive.Macro.annotationParamNames in sync! @compileTimeOnly("enable macro paradise to expand macro annotations") class Pipe(name: String, pure: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro Pipe.Macro.impl } object Pipe { private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator { import c.universe._ val annotationParamNames = Seq( "name", "pure" ) override val annotationName: String = "Pipe" override def mainAnnotationObject = q"angulate2.core.PipeFacade" } } @createJS trait PipeTransform0[T,R] { def transform(value: T): R } @createJS trait PipeTransform1[T,A1,R] { def transform(value: T, arg1: A1): R } @createJS trait PipeTransform2[T,A1,A2,R] { def transform(value: T, arg1: A1, arg2: A2): R } @createJS trait PipeTransform3[T,A1,A2,A3,R] { def transform(value: T, arg1: A1, arg2: A2, arg3: A3): R }
Example 53
Source File: Directive.scala From angulate2 with MIT License | 5 votes |
// Project: angulate2 (https://github.com/jokade/angulate2) // Description: Angular2 @Directive macro annotation // Copyright (c) 2016 Johannes.Kastner <[email protected]> // Distributed under the MIT License (see included LICENSE file) package angulate2.core import angulate2.internal.{ClassDecorator, FieldDecorator} import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @js.native @JSImport("@angular/core","Directive") object DirectiveFacade extends js.Object { def apply(options: js.Object) : js.Object = js.native } // NOTE: keep the constructor parameter list and Directive.Macro.annotationParamNames in sync! @compileTimeOnly("enable macro paradise to expand macro annotations") class Directive(selector: String = null, inputs: js.Array[String] = null, outputs: js.Array[String] = null, host: js.Dictionary[String] = null, template: String = null, providers: js.Array[js.Any] = null, exportAs: String = null, queries: js.Any = null) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro Directive.Macro.impl } object Directive { private[angulate2] abstract class BaseMacro extends ClassDecorator with FieldDecorator private[angulate2] class Macro(val c: whitebox.Context) extends BaseMacro { import c.universe._ override def annotationName = "Directive" override def mainAnnotationObject: c.universe.Tree = q"angulate2.core.DirectiveFacade" override def annotationParamNames: Seq[String] = Seq( "selector", "inputs", "outputs", "host", "template", "providers", "exportAs", "queries" ) } }
Example 54
Source File: Routes.scala From angulate2 with MIT License | 5 votes |
// Project: angulate2 (https://github.com/jokade/angulate2) // Description: Angulate2 extension for simplified creation of routing modules // Copyright (c) 2016 Johannes.Kastner <[email protected]> // Distributed under the MIT License (see included LICENSE file) package angulate2.ext import angulate2.internal.ClassDecorator import angulate2.router.Route import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.experimental.macros import scala.reflect.macros.whitebox import scala.scalajs.js @compileTimeOnly("enable macro paradise to expand macro annotations") class Routes(root: Boolean, routes: Route*) extends StaticAnnotation { def this(providers: js.Array[js.Any])(root: Boolean, routes: Route*) = this(root,routes:_*) def macroTransform(annottees: Any*): Any = macro Routes.Macro.impl } object Routes { private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator { import c.universe._ val annotationParamNames = Seq( "root", "routes*" ) override val firstArglistParamNames = Seq( "providers" ) override val annotationName: String = "Routes" override def mainAnnotationObject = q"angulate2.core.NgModuleFacade" private val routerModule = q"angulate2.ops.@@[angulate2.router.RouterModule]" override def analyze: Analysis = super.analyze andThen { case (cls: ClassParts, data) => val cdd = ClassDecoratorData(data) val routes = q"scalajs.js.Array(..${cdd.annotParams("routes")})" val remainingParams = cdd.annotParams - "root" - "routes" val imports = cdd.annotParams("root") match { case Literal(Constant(true)) => q"scalajs.js.Array(angulate2.router.RouterModule.forRoot($routes))" case Literal(Constant(false)) => q"scalajs.js.Array(angulate2.router.RouterModule.forChild($routes))" } (cls, ClassDecoratorData.update(data,cdd.copy(annotParams = remainingParams ++ Map("imports" -> imports, "exports" -> routerModule)))) case default => default } } }
Example 55
Source File: DefaultReaderMacro.scala From grafter with MIT License | 5 votes |
package org.zalando.grafter.macros import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.whitebox import ReaderMacros._ object DefaultReaderMacro { val annotationName = "defaultReader" def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ val (classTree, companionTree): (Tree, Option[Tree]) = annotationInputs(c)(annotationName)(annottees) classTree match { case ClassDef(_, className, typeParams, _) => val genericTypeName = internal.reificationSupport.freshTypeName("A") val typeParam = typeParameter(annotationName)(c) typeParams match { case _ :: Nil => outputs(c)(classTree, className, companionTree) { q""" implicit def reader[$genericTypeName, F[_]](implicit defaultReader: cats.data.Reader[$genericTypeName, $typeParam[F]]): cats.data.Reader[$genericTypeName, $className[F]] = org.zalando.grafter.GenericReader.widenReader(defaultReader) """ } case Nil => outputs(c)(classTree, className, companionTree) { q""" implicit def reader[$genericTypeName](implicit defaultReader: cats.data.Reader[$genericTypeName, $typeParam]): cats.data.Reader[$genericTypeName, $className] = org.zalando.grafter.GenericReader.widenReader(defaultReader) """ } case other => c.abort(c.macroApplication.pos, s"the @$annotationName annotation must specify a type containing at most one type parameter, found $other") } case other => c.abort(c.macroApplication.pos, s"the @$annotationName annotation must annotate a trait, found $other") } } } class defaultReader[A] extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro DefaultReaderMacro.impl }
Example 56
Source File: ReaderMacros.scala From grafter with MIT License | 5 votes |
package org.zalando.grafter.macros import scala.collection.mutable.ListBuffer import scala.reflect.macros.whitebox object ReaderMacros { def typeParameter(name: String)(c: whitebox.Context) = { import c.universe._ val traverser = new Traverser { val types: ListBuffer[c.universe.TypeName] = new ListBuffer[TypeName]() override def traverse(tree: Tree): Unit = tree match { case New(AppliedTypeTree(Ident(TypeName(_)), typeIds)) => types.appendAll(typeIds.collect { case Ident(typeName: TypeName) => typeName }) case _ => super.traverse(tree) } } traverser.traverse(c.macroApplication) traverser.types.headOption match { case Some(t) => t case None => c.abort(c.enclosingPosition, s"the @$name annotation requires a type parameter") } } }
Example 57
Source File: ReaderOfMacro.scala From grafter with MIT License | 5 votes |
package org.zalando.grafter.macros import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.whitebox import ReaderMacros._ object ReaderOfMacro { val annotationName = "readerOf" def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ def name(t: Name) = t.decodedName.toString.trim val (classTree, companionTree): (Tree, Option[Tree]) = annotationInputs(c)(annotationName)(annottees) classTree match { case ClassDef(_, className, _, Template(_, _, fields)) => val typeParam = typeParameter(annotationName)(c) def params = fieldsNamesAndTypes(c)(fields) val paramNames = params.map(_._1).distinct val implicits = params.map { case (p, _type) => q"""private val ${TermName("_"+name(p))}: cats.data.Reader[$typeParam, ${_type}] = implicitly[cats.data.Reader[$typeParam, ${_type}]];""" } val readValues = paramNames.map { p => q"""val ${TermName("_"+name(p)+"Value")} = ${TermName("_"+name(p))}.apply(r);""" } val values = paramNames.map { p => q"""${TermName("_"+name(p)+"Value")}""" } val klassName = name(className) val reader = c.Expr[Any]( q""" implicit val reader: cats.data.Reader[$typeParam, ${TypeName(klassName)}] = { cats.data.Reader { r => ..$readValues new ${TypeName(klassName)}(...${List(values)}) } } """) outputs(c)(classTree, className, companionTree) { q""" ..$implicits ..$reader """ } case other => c.abort(c.macroApplication.pos, s"the @$annotationName annotation must annotate a class, found $other") } } } class readerOf[A] extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro ReaderOfMacro.impl }
Example 58
Source File: Facades.scala From scalapy with MIT License | 5 votes |
package me.shadaj.scalapy.py import scala.reflect.macros.whitebox import scala.language.experimental.macros import scala.annotation.StaticAnnotation class native extends StaticAnnotation object FacadeImpl { def creator[T <: Any](c: whitebox.Context)(implicit tag: c.WeakTypeTag[T]): c.Tree = { import c.universe._ if (!tag.tpe.typeSymbol.annotations.exists(_.tpe =:= typeOf[native])) { c.error(c.enclosingPosition, "Cannot derive a creator for a trait that is not annotated as @py.native") } q"""new _root_.me.shadaj.scalapy.py.FacadeCreator[${tag.tpe}] { def create(value: _root_.me.shadaj.scalapy.py.PyValue) = new _root_.me.shadaj.scalapy.py.FacadeValueProvider(value) with ${tag.tpe} {} }""" } def native_impl[T: c.WeakTypeTag](c: whitebox.Context): c.Expr[T] = { import c.universe._ if (!c.enclosingClass.symbol.annotations.exists(_.tpe =:= typeOf[native])) { c.error(c.enclosingPosition, "py.native implemented functions can only be declared inside traits annotated as @py.native") } val method = c.internal.enclosingOwner.asMethod val methodName = method.name.toString val returnType = method.returnType val paramss = method.paramLists paramss.headOption match { case Some(params) => val paramExprs = params.map(_.name) c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].applyDynamic($methodName)(..$paramExprs).as[$returnType]") case scala.None => c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].selectDynamic($methodName).as[$returnType]") } } def native_named_impl[T: c.WeakTypeTag](c: whitebox.Context): c.Expr[T] = { import c.universe._ if (!c.enclosingClass.symbol.annotations.exists(_.tpe =:= typeOf[native])) { c.error(c.enclosingPosition, "py.native implemented functions can only be declared inside traits annotated as @py.native") } val method = c.internal.enclosingOwner.asMethod val methodName = method.name.toString val returnType = method.returnType val paramss = method.paramLists paramss.headOption match { case Some(params) => val paramExprs = params.map { p => val paramName = q"${p.asTerm}".toString s"""("${p.name}", $paramName)""" } c.Expr[T](c.parse(s"""as[_root_.me.shadaj.scalapy.py.Dynamic].applyDynamicNamed("$methodName")(${paramExprs.mkString(",")}).as[$returnType]""")) case scala.None => c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].selectDynamic($methodName).as[$returnType]") } } }
Example 59
Source File: autoApplyK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoApplyK") class autoApplyK(autoDerivation: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoApplyKMacros.newDef } private [tagless] class autoApplyKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator { import c.universe._ private def generateApplyKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("applyKFor" + algebraName), typeParams, tq"_root_.cats.tagless.ApplyK[$algebraType]", q"_root_.cats.tagless.Derive.applyK[$algebraType]" ) def instanceDef(algebra: AlgDefn.UnaryAlg): Tree = algebra.forVaryingEffectType(generateApplyKFor(algebra.name)) def newDef(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: autoDerivationDef(algebra) :: Nil) }
Example 60
Source File: autoApply.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoApply") class autoApply extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoApplyMacros.applyInst } private[tagless] class autoApplyMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateApplyFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("applyFor" + algebraName), typeParams, tq"_root_.cats.Apply[$algebraType]", q"_root_.cats.tagless.Derive.apply[$algebraType]" ) def applyInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateApplyFor(algebra.name)) :: Nil } }
Example 61
Source File: autoProductNK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoProductK") class autoProductNK extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoProductNKMacros.productKInst } private [tagless] class autoProductNKMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ def productMethod(typedef: TypeDefinition)(arity: Int): Tree = { def af(n: Int) = TermName("af" + n) val name = typedef.ident val range = 1 to arity // tparam"F1[_], F2[_], F3[_]" val effectTypeParams: List[TypeDef] = range.map(n => createTypeParam("F" + n, 1)).toList val effectTypeParamsNames = tArgs(effectTypeParams) //Tuple3K val productTypeName = tq"_root_.cats.tagless.${TypeName("Tuple" + arity + "K")}" val methods = typedef.impl.body.map { case q"def $method[..$typeParams](...$paramLists): ${_}[$resultType]" => val returnItems = range.map(n => q"${af(n)}.$method(...${argumentLists(paramLists)})") q"""def $method[..$typeParams](...$paramLists): $productTypeName[..$effectTypeParamsNames]#λ[$resultType] = (..$returnItems) """ case statement => abort(s"autoProductK does not support algebra with such statement: $statement") } //af1: A[F1], af2: A[F2], af3: A[F3] val inboundInterpreters: Seq[ValDef] = (range zip effectTypeParamsNames).map { case (idx, fx) => ValDef( Modifiers(Flag.PARAM), af(idx), typedef.applied(fx), EmptyTree ) } q""" def ${TermName("product" + arity + "K")}[..$effectTypeParams](..$inboundInterpreters): $name[$productTypeName[..$effectTypeParamsNames]#λ] = new $name[$productTypeName[..$effectTypeParamsNames]#λ] { ..$methods } """ } def productKInst(annottees: c.Tree*): c.Tree = enrich(annottees.toList) { td => val productMethods = (3 to 9).map(productMethod(td)) Seq(td.defn, addStats(td.companion, productMethods)) } }
Example 62
Source File: autoInvariantK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoInvariantK") class autoInvariantK(autoDerivation: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoInvariantKMacros.newDef } private [tagless] class autoInvariantKMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateInvariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("invariantKFor" + algebraName), typeParams, tq"_root_.cats.tagless.InvariantK[$algebraType]", q"_root_.cats.tagless.Derive.invariantK[$algebraType]" ) def instanceDef(algebra: AlgDefn.UnaryAlg): Tree = algebra.forVaryingEffectType(generateInvariantKFor(algebra.name)) def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = { algDefn.forVaryingEffectTypeFullyRefined { (algebraType, tparams) => val impl = Seq( generateInvariantKFor("FullyRefined" + algDefn.name)( algebraType, tparams ), generateAutoDerive(algDefn.fullyRefinedTypeSig)( algebraType, tparams ) ) q"object fullyRefined { ..$impl }" } } def companionIMapKDef(algDefn: AlgDefn.UnaryAlg) = { val from = TermName("af") val F = createFreshTypeParam("F", 1) val G = createFreshTypeParam("G", 1) val algebraF = algDefn.newTypeSig(F) val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from) algDefn.forVaryingEffectType((algebraType, tparams) => q""" def imapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}])(gk: _root_.cats.~>[..${tArgs(G, F)}]): $fullyRefinedAlgebraG = _root_.cats.tagless.InvariantK[$algebraType].imapK($from)(fk)(gk).asInstanceOf[$fullyRefinedAlgebraG] """) } def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = { val F = createFreshTypeParam("F", 1) val G = createFreshTypeParam("G", 1) val algebraF = newTypeSig(F) val algebraG = newTypeSig(G) q""" object autoDerive { @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter")) implicit def fromFunctorK[$F, $G, ..$tparams]( implicit af: $algebraF, IK: _root_.cats.tagless.InvariantK[$algebraType], fk: _root_.cats.~>[..${tArgs(F, G)}], gk: _root_.cats.~>[..${tArgs(G, F)}]) : $algebraG = IK.imapK(af)(fk)(gk) }""" } def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) = if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree def newDef(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionIMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil) }
Example 63
Source File: autoSemigroupal.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoSemigroupal") class autoSemigroupal extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoSemigroupalMacros.semigroupalInst } private[tagless] class autoSemigroupalMacros(override val c: whitebox.Context) extends MacroUtils { import c.universe._ private def generateSemigroupalFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("semigroupalFor" + algebraName), typeParams, tq"_root_.cats.Semigroupal[$algebraType]", q"_root_.cats.tagless.Derive.semigroupal[$algebraType]" ) def semigroupalInst(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra => algebra.forVaryingEffectType(generateSemigroupalFor(algebra.name)) :: Nil } }
Example 64
Source File: autoFunctorK.scala From cats-tagless with Apache License 2.0 | 5 votes |
package cats.tagless import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.collection.immutable.Seq import scala.reflect.macros.whitebox @compileTimeOnly("Cannot expand @autoFunctorK") class autoFunctorK(autoDerivation: Boolean = true) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro autoFunctorKMacros.newDef } private [tagless] class autoFunctorKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator { import c.universe._ private def generateFunctorKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) = typeClassInstance( TermName("functorKFor" + algebraName), typeParams, tq"_root_.cats.tagless.FunctorK[$algebraType]", q"_root_.cats.tagless.Derive.functorK[$algebraType]" ) def instanceDef(algebra: AlgDefn.UnaryAlg): Tree = algebra.forVaryingEffectType(generateFunctorKFor(algebra.name)) def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = { algDefn.forVaryingEffectTypeFullyRefined { (algebraType, tparams) => val impl = Seq( generateFunctorKFor("FullyRefined" + algDefn.name)( algebraType, tparams ), generateAutoDerive(algDefn.fullyRefinedTypeSig)( algebraType, tparams ) ) q"object fullyRefined { ..$impl }" } } def newDef(annottees: c.Tree*): c.Tree = enrichAlgebra(annottees.toList)( algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil) } private [tagless] trait CovariantKMethodsGenerator { self: MacroUtils => import c.universe._ def companionMapKDef(algDefn: AlgDefn.UnaryAlg) = { val from = TermName("af") val F = createFreshTypeParam("F", 1) val G = createFreshTypeParam("G", 1) val algebraF = algDefn.newTypeSig(F) val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from) algDefn.forVaryingEffectType((algebraType, tparams) => q""" def mapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}]): $fullyRefinedAlgebraG = _root_.cats.tagless.FunctorK[$algebraType].mapK($from)(fk).asInstanceOf[$fullyRefinedAlgebraG] """) } def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = { val F = createFreshTypeParam("F", 1) val G = createFreshTypeParam("G", 1) val algebraF = newTypeSig(F) val algebraG = newTypeSig(G) q""" object autoDerive { @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter")) implicit def fromFunctorK[$F, $G, ..$tparams]( implicit fk: _root_.cats.~>[..${tArgs(F, G)}], FK: _root_.cats.tagless.FunctorK[$algebraType], af: $algebraF) : $algebraG = FK.mapK(af)(fk) }""" } def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) = if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree }