scala.reflect.macros.blackbox Scala Examples
The following examples show how to use scala.reflect.macros.blackbox.
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: TransactionMacros.scala From scarango with MIT License | 5 votes |
package com.outr.arango.transaction import com.outr.arango.Graph import scala.annotation.compileTimeOnly import scala.concurrent.Future import scala.reflect.macros.blackbox @compileTimeOnly("Enable macro paradise to expand compile-time macros") object TransactionMacros { def simple[G <: Graph, R](c: blackbox.Context) (transaction: c.Expr[(G) => Future[R]]) (implicit g: c.WeakTypeTag[G]): c.Expr[Future[R]] = { import c.universe._ c.Expr[Future[R]]( q""" import com.outr.arango.transaction._ import scribe.Execution.global """) ??? } }
Example 2
Source File: GraphMacros.scala From scarango with MIT License | 5 votes |
package com.outr.arango import scala.annotation.compileTimeOnly import scala.reflect.macros.blackbox @compileTimeOnly("Enable macro paradise to expand compile-time macros") object GraphMacros { def store[T](c: blackbox.Context) (key: c.Expr[String]) (implicit t: c.WeakTypeTag[T]): c.Expr[DatabaseStore[T]] = { import c.universe._ val graph = c.prefix val tree = q""" DatabaseStore[$t]($key, $graph, Serialization.auto[$t]) """ c.Expr[DatabaseStore[T]](tree) } def queryBuilderAs[D](c: blackbox.Context)(implicit d: c.WeakTypeTag[D]): c.Expr[QueryBuilder[D]] = { import c.universe._ val builder = c.prefix if (d.tpe <:< typeOf[Document[_]] && d.tpe.companion <:< typeOf[DocumentModel[_]]) { c.Expr[QueryBuilder[D]](q"$builder.as[$d](${d.tpe.typeSymbol.companion}.serialization)") } else { c.Expr[QueryBuilder[D]](q"$builder.as[$d](_root_.com.outr.arango.Serialization.auto[$d])") } } def vertex[D <: Document[D]](c: blackbox.Context) (implicit d: c.WeakTypeTag[D]): c.Expr[Collection[D]] = { import c.universe._ val graph = c.prefix val companion = d.tpe.typeSymbol.companion c.Expr[Collection[D]]( q""" import com.outr.arango._ new Collection[$d]($graph, $companion, CollectionType.Document, $companion.indexes, None) """) } def edge[D <: Document[D]](c: blackbox.Context) (implicit d: c.WeakTypeTag[D]): c.Expr[Collection[D]] = { import c.universe._ val graph = c.prefix val companion = d.tpe.typeSymbol.companion c.Expr[Collection[D]]( q""" import com.outr.arango._ new Collection[$d]($graph, $companion, CollectionType.Edge, $companion.indexes, None) """) } }
Example 3
Source File: Macros.scala From scarango with MIT License | 5 votes |
package com.outr.arango import scala.annotation.compileTimeOnly import scala.reflect.macros.blackbox @compileTimeOnly("Enable macro paradise to expand compile-time macros") object Macros { def serializationAuto[D](c: blackbox.Context) (implicit d: c.WeakTypeTag[D]): c.Expr[Serialization[D]] = { import c.universe._ c.Expr[Serialization[D]]( q""" import _root_.com.outr.arango._ import _root_.profig._ import _root_.io.circe.Json Serialization[$d]( doc2Json = (d: $d) => JsonUtil.toJson[$d](d), json2Doc = (j: Json) => JsonUtil.fromJson[$d](j) ) """) } }
Example 4
Source File: FUUID.scala From fuuid with MIT License | 5 votes |
package io.chrisdavenport.fuuid import cats._ import cats.implicits._ import cats.effect.Sync import java.util.UUID import scala.reflect.macros.blackbox final class FUUID private (private val uuid: UUID){ // Direct show method so people do not use toString def show: String = uuid.show // -1 less than, 0 equal to, 1 greater than def compare(that: FUUID): Int = this.uuid.compareTo(that.uuid) // Returns 0 when equal def eqv(that: FUUID): Boolean = compare(that) == 0 override def equals(obj: scala.Any): Boolean = obj match { case that: FUUID => eqv(that) case _ => false } override def hashCode: Int = uuid.hashCode override def toString: String = uuid.toString } object FUUID { implicit val instancesFUUID: Hash[FUUID] with Order[FUUID] with Show[FUUID] = new Hash[FUUID] with Order[FUUID] with Show[FUUID]{ override def show(t: FUUID): String = t.show override def eqv(x: FUUID, y: FUUID): Boolean = x.eqv(y) override def hash(x: FUUID): Int = x.hashCode override def compare(x: FUUID, y: FUUID): Int = x.compare(y) } def fromString(s: String): Either[Throwable, FUUID] = Either.catchNonFatal(new FUUID(UUID.fromString(s))) def fromStringOpt(s: String): Option[FUUID] = fromString(s).toOption def fromStringF[F[_]](s: String)(implicit AE: ApplicativeError[F, Throwable]): F[FUUID] = fromString(s).fold(AE.raiseError, AE.pure) def fromUUID(uuid: UUID): FUUID = new FUUID(uuid) def randomFUUID[F[_]: Sync]: F[FUUID] = Sync[F].delay( new FUUID(UUID.randomUUID) ) def fuuid(s: String): FUUID = macro Macros.fuuidLiteral private[FUUID] class Macros(val c: blackbox.Context) { import c.universe._ def fuuidLiteral(s: c.Expr[String]): c.Expr[FUUID] = s.tree match { case Literal(Constant(s: String))=> fromString(s) .fold( e => c.abort(c.enclosingPosition, e.getMessage.replace("UUID", "FUUID")), _ => c.Expr(q""" @SuppressWarnings(Array("org.wartremover.warts.Throw")) val fuuid = _root_.io.chrisdavenport.fuuid.FUUID.fromString($s).fold(throw _, _root_.scala.Predef.identity) fuuid """) ) case _ => c.abort( c.enclosingPosition, s"This method uses a macro to verify that a FUUID literal is valid. Use FUUID.fromString if you have a dynamic value you want to parse as an FUUID." ) } } object Unsafe { def toUUID(fuuid: FUUID): UUID = fuuid.uuid def withUUID[A](fuuid: FUUID)(f: UUID => A): A = f(fuuid.uuid) } }
Example 5
Source File: DisposableFunctionClientFactoryMacro.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.client import io.github.shogowada.scala.jsonrpc.common.JSONRPCMacroUtils import scala.concurrent.Future import scala.reflect.macros.blackbox class DisposableFunctionClientFactoryMacro[CONTEXT <: blackbox.Context](val c: CONTEXT) { import c.universe._ private lazy val macroUtils = JSONRPCMacroUtils[c.type](c) private lazy val methodClientFactoryMacro = new JSONRPCMethodClientFactoryMacro[c.type](c) def getOrCreate( client: c.Tree, server: c.Tree, disposableFunctionMethodName: c.Tree, disposableFunctionType: c.Type ): c.Tree = { val disposableFunctionRepository = macroUtils.getDisposableFunctionRepository(server) val newDisposableFunction = create(client, server, disposableFunctionType, disposableFunctionMethodName) q""" $disposableFunctionRepository .getOrAdd($disposableFunctionMethodName, () => $newDisposableFunction) .asInstanceOf[$disposableFunctionType] """ } private def create( client: c.Tree, server: c.Tree, disposableFunctionType: c.Type, disposableFunctionMethodName: c.Tree ): c.Tree = { val typeArgs: Seq[Type] = disposableFunctionType.typeArgs val paramTypes: Seq[Type] = typeArgs.init val returnType: Type = typeArgs.last val function = methodClientFactoryMacro.createAsFunction(client, Some(server), disposableFunctionMethodName, paramTypes, returnType) val disposeMethod = createDisposeMethod(server, client, disposableFunctionMethodName) def getApplyParameterName(index: Int) = TermName(s"v$index") val applyParameters: Seq[Tree] = paramTypes.zipWithIndex .map { case (paramType, index) => val paramName = getApplyParameterName(index) q"$paramName: $paramType" } val applyParameterNames = paramTypes.indices .map(getApplyParameterName) q""" new $disposableFunctionType { override val identifier = $function override def apply(..$applyParameters) = $function(..$applyParameterNames) $disposeMethod } """ } private def createDisposeMethod( server: Tree, client: Tree, disposableFunctionMethodName: Tree ): Tree = { val disposableFunctionRepository = macroUtils.getDisposableFunctionRepository(server) val disposeClient = methodClientFactoryMacro.createAsFunction( client, Some(server), q"Constants.DisposeMethodName", Seq(macroUtils.getType[String]), macroUtils.getType[Future[Unit]] ) q""" override def dispose(): Future[Unit] = { $disposableFunctionRepository.remove($disposableFunctionMethodName) $disposeClient($disposableFunctionMethodName) } """ } }
Example 6
Source File: DisposableFunctionServerFactoryMacro.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.server import io.github.shogowada.scala.jsonrpc.common.JSONRPCMacroUtils import scala.reflect.macros.blackbox class DisposableFunctionServerFactoryMacro[Context <: blackbox.Context](val c: Context) { import c.universe._ private lazy val macroUtils = JSONRPCMacroUtils[c.type](c) private lazy val requestJSONHandlerFactoryMacro = new JSONRPCRequestJSONHandlerFactoryMacro[c.type](c) def getOrCreate( client: Tree, server: Tree, disposableFunction: Tree, disposableFunctionType: Type ): Tree = { val requestJSONHandlerRepository = macroUtils.getRequestJSONHandlerRepository(server) val disposableFunctionMethodNameRepository = macroUtils.getDisposableFunctionMethodNameRepository(client) val disposeFunctionMethodHandler = requestJSONHandlerFactoryMacro.createDisposeFunctionMethodHandler(server, client) val handler = requestJSONHandlerFactoryMacro.createFromDisposableFunction(client, server, disposableFunction, disposableFunctionType) q""" $requestJSONHandlerRepository.addIfAbsent(Constants.DisposeMethodName, () => ($disposeFunctionMethodHandler)) val methodName: String = $disposableFunctionMethodNameRepository.getOrAddAndNotify( $disposableFunction, (newMethodName) => { $requestJSONHandlerRepository.add(newMethodName, $handler) } ) methodName """ } }
Example 7
Source File: JSONRPCParameterFactory.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.common import scala.reflect.macros.blackbox object JSONRPCParameterFactory { def apply[Context <: blackbox.Context](c: Context): JSONRPCParameterFactory[c.type] = new JSONRPCParameterFactory[c.type](c) } class JSONRPCParameterFactory[Context <: blackbox.Context](val c: Context) { import c.universe._ private lazy val valueFactory = JSONRPCValueFactory[c.type](c) def jsonRPCToScala( server: Tree, maybeClient: Option[Tree], argument: Tree, argumentType: Type ): Tree = { valueFactory.jsonRPCToScala( maybeClient = maybeClient, maybeServer = Option(server), argument, argumentType ) } def jsonRPCType(paramTypes: Seq[c.Type]): Tree = { val parameterTypes: Iterable[Tree] = paramTypes .map(jsonRPCType) if (parameterTypes.size == 1) { val parameterType = parameterTypes.head tq"Tuple1[$parameterType]" } else { tq"(..$parameterTypes)" } } private def jsonRPCType(paramType: Type): Tree = { valueFactory.jsonRPCType(paramType) } def scalaToJSONRPC( client: Tree, maybeServer: Option[Tree], parameter: Tree, parameterType: Type ): Tree = { valueFactory.scalaToJSONRPC( maybeClient = Option(client), maybeServer = maybeServer, value = parameter, valueType = parameterType ) } }
Example 8
Source File: JSONRPCResultFactory.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.common import scala.reflect.macros.blackbox object JSONRPCResultFactory { def apply[Context <: blackbox.Context](c: Context): JSONRPCResultFactory[c.type] = new JSONRPCResultFactory[c.type](c) } class JSONRPCResultFactory[Context <: blackbox.Context](val c: Context) { import c.universe._ private lazy val valueFactory = JSONRPCValueFactory[c.type](c) def jsonRPCToScala( client: Tree, maybeServer: Option[Tree], result: Tree, resultType: Type ): Tree = { valueFactory.jsonRPCToScala( maybeClient = Option(client), maybeServer = maybeServer, value = result, valueType = resultType ) } def jsonRPCType(resultType: Type): Tree = { valueFactory.jsonRPCType(resultType) } def scalaToJSONRPC( server: Tree, maybeClient: Option[Tree], result: Tree, resultType: Type ): Tree = { valueFactory.scalaToJSONRPC( maybeServer = Option(server), maybeClient = maybeClient, value = result, valueType = resultType ) } }
Example 9
Source File: UpickleJSONSerializer.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.serializers import upickle.Js import scala.language.experimental.macros import scala.reflect.macros.blackbox object JSONRPCPickler extends upickle.AttributeTagged { override implicit def OptionW[T: Writer]: Writer[Option[T]] = { Writer { case None => Js.Null case Some(value) => implicitly[Writer[T]].write(value) } } override implicit def OptionR[T: Reader]: Reader[Option[T]] = { Reader { case Js.Null => None case value: Js.Value => Some(implicitly[Reader[T]].read(value)) } } implicit def IdW: Writer[Either[String, BigDecimal]] = { Writer[Either[String, BigDecimal]] { case Left(value) => writeJs(value) case Right(value) => writeJs(value) } } implicit def IdR: Reader[Either[String, BigDecimal]] = { Reader[Either[String, BigDecimal]] { case value: Js.Str => Left(readJs[String](value)) case value: Js.Num => Right(readJs[BigDecimal](value)) } } } class UpickleJSONSerializer extends JSONSerializer { override def serialize[T](value: T): Option[String] = macro UpickleJSONSerializerMacro.serialize[T] override def deserialize[T](json: String): Option[T] = macro UpickleJSONSerializerMacro.deserialize[T] } object UpickleJSONSerializer { def apply() = new UpickleJSONSerializer } object UpickleJSONSerializerMacro { def serialize[T](c: blackbox.Context)(value: c.Expr[T]): c.Expr[Option[String]] = { import c.universe._ c.Expr[Option[String]]( q""" scala.util.Try(io.github.shogowada.scala.jsonrpc.serializers.JSONRPCPickler.write($value)).toOption """ ) } def deserialize[T: c.WeakTypeTag](c: blackbox.Context)(json: c.Expr[String]): c.Expr[Option[T]] = { import c.universe._ val deserializeType = weakTypeOf[T] c.Expr[Option[T]]( q""" scala.util.Try(io.github.shogowada.scala.jsonrpc.serializers.JSONRPCPickler.read[$deserializeType]($json)).toOption """ ) } }
Example 10
Source File: CirceJSONSerializer.scala From scala-json-rpc with MIT License | 5 votes |
package io.github.shogowada.scala.jsonrpc.serializers import io.circe.{Decoder, Encoder, Error, Json} import scala.language.experimental.macros import scala.reflect.macros.blackbox object CirceJSONCoder { def encode[T](value: T)(implicit encoder: Encoder[T]): Json = { encoder(value) } def decode[T](json: String)(implicit decoder: Decoder[T]): Either[Error, T] = { io.circe.parser.decode[T](json) } } class CirceJSONSerializer extends JSONSerializer { override def serialize[T](value: T): Option[String] = macro CirceJSONSerializerMacro.serialize[T] override def deserialize[T](json: String): Option[T] = macro CirceJSONSerializerMacro.deserialize[T] } object CirceJSONSerializer { def apply(): CirceJSONSerializer = { new CirceJSONSerializer } } object CirceJSONSerializerMacro { def serialize[T](c: blackbox.Context)(value: c.Expr[T]): c.Expr[Option[String]] = { import c.universe._ c.Expr[Option[String]]( q""" { import io.circe.generic.auto._ scala.util.Try(io.circe.Printer.noSpaces.pretty(io.github.shogowada.scala.jsonrpc.serializers.CirceJSONCoder.encode($value))).toOption } """ ) } def deserialize[T: c.WeakTypeTag](c: blackbox.Context)(json: c.Expr[String]): c.Expr[Option[T]] = { import c.universe._ val deserializeType = weakTypeOf[T] c.Expr[Option[T]]( q""" { import io.circe.generic.auto._ io.github.shogowada.scala.jsonrpc.serializers.CirceJSONCoder.decode[$deserializeType]($json).toOption } """ ) } }
Example 11
Source File: Mergeable.scala From scalajs-react-bootstrap with MIT License | 5 votes |
package com.acework.js.utils import scala.reflect.macros.blackbox trait Common { def getFieldNamesAndTypes(c: blackbox.Context)(tpe: c.universe.Type): Iterable[(c.universe.Name, c.universe.Type)] = { import c.universe._ object CaseField { def unapply(trmSym: TermSymbol): Option[(Name, Type)] = { if (trmSym.isVal && trmSym.isCaseAccessor) Some((TermName(trmSym.name.toString.trim), trmSym.typeSignature)) else None } } tpe.decls.collect { case CaseField(nme, tpe) => (nme, tpe) } } } trait Mergeable[T] { def merge(t: T, map: Map[String, Any]): T } object Mergeable { implicit def materializeMergeable[T]: Mergeable[T] = macro materializeMergeableImpl[T] def materializeMergeableImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Mergeable[T]] = { import c.universe._ val tpe = weakTypeOf[T] val companion: Symbol = tpe.typeSymbol.companion // get fields from primary constructor val fields = tpe.decls.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m }.get.paramLists.head val fromMapParams = fields.map { field => val name = field.asTerm.name val decoded = name.decodedName.toString val returnType = tpe.decl(name).typeSignature q"map.getOrElse($decoded, t.$name).asInstanceOf[$returnType]" } //val params: Iterable[Name] = tpe.decls.collect { // case param if param.isMethod && param.asMethod.isCaseAccessor => param.name // } c.Expr[Mergeable[T]] { q""" new Mergeable[$tpe] { def merge(t: $tpe, map: Map[String, Any]) = $companion(..$fromMapParams) } """ } } }
Example 12
Source File: package.scala From refined with MIT License | 5 votes |
package eu.timepit.refined import _root_.scalaz.{@@, Contravariant, Equal, MonadError, Show} import eu.timepit.refined.api.{RefType, Validate} import scala.reflect.macros.blackbox package object scalaz { implicit val scalazTagRefType: RefType[@@] = new RefType[@@] { override def unsafeWrap[T, P](t: T): T @@ P = t.asInstanceOf[T @@ P] override def unwrap[T](tp: T @@ _): T = tp.asInstanceOf[T] override def unsafeRewrap[T, A, B](ta: T @@ A): T @@ B = ta.asInstanceOf[T @@ B] override def unsafeWrapM[T: c.WeakTypeTag, P: c.WeakTypeTag]( c: blackbox.Context )(t: c.Expr[T]): c.Expr[T @@ P] = c.universe.reify(t.splice.asInstanceOf[T @@ P]) override def unsafeRewrapM[T: c.WeakTypeTag, A: c.WeakTypeTag, B: c.WeakTypeTag]( c: blackbox.Context )(ta: c.Expr[T @@ A]): c.Expr[T @@ B] = c.universe.reify(ta.splice.asInstanceOf[T @@ B]) } implicit def refTypeShow[F[_, _], T: Show, P](implicit rt: RefType[F]): Show[F[T, P]] = scalaz.derivation.refTypeViaContravariant[F, Show, T, P] @deprecated("Generic derivation instances have been moved into the `derivation` object", "0.9.4") def refTypeContravariant[R[_, _], F[_], A, B]( implicit C: Contravariant[F], R: RefType[R], F: F[A] ): F[R[A, B]] = scalaz.derivation.refTypeViaContravariant[R, F, A, B] @deprecated("Generic derivation instances have been moved into the `derivation` object", "0.9.4") def refTypeMonadError[R[_, _], F[_], A, B]( implicit M: MonadError[F, String], R: RefType[R], V: Validate[A, B], F: F[A] ): F[R[A, B]] = scalaz.derivation.refTypeViaMonadError[R, F, A, B] }
Example 13
Source File: MacroUtils.scala From refined with MIT License | 5 votes |
package eu.timepit.refined.macros import eu.timepit.refined.api.{Refined, RefType} import scala.reflect.macros.blackbox import scala.util.{Success, Try} import shapeless.tag.@@ trait MacroUtils { val c: blackbox.Context import c.universe.weakTypeOf def abort(msg: String): Nothing = c.abort(c.enclosingPosition, msg) def eval[T](t: c.Expr[T]): T = { // Duplicate and untypecheck before calling `eval`, see: // http://www.scala-lang.org/api/2.12.0/scala-reflect/scala/reflect/macros/Evals.html#eval[T]%28expr:Evals.this.Expr[T]%29:T val expr = c.Expr[T](c.untypecheck(t.tree.duplicate)) // Try evaluating expr twice before failing, see // https://github.com/fthomas/refined/issues/3 tryN(2, c.eval(expr)) } def tryN[T](n: Int, t: => T): T = Stream.fill(n)(Try(t)).collectFirst { case Success(r) => r }.getOrElse(t) protected def refTypeInstance[F[_, _]](rt: c.Expr[RefType[F]]): RefType[F] = if (rt.tree.tpe =:= weakTypeOf[RefType[Refined]]) RefType.refinedRefType.asInstanceOf[RefType[F]] else if (rt.tree.tpe =:= weakTypeOf[RefType[@@]]) RefType.tagRefType.asInstanceOf[RefType[F]] else eval(rt) }
Example 14
Source File: InferMacro.scala From refined with MIT License | 5 votes |
package eu.timepit.refined.macros import eu.timepit.refined.api.Inference.==> import eu.timepit.refined.api.RefType import eu.timepit.refined.internal.Resources import scala.reflect.macros.blackbox class InferMacro(val c: blackbox.Context) extends MacroUtils { import c.universe._ def impl[F[_, _], T: c.WeakTypeTag, A: c.WeakTypeTag, B: c.WeakTypeTag](ta: c.Expr[F[T, A]])( rt: c.Expr[RefType[F]], ir: c.Expr[A ==> B] ): c.Expr[F[T, B]] = { val inference = eval(ir) if (inference.notValid) { abort(Resources.invalidInference(weakTypeOf[A].toString, weakTypeOf[B].toString)) } refTypeInstance(rt).unsafeRewrapM(c)(ta) } }
Example 15
Source File: LiteralMatchers.scala From refined with MIT License | 5 votes |
package eu.timepit.refined.macros import scala.reflect.macros.blackbox trait LiteralMatchers { val c: blackbox.Context import c.universe._ private[macros] object BigIntMatcher { def unapply(expr: c.Tree): Option[BigInt] = expr match { case q"scala.`package`.BigInt.apply(${lit: Literal})" => lit.value.value match { case i: Int => Some(BigInt(i)) case l: Long => Some(BigInt(l)) case s: String => scala.util.Try(BigInt(s)).toOption case _ => None } case _ => None } } private[macros] object BigDecimalMatcher { def unapply(expr: c.Tree): Option[BigDecimal] = { val constant = expr match { case q"scala.`package`.BigDecimal.apply(${lit: Literal})" => Some(lit.value.value) case q"scala.`package`.BigDecimal.exact(${lit: Literal})" => Some(lit.value.value) case q"scala.`package`.BigDecimal.valueOf(${lit: Literal})" => Some(lit.value.value) case _ => None } constant.flatMap { case i: Int => Some(BigDecimal(i)) case l: Long => Some(BigDecimal(l)) case d: Double => Some(BigDecimal(d)) case s: String => scala.util.Try(BigDecimal(s)).toOption case _ => None } } } }
Example 16
Source File: RefineMacro.scala From refined with MIT License | 5 votes |
package eu.timepit.refined.macros import eu.timepit.refined.api.{RefType, Validate} import eu.timepit.refined.char.{Digit, Letter, LowerCase, UpperCase, Whitespace} import eu.timepit.refined.collection.NonEmpty import eu.timepit.refined.internal.Resources import eu.timepit.refined.numeric.{Negative, NonNegative, NonPositive, Positive} import scala.reflect.macros.blackbox class RefineMacro(val c: blackbox.Context) extends MacroUtils with LiteralMatchers { import c.universe._ def impl[F[_, _], T: c.WeakTypeTag, P: c.WeakTypeTag](t: c.Expr[T])( rt: c.Expr[RefType[F]], v: c.Expr[Validate[T, P]] ): c.Expr[F[T, P]] = { val tValue: T = t.tree match { case Literal(Constant(value)) => value.asInstanceOf[T] case BigDecimalMatcher(value) => value.asInstanceOf[T] case BigIntMatcher(value) => value.asInstanceOf[T] case _ => abort(Resources.refineNonCompileTimeConstant) } val validate = validateInstance(v) val res = validate.validate(tValue) if (res.isFailed) { abort(validate.showResult(tValue, res)) } refTypeInstance(rt).unsafeWrapM(c)(t) } def implApplyRef[FTP, F[_, _], T: c.WeakTypeTag, P: c.WeakTypeTag](t: c.Expr[T])( ev: c.Expr[F[T, P] =:= FTP], rt: c.Expr[RefType[F]], v: c.Expr[Validate[T, P]] ): c.Expr[FTP] = c.Expr[FTP](impl(t)(rt, v).tree) private def validateInstance[T, P](v: c.Expr[Validate[T, P]])( implicit T: c.WeakTypeTag[T], P: c.WeakTypeTag[P] ): Validate[T, P] = validateInstances .collectFirst { case (tpeT, instancesForT) if tpeT =:= T.tpe => instancesForT.collectFirst { case (tpeP, validate) if tpeP =:= P.tpe => validate.asInstanceOf[Validate[T, P]] } } .flatten .getOrElse(eval(v)) private val validateInstances: List[(Type, List[(Type, Any)])] = { def instance[T, P](implicit P: c.WeakTypeTag[P], v: Validate[T, P]): (Type, Validate[T, P]) = P.tpe -> v List( weakTypeOf[Int] -> List( instance[Int, Positive], instance[Int, NonPositive], instance[Int, Negative], instance[Int, NonNegative] ), weakTypeOf[Long] -> List( instance[Long, Positive], instance[Long, NonPositive], instance[Long, Negative], instance[Long, NonNegative] ), weakTypeOf[Double] -> List( instance[Double, Positive], instance[Double, NonPositive], instance[Double, Negative], instance[Double, NonNegative] ), weakTypeOf[String] -> List( instance[String, NonEmpty] ), weakTypeOf[Char] -> List( instance[Char, Digit], instance[Char, Letter], instance[Char, LowerCase], instance[Char, UpperCase], instance[Char, Whitespace] ) ) } }
Example 17
Source File: virtualize.scala From spatial with MIT License | 5 votes |
package forge.tags import language.experimental.macros import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox val inputs = annottees.toList val outputs = inputs match { case (a:ValDef) :: as if a.mods.hasFlag(Flag.PARAM) => c.warning(c.enclosingPosition, "@virtualize cannot be used on parameters.") inputs case (_:TypeDef) :: as => c.warning(c.enclosingPosition, "@virtualize cannot be used on type aliases.") inputs case a :: as => runVirtualizer(a) ::: as case Nil => Nil } //info(showCode(outputs.head)) q"..$outputs" } }
Example 18
package forge.tags import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class rig extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro rig.impl } object rig { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val withCtx = ctx.impl(c)(annottees:_*) val withState = stateful.impl(c)(withCtx) withState } }
Example 19
Source File: rewrite.scala From spatial with MIT License | 5 votes |
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class rewrite extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro rewrite.impl } object rewrite { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import c.universe._ import util._ annottees.head match { case _:DefDef => case _ => c.error(c.enclosingPosition, "Rewrite can only be used on defs") } def incorrectSignature(): Unit = { c.error(c.enclosingPosition, "Rewrite def must have signature 'def name(rhs: T): Unit") } def noImplicitsAllowed(): Unit = { c.error(c.enclosingPosition, "Rewrite def cannot have implicit parameters") } def noTypeParametersAllowed(): Unit = { c.error(c.enclosingPosition, "Rewrite def cannot have type parameters") } val tree = api.impl(c)(annottees:_*) match { case d: DefDef => val paramss = d.paramss if (paramss.length != 2) incorrectSignature() else if (paramss.head.length != 1) incorrectSignature() else if (paramss(1).length != 2) noImplicitsAllowed() else if (d.tparams.nonEmpty) noTypeParametersAllowed() val arg0 = paramss.head.head val name = Literal(Constant(d.name.toString)) d.rhs match { case Match(_,_) => case _ => c.error(c.enclosingPosition, "Rewrite rule must be a partial function") } val pf = q"""val ${d.name}: PartialFunction[(Op[_],SrcCtx,State),Option[Sym[_]]] = {case (__op,__ctx,__state) => val ${arg0.name} = __op.asInstanceOf[${arg0.tp.get}]; implicit val ctx = __ctx; implicit val state = __state; val func: PartialFunction[Op[_],Sym[_]] = ${d.rhs} if (func.isDefinedAt(${arg0.name})) Some(func.apply(${arg0.name})) else None } """ val add = if (!showCode(arg0.tp.get).startsWith("Op[")) { q"""IR.rewrites.add[${arg0.tp.get}]($name,${d.name})""" } else { q"""IR.rewrites.addGlobal($name,${d.name})""" } q"$pf; $add" case t => invalidAnnotationUse("rewrite", "defs") t } //c.info(c.enclosingPosition, showCode(tree), force = true) tree } }
Example 20
Source File: stateful.scala From spatial with MIT License | 5 votes |
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.blackbox final class stateful extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro stateful.impl } private[forge] object stateful { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import util._ import c.universe._ def injectState(df: DefDef) = df.injectImplicit("state", tq"argon.State", tq"State") val tree = annottees.head match { case df: DefDef => injectState(df) case mf: ModuleDef => mf.mapMethods(injectState) case _ => invalidAnnotationUse("stateful", "objects", "defs") } tree } }
Example 21
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class ctx extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro ctx.impl } private[forge] object ctx { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import util._ import c.universe._ val tree = annottees.head match { case df: DefDef => df.injectImplicit("ctx", tq"forge.SrcCtx", tq"SrcCtx") case _ => invalidAnnotationUse("ctx", "defs") } tree } }
Example 22
Source File: AppTag.scala From spatial with MIT License | 5 votes |
package forge.tags import language.experimental.macros import scala.reflect.macros.blackbox class AppTag(dsl: String, dslApp: String) { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new Virtualizer[c.type](c) import util._ import c.universe._ val appType = Ident(TypeName(dslApp)) val inputs = annottees.toList val outputs: List[Tree] = inputs match { case (a:ValDef) :: as if !a.mods.hasFlag(Flag.PARAM) => runVirtualizer(a) ::: as case (a:DefDef) :: as => runVirtualizer(a) ::: as case (a:ClassDef) :: as => val mod = a.mixIn(appType) runVirtualizer(mod) ::: as case (a:ModuleDef) :: as => val mod = a.mixIn(appType) runVirtualizer(mod) ::: as case _ => invalidAnnotationUse(dsl, "classes", "objects", "traits", "defs") } //info(showCode(outputs.head)) q"..$outputs" } }
Example 23
Source File: curriedUpdate.scala From spatial with MIT License | 5 votes |
package forge.tags import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox class curriedUpdate extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro curriedUpdate.impl } object curriedUpdate { private val updateRenamed = "update$r" def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { import c.universe._ annottees.head match { case DefDef(mods, TermName(name), tparams, vparamss, tpt, rhs) => if (name.toString != "update") c.abort(c.enclosingPosition, "curriedUpdate can only be applied to the update method") if (vparamss.size != 3) c.abort(c.enclosingPosition, "curriedUpdate must have three argument list") if (vparamss.head.isEmpty) c.abort(c.enclosingPosition, "The first argument list must not be empty") if (vparamss(1).size != 1) c.abort(c.enclosingPosition, "The second argument list must have only one element") if (vparamss(2).size != 2) c.abort(c.enclosingPosition, "The third argument list must have two elements") val imprt = q"import scala.language.experimental.macros" val updateR = DefDef(mods, TermName(updateRenamed), tparams, vparamss, tpt, rhs) val updateC = if (mods.hasFlag(Flag.OVERRIDE)) { q"override def update(values: Any*): Unit = macro forge.tags.curriedUpdate.updateMacroDispatcher" } else { q"def update(values: Any*): Unit = macro forge.tags.curriedUpdate.updateMacroDispatcher" } val result = q"$imprt ; $updateR ; $updateC" //c.info(c.enclosingPosition, showCode(result), true) result case _ => c.abort(c.enclosingPosition, "curriedUpdate can only be applied on defs") } } def updateMacroDispatcher(c: blackbox.Context)(values: c.Tree*): c.Tree = { import c.universe._ val inds = values.take(values.size - 3) val value = values(values.size - 3) val ctx = values(values.size - 2) val state = values(values.size - 1) val self = c.prefix.tree q"$self.${TermName(updateRenamed)}(..$inds)($value)($ctx, $state)" } }
Example 24
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class mod extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro mod.impl } object mod { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import c.universe._ import util._ val tree = annottees.head match { case cls: ClassDef => val names = cls.constructorArgs.head.map(_.name) //cls.asCaseClass.injectMethod(q"final override def names = Seq(..$names)") cls case t => c.error(c.enclosingPosition, "@mod annotation can only be used on classes.") t } c.info(c.enclosingPosition, showCode(tree), force = true) tree } }
Example 25
Source File: flow.scala From spatial with MIT License | 5 votes |
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class flow extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro flow.impl } object flow { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import c.universe._ import util._ annottees.head match { case _:DefDef => case _ => c.error(c.enclosingPosition, "@flow can only be used on defs") } def incorrectSignature(): Unit = { c.error(c.enclosingPosition, "@flow def must have signature 'def name(lhs: Sym[_], rhs: Op[_]): Unit") } val tree = api.impl(c)(annottees:_*) match { case d: DefDef => val paramss = d.paramss if (paramss.length != 2) incorrectSignature() else if (paramss.head.length != 2) incorrectSignature() val arg0 = paramss.head.apply(0) val arg1 = paramss.head.apply(1) if (!arg0.tp.exists{t => isWildcardType(t, "Sym") } || !arg1.tp.exists{t => isWildcardType(t, "Op")}) { incorrectSignature() } val name = Literal(Constant(d.name.toString)) val pf = q"""val ${d.name}: PartialFunction[(Sym[_],Op[_],forge.SrcCtx,argon.State),Unit] = {case (__sym,__op,__ctx,__state) => val ${arg0.name} = __sym; val ${arg1.name} = __op; implicit val ctx = __ctx; implicit val state = __state; ${d.rhs} } """ val add = q""" IR.flows.add($name,${d.name}) """ q"$pf; $add" case t => __c.error(__c.enclosingPosition, "@flow can only be used on defs") t } //c.info(c.enclosingPosition, showCode(tree), force = true) tree } }
Example 26
Source File: globalRewrite.scala From spatial with MIT License | 5 votes |
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class globalRewrite extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro globalRewrite.impl } object globalRewrite { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import c.universe._ import util._ annottees.head match { case _:DefDef => case _ => c.error(c.enclosingPosition, "@globalRewrite can only be used on defs") } def incorrectSignature(): Unit = { c.error(c.enclosingPosition, "@globalRewrite def must have signature 'def name(rhs: T): Unit") } def noImplicitsAllowed(): Unit = { c.error(c.enclosingPosition, "@globalRewrite def cannot have implicit parameters") } def noTypeParametersAllowed(): Unit = { c.error(c.enclosingPosition, "@globalRewrite def cannot have type parameters") } val tree = api.impl(c)(annottees:_*) match { case d: DefDef => val paramss = d.paramss if (paramss.length != 2) incorrectSignature() else if (paramss.head.length != 1) incorrectSignature() else if (paramss(1).length != 2) noImplicitsAllowed() else if (d.tparams.nonEmpty) noTypeParametersAllowed() val arg0 = paramss.head.head val name = Literal(Constant(d.name.toString)) d.rhs match { case Match(_,_) => case _ => c.error(c.enclosingPosition, "@globalRewrite rule must be a partial function") } val pf = q"""val ${d.name}: PartialFunction[(Op[_],SrcCtx,State),Option[Sym[_]]] = {case (__op,__ctx,__state) => if (__op.isInstanceOf[${arg0.tp.get}]) { val ${arg0.name} = __op.asInstanceOf[${arg0.tp.get}]; implicit val ctx = __ctx; implicit val state = __state; val func: PartialFunction[Op[_],Sym[_]] = ${d.rhs} if (func.isDefinedAt(${arg0.name})) Some(func.apply(${arg0.name})) else None } else None } """ val add = q""" core.rewrites.addGlobal($name,${d.name}) """ q"$pf; $add" case t => c.error(c.enclosingPosition, "@globalRewrite can only be used on defs") t } c.info(c.enclosingPosition, showCode(tree), force = true) tree } }
Example 27
Source File: SrcCtxMacro.scala From spatial with MIT License | 5 votes |
package forge.tags import forge.SrcCtx import scala.reflect.macros.blackbox import scala.language.experimental.macros object SrcCtxMacro { def impl(c: blackbox.Context): c.Expr[SrcCtx] = { import c.universe._ val pos = c.enclosingPosition val path = pos.source.path val filename = pos.source.file.name val line = pos.line val column = pos.column val lineContent = if (line > 0) Some(pos.source.lineToString(line-1)) else None c.Expr(q"forge.SrcCtx($path, $filename, $line, $column, $lineContent)") } }
Example 28
Source File: data.scala From spatial with MIT License | 5 votes |
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class data extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro data.impl } object data { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val utils = new MacroUtils(c) import utils._ import c.universe._ annottees.head match { case _:ModuleDef => stateful.impl(c)(annottees:_*) case _ => invalidAnnotationUse("data", "objects") } } }
Example 29
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class api extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro api.impl } private[forge] object api { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val utils = new MacroUtils[c.type](c) import utils._ import c.universe._ annottees.head match { case df: DefDef => val withCtx = ctx.impl(c)(annottees:_*) val withState = stateful.impl(c)(withCtx) withState case _ => invalidAnnotationUse("api", "defs") } } }
Example 30
package forge.tags import utils.tags.MacroUtils import language.experimental.macros import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox object ref { def implement(c: blackbox.Context)(cls: c.universe.ClassDef, obj: c.universe.ModuleDef): (c.universe.ClassDef, c.universe.ModuleDef) = { val util = new MacroUtils[c.type](c) import util._ import c.universe._ val (vargs,iargs) = cls.constructorArgs match { case List(v,i) if i.isImplicit => (v,i) case List(v) => (v, Nil) case _ => c.abort(c.enclosingPosition, "Ref classes can have at most one explicit and one implicit parameter list") } // TODO[5]: Should check that @ref class A mixes in Ref[?,A] val name = cls.name val tparams = cls.tparams val targs = cls.typeArgs val vnames = vargs.map(_.name) val inames = iargs.map(_.name) val cnames = vnames ++ inames val fullName = targsType(name, targs) val cls2 = cls.injectMethod(q"private def cargs: Seq[Any] = Seq(..$cnames)".asDef) .injectMethod(q"override protected def fresh = new $name[..$targs](..$vnames)".asDef) .injectField(q"override protected val __typePrefix = ${cls.nameLiteral}".asVal) .injectField(q"override protected val __typeArgs = cargs.collect{case t: argon.Type[_] => t}".asVal) .injectField(q"override protected val __typeParams = Seq(..$inames).filter{case t: argon.Type[_] => false; case _ => true}".asVal) val obj2 = (vargs, iargs) match { case (Nil,Nil) => obj.injectField(q"implicit val tp: $fullName = argon.proto(new $name[..$targs])".asVal) case (Nil, _) => obj.injectMethod(q"implicit def tp[..$tparams](..$iargs): $fullName = argon.proto(new $name[..$targs]()(..$inames))".asDef) case (_, Nil) => obj.injectMethod(q"def tp[..$tparams](..$vargs): $fullName = argon.proto(new $name[..$targs](..$vnames))".asDef) case _ => obj.injectMethod(q"def tp[..$tparams](..$vargs)(..$iargs): $fullName = argon.proto(new $name[..$targs](..$vnames)(..$inames))".asDef) } (cls2, obj2) } def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import util._ import c.universe._ val (cls,obj) = annottees.toList match { case List(cd: ClassDef, md: ModuleDef) => (cd,md) case List(cd: ClassDef) => (cd, q"object ${cd.nameTerm}".asObject) case _ => invalidAnnotationUse("ref", "classes") } val (cls2, obj2) = implement(c)(cls, obj) //c.info(c.enclosingPosition, showCode(cls2), force = true) //c.info(c.enclosingPosition, showCode(obj2), force = true) q"..${List(cls2,obj2)}" } }
Example 31
package forge.tags import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.blackbox final class op extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro op.impl } object op { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import c.universe._ import util._ val (cls,obj) = annottees.toList match { case List(cd: ClassDef, md: ModuleDef) => (cd,md) case List(cd: ClassDef) => (cd, q"object ${cd.nameTerm}".asObject) case _ => invalidAnnotationUse("op", "classes") } val name = cls.name val names = cls.constructorArgs.head.map(_.name) val types = cls.constructorArgs.head.map(_.tp.get) val targs = cls.typeArgs val fnames = names.map{name => q"$$f($name)" } val updates = names.zip(fnames).map{case (name,fname) => q"$name = $fname" } val cls2 = cls.asCaseClass.withVarParams .injectMethod(q"override def mirror($$f:Tx) = new $name[..$targs](..$fnames)".asDef) .injectMethod(q"override def update($$f:Tx) = { ..$updates }".asDef) val obj2 = obj // TODO[5]: Not clear how this would be typed, or if its even an intuitive extractor //c.info(c.enclosingPosition, showCode(cls2), force = true) q"..${List(cls2,obj2)}" } }
Example 32
Source File: instrument.scala From spatial with MIT License | 5 votes |
package utils.tags import scala.annotation.StaticAnnotation import scala.reflect.macros.blackbox import scala.language.experimental.macros final class instrument extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro instrument.impl } private[utils] object instrument { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val util = new MacroUtils[c.type](c) import util._ import c.universe._ def instrument(df: DefDef): DefDef = { if (df.body != EmptyTree) df.modifyBody{body => q"instrument(${df.nameLiteral}){ $body }"} else df } val tree = annottees.head match { case cls: ClassDef => cls.mapMethods(m => instrument(m)).mixIn(tq"utils.Instrumented") case obj: ModuleDef => obj.mapMethods(m => instrument(m)).mixIn(tq"utils.Instrumented") case _ => invalidAnnotationUse("@instrument", "objects", "defs") } //c.info(c.enclosingPosition, showCode(tree), force = true) tree } }
Example 33
Source File: StreamStructs.scala From spatial with MIT License | 5 votes |
package spatial.tags import argon.tags import argon.tags.{Arith, Bits} import utils.tags.MacroUtils import scala.annotation.StaticAnnotation import scala.language.experimental.macros import scala.reflect.macros.blackbox abstract class TypeclassMacro[Ctx <: blackbox.Context](val c: Ctx) { import c.universe._ def implement(cls: ClassDef, obj: ModuleDef, fields: Seq[ValDef]): (ClassDef,ModuleDef) } object StagedStreamStructsMacro { def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = { val typeclasses: Seq[tags.TypeclassMacro[c.type]] = Seq( new Bits[c.type](c), new Arith[c.type](c) ) val utils = new MacroUtils[c.type](c) import c.universe._ import utils._ val (cls,obj) = annottees.toList match { case List(cd: ClassDef, md: ModuleDef) => (cd,md) case List(cd: ClassDef) => (cd, q"object ${cd.nameTerm}".asObject) case _ => invalidAnnotationUse("streamstruct", "classes") } val fields = cls.constructorArgs.head val methods = cls.nonConstructorMethods.filterNot{_.mods.hasFlag(Flag.CASEACCESSOR) } val parents: Seq[String] = cls.parents.collect{case Ident(TypeName(name)) => name } // TODO[5]: What to do if class has parents? Error? if (fields.isEmpty) abort("Classes need at least one field in order to be transformed into a @streamstruct.") if (methods.nonEmpty) { error(s"@streamstruct class had ${methods.length} disallowed methods:\n" + methods.map{method => " " + showCode(method.modifyBody(_ => EmptyTree)) }.mkString("\n")) abort("@streamstruct classes with methods are not yet supported") } if (cls.tparams.nonEmpty) abort("@streamstruct classes with type parameters are not yet supported") if (cls.fields.exists(_.isVar)) abort("@streamstruct classes with var fields are not yet supported") val fieldTypes = fields.map{field => q"${field.nameLiteral} -> argon.lang.Bits[${field.tpTree}]" } val fieldNames = fields.map{field => q"${field.nameLiteral} -> ${field.name}"} val fieldOpts = fields.map{field => field.withRHS(q"null") } val fieldOrElse = fields.map{field => q"Option(${field.name}).getOrElse{this.${field.name}(ctx,state)}" } var cls2 = q"class ${cls.name}[..${cls.tparams}]() extends spatial.lang.StreamStruct[${cls.fullName}]".asClass var obj2 = obj fields.foreach{field => cls2 = cls2.injectMethod( q"""def ${field.name}(implicit ctx: forge.SrcCtx, state: argon.State): ${field.tpTree} = { field[${field.tpTree}](${field.nameLiteral})(argon.lang.Bits[${field.tpTree}],ctx,state) }""".asDef) } cls2 = { cls2.injectField(q"lazy val fields = Seq(..$fieldTypes)".asVal) .mixIn(tq"argon.Ref[Any,${cls.fullName}]") .injectMethod( q"""def copy(..$fieldOpts)(implicit ctx: forge.SrcCtx, state: argon.State): ${cls.fullName} = { ${obj2.name}.apply(..$fieldOrElse)(ctx, state) }""".asDef) .injectField(q"""override val box = implicitly[${cls.fullName} <:< ( spatial.lang.StreamStruct[${cls.fullName}] with argon.lang.types.Bits[${cls.fullName}] with argon.lang.types.Arith[${cls.fullName}]) ]""".asVal) } obj2 = { obj2.injectMethod( q"""def apply[..${cls.tparams}](..$fields)(implicit ctx: forge.SrcCtx, state: argon.State): ${cls.fullName} = { spatial.lang.StreamStruct[${cls.fullName}]( ..$fieldNames )(spatial.lang.StreamStruct.tp[${cls.fullName}], ctx, state) } """.asDef) } val (cls3,obj3) = typeclasses.foldRight((cls2,obj2)){case (tc, (c,o)) => tc.implement(c, o, fields) } val (cls4, obj4) = forge.tags.ref.implement(c)(cls3, obj3) val out = q"$cls4; $obj4" //info(showRaw(out)) //info(showCode(out)) out } }
Example 34
Source File: Bits.scala From spatial with MIT License | 5 votes |
package argon.tags import utils.tags.MacroUtils import scala.language.experimental.macros import scala.reflect.macros.blackbox class Bits[Ctx <: blackbox.Context](override val c: Ctx) extends TypeclassMacro[Ctx](c) { import c.universe._ def implement(cls: ClassDef, obj: ModuleDef, fields: Seq[ValDef]): (ClassDef, ModuleDef) = { val utils = new MacroUtils[c.type](c) import c.universe._ import utils._ val fieldTypes = fields.map(_.tpTree) val fieldNames = fields.map(_.name) val bitssOpt = fieldTypes.map{tp => q"new argon.static.ExpTypeLowPriority(argon.Type[$tp]).getView[argon.lang.types.Bits]" } val bitss = bitssOpt.map{bits => q"$bits.get" } val nbitss = bitss.map{bits => q"$bits.nbits(ctx,state)" } val zeros = bitss.map{bits => q"$bits.zero(ctx,state)" } val ones = bitss.map{bits => q"$bits.one(ctx,state)" } val maxes = fieldNames.zip(bitss).map{case (name,bits) => q"$bits.random(max.map(_.$name(ctx,state)))(ctx,state)"} val clsName = cls.fullName val cls2 = { cls.mixIn(tq"Bits[$clsName]") .injectMethod( q"""private def bitsCheck(op: java.lang.String)(func: => ${cls.fullName})(implicit ctx: forge.SrcCtx, state: argon.State): ${cls.fullName} = { val bitsOpt = List(..$bitssOpt) if (!bitsOpt.forall(_.isDefined)) { argon.error(ctx, s"$$op not defined for $${this.tp}")(state) argon.error(ctx)(state) argon.err[${cls.fullName}](s"$$op not defined for $${this.tp}")(argon.Type[${cls.fullName}],state) } else func }""".asDef) .injectMethod( q"""def nbits(implicit ctx: forge.SrcCtx, state: argon.State): scala.Int = { val bitsOpt = List(..$bitssOpt) if (!bitsOpt.forall(_.isDefined)) { argon.error(ctx, s"nbits is not defined for $${this.tp}")(state) argon.error(ctx)(state) 0 } else List(..$nbitss).sum }""".asDef) .injectMethod(q"""def zero(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = bitsCheck("zero"){ ${obj.name}.apply(..$zeros)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def one(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = bitsCheck("one"){ ${obj.name}.apply(..$ones)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def random(max: Option[$clsName])(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = bitsCheck("random"){ ${obj.name}.apply(..$maxes)(ctx,state) }(ctx,state)""".asDef) } val obj2 = obj (cls2, obj2) } }
Example 35
Source File: Arith.scala From spatial with MIT License | 5 votes |
package argon.tags import utils.tags.MacroUtils import scala.language.experimental.macros import scala.reflect.macros.blackbox class Arith[Ctx <: blackbox.Context](override val c: Ctx) extends TypeclassMacro[Ctx](c) { import c.universe._ def implement(cls: ClassDef, obj: ModuleDef, fields: Seq[ValDef]): (ClassDef, ModuleDef) = { val utils = new MacroUtils[c.type](c) import c.universe._ import utils._ val fieldTypes = fields.map(_.tpTree) val fieldNames = fields.map(_.name) val arithOpt = fieldTypes.map{tp => q"new argon.static.ExpTypeLowPriority(argon.Type[$tp]).getView[argon.lang.types.Arith]" } val arith = arithOpt.map{a => q"$a.get" } val fieldPairs = fieldNames.zip(arith) val neg = fieldPairs.map{case (name,a) => q"$a.neg(this.$name(ctx,state))(ctx,state)"} val add = fieldPairs.map{case (name,a) => q"$a.add(this.$name(ctx,state),that.$name(ctx,state))(ctx,state)" } val sub = fieldPairs.map{case (name,a) => q"$a.sub(this.$name(ctx,state),that.$name(ctx,state))(ctx,state)" } val mul = fieldPairs.map{case (name,a) => q"$a.mul(this.$name(ctx,state),that.$name(ctx,state))(ctx,state)" } val div = fieldPairs.map{case (name,a) => q"$a.div(this.$name(ctx,state),that.$name(ctx,state))(ctx,state)" } val mod = fieldPairs.map{case (name,a) => q"$a.mod(this.$name(ctx,state),that.$name(ctx,state))(ctx,state)" } val abs = fieldPairs.map{case (name,a) => q"$a.abs(a.$name(ctx,state))(ctx,state)" } val ceil = fieldPairs.map{case (name,a) => q"$a.ceil(a.$name(ctx,state))(ctx,state)" } val floor = fieldPairs.map{case (name,a) => q"$a.floor(a.$name(ctx,state))(ctx,state)" } val clsName = cls.fullName val cls2 = { cls.mixIn(tq"Arith[$clsName]") .injectMethod( q"""private def __arith(op: java.lang.String)(func: => ${cls.fullName})(implicit ctx: forge.SrcCtx, state: argon.State): ${cls.fullName} = { val arithOpt = List(..$arithOpt) if (!arithOpt.forall(_.isDefined) || arithOpt.exists(_ eq null)) { argon.error(ctx, op + " not defined for " + this.tp)(state) argon.error(ctx)(state) argon.err[${cls.fullName}](op + " not defined for " + this.tp)(argon.Type[${cls.fullName}],state) } else func }""".asDef) .injectMethod(q"""def unary_-()(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("negate"){ ${obj.name}.apply(..$neg)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def +(that: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("+"){ ${obj.name}.apply(..$add)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def -(that: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("-"){ ${obj.name}.apply(..$sub)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def *(that: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("*"){ ${obj.name}.apply(..$mul)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def /(that: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("/"){ ${obj.name}.apply(..$div)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def %(that: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("%"){ ${obj.name}.apply(..$mod)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def abs(a: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("abs"){ ${obj.name}.apply(..$abs)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def ceil(a: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("ceil"){ ${obj.name}.apply(..$ceil)(ctx,state) }(ctx,state)""".asDef) .injectMethod(q"""def floor(a: $clsName)(implicit ctx: forge.SrcCtx, state: argon.State): $clsName = __arith("floor"){ ${obj.name}.apply(..$floor)(ctx,state) }(ctx,state)""".asDef) } val obj2 = obj (cls2, obj2) } }
Example 36
Source File: ProtoMacrosCirce.scala From scalapb-circe with MIT License | 5 votes |
package scalapb_circe import scalapb.{GeneratedMessage, GeneratedMessageCompanion} import scala.reflect.macros.blackbox import language.experimental.macros import scala.util.Try object ProtoMacrosCirce { implicit class ProtoContextCirce(private val c: StringContext) extends AnyVal { def struct(): com.google.protobuf.struct.Struct = macro ProtoMacrosCirce.protoStructInterpolation def value(): com.google.protobuf.struct.Value = macro ProtoMacrosCirce.protoValueInterpolation } implicit class FromJsonCirce[A <: GeneratedMessage]( private val companion: GeneratedMessageCompanion[A] ) extends AnyVal { def fromJsonConstant(json: String): A = macro ProtoMacrosCirce.fromJsonConstantImpl0[A] def fromJson(json: String): A = macro ProtoMacrosCirce.fromJsonImpl[A] def fromJsonDebug(json: String): A = macro ProtoMacrosCirce.fromJsonDebugImpl def fromJsonOpt(json: String): Option[A] = macro ProtoMacrosCirce.fromJsonOptImpl[A] def fromJsonEither(json: String): Either[Throwable, A] = macro ProtoMacrosCirce.fromJsonEitherImpl[A] def fromJsonTry(json: String): Try[A] = macro ProtoMacrosCirce.fromJsonTryImpl[A] } } class ProtoMacrosCirce(override val c: blackbox.Context) extends scalapb_json.ProtoMacrosCommon(c) { import c.universe._ override def fromJsonImpl[A: c.WeakTypeTag](json: c.Tree): c.Tree = { val A = weakTypeTag[A] q"_root_.scalapb_circe.JsonFormat.fromJsonString[$A]($json)" } override def fromJsonConstantImpl[A <: GeneratedMessage: c.WeakTypeTag: GeneratedMessageCompanion]( string: String ): c.Tree = { val A = weakTypeTag[A] scalapb_circe.JsonFormat.fromJsonString[A](string) q"_root_.scalapb_circe.JsonFormat.fromJsonString[$A]($string)" } private[this] def parseJson(json: String): io.circe.Json = { io.circe.parser.parse(json).fold(throw _, identity) } override protected[this] def protoString2Struct(string: String): c.Tree = { val json = parseJson(string) val struct = StructFormat.structParser(json) q"$struct" } override protected[this] def protoString2Value(string: String): c.Tree = { val json = parseJson(string) val value = StructFormat.structValueParser(json) q"$value" } }
Example 37
Source File: StyleMacros.scala From udash-core with Apache License 2.0 | 5 votes |
package io.udash.css.macros import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.blackbox class StyleMacros(override val c: blackbox.Context) extends AbstractMacroCommons(c) { import c.universe._ val Package = q"_root_.io.udash.css" val StyleCls = tq"$Package.CssStyle" val StyleNameCls = tq"$Package.CssStyleName" val StyleImplCls = tq"$Package.CssStyleImpl" val KeyframesCls = tq"$Package.CssKeyframes" val FontFaceCls = tq"$Package.CssFontFace" val Dsl = q"scalacss.internal.Dsl" val Compose = q"scalacss.internal.Compose" val FontSrcSelector = tq"scalacss.internal.FontFace.FontSrcSelector" private def handleScalaJs(name: Tree, other: Tree): Tree = if (isScalaJs) { q"""new $StyleNameCls($name)""" } else other private def style(name: Tree, impl: Tree*): c.Tree = handleScalaJs(name, q""" { val tmp = new $StyleImplCls($name, $Dsl.style(..$impl)($Compose.trust)) ${c.prefix}.elementsBuffer += tmp tmp } """) def mixin(impl: Tree*): Tree = { val fullName = c.internal.enclosingOwner.fullName.replace('.', '-') handleScalaJs(q"$fullName", q"""new $StyleImplCls($fullName, $Dsl.style(..$impl)($Compose.trust))""") } def style(impl: Tree*): Tree = { val fullName = c.internal.enclosingOwner.fullName.replace('.', '-') style(q"$fullName", impl: _*) } def namedStyle(className: Tree, impl: Tree*): Tree = style(className, impl: _*) private def keyframes(name: Tree, impl: Tree*): Tree = handleScalaJs(name, q""" { val tmp = new $KeyframesCls($name, Seq(..$impl).map { case (p, s) => (p, $Dsl.style(s: _*)($Compose.trust)) } ) ${c.prefix}.elementsBuffer += tmp tmp } """) def keyframes(impl: Tree*): Tree = { val fullName = c.internal.enclosingOwner.fullName.replace('.', '-') keyframes(q"$fullName", impl: _*) } def namedKeyframes(className: Tree, impl: Tree*): Tree = keyframes(className, impl: _*) private def fontFace(name: Tree, font: Tree): Tree = handleScalaJs(name, q""" { val tmp = new $FontFaceCls($name, $font.apply(new $FontSrcSelector(None))) ${c.prefix}.elementsBuffer += tmp tmp } """) def fontFace(font: Tree): Tree = { val fullName = c.internal.enclosingOwner.fullName.replace('.', '-') fontFace(q"$fullName", font) } def nameFontFace(className: Tree, font: Tree): Tree = fontFace(className, font) }
Example 38
Source File: AllValuesMacro.scala From udash-core with Apache License 2.0 | 5 votes |
package io.udash package macros import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.blackbox // Although published within `macros` module, this macro is not intended to be used outside udash-core codebase. private[udash] class AllValuesMacro(override val c: blackbox.Context) extends AbstractMacroCommons(c) { import c.universe._ def ofType[V: WeakTypeTag](obj: Tree): Tree = { val valueType = weakTypeOf[V] val names = accessibleMembers(obj.tpe).iterator.filter { s => (s.isMethod || s.isModule) && s.typeSignature.paramLists.iterator.flatten.isEmpty && s.typeSignature.typeParams.isEmpty && s.typeSignatureIn(obj.tpe).finalResultType <:< valueType }.map(_.name.toTermName).toVector val objName = c.freshName(TermName("obj")) q""" val $objName = $obj $ListObj[$valueType](..${names.map(n => q"$objName.$n")}) """ } }
Example 39
Source File: TestMacros.scala From udash-core with Apache License 2.0 | 5 votes |
package io.udash package macros import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.{TypecheckException, blackbox} class TestMacros(val ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ private def stringLiteral(tree: Tree): String = tree match { case StringLiteral(str) => str case Select(StringLiteral(str), TermName("stripMargin")) => str.stripMargin case _ => abort(s"expected string literal, got $tree") } def typeErrorImpl(code: Tree): Tree = { val codeTree = c.parse(stringLiteral(code)) try { c.typecheck(codeTree) abort("expected typechecking error, none was raised") } catch { case TypecheckException(_, msg) => q"$msg" } } }
Example 40
Source File: compiletime.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless.test import scala.language.experimental.macros import scala.concurrent.duration.FiniteDuration import scala.reflect.macros.blackbox object compileTime { def apply(code: String): FiniteDuration = macro CompileTimeMacros.applyImpl } @macrocompat.bundle class CompileTimeMacros(val c: blackbox.Context) { import c.universe._ def applyImpl(code: Tree): Tree = { def wallClock(codeStr: String): Long = { try { val t1 = System.nanoTime() c.typecheck(c.parse(codeStr)) val t2 = System.nanoTime() t2 - t1 } catch { case ex: Exception => c.abort(c.enclosingPosition, ex.getMessage) } } val Literal(Constant(codeStr: String)) = code val elapsedTime = wallClock(codeStr) q"_root_.scala.concurrent.duration.Duration.fromNanos($elapsedTime)" } }
Example 41
Source File: MacroBase.scala From scalajs-angulate with MIT License | 5 votes |
// - Project: scalajs-angulate (https://github.com/jokade/scalajs-angulate) // Description: Provides a base class for macros with common utility functions // // Distributed under the MIT License (see included file LICENSE) package biz.enef.angulate.impl import acyclic.file import biz.enef.angulate.named import scala.reflect.macros.blackbox protected[angulate] abstract class MacroBase { val c: blackbox.Context import c.universe._ protected[this] def createDIArray(ct: Type) = { val m = getConstructor(ct) val deps = getDINames(m) val (params,args) = makeArgsList(m) q"""js.Array[Any](..$deps, ((..$params) => new $ct(..$args)):js.Function)""" } protected[this] def getConstructor(ct: Type) = ct.decls.filter( _.isConstructor ).collect{ case m: MethodSymbol => m}.head // TODO: support DI name annotations protected[this] def createFunctionDIArray(t: c.Tree) = { val (f,params) = analyzeFunction(t) val diNames = params.map( p => p._2.toString ) q"js.Array[Any](..$diNames, $f:js.Function)" } protected[this] def analyzeFunction(t: c.Tree) = { val (m:Tree,params:List[ValDef]) = t match { case q"(..$params) => $body" => (t,params) case q"{(..$params) => $body}" => (t.children.head,params) } val args = params.map{ p => val q"$mods val $name: $tpe = $rhs" = p (mods,name,tpe,rhs) } (m,args) } }
Example 42
Source File: LoggerMacros.scala From log4cats with Apache License 2.0 | 5 votes |
package io.chrisdavenport.log4cats.slf4j.internal import scala.annotation.tailrec import scala.reflect.macros.blackbox loggerBySymbolName(s) } else { val typeArgs = List.fill(typeParams.length)(WildcardType) val typeConstructor = tq"$typeSymbol[..${typeArgs}]" loggerByParam(q"_root_.scala.Predef.classOf[$typeConstructor]") } } } @inline def isInnerClass(s: Symbol) = s.isClass && !(s.owner.isPackage) val instanceByName = Slf4jLoggerInternal.singletonsByName && (cls.isModule || cls.isModuleClass) || cls.isClass && isInnerClass( cls ) if (instanceByName) { loggerBySymbolName(cls) } else { loggerByType(cls) } } }
Example 43
Source File: ScribeMacros.scala From scribe with MIT License | 5 votes |
package scribe import scala.annotation.compileTimeOnly import scala.collection.mutable.ListBuffer import scala.language.experimental.macros import scala.reflect.macros.blackbox @compileTimeOnly("Enable macros to expand") object ScribeMacros { def formatter(c: blackbox.Context)(args: c.Tree*): c.Tree = { import c.universe._ c.prefix.tree match { case Apply(_, List(Apply(_, rawParts))) => { val parts = rawParts map { case t @ Literal(Constant(const: String)) => (const, t.pos) } val list = ListBuffer.empty[c.Tree] val argsVector = args.toVector parts.zipWithIndex.foreach { case ((raw, _), index) => { if (raw.nonEmpty) { list += q"_root_.scribe.format.FormatBlock.RawString($raw)" } if (index < argsVector.size) { list += argsVector(index) } } } q"_root_.scribe.format.Formatter.fromBlocks(..$list)" } case _ => c.abort(c.enclosingPosition, "Bad usage of formatter interpolation.") } } }
Example 44
Source File: ShouldNotTypecheck.scala From lagom with Apache License 2.0 | 5 votes |
package com.lightbend.lagom.macrotestkit import scala.language.experimental.macros import java.util.regex.Pattern import scala.reflect.macros.TypecheckException import scala.reflect.macros.blackbox object ShouldNotTypecheck { def apply(name: String, code: String): Unit = macro ShouldNotTypecheck.applyImplNoExp def apply(name: String, code: String, expected: String): Unit = macro ShouldNotTypecheck.applyImpl } final class ShouldNotTypecheck(val c: blackbox.Context) { import c.universe._ def applyImplNoExp(name: Expr[String], code: Expr[String]): Expr[Unit] = applyImpl(name, code, c.Expr(EmptyTree)) def applyImpl(name: Expr[String], code: Expr[String], expected: Expr[String]): Expr[Unit] = { val Expr(Literal(Constant(codeStr: String))) = code val Expr(Literal(Constant(nameStr: String))) = name val (expPat, expMsg) = expected.tree match { case EmptyTree => (Pattern.compile(".*"), "Expected some error.") case Literal(Constant(s: String)) => (Pattern.compile(s, Pattern.CASE_INSENSITIVE), "Expected error matching: " + s) } try c.typecheck(c.parse("{ " + codeStr + " }")) catch { case e: TypecheckException => val msg = e.getMessage if (!expPat.matcher(msg).matches) { c.abort(c.enclosingPosition, s"$nameStr failed in an unexpected way.\n$expMsg\nActual error: $msg") } else { println(s"$nameStr passed.") return reify(()) } } c.abort(c.enclosingPosition, s"$nameStr succeeded unexpectedly.\n$expMsg") } }
Example 45
Source File: ScaladslServerMacroImpl.scala From lagom with Apache License 2.0 | 5 votes |
package com.lightbend.lagom.internal.scaladsl.server import com.lightbend.lagom.internal.scaladsl.client.ScaladslClientMacroImpl import com.lightbend.lagom.scaladsl.api.Descriptor import com.lightbend.lagom.scaladsl.api.Service import com.lightbend.lagom.scaladsl.server.LagomServer import com.lightbend.lagom.scaladsl.server.LagomServiceBinder import scala.reflect.macros.blackbox private[lagom] class ScaladslServerMacroImpl(override val c: blackbox.Context) extends ScaladslClientMacroImpl(c) { import c.universe._ val server = q"_root_.com.lightbend.lagom.scaladsl.server" def simpleBind[T <: Service](serviceFactory: Tree)(implicit serviceType: WeakTypeTag[T]): Expr[LagomServer] = { val binder = createBinder[T] c.Expr[LagomServer](q"""{ $server.LagomServer.forService( $binder.to($serviceFactory) ) } """) } def readDescriptor[T <: Service](implicit serviceType: WeakTypeTag[T]): Expr[Descriptor] = { val extracted = validateServiceInterface[T](serviceType) val serviceMethodImpls: Seq[Tree] = (extracted.serviceCalls ++ extracted.topics).map { serviceMethod => val methodParams = serviceMethod.paramLists.map { paramList => paramList.map(param => q"${param.name.toTermName}: ${param.typeSignature}") } q""" override def ${serviceMethod.name}(...$methodParams) = { throw new _root_.scala.NotImplementedError("Service methods and topics must not be invoked from service trait") } """ } match { case Seq() => Seq(EmptyTree) case s => s } c.Expr[Descriptor](q""" new ${serviceType.tpe} { ..$serviceMethodImpls }.descriptor """) } }
Example 46
Source File: DeriveMacroSupport.scala From sangria with Apache License 2.0 | 5 votes |
package sangria.macros.derive import scala.reflect.internal.{StdNames, SymbolTable, Definitions} import scala.reflect.macros.blackbox trait DeriveMacroSupport { val c: blackbox.Context val universe: c.universe.type = c.universe import c.universe._ def reportErrors(errors: Seq[(Position, String)]) = { require(errors.nonEmpty) val (lastPos, lastError) = errors.last errors.dropRight(1).foreach{case (pos, error) => c.error(pos, error)} c.abort(lastPos, lastError) } protected def symbolName(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLName] => arg} .headOption protected def symbolOutputType(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLOutputType] => arg} .headOption protected def symbolInputType(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLInputType] => arg} .headOption protected def symbolDescription(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLDescription] => arg} .headOption protected def symbolDefault(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLDefault] => arg} .headOption protected def symbolDeprecation(annotations: List[Annotation]): Option[Tree] = annotations .map (_.tree) .collect {case q"new $name($arg)" if name.tpe =:= typeOf[GraphQLDeprecated] => arg} .headOption protected def symbolFieldTags(annotations: List[Annotation]): Tree = annotations .map (_.tree) .foldLeft(q"List[sangria.execution.FieldTag]()") { case (acc, q"new $name(..$fieldTags)") if name.tpe =:= typeOf[GraphQLFieldTags] => q"$acc ++ $fieldTags" case (acc, _) => acc } protected def memberExcluded(annotations: List[Annotation]): Boolean = annotations.find(_.tree.tpe =:= typeOf[GraphQLExclude]).fold(false)(_ => true) protected def memberField(annotations: List[Annotation]): Boolean = annotations.find(_.tree.tpe =:= typeOf[GraphQLField]).fold(false)(_ => true) // TODO: most probably not needed, so should be removed in future protected def defaultMethodArgValue(method: String, pos: Int) = { val defs = c.universe.asInstanceOf[Definitions with SymbolTable with StdNames] defs.nme.defaultGetterName(defs.newTermName(method), pos) } def checkSetting[T : WeakTypeTag](setting: Tree) = weakTypeTag[T].tpe =:= c.typecheck(setting).tpe }
Example 47
Source File: ParseMacro.scala From sangria with Apache License 2.0 | 5 votes |
package sangria.macros import sangria.parser.{SyntaxError, QueryParser} import scala.reflect.macros.blackbox class ParseMacro(context: blackbox.Context) extends { val c = context } with MacroAstLiftable { import c.universe._ def impl(args: Expr[Any]*) = if (args.nonEmpty) c.abort(c.enclosingPosition, "String interpolation is not supported for `graphql`/`gql` macro at the moment.") else c.prefix.tree match { // Expects a string interpolation that doesn't contain any // expressions, thus containing only a single tree case Apply(_, List(Apply(_, t :: Nil))) => val q"${gql: String}" = t try { q"${QueryParser.parse(gql).get}" } catch { case error: SyntaxError => syntaxError(error) } case _ => c.abort(c.enclosingPosition, "Invalid `graphql` invocation syntax.") } def implInput(args: Expr[Any]*) = if (args.nonEmpty) c.abort(c.enclosingPosition, "String interpolation is not supported for `graphqlInput`/`gqlInp` macro at the moment.") else c.prefix.tree match { // Expects a string interpolation that doesn't contain any // expressions, thus containing only a single tree case Apply(_, List(Apply(_, t :: Nil))) => val q"${gql: String}" = t try { q"${QueryParser.parseInput(gql).get}" } catch { case error: SyntaxError => syntaxError(error) } case _ => c.abort(c.enclosingPosition, "Invalid `graphql` invocation syntax.") } def implInputDoc(args: Expr[Any]*) = if (args.nonEmpty) c.abort(c.enclosingPosition, "String interpolation is not supported for `gqlInpDoc` macro at the moment.") else c.prefix.tree match { // Expects a string interpolation that doesn't contain any // expressions, thus containing only a single tree case Apply(_, List(Apply(_, t :: Nil))) => val q"${gql: String}" = t try { q"${QueryParser.parseInputDocument(gql).get}" } catch { case error: SyntaxError => syntaxError(error) } case _ => c.abort(c.enclosingPosition, "Invalid `graphql` invocation syntax.") } def syntaxError(error: SyntaxError) = { val errorPos = error.originalError.position val enclosingCol = if (errorPos.line == 1) calcStringStart else 0 val source = c.enclosingPosition.source val line = source.lineToOffset(c.enclosingPosition.line + (errorPos.line - 2)) val col = line + enclosingCol + (errorPos.column - 1) val pos = c.enclosingPosition.withPoint(col) c.abort(pos, error.formattedError(showPosition = false)) } def calcStringStart: Int = { val source = c.enclosingPosition.source val content = source.lineToString(c.enclosingPosition.line - 1) val contentStart = content.substring(c.enclosingPosition.column - 1) val offset = "(\\w+\"+)".r.findFirstMatchIn(contentStart).fold(0)(_.end) c.enclosingPosition.column - 1 + offset } }
Example 48
Source File: MacroSupport.scala From borer with Mozilla Public License 2.0 | 5 votes |
package io.bullet.borer.derivation.internal import io.bullet.borer.{Decoder, Encoder} import io.bullet.borer.deriver.DeriveWith import scala.reflect.macros.blackbox private[derivation] object MacroSupport { sealed trait Key extends Product { def value: Any } object Key { final case class String(value: java.lang.String) extends Key final case class Long(value: scala.Long) extends Key } val EncoderPlaceholder = Encoder[Any]((_, _) => sys.error("Internal Error: Unresolved Encoder Placeholder")) val DecoderPlaceholder = Decoder[Any](_ => sys.error("Internal Error: Unresolved Decoder Placeholder")) def sortAndVerifyNoCollisions[T](array: Array[(Key, T)])(onCollision: (Key, T, T) => Nothing): Unit = { def lessThan(comp: Int, k: Key, a: T, b: T): Boolean = if (comp == 0) onCollision(k, a, b) else comp < 0 java.util.Arrays.sort( array, Ordering.fromLessThan[(Key, T)] { case ((k @ Key.Long(x), a), (Key.Long(y), b)) => lessThan(java.lang.Long.compare(x, y), k, a, b) case ((k @ Key.String(x), a), (Key.String(y), b)) => lessThan(x compare y, k, a, b) case ((x, _), _) => x.isInstanceOf[Key.Long] // we sort LongKeys before StringKeys }) } def codecMacro[T: c.WeakTypeTag](c: blackbox.Context)(objectName: String, de: String, dd: String): c.Tree = { import c.universe._ val tpe = weakTypeOf[T] val borerPkg = c.mirror.staticPackage("_root_.io.bullet.borer") val prefix = q"$borerPkg.derivation.${TermName(objectName)}" val encName = TermName(c.freshName("encoder")) val decName = TermName(c.freshName("decoder")) q"""val $encName = $prefix.${TermName(de)}[$tpe] val $decName = $prefix.${TermName(dd)}[$tpe] $borerPkg.Codec($encName, $decName)""" } def deriveAll[T: ctx.WeakTypeTag](ctx: blackbox.Context)( isEncoder: Boolean, objectName: String, macroName: String, altMacroName: String): ctx.Tree = DeriveWith[T](ctx) { new CodecDeriver[ctx.type](ctx) { import c.universe._ def deriveForCaseObject(tpe: Type, module: ModuleSymbol) = c.abort( c.enclosingPosition, s"The `$macroName` macro can only be used on sealed traits or sealed abstract " + s"classes, not on case objects. Use `$altMacroName` instead!") def deriveForCaseClass( tpe: Type, companion: ModuleSymbol, params: List[CaseParam], annotationTrees: List[Tree], constructorIsPrivate: Boolean) = c.abort( c.enclosingPosition, s"The `$macroName` macro can only be used on sealed traits or sealed abstract " + s"classes, not on case classes. Use `$altMacroName` instead!") def deriveForSealedTrait(node: AdtTypeNode) = { val altMacro = q"$borerPkg.derivation.${TermName(objectName)}.${TermName(altMacroName)}" val tc = if (isEncoder) encoderType else decoderType val subs = subsWithoutImplicitTypeclassInstances(node, tc) q"""{ ..${subs.map(x => q"implicit val ${TermName(c.freshName())} = $altMacro[${x.tpe}]")} $altMacro[${node.tpe}] }""" } } } }
Example 49
Source File: Scalac.scala From borer with Mozilla Public License 2.0 | 5 votes |
package io.bullet.borer import scala.reflect.macros.blackbox import scala.util.control.NonFatal import scala.util.matching.Regex object Scalac { sealed trait TypeCheck { def assertErrorMsgMatches(string: String): Unit def assertErrorMsgMatches(regex: Regex): Unit } object TypeCheck { final case class Result(code: String, tpe: String) extends TypeCheck { def assertErrorMsgMatches(string: String): Unit = assertErrorMsgMatches(null: Regex) def assertErrorMsgMatches(regex: Regex): Unit = sys.error(s"Code Fragment compiled without error to an expression of type `$tpe`:\n\n$code") } final case class Error(msg: String) extends TypeCheck { def assertErrorMsgMatches(string: String): Unit = assert(msg == string, string) def assertErrorMsgMatches(regex: Regex): Unit = assert(regex.findAllIn(msg).hasNext, regex) private def assert(value: Boolean, expected: Any): Unit = if (!value) sys.error(s"Expected compiler error matching [$expected] but got [$msg]") } } def typecheck(codeFragment: String): TypeCheck = macro Macro.typecheck private object Macro { def typecheck(c: blackbox.Context)(codeFragment: c.Tree): c.Tree = { import c.universe._ val fragment = codeFragment match { case Literal(Constant(x: String)) => x case _ => c.abort(c.enclosingPosition, "`codeFragment` argument must be a literal string") } try { val name0 = TermName(c.freshName) val name1 = TermName(c.freshName) c.typecheck(c.parse(s"object $name0 { val $name1 = { $fragment } }")) match { case ModuleDef(_, _, Template(_, _, List(_, valDef: ValDef, defDef: DefDef))) => val tpe = defDef.symbol.asMethod.returnType.toString q"_root_.io.bullet.borer.Scalac.TypeCheck.Result(${showCode(valDef.rhs)}, $tpe)" case x => c.abort(c.enclosingPosition, s"Unexpected scalac result:\n\n${showCode(x)}") } } catch { case NonFatal(e) => q"_root_.io.bullet.borer.Scalac.TypeCheck.Error(${e.getMessage})" } } } }
Example 50
Source File: MacroUtil.scala From scala-tsi with MIT License | 5 votes |
package com.scalatsi import scala.reflect.macros.blackbox private[scalatsi] class MacroUtil[C <: blackbox.Context](val c: C) { private[this] var lookingUpList = List[c.Type]() // looking up implicits ourselves requires us to do our own error and divergence checking def lookupOptionalImplicit(T: c.Type): Option[c.Tree] = { val orLookingUpList = lookingUpList val found = try { if (orLookingUpList.exists(alreadyLookingUp => T <:< alreadyLookingUp)) { // We've entered this type before => we've entered a recursive loop and must stop c.universe.EmptyTree } else { lookingUpList = T :: orLookingUpList // look up implicit type, return EmptyTree if not found c.inferImplicitValue(T, silent = true) } } catch { case _: Exception => c.universe.EmptyTree } finally { lookingUpList = orLookingUpList } Option(found) .filter(_ != c.universe.EmptyTree) } def lookupOptionalGenericImplicit[T: c.WeakTypeTag, F[_]](implicit tsTypeTag: c.WeakTypeTag[F[_]]): Option[c.Tree] = { // Get the T => F[T] function val typeConstructor = c.weakTypeOf[F[_]].typeConstructor // Construct the F[T] type we need to look up val lookupType = c.universe.appliedType(typeConstructor, c.weakTypeOf[T]) lookupOptionalImplicit(lookupType) } }
Example 51
Source File: MacroUtils.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl import scala.reflect.macros.blackbox trait MacroUtils extends BaseMacroDefinitions with CaseClassUtils with LoggingUtils { val c: blackbox.Context import c.universe._ def eval[T](expr: Expr[T]): Option[T] = { util.Try(c.eval(c.Expr[T](c.untypecheck(expr.tree)))).toOption } case class SelectChain(chain: Seq[String]) implicit lazy val selectChainUnliftable: Unliftable[SelectChain] = Unliftable[SelectChain] { case Ident(name) => SelectChain(Seq(name.decodedName.toString)) case select: Select => def selectAllNames(s: Tree): Seq[String] = s match { case Select(rest, name) => selectAllNames(rest) :+ name.decodedName.toString case Ident(name) => Seq(name.decodedName.toString) } SelectChain(selectAllNames(select)) } case class BuilderField(name: String, tpe: Type) implicit lazy val builderFieldUnliftable: Unliftable[BuilderField] = Unliftable[BuilderField] { case lambda@q"((${ValDef(_, name, _, _)}) => ${b: SelectChain})" if b.chain.size == 2 && name.decodedName.toString == b.chain.head => val tpe = lambda match { case q"($_ => ${body: Tree})" => body.tpe } BuilderField(b.chain(1), tpe) } object Untyped { def unapply(arg: Tree): Option[Tree] = arg match { case Typed(t, _) => Untyped.unapply(t) case _ => Some(arg) } } implicit lazy val optionTreeUnliftable: Unliftable[Option[Tree]] = Unliftable[Option[Tree]] { case q"$col.Some.apply[$_](${res: Tree})" => Some(res) case q"$col.None" => None } }
Example 52
Source File: AutoDerivationMacro.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl.derivation import tethys.commons.LowPriorityInstance import tethys.{JsonObjectWriter, JsonReader, JsonWriter} import scala.reflect.macros.blackbox class AutoDerivationMacro(val c: blackbox.Context) extends WriterDerivation with ReaderDerivation { import c.universe._ override protected def showError: Boolean = true def jsonWriter[A: WeakTypeTag]: Expr[LowPriorityInstance[JsonObjectWriter[A]]] = { val tpe = weakTypeOf[A] val clazz = classSym(tpe) val instance: Expr[JsonWriter[A]] = { if (isRecursiveDerivation) { fail(s"Stop recursive derivation of JsonWriter[$tpe]") } else if (isCaseClass(tpe)) { deriveWriter[A] } else if (clazz.isSealed) { deriveWriterForSealedClass[A] } else { fail(s"Can't auto derive JsonWriter[$tpe]") } } c.Expr[LowPriorityInstance[JsonObjectWriter[A]]] { c.untypecheck { q"new ${weakTypeOf[LowPriorityInstance[JsonObjectWriter[A]]]}($instance)" } } } def jsonReader[A: WeakTypeTag]: Expr[LowPriorityInstance[JsonReader[A]]] = { val tpe = weakTypeOf[A] if (isRecursiveDerivation) { fail(s"Stop recursive derivation of JsonReader[$tpe]") } else if (isCaseClass(tpe)) { val instance = deriveReader[A] c.Expr[LowPriorityInstance[JsonReader[A]]] { c.untypecheck { q"new ${weakTypeOf[LowPriorityInstance[JsonReader[A]]]}($instance)" } } } else { fail(s"Can't auto derive JsonReader[$tpe]") } } private def isRecursiveDerivation: Boolean = { val tpes = c.enclosingMacros.map(_.macroApplication).collect { case q"$_.${method: TermName}[${tt: Tree}]" => method -> tt.tpe } val counts = tpes.map { case (m1, t1) => tpes.foldLeft(0) { case (count, (m2, t2)) if m1 == m2 && t1 =:= t2 => count + 1 case (count, _) => count } } counts.exists(_ > 1) } }
Example 53
Source File: SemiautoDerivationMacro.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl.derivation import tethys.derivation.builder._ import tethys.derivation.impl.builder.WriterBuilderCommons import tethys.{JsonObjectWriter, JsonReader} import scala.reflect.macros.blackbox class SemiautoDerivationMacro(val c: blackbox.Context) extends WriterDerivation with ReaderDerivation with WriterBuilderCommons { import c.universe._ def simpleJsonWriter[A: WeakTypeTag]: Expr[JsonObjectWriter[A]] = { val tpe = weakTypeOf[A] val clazz = classSym(tpe) if (isCaseClass(tpe)) { deriveWriter[A] } else if (clazz.isSealed) { deriveWriterForSealedClass[A] } else { abort(s"Can't auto derive JsonWriter[$tpe]") } } def jsonWriterWithBuilder[A: WeakTypeTag](builder: Expr[WriterBuilder[A]]): Expr[JsonObjectWriter[A]] = { val description = convertWriterBuilder[A](builder) describedJsonWriter[A](c.Expr[WriterDescription[A]](c.typecheck(description.tree))) } def jsonWriterWithConfig[A: WeakTypeTag](config: Expr[WriterDerivationConfig]): Expr[JsonObjectWriter[A]] = { val description = MacroWriteDescription( tpe = weakTypeOf[A], config = c.Expr[WriterDerivationConfig](c.untypecheck(config.tree)), operations = Seq.empty ) deriveWriter[A](description) } def describedJsonWriter[A: WeakTypeTag](description: Expr[WriterDescription[A]]): Expr[JsonObjectWriter[A]] = { val tpe = weakTypeOf[A] if (!isCaseClass(tpe)) { abort(s"Can't auto derive JsonWriter[$tpe]") } else { deriveWriter[A](unliftWriterMacroDescription(description)) } } def simpleJsonReader[A: WeakTypeTag]: Expr[JsonReader[A]] = { val tpe = weakTypeOf[A] if (isCaseClass(tpe)) { deriveReader[A] } else { fail(s"Can't auto derive JsonReader[$tpe]") } } def jsonReaderWithBuilder[A: WeakTypeTag](builder: Expr[ReaderBuilder[A]]): Expr[JsonReader[A]] = { val description = convertReaderBuilder[A](builder) describedJsonReader[A](c.Expr[ReaderDescription[A]](c.typecheck(description.tree))) } def describedJsonReader[A: WeakTypeTag](description: Expr[ReaderDescription[A]]): Expr[JsonReader[A]] = { val tpe = weakTypeOf[A] if (isCaseClass(tpe)) { deriveReader[A](unliftReaderMacroDescription(description)) } else { fail(s"Can't auto derive JsonReader[$tpe]") } } def jsonReaderWithConfig[A: WeakTypeTag](config: Expr[ReaderDerivationConfig]): Expr[JsonReader[A]] = { val tpe = weakTypeOf[A] if (isCaseClass(tpe)) { deriveReader[A](ReaderMacroDescription( config = c.Expr[ReaderDerivationConfig](c.untypecheck(config.tree)), operations = Seq() )) } else { fail(s"Can't auto derive JsonReader[$tpe]") } } private def unliftWriterMacroDescription[A: WeakTypeTag](description: Expr[WriterDescription[A]]): MacroWriteDescription = { description.tree match { case Untyped(q"${description: MacroWriteDescription}") => description } } private def unliftReaderMacroDescription[A: WeakTypeTag](description: Expr[ReaderDescription[A]]): ReaderMacroDescription = { description.tree match { case Untyped(q"${description: ReaderMacroDescription}") => description } } }
Example 54
Source File: DerivationUtils.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl.derivation import tethys.derivation.impl.LoggingUtils import scala.reflect.macros.blackbox trait DerivationUtils extends LoggingUtils { val c: blackbox.Context import c.universe._ protected def showError: Boolean = false protected def fail(msg: String): Nothing = abort(msg) protected def collectDistinctSubtypes(tpe: Type): List[Type] = { val baseClass = classSym(tpe) val baseArgs = tpe.dealias.typeArgs val tpes = collectSubclasses(baseClass).map { sym => def substituteArgs: List[Type] = { val subst = c.internal.thisType(sym).baseType(baseClass).typeArgs sym.typeParams.map { param => val paramTpe = param.asType.toType val index = subst.indexWhere(_ =:= paramTpe) if(index != -1) baseArgs(index) else fail(s"$sym contains additional type parameter that can't be derived in compile time") } } appliedType(sym, substituteArgs) } tpes.foldLeft(List.empty[Type]) { case (acc, t) => if(!acc.exists(_ =:= t)) t :: acc else acc } } protected def collectSubclasses(classSym: ClassSymbol): List[ClassSymbol] = { classSym.knownDirectSubclasses.toList.flatMap { child0 => val child = child0.asClass child.typeSignature // Workaround for <https://issues.scala-lang.org/browse/SI-7755> if (child.isSealed && (child.isAbstract || child.isTrait)) collectSubclasses(child) else List(child) } } protected def classSym(tpe: Type): ClassSymbol = { val sym = tpe.typeSymbol if (!sym.isClass) fail(s"$sym is not a class or trait") val classSym = sym.asClass classSym.typeSignature // Workaround for <https://issues.scala-lang.org/browse/SI-7755> classSym } }
Example 55
Source File: ReaderBuilderUtils.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl.builder import tethys.derivation.builder.ReaderDerivationConfig import tethys.derivation.impl.MacroUtils import scala.reflect.macros.blackbox trait ReaderBuilderUtils extends MacroUtils { val c: blackbox.Context import c.universe._ case class ReaderMacroDescription(config: c.Expr[ReaderDerivationConfig], operations: Seq[ReaderMacroOperation]) sealed trait Field { def name: String def tpe: Type } object Field { final case class ClassField(name: String, tpe: Type) extends Field final case class RawField(name: String, tpe: Type) extends Field } sealed trait ReaderMacroOperation { def field: String } object ReaderMacroOperation { final case class ExtractFieldAs(field: String, tpe: Type, as: Type, fun: Tree) extends ReaderMacroOperation final case class ExtractFieldValue(field: String, from: Seq[Field], fun: Tree) extends ReaderMacroOperation final case class ExtractFieldReader(field: String, from: Seq[Field], fun: Tree) extends ReaderMacroOperation } implicit lazy val readerMacroDescriptionLiftable: Liftable[ReaderMacroDescription] = Liftable[ReaderMacroDescription] { case ReaderMacroDescription(config, operations) => q"$buildersPack.ReaderDescription(${config.tree} ,_root_.scala.Seq(..$operations))" } implicit lazy val readerMacroDescriptionUnliftable: Unliftable[ReaderMacroDescription] = Unliftable[ReaderMacroDescription] { case q"$_.ReaderDescription.apply[$_](${config: Tree} ,$_.Seq.apply[$_](..${operations: Seq[ReaderMacroOperation]}))" => ReaderMacroDescription(c.Expr[ReaderDerivationConfig](c.untypecheck(config)), operations) } implicit lazy val fieldLiftable: Liftable[Field] = Liftable[Field] { case Field.ClassField(name, tpe) => q"$buildersPack.ReaderDescription.Field.ClassField[$tpe]($name)" case Field.RawField(name, tpe) => q"$buildersPack.ReaderDescription.Field.RawField[$tpe]($name)" } implicit lazy val fieldUnliftable: Unliftable[Field] = Unliftable[Field] { case q"$_.ReaderDescription.Field.ClassField.apply[${tpe: Tree}](${name: String})" => Field.ClassField(name, tpe.tpe) case q"$_.ReaderDescription.Field.RawField.apply[${tpe: Tree}](${name: String})" => Field.RawField(name, tpe.tpe) case q"${f: BuilderField}" => Field.ClassField(f.name, f.tpe) case q"$_.ReaderFieldStringOps(${name: String}).as[${tpe: Tree}]" => Field.RawField(name, tpe.tpe) case q"$_.ReaderFieldSymbolOps(scala.Symbol.apply(${name: String})).as[${tpe: Tree}]" => Field.RawField(name, tpe.tpe) } implicit lazy val readerMacroOperationLiftable: Liftable[ReaderMacroOperation] = Liftable[ReaderMacroOperation] { case ReaderMacroOperation.ExtractFieldAs(field, tpe, as, fun) => q"$buildersPack.ReaderDescription.BuilderOperation.ExtractFieldAs[$as, $tpe]($field, $fun)" case ReaderMacroOperation.ExtractFieldValue(field, from, fun) => q"$buildersPack.ReaderDescription.BuilderOperation.ExtractFieldValue($field, _root_.scala.Seq(..$from), $fun)" case ReaderMacroOperation.ExtractFieldReader(field, from, fun) => q"$buildersPack.ReaderDescription.BuilderOperation.ExtractFieldReader($field, _root_.scala.Seq(..$from), $fun)" } implicit lazy val readerMacroOperationUnliftable: Unliftable[ReaderMacroOperation] = Unliftable[ReaderMacroOperation] { case q"$_.ReaderDescription.BuilderOperation.ExtractFieldAs.apply[${as: Tree}, ${tpe: Tree}](${field: String}, ${fun: Tree})" => ReaderMacroOperation.ExtractFieldAs(field, tpe.tpe, as.tpe, fun) case q"$_.ReaderDescription.BuilderOperation.ExtractFieldValue.apply(${field: String}, $_.Seq.apply[$_](..${from: Seq[Field]}), ${fun: Tree})" => ReaderMacroOperation.ExtractFieldValue(field, from, fun) case q"$_.ReaderDescription.BuilderOperation.ExtractFieldReader.apply(${field: String}, $_.Seq.apply[$_](..${from: Seq[Field]}), ${fun: Tree})" => ReaderMacroOperation.ExtractFieldReader(field, from, fun) } }
Example 56
Source File: ReaderDescriptionCommons.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl.builder import tethys.derivation.builder.{ReaderBuilder, ReaderDerivationConfig, ReaderDescription} import scala.reflect.macros.blackbox trait ReaderDescriptionCommons extends ReaderBuilderUtils { val c: blackbox.Context import c.universe._ def convertReaderBuilder[A: WeakTypeTag](builder: Expr[ReaderBuilder[A]]): Expr[ReaderDescription[A]] = { val description = extractDescription(builder.tree) c.Expr[ReaderDescription[A]] { c.untypecheck { q"$description" } } } protected lazy val emptyReaderConfig: Expr[ReaderDerivationConfig] = c.Expr[ReaderDerivationConfig](c.untypecheck( q"tethys.derivation.builder.ReaderDerivationConfig.empty" )) private def extractDescription(tree: Tree): ReaderMacroDescription = tree match { // ===== ROOT ===== case q"ReaderBuilder.apply[$_]" => ReaderMacroDescription(emptyReaderConfig, Seq()) case q"$_.ReaderBuilder.apply[$_]" => ReaderMacroDescription(emptyReaderConfig, Seq()) // ===== FieldAs ===== case q"${rest: Tree}.extract[${tpe: Tree}](${f: BuilderField}).as[${as: Tree}].apply(${fun: Tree})" => val description = extractDescription(rest) description.copy(operations = description.operations :+ ReaderMacroOperation.ExtractFieldAs( f.name, tpe.tpe, as.tpe, fun )) // ===== FieldValue ===== case q"${rest: Tree}.extract[$tpe](${f: BuilderField}).from[..$_](..${fs: Seq[Field]}).apply(${fun: Tree})" => val description = extractDescription(rest) description.copy(operations = description.operations :+ ReaderMacroOperation.ExtractFieldValue( f.name, fs, fun )) case q"${rest: Tree}.extract[$tpe](${f: BuilderField}).from[..$_](..${fs: Seq[Field]}).and[..$_](..${ands: Seq[Field]}).apply(${fun: Tree})" => val description = extractDescription(rest) description.copy(operations = description.operations :+ ReaderMacroOperation.ExtractFieldValue( f.name, fs ++ ands, fun )) // ===== FieldReader ===== case q"${rest: Tree}.extractReader[$tpe](${f: BuilderField}).from[..$_](..${fs: Seq[Field]}).apply(${fun: Tree})" => val description = extractDescription(rest) description.copy(operations = description.operations :+ ReaderMacroOperation.ExtractFieldReader( f.name, fs, fun )) case q"${rest: Tree}.extractReader[$tpe](${f: BuilderField}).from[..$_](..${fs: Seq[Field]}).and[..$_](..${ands: Seq[Field]}).apply(${fun: Tree})" => val description = extractDescription(rest) description.copy(operations = description.operations :+ ReaderMacroOperation.ExtractFieldReader( f.name, fs ++ ands, fun )) // ===== FieldStyle ===== case q"${rest: Tree}.fieldStyle(${style: Tree})" => val description = extractDescription(rest) description.copy(config = c.Expr[ReaderDerivationConfig]( q"${description.config.tree}.withFieldStyle($style)" )) // ===== isStrict ===== case q"${rest: Tree}.strict" => val description = extractDescription(rest) description.copy(config = c.Expr[ReaderDerivationConfig]( q"${description.config.tree}.strict" )) // ===== NOPE ===== case _ => abort(s"Unknown builder tree: $tree") } }
Example 57
Source File: MacroLogging.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl import scala.language.experimental.macros import scala.reflect.macros.blackbox object MacroLogging { def logCode[A](tree: A): A = macro MacroLoggingImpl.logCode def logTree[A](tree: A): A = macro MacroLoggingImpl.logTree private class MacroLoggingImpl(val c: blackbox.Context) { import c.universe._ def logCode(tree: Tree): Tree = { c.info(c.enclosingPosition, show(tree), force = false) tree } def logTree(tree: Tree): Tree = { c.info(c.enclosingPosition, showRaw(tree), force = false) tree } } }
Example 58
Source File: CaseClassUtils.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.derivation.impl import scala.reflect.macros.blackbox trait CaseClassUtils extends LoggingUtils { val c: blackbox.Context import c.universe._ case class CaseClassDefinition(tpe: Type, fields: List[CaseClassField], typeParamsToRealTypes: Map[String, Type]) case class CaseClassField(name: String, tpe: Type) def caseClassDefinition[A: WeakTypeTag]: CaseClassDefinition = caseClassDefinition(weakTypeOf[A]) def caseClassDefinition(tpe: Type): CaseClassDefinition = { val ctor = getConstructor(tpe) val typeParamsToRealTypes = extractTypeParamsToRealTypes(tpe) CaseClassDefinition( tpe = tpe, fields = ctor.paramLists.head.map(constructorParameterToCaseClassField(tpe)), typeParamsToRealTypes = typeParamsToRealTypes ) } def isCaseClass[A: WeakTypeTag]: Boolean = isCaseClass(weakTypeOf[A]) def isCaseClass(tpe: Type): Boolean = { tpe.typeSymbol.isClass && (tpe.typeSymbol.asClass.isCaseClass || tpe.member(TermName("copy")).isMethod && tpe <:< weakTypeOf[Product]) } private def getConstructor(tpe: Type): MethodSymbol = { tpe.decls.collectFirst { case s: MethodSymbol if s.isPrimaryConstructor => s }.getOrElse { abort(s"Type '${tpe.typeSymbol.name.decodedName.toString} doesn't have main constructor") } } private def constructorParameterToCaseClassField(tpe: Type)(param: Symbol): CaseClassField = { val possibleRealType = tpe.decls.collectFirst { case s if s.name == param.name => s.typeSignatureIn(tpe).finalResultType } CaseClassField( name = param.name.decodedName.toString, tpe = possibleRealType.getOrElse(param.typeSignatureIn(tpe)) ) } private def extractTypeParamsToRealTypes(tpe: Type): Map[String, Type] = { val ctorTypeArgs = getConstructor(tpe).typeSignature.finalResultType.typeArgs ctorTypeArgs.zip(tpe.typeArgs).map { case (gen, real) => gen.typeSymbol.name.decodedName.toString -> real }.toMap } }
Example 59
Source File: CollectionBuilder.scala From tethys with Apache License 2.0 | 5 votes |
package tethys.compat import scala.collection.{IterableFactory, IterableFactoryDefaults, MapFactory, mutable} import scala.language.experimental.macros import scala.language.higherKinds import scala.reflect.macros.blackbox trait CollectionBuilder[A, C] { def newBuilder: mutable.Builder[A, C] } object CollectionBuilder { final class IterableFactoryCollectionBuilder[A, C[_]](factory: IterableFactory[C]) extends CollectionBuilder[A, C[A]] { override def newBuilder: mutable.Builder[A, C[A]] = factory.newBuilder[A] } final class MapFactoryCollectionBuilder[K, V, M[_, _]](factory: MapFactory[M]) extends CollectionBuilder[(K, V), M[K, V]] { override def newBuilder: mutable.Builder[(K, V), M[K, V]] = factory.newBuilder[K, V] } implicit def iterableFactoryCollectionBuilder[A, C[X] <: IterableFactoryDefaults[X, C]]: IterableFactoryCollectionBuilder[A, C] = macro CollectionBuilderMacroImpl.fromIterableFactory[A, C] implicit def mapFactoryCollectionBuilder[K, V, M[X, Y] <: Map[X, Y]]: MapFactoryCollectionBuilder[K, V, M] = macro CollectionBuilderMacroImpl.fromMapFactory[K, V, M] private class CollectionBuilderMacroImpl(val c: blackbox.Context) { import c.universe._ def fromIterableFactory[A, C[X] <: IterableFactoryDefaults[X, C]](implicit A: WeakTypeTag[A], C: WeakTypeTag[C[A]]): Tree = { val ref = C.tpe.typeSymbol.companion q"new tethys.compat.CollectionBuilder.IterableFactoryCollectionBuilder[${A.tpe}, ${C.tpe}]($ref)" } def fromMapFactory[K, V, M[X, Y] <: Map[X, Y]](implicit K: WeakTypeTag[K], V: WeakTypeTag[V], M: WeakTypeTag[M[K, V]]): Tree = { val ref = M.tpe.typeSymbol.companion q"new tethys.compat.CollectionBuilder.MapFactoryCollectionBuilder[${K.tpe}, ${V.tpe}, ${M.tpe}]($ref)" } } }
Example 60
Source File: GenKeyCodecMacros.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros.serialization import scala.reflect.macros.blackbox class GenKeyCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) { import c.universe._ final def GenKeyCodecObj: Tree = q"$SerializationPkg.GenKeyCodec" final def GenKeyCodecCls: Tree = tq"$SerializationPkg.GenKeyCodec" def forSealedEnum[T: WeakTypeTag]: Tree = { val tpe = weakTypeOf[T] knownSubtypes(tpe).map { subtypes => def singleValue(st: Type): Tree = singleValueFor(st).getOrElse(abort(s"$st is not an object")) val nameBySym = subtypes.groupBy(st => targetName(st.typeSymbol)).map { case (name, List(subtype)) => (subtype.typeSymbol, name) case (name, kst) => abort(s"Objects ${kst.map(_.typeSymbol.name).mkString(", ")} have the same @name: $name") } q""" new $GenKeyCodecCls[$tpe] { def tpeString = ${tpe.toString} def read(key: $StringCls): $tpe = key match { case ..${subtypes.map(st => cq"${nameBySym(st.typeSymbol)} => ${singleValue(st)}")} case _ => throw new $SerializationPkg.GenCodec.ReadFailure(s"Cannot read $$tpeString, unknown object: $$key") } def write(value: $tpe): String = value match { case ..${subtypes.map(st => cq"_: $st => ${nameBySym(st.typeSymbol)}")} } } """ }.getOrElse(abort(s"$tpe is not a sealed trait or class")) } def forTransparentWrapper[T: WeakTypeTag]: Tree = { val tpe = weakTypeOf[T].dealias val codecTpe = getType(tq"$GenKeyCodecCls[$tpe]") val (applyUnapply, param) = applyUnapplyFor(tpe) match { case Some(au@ApplyUnapply(_, _, _, _, List(soleParam))) => (au, soleParam) case _ => abort(s"$tpe is not a case class (or case class-like type) with exactly one field") } val wrappedCodecTpe = getType(tq"$GenKeyCodecCls[${param.typeSignature}]") val clue = s"Cannot materialize $codecTpe because of problem with parameter ${param.name}:\n" val wrappedCodec = inferCachedImplicit(wrappedCodecTpe, ErrorCtx(clue, param.pos)).reference(Nil) val unwrapped = if (applyUnapply.standardCaseClass) q"value.${param.name.toTermName}" else q""" ${applyUnapply.typedCompanion}.unapply[..${tpe.typeArgs}](value) .getOrElse(throw new $SerializationPkg.GenCodec.WriteFailure( s"Cannot write $$tpeString, unapply failed for $$value")) """ q""" new $codecTpe { ..$cachedImplicitDeclarations def tpeString: $StringCls = ${tpe.toString} def read(key: $StringCls): $tpe = ${applyUnapply.mkApply(List(q"$wrappedCodec.read(key)"))} def write(value: $tpe): $StringCls = $wrappedCodec.write($unwrapped) } """ } }
Example 61
Source File: CodecMacroCommons.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros.serialization import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.blackbox abstract class CodecMacroCommons(ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ final def SerializationPkg: Tree = q"$CommonsPkg.serialization" final lazy val NameAnnotType = staticType(tq"$SerializationPkg.name") final lazy val NameAnnotNameSym = NameAnnotType.member(TermName("name")) final lazy val WhenAbsentAnnotType = staticType(tq"$SerializationPkg.whenAbsent[_]") final def JavaInteropObj: Tree = q"$CommonsPkg.jiop.JavaInterop" final def JListObj: Tree = q"$JavaInteropObj.JList" final def JListCls: Tree = tq"$JavaInteropObj.JList" final def ListBufferCls: Tree = tq"$CollectionPkg.mutable.ListBuffer" final def BMapCls: Tree = tq"$CollectionPkg.Map" final def NOptObj: Tree = q"$MiscPkg.NOpt" final def NOptCls: Tree = tq"$MiscPkg.NOpt" final def OptObj: Tree = q"$CommonsPkg.Opt" final def OptCls: Tree = tq"$CommonsPkg.Opt" final lazy val TransparentAnnotType = staticType(tq"$SerializationPkg.transparent") final lazy val TransientDefaultAnnotType = staticType(tq"$SerializationPkg.transientDefault") final lazy val FlattenAnnotType = staticType(tq"$SerializationPkg.flatten") final lazy val OutOfOrderAnnotType = staticType(tq"$SerializationPkg.outOfOrder") final lazy val GeneratedAnnotType = staticType(tq"$SerializationPkg.generated") final lazy val DefaultCaseAnnotType = staticType(tq"$SerializationPkg.defaultCase") final def GenCodecObj: Tree = q"$SerializationPkg.GenCodec" final def GenCodecCls: Tree = tq"$SerializationPkg.GenCodec" final val DefaultCaseField = "_case" def tupleGet(i: Int) = TermName(s"_${i + 1}") def targetName(sym: Symbol): String = findAnnotation(sym, NameAnnotType).fold(sym.name.decodedName.toString)(_.findArg[String](NameAnnotNameSym)) def caseAccessorFor(sym: Symbol): Symbol = if (sym.isParameter && sym.owner.isConstructor) { val ownerClass = sym.owner.owner.asClass if (ownerClass.isCaseClass) { alternatives(ownerClass.toType.member(sym.name)).find(_.asTerm.isCaseAccessor).getOrElse(NoSymbol) } else NoSymbol } else NoSymbol def withAccessed(sym: Symbol): List[Symbol] = if (sym.isTerm) { val tsym = sym.asTerm if (tsym.isGetter) List(sym, tsym.accessed) else List(sym) } else List(sym) def hasAnnotation(sym: Symbol, annotTpe: Type): Boolean = findAnnotation(sym, annotTpe).nonEmpty def isTransparent(sym: Symbol): Boolean = hasAnnotation(sym, TransparentAnnotType) def isGenerated(sym: Symbol): Boolean = hasAnnotation(sym, GeneratedAnnotType) }
Example 62
Source File: UniversalMacros.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros import scala.reflect.macros.blackbox class UniversalMacros(ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ def sourceCode: Tree = { if (!ctx.compilerSettings.contains("-Yrangepos")) { abort("sourceCode only works with range positions enabled (-Yrangepos)") } val Apply(_, List(prefix)) = c.prefix.tree val pos = prefix.pos val code = new String(pos.source.content, pos.start, pos.end - pos.start) def lineIndent(line: String): Int = line.indexWhere(c => !c.isWhitespace) match { case -1 => 0 case i => i } val indentToStrip = lineIndent(pos.source.lineToString(pos.source.offsetToLine(pos.start))) val stripped = code.split('\n').map(l => l.drop(indentToStrip min lineIndent(l))).mkString("\n") q"$stripped" } def withSourceCode: Tree = { val Apply(_, List(prefix)) = c.prefix.tree q"($prefix, $sourceCode)" } def showAst[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, showCode(prefix)) prefix } def showRawAst[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, showRaw(prefix)) prefix } def showSymbol[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, show(prefix.symbol)) prefix } def showSymbolFullName[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, prefix.symbol.fullName) prefix } def showType[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, showCode(tq"${prefix.tpe.widen}")) prefix } def showRawType[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, showRaw(prefix.tpe.widen)) prefix } def showTypeSymbol[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, show(prefix.tpe.typeSymbol)) prefix } def showTypeSymbolFullName[A]: Tree = { val Apply(_, List(prefix)) = c.prefix.tree c.error(prefix.pos, prefix.tpe.typeSymbol.fullName) prefix } }
Example 63
Source File: DelegationMacros.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros.misc import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.blackbox class DelegationMacros(ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ final def DelegationCls: Tree = tq"$MiscPkg.Delegation" def delegate[A: WeakTypeTag, B: WeakTypeTag](source: Tree): Tree = instrument { val targetTpe = weakTypeOf[B] val targetSymbol = targetTpe.dealias.typeSymbol if (!targetSymbol.isClass && !targetSymbol.asClass.isAbstract) { abort(s"$targetTpe is not a trait or abstract class") } val wrappedName = c.freshName(TermName("w")) val methodDelegations = targetTpe.members.iterator .filter(m => m.isAbstract) .flatMap { m => if (m.isPublic && m.isMethod && !m.asTerm.isSetter) { val ms = m.asMethod val name = m.name.toTermName val mtpe = m.typeSignatureIn(targetTpe) val typeNames = mtpe.typeParams.map(_.name.toTypeName) val typeDefs = mtpe.typeParams.map(typeSymbolToTypeDef(_)) val paramNames = mtpe.paramLists.map(_.map(p => if (isRepeated(p)) q"${p.name.toTermName}: _*" else q"${p.name.toTermName}")) val paramLists = mtpe.paramLists.map(_.map(paramSymbolToValDef)) val resultTpeTree = treeForType(mtpe.finalResultType) val result = if (ms.isGetter) q"val $name: $resultTpeTree = $wrappedName.$name" else q"def $name[..$typeDefs](...$paramLists): $resultTpeTree = $wrappedName.$name[..$typeNames](...$paramNames)" Some(result) } else { error(s"Can't delegate ${m.name} - only public defs and vals can be delegated") None } }.toList q""" val $wrappedName = $source new $targetTpe { ..$methodDelegations } """ } def materializeDelegation[A: WeakTypeTag, B: WeakTypeTag]: Tree = instrument { val targetTpe = weakTypeOf[B] val sourceTpe = weakTypeOf[A] q""" new $DelegationCls[$sourceTpe, $targetTpe] { def delegate(source: $sourceTpe): $targetTpe = ${delegate[A, B](q"source")} } """ } }
Example 64
Source File: SealedMacros.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros.misc import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.blackbox class SealedMacros(ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ final lazy val OrderedEnumType: Type = staticType(tq"$MiscPkg.OrderedEnum") def caseObjectsFor[T: WeakTypeTag]: Tree = instrument { val tpe = weakTypeOf[T] knownSubtypes(tpe).map { subtypes => val objects = subtypes.map(subTpe => singleValueFor(subTpe) .getOrElse(abort(s"All possible values of a SealedEnum must be objects but $subTpe is not"))) val result = q"$ListObj(..$objects)" if (tpe <:< OrderedEnumType) q"$result.sorted" else result }.getOrElse(abort(s"$tpe is not a sealed trait or class")) } def instancesFor[TC: WeakTypeTag, T: WeakTypeTag]: Tree = instrument { val tpe = weakTypeOf[T] def instanceTpe(forTpe: Type): Type = weakTypeOf[TC] match { case TypeRef(pre, sym, Nil) => internal.typeRef(pre, sym, List(forTpe)) case _ => abort(s"expected type constructor") } val subtypes = knownSubtypes(tpe).getOrElse(abort(s"$tpe is not a sealed hierarchy root")) q"${subtypes.map(st => q"""$ImplicitsObj.infer[${instanceTpe(st)}]("")""")}" } }
Example 65
Source File: LazyLoggingMacros.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package macros.misc import com.avsystem.commons.macros.MacroCommons import scala.reflect.macros.blackbox class LazyLoggingMacros(val c: blackbox.Context) extends MacroCommons { import c.universe._ val DelegationCls = tq"$MiscPkg.Delegation" def warningImpl(msg: Tree) = q""" if(${c.prefix}.rawLog.isWarningEnabled) { ${c.prefix}.rawLog.warning($msg) } """ def infoImpl(msg: Tree) = q""" if(${c.prefix}.rawLog.isInfoEnabled) { ${c.prefix}.rawLog.info($msg) } """ def debugImpl(msg: Tree) = q""" if(${c.prefix}.rawLog.isDebugEnabled) { ${c.prefix}.rawLog.debug($msg) } """ }
Example 66
Source File: TestUtils.scala From scala-commons with MIT License | 5 votes |
package com.avsystem.commons package analyzer import com.avsystem.commons.annotation.{atLeast, explicitGenerics, macroPrivate} import scala.reflect.macros.blackbox object TestUtils { def need3Params(@atLeast(3) args: Any*) = () @macroPrivate def macroPrivateMethod = 42 def invokeMacroPrivateMethod: Int = macro invokeMacroPrivateMethodImpl def invokeMacroPrivateMethodImpl(c: blackbox.Context): c.Tree = { import c.universe._ q"${c.prefix}.macroPrivateMethod" } object Extractor { @macroPrivate def unapply(any: Any): Option[Any] = None } def genericMacroImpl[T](c: blackbox.Context)(arg: c.Tree): c.Tree = arg @explicitGenerics def genericMethod[T](arg: T): T = arg @explicitGenerics def genericMacro[T](arg: T): T = macro genericMacroImpl[T] }
Example 67
Source File: ExportMacros.scala From pureconfig with Mozilla Public License 2.0 | 5 votes |
package pureconfig.generic import scala.reflect.macros.blackbox import pureconfig._ class ExportMacros(val c: blackbox.Context) { import c.universe._ final def exportDerivedReader[A](implicit a: c.WeakTypeTag[A]): c.Expr[Exported[ConfigReader[A]]] = { c.typecheck(q"_root_.shapeless.lazily[_root_.pureconfig.generic.DerivedConfigReader[$a]]", silent = true) match { case EmptyTree => c.abort(c.enclosingPosition, s"Unable to infer value of type $a") case t => c.Expr[Exported[ConfigReader[A]]]( q"new _root_.pureconfig.Exported($t: _root_.pureconfig.ConfigReader[$a])") } } final def exportDerivedWriter[A](implicit a: c.WeakTypeTag[A]): c.Expr[Exported[ConfigWriter[A]]] = { c.typecheck(q"_root_.shapeless.lazily[_root_.pureconfig.generic.DerivedConfigWriter[$a]]", silent = true) match { case EmptyTree => c.abort(c.enclosingPosition, s"Unable to infer value of type $a") case t => c.Expr[Exported[ConfigWriter[A]]]( q"new _root_.pureconfig.Exported($t: _root_.pureconfig.ConfigWriter[$a])") } } }
Example 68
Source File: ProtoBinWrapper.scala From aerospike-scala with Apache License 2.0 | 5 votes |
package ru.tinkoff.aerospikeproto.wrapper import com.aerospike.client.Value import com.aerospike.client.Value.BytesValue import com.trueaccord.lenses.Updatable import com.trueaccord.scalapb.{GeneratedMessage, Message} import ru.tinkoff.aerospikemacro.converters.BinWrapper import scala.language.experimental.macros import scala.reflect.macros.blackbox trait ProtoBinWrapper[T <: GeneratedMessage with Message[T] with Updatable[T]] extends BinWrapper[T] { override def toValue(v: T): Value = new BytesValue(v.toByteArray) override def fetch(any: Any): Option[T] = scala.util.Try { Value.getFromRecordObject(any) match { case b: BytesValue => b.getObject match { case arr: Array[Byte] => parse(arr) } } }.toOption def parse: Array[Byte] => T } object ProtoBinWrapper { implicit def materialize[T <: GeneratedMessage with Message[T] with Updatable[T]]: ProtoBinWrapper[T] = macro impl[T] def impl[T <: GeneratedMessage with Message[T] with Updatable[T] : c.WeakTypeTag] (c: blackbox.Context): c.Expr[ProtoBinWrapper[T]] = { import c.universe._ val tpe = weakTypeOf[T] val simpleName = tpe.typeSymbol.fullName.split('.').last val termName = q"${TermName(simpleName)}" c.Expr[ProtoBinWrapper[T]] { q""" import com.aerospike.client.Value import com.aerospike.client.Value.BytesValue import com.trueaccord.lenses.Updatable import com.trueaccord.scalapb.{GeneratedMessage, Message} import ru.tinkoff.aerospikemacro.converters.BinWrapper new ProtoBinWrapper[$tpe] { override def parse: Array[Byte] => $tpe = $termName.parseFrom } """ } } }
Example 69
Source File: Printer.scala From aerospike-scala with Apache License 2.0 | 5 votes |
package ru.tinkoff.aerospikemacro.printer import scala.language.experimental.macros import scala.reflect.macros.blackbox object Printer { def printNameValue[T](x: T): Unit = macro impl[T] def impl[R](c: blackbox.Context)(x: c.Tree): c.Tree = { import c.universe._ val tpe = weakTypeOf[R] val name = x match { case Select(_, TermName(s)) => s case _ => "" } val isArray = tpe.widen.typeSymbol.name.eq(TypeName("Array")) q""" println("-"*20) println($name + " => " + $x) """ } }
Example 70
Source File: IgnoreMacro.scala From diffx with Apache License 2.0 | 5 votes |
package com.softwaremill.diffx import scala.annotation.tailrec import scala.reflect.macros.blackbox object IgnoreMacro { private val ShapeInfo = "Path must have shape: _.field1.field2.each.field3.(...)" def ignoreMacro[T: c.WeakTypeTag, U: c.WeakTypeTag]( c: blackbox.Context )(path: c.Expr[T => U]): c.Tree = applyIgnored[T, U](c)(ignoredFromPathMacro(c)(path)) private def applyIgnored[T: c.WeakTypeTag, U: c.WeakTypeTag](c: blackbox.Context)( path: c.Expr[List[String]] ): c.Tree = { import c.universe._ q"""{ ${c.prefix}.ignoreUnsafe($path:_*) }""" } @tailrec def collectPathElements(tree: c.Tree, acc: List[PathElement]): List[PathElement] = { def typeSupported(diffxIgnoreType: c.Tree) = Seq("DiffxEach", "DiffxEither", "DiffxEachMap") .exists(diffxIgnoreType.toString.endsWith) tree match { case q"$parent.$child " => collectPathElements(parent, TermPathElement(child) :: acc) case q"$tpname[..$_]($t)($f) " if typeSupported(tpname) => val newAcc = acc match { // replace the term controlled by quicklens case TermPathElement(term, xargs @ _*) :: rest => FunctorPathElement(f, term, xargs: _*) :: rest case pathEl :: _ => c.abort(c.enclosingPosition, s"Invalid use of path element $pathEl. $ShapeInfo, got: ${path.tree}") case Nil => c.abort(c.enclosingPosition, s"Invalid use of path element(Nil). $ShapeInfo, got: ${path.tree}") } collectPathElements(t, newAcc) case t: Ident => acc case _ => c.abort(c.enclosingPosition, s"Unsupported path element. $ShapeInfo, got: $tree") } } val pathEls = path.tree match { case q"($arg) => $pathBody " => collectPathElements(pathBody, Nil) case _ => c.abort(c.enclosingPosition, s"$ShapeInfo, got: ${path.tree}") } c.Expr[List[String]](q"${pathEls.collect { case TermPathElement(c) => c.decodedName.toString }}") } private[diffx] def ignoredFromPath[T, U](path: T => U): List[String] = macro ignoredFromPathMacro[T, U] }
Example 71
Source File: FeatureBuilderMacros.scala From TransmogrifAI with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.salesforce.op.features import com.salesforce.op.features.types._ import scala.language.experimental.macros import scala.reflect.macros.blackbox private object ParamRename { def apply(c: blackbox.Context) = { import c.universe._ new Transformer { var i = 0 var renames = Map[String, String]() override def transform(tree: Tree): Tree = { val nt = tree match { case ValDef(m, TermName(v), tpe, tr) if m.hasFlag(Flag.PARAM) => val newName = "x$" + i.toString i = i + 1 renames = renames + (v -> newName) ValDef(m, TermName(newName), tpe, tr) case Ident(TermName(v)) if renames.contains(v) => Ident(TermName(renames(v))) case x => x } super.transform(nt) } } } } // scalastyle:on }
Example 72
Source File: ConfiguredJsonCodec.scala From circe-generic-extras with Apache License 2.0 | 5 votes |
package io.circe.generic.extras import io.circe.generic.util.macros.JsonCodecMacros import scala.language.experimental.macros import scala.reflect.macros.blackbox class ConfiguredJsonCodec( encodeOnly: Boolean = false, decodeOnly: Boolean = false ) extends scala.annotation.StaticAnnotation { def macroTransform(annottees: Any*): Any = macro ConfiguredJsonCodecMacros.jsonCodecAnnotationMacro } private[generic] class ConfiguredJsonCodecMacros(val c: blackbox.Context) extends JsonCodecMacros { import c.universe._ protected[this] def semiautoObj: Symbol = symbolOf[semiauto.type].asClass.module protected[this] def deriveMethodPrefix: String = "deriveConfigured" def jsonCodecAnnotationMacro(annottees: Tree*): Tree = constructJsonCodec(annottees: _*) }
Example 73
Source File: Macros.scala From seed with Apache License 2.0 | 5 votes |
import scala.reflect.macros.blackbox import scala.language.experimental.macros import scala.annotation.StaticAnnotation object helloMacro { def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ import Flag._ val result = { annottees.map(_.tree).toList match { case q"object $name extends ..$parents { ..$body }" :: Nil => q""" object $name extends ..$parents { def hello: ${typeOf[String]} = "hello" ..$body } """ } } c.Expr[Any](result) } } class hello extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro helloMacro.impl }
Example 74
Source File: Macros.scala From seed with Apache License 2.0 | 5 votes |
import scala.reflect.macros.blackbox import scala.language.experimental.macros import scala.annotation.StaticAnnotation object helloMacro { def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ import Flag._ val result = { annottees.map(_.tree).toList match { case q"object $name extends ..$parents { ..$body }" :: Nil => q""" object $name extends ..$parents { def hello: ${typeOf[String]} = "hello" ..$body } """ } } c.Expr[Any](result) } } class hello extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro helloMacro.impl }
Example 75
Source File: Macros.scala From seed with Apache License 2.0 | 5 votes |
import scala.reflect.macros.blackbox import scala.language.experimental.macros import scala.annotation.StaticAnnotation object helloMacro { def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ import Flag._ val result = { annottees.map(_.tree).toList match { case q"object $name extends ..$parents { ..$body }" :: Nil => q""" object $name extends ..$parents { def hello: ${typeOf[String]} = "hello" ..$body } """ } } c.Expr[Any](result) } } class hello extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro helloMacro.impl }
Example 76
Source File: LambdaHTTPApiAnnotation.scala From quaich with Apache License 2.0 | 5 votes |
package codes.bytes.quaich.api.http.macros import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.language.postfixOps import scala.reflect.macros.blackbox import scala.language.experimental.macros object LambdaHTTPApi { // todo - check for companion object and reject def annotation_impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ import Flag._ val p = c.enclosingPosition val inputs = annottees.map(_.tree).toList val result: Tree = inputs match { case (cls @ q"$mods class $name[..$tparams] extends ..$parents { ..$body }") :: Nil if mods.hasFlag(ABSTRACT) ⇒ c.abort(p, "! The @LambdaHTTPApi annotation is not valid on abstract classes.") cls // todo - detect and handle companion object! case (cls @ q"$mods class $name[..$tparams] extends ..$parents { ..$body }") :: Nil ⇒ //val baseName = name.decodedName.toString //val handlerName = TermName(s"$baseName$$RequestHandler") //val handlerName = name.toTermName val handlerName = name.asInstanceOf[TypeName].toTermName val cls = q""" $mods class $name[..$tparams]( val request: codes.bytes.quaich.api.http.LambdaHTTPRequest, val context: codes.bytes.quaich.api.http.LambdaContext ) extends ..$parents with codes.bytes.quaich.api.http.HTTPHandler { import org.json4s.jackson.JsonMethods._ import org.json4s.jackson.Serialization import org.json4s.jackson.Serialization._ import org.json4s.{NoTypeHints, _} protected implicit val formats = Serialization.formats(NoTypeHints) ..$body } """ val obj = q""" object $handlerName extends codes.bytes.quaich.api.http.HTTPApp { def newHandler( request: codes.bytes.quaich.api.http.LambdaHTTPRequest, context: codes.bytes.quaich.api.http.LambdaContext ): codes.bytes.quaich.api.http.HTTPHandler = new $name(request, context) } """ q"$cls; $obj" case Nil ⇒ c.abort(p, s"Cannot annotate an empty Tree.") case _ ⇒ c.abort(p, s"! The @LambdaHTTPApi Annotation is only valid on non-abstract Classes") } //c.info(p, "result: " + result, force = true) c.Expr[Any](result) } } @compileTimeOnly("Setup the macro paradise compiler plugin to enable expansion of macro annotations.") class LambdaHTTPApi extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro LambdaHTTPApi.annotation_impl } // vim: set ts=2 sw=2 sts=2 et:
Example 77
Source File: BodyElementCollectorMacro.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.dsl import scala.reflect.macros.{ TypecheckException, blackbox } class BodyElementCollectorMacro(context: blackbox.Context) { val c: blackbox.Context = context import c.universe._ private val initTreeFold: (Tree, List[Tree]) = q"Nil" -> Nil def collectImpl(body: Tree): Tree = { val contextType = c.prefix.tree.tpe val validContext = typeOf[BodyElementCollector[_, _]] if (!(contextType <:< validContext)) c.abort(c.enclosingPosition, s"Macro only allowed to be used directly inside of a `$validContext`") else { val elementType = contextType.typeArgs.head blockOrApplyExpressionList(body, elementType) { elements => val (finalTree, rest) = elements.foldLeft(initTreeFold) { case ((accTree, accSingle), elem) => if (elem.tpe <:< elementType) accTree -> (accSingle :+ elem) //todo avoid List.append else q"$accTree ++ $accSingle ++ $elem" -> Nil } q"${c.prefix.tree}.get($finalTree ++ $rest)" } } } private def blockOrApplyExpressionList(body: Tree, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = body match { case block: Block => blockExpressionList(block, elementType)(typesTreesFn) case app: Apply => singleExpressionList(app, elementType)(typesTreesFn) case Typed(app: Apply, _) => singleExpressionList(app, elementType)(typesTreesFn) case s @ Select(_, _) => singleExpressionList(s, elementType)(typesTreesFn) case e => val unsupportedMessage = s"Unsupported expression. Only expressions of type `$elementType` are allowed here." c.abort(e.pos, s"$unsupportedMessage\nfound '$e' of type '${e.tpe}'") } private def singleExpressionList(app: Tree, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = typeCheck(elementType, seqElementType(elementType))(app) match { case Right(checked) => typesTreesFn(checked :: Nil) case Left((pos, error)) => c.abort(pos, error) } private def seqElementType(elementType: Type): Type = c.typecheck(q"Seq[$elementType]()").tpe private def blockExpressionList(block: Block, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = { val allStats = block.stats :+ block.expr //todo avoid List.append val seq = seqElementType(elementType) val checked = allStats.map(typeCheck(elementType, seq)) if (checked.exists(_.isLeft)) { val errors = checked.collect { case Left(error) => error } errors.dropRight(1).foreach { case (pos, error) => c.error(pos, error) } val lastError = errors.last c.abort(lastError._1, lastError._2) } else typesTreesFn(checked.collect { case Right(typed) => typed }) } private def typeCheck(elementType: Type, seq: Type)(tree: Tree): Either[(c.universe.Position, String), c.Tree] = { val checked = c.typecheck(tree) // checked.tpe is null if the statement is an import if (checked.tpe == null) Left(tree.pos -> s"Expected expression of either `$elementType` or `$seq` but found '$tree'") else if (checked.tpe <:< elementType || checked.tpe <:< seq) Right(checked) else try Right(c.typecheck(tree, pt = elementType)) catch { case TypecheckException(_, msg) => Left(tree.pos -> (s"Result of this expression can be either `$elementType` or `$seq`. " + msg)) } } }
Example 78
Source File: Macro.scala From tofu with Apache License 2.0 | 5 votes |
package tofu.optics.macros.internal import tofu.optics.{Contains, PContains} import scala.reflect.macros.blackbox object Macro { def mkContains[S, T, A, B](fieldName: String): PContains[S, T, A, B] = macro MacroImpl.mkContains_impl[S, T, A, B] } private[macros] class MacroImpl(val c: blackbox.Context) { def genContains_impl[S: c.WeakTypeTag, A: c.WeakTypeTag](field: c.Expr[S => A]): c.Expr[Contains[S, A]] = { import c.universe._ object SelectChain { def unapply(tree: Tree): Option[(Name, Seq[(Type, TermName)])] = tree match { case Select(tail @ Ident(termUseName), field: TermName) => Some((termUseName, Seq(tail.tpe.widen -> field))) case Select(tail, field: TermName) => SelectChain .unapply(tail) .map(t => t.copy(_2 = t._2 :+ (tail.tpe.widen -> field))) case _ => None } } field match { // _.field case Expr( Function( List(ValDef(_, termDefName, _, EmptyTree)), Select(Ident(termUseName), fieldNameName) ) ) if termDefName.decodedName.toString == termUseName.decodedName.toString => val fieldName = fieldNameName.decodedName.toString mkContains_impl[S, S, A, A](c.Expr[String](q"$fieldName")) // _.field1.field2... case Expr( Function( List(ValDef(_, termDefName, _, EmptyTree)), SelectChain(termUseName, typesFields) ) ) if termDefName.decodedName.toString == termUseName.decodedName.toString => c.Expr[Contains[S, A]]( typesFields.map { case (t, f) => q"_root_.tofu.optics.macros.GenContains[$t](_.$f)" } .reduce((a, b) => q"$a andThen $b") ) case _ => c.abort( c.enclosingPosition, s"Illegal field reference ${show(field.tree)}; please use _.field1.field2... instead" ) } } def mkContains_impl[S: c.WeakTypeTag, T: c.WeakTypeTag, A: c.WeakTypeTag, B: c.WeakTypeTag]( fieldName: c.Expr[String] ): c.Expr[PContains[S, T, A, B]] = { import c.universe._ val (sTpe, tTpe, aTpe, bTpe) = (weakTypeOf[S], weakTypeOf[T], weakTypeOf[A], weakTypeOf[B]) val strFieldName = c.eval(c.Expr[String](c.untypecheck(fieldName.tree.duplicate))) val fieldMethod = sTpe.decls.collectFirst { case m: MethodSymbol if m.isCaseAccessor && m.name.decodedName.toString == strFieldName => m }.getOrElse(c.abort(c.enclosingPosition, s"Cannot find method $strFieldName in $sTpe")) val constructor = sTpe.decls.collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m }.getOrElse(c.abort(c.enclosingPosition, s"Cannot find constructor in $sTpe")) val field = constructor.paramLists.head .find(_.name.decodedName.toString == strFieldName) .getOrElse(c.abort(c.enclosingPosition, s"Cannot find constructor field named $fieldName in $sTpe")) c.Expr[PContains[S, T, A, B]](q""" import _root_.tofu.optics.PContains import _root_.scala.language.higherKinds // prevent warning at call site new PContains[$sTpe, $tTpe, $aTpe, $bTpe]{ override def extract(s: $sTpe): $aTpe = s.$fieldMethod override def set(s: $sTpe, a: $bTpe): $tTpe = s.copy($field = a) } """) } }
Example 79
Source File: Macros.scala From swave with Mozilla Public License 2.0 | 5 votes |
package swave.core import scala.reflect.macros.blackbox package object macros { def requireArg(cond: Boolean): Unit = macro Macros.requireArgImpl def requireArg(cond: Boolean, msg: Any): Unit = macro Macros.requireArg1Impl def requireState(cond: Boolean): Unit = macro Macros.requireStateImpl def requireState(cond: Boolean, msg: Any): Unit = macro Macros.requireState1Impl } package macros { private[macros] object Macros { def requireArgImpl(c: blackbox.Context)(cond: c.Expr[Boolean]): c.Expr[Unit] = { import c.universe._ reify { if (!cond.splice) throw new IllegalArgumentException } } def requireArg1Impl(c: blackbox.Context)(cond: c.Expr[Boolean], msg: c.Expr[Any]): c.Expr[Unit] = { import c.universe._ reify { if (!cond.splice) { throw new IllegalArgumentException(msg.splice.toString) } } } def requireStateImpl(c: blackbox.Context)(cond: c.Expr[Boolean]): c.Expr[Unit] = { import c.universe._ reify { if (!cond.splice) { throw new IllegalStateException } } } def requireState1Impl(c: blackbox.Context)(cond: c.Expr[Boolean], msg: c.Expr[Any]): c.Expr[Unit] = { import c.universe._ reify { if (!cond.splice) { throw new IllegalStateException(msg.splice.toString) } } } } }
Example 80
Source File: Macros.scala From perfolation with MIT License | 5 votes |
package perfolation import scala.StringContext.InvalidEscapeException import scala.annotation.compileTimeOnly import scala.language.experimental.macros import scala.reflect.macros.blackbox @compileTimeOnly("Enable macros to expand") object Macros { def p(c: blackbox.Context)(args: c.Expr[Any]*): c.Expr[String] = px(c)(args: _*)(scala.StringContext.processEscapes) def raw(c: blackbox.Context)(args: c.Expr[Any]*): c.Expr[String] = px(c)(args: _*)(identity) private[this] def px(c: blackbox.Context)(args: c.Expr[Any]*)(process: String => String): c.Expr[String] = { import c.universe._ val constants = (c.prefix.tree match { case Apply(_, List(Apply(_, literals))) => literals }).map { case Literal(Constant(s: String)) => try process(s) catch { case ex: InvalidEscapeException => c.abort(c.enclosingPosition, ex.getMessage) } } if (args.isEmpty) c.Expr(Literal(Constant(constants.mkString))) else { val (valDeclarations, values) = args.map { arg => arg.tree match { case tree @ Literal(Constant(_)) => (EmptyTree, if (tree.tpe <:< definitions.NullTpe) q"(null: String)" else tree) case tree => val name = TermName(c.freshName()) val tpe = if (tree.tpe <:< definitions.NullTpe) typeOf[String] else tree.tpe (q"val $name: $tpe = $arg", Ident(name)) } }.unzip val stringBuilderWithAppends = constants.zipAll(values, "", null) .foldLeft(q"perfolation.stringBuilder()") { case (sb, (s, v)) => val len = s.length if (len == 0) { if (v == null) sb else q"$sb.append($v)" } else if (len == 1) { if (v == null) q"$sb.append(${s.charAt(0)})" else q"$sb.append(${s.charAt(0)}).append($v)" } else { if (v == null) q"$sb.append($s)" else q"$sb.append($s).append($v)" } } c.Expr(c.typecheck(q"..$valDeclarations; $stringBuilderWithAppends.toString")) } } }
Example 81
Source File: CypherStringInterpolator.scala From neotypes with MIT License | 5 votes |
package neotypes import types.QueryParam import scala.reflect.macros.blackbox final class CypherStringInterpolator(private val sc: StringContext) extends AnyVal { def c(args: Any*): DeferredQueryBuilder = macro CypherStringInterpolator.macroImpl } object CypherStringInterpolator { def createQuery(sc: StringContext)(parameters: QueryParam*): DeferredQueryBuilder = { val queries = sc.parts.iterator.map(DeferredQueryBuilder.Query) val params = parameters.iterator.map(DeferredQueryBuilder.Param) val queryParts = new Iterator[DeferredQueryBuilder.Part] { private var paramNext: Boolean = false override def hasNext: Boolean = queries.hasNext override def next(): DeferredQueryBuilder.Part = if (paramNext && params.hasNext) { paramNext = false params.next() } else { paramNext = true queries.next() } } new DeferredQueryBuilder(queryParts.toList) } def macroImpl(c: blackbox.Context)(args: c.Expr[Any]*): c.Expr[DeferredQueryBuilder] = { import c.universe._ val q"$foo($sc)" = c.prefix.tree neotypes.internal.utils.void(q"$foo") val parameters = args.map { arg => val nextElement = arg.tree val tpe = nextElement.tpe.widen q"neotypes.mappers.ParameterMapper[${tpe}].toQueryParam(${nextElement})" } c.Expr( q"neotypes.CypherStringInterpolator.createQuery(${sc})(..${parameters})" ) } }
Example 82
Source File: Connections.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox class Connections(val c: blackbox.Context) { import c.universe._ def setup(setup: Tree): Tree = { val q"$_.$name[$tpt](...$_)" = c.macroApplication q"${termNames.ROOTPKG}.loci.language.Connections.$name(${signature(tpt)}, $setup)" } def factory(factory: Tree)(args: Tree*): Tree = { val q"$_.$name[$tpt](...$_)" = c.macroApplication val arguments = if (args.size == 1) args :+ q"${termNames.ROOTPKG}.scala.collection.immutable.Map.empty" else args q"${termNames.ROOTPKG}.loci.language.Connections.$name(..${signature(tpt) +: factory +: arguments})" } private val documentationCompiler = c.compilerSettings.size > 1 && (c.compilerSettings sliding 2 exists { case Seq(flag, value) => flag == "-d" && ((value endsWith "/api") || (value endsWith "\\api")) }) private def signature(tpt: Tree) = { val name = TermName(s"$$loci$$peer$$sig$$${tpt.symbol.name}") tpt match { case _ if documentationCompiler => q"${termNames.ROOTPKG}.scala.Predef.???" case tq"$prefix.$_" if (prefix.tpe member name) != NoSymbol => q"$prefix.$name" case _ => c.abort( if (tpt.pos != NoPosition) tpt.pos else c.enclosingPosition, s"$tpt is not a peer type") } } }
Example 83
Source File: Component.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox trait Component[C <: blackbox.Context] { val engine: Engine[C] val phases: Seq[Phase] } object Component { type AnyFactory = Factory[Component] abstract class Factory[+Comp[C <: blackbox.Context] <: Component[C]]( val requires: Seq[AnyFactory] = Seq.empty) { def asInstance[C <: blackbox.Context]: PartialFunction[Component[C], Comp[C]] def apply[C <: blackbox.Context](engine: Engine[C]): Comp[C] } }
Example 84
Source File: Remote.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox object Remote { def asRemote[P: c.WeakTypeTag](c: blackbox.Context): c.Tree = { import c.universe._ val q"$expr.asRemote[$tpt]" = c.macroApplication val enclosingMultitierMacro = c.enclosingMacros exists { c => import c.universe._ val multitier = c.mirror.staticClass(s"${termNames.ROOTPKG}.loci.multitier") c.macroApplication match { case q"new $expr[..$tpts](...$exprss).macroTransform[..$_](...$_)" => c.typecheck(q"new $expr[..$tpts](...$exprss)", silent = true) match { case q"new $expr[..$_](...$_)" => expr.symbol == multitier case _ => false } case _ => false } } val documentationCompiler = c.compilerSettings.size > 1 && (c.compilerSettings sliding 2 exists { case Seq(flag, value) => flag == "-d" && ((value endsWith "/api") || (value endsWith "\\api")) }) if (!enclosingMultitierMacro && !documentationCompiler) { val remote = weakTypeOf[Remote[P]] val reference = typeOf[runtime.Remote.Reference] val name = TermName(s"$$loci$$peer$$sig$$${tpt.symbol.name}") val prefix = tpt match { case tq"$prefix.$_" if (prefix.tpe member name) != NoSymbol => prefix case _ => c.abort( if (tpt.pos != NoPosition) tpt.pos else c.enclosingPosition, s"$tpt is not a peer type") } val signature = q"$prefix.$name" val ref = TermName("$loci$ref") q"""$expr match { case $ref: $reference if $ref.signature <= $signature => ${termNames.ROOTPKG}.scala.Some[$remote]($ref) case _ => ${termNames.ROOTPKG}.scala.None }""" } else if (documentationCompiler) atPos(tpt.pos) { q"${termNames.ROOTPKG}.scala.Predef.???" } else atPos(tpt.pos) { q"${termNames.ROOTPKG}.loci.runtime.Remote.cast[$tpt]($expr)" } } }
Example 85
Source File: ContextReference.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox trait ContextReference { object Value { trait Base[C <: blackbox.Context] { val c: C } } type Value[C <: blackbox.Context] <: Value.Base[C] def apply[C <: blackbox.Context](c: C): Value[c.type] private var value: Value[_] = _ final def get(c: blackbox.Context): Value[c.type] = this.value match { case value: Value[c.type] @unchecked if value.c eq c => value case _ => val value = apply(c) this.value = value value } }
Example 86
Source File: Logging.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox object Logging { def apply(c: blackbox.Context) = new Logging(c) } class Logging(c: blackbox.Context) { private val info = c.compilerSettings contains "-verbose" private val debug = c.settings contains "loci.macro.verbose" private val code = c.settings contains "loci.macro.expanded-code" def infoEnabled = info || debug def debugEnabled = debug def codeEnabled = code def info(message: => String): Unit = if (infoEnabled) c.info(c.universe.NoPosition, message, force = true) def debug(message: => String): Unit = if (debugEnabled) c.info(c.universe.NoPosition, message, force = true) def code(message: => String): Unit = if (codeEnabled) c.info(c.universe.NoPosition, message, force = true) }
Example 87
Source File: MultitierTypes.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl package preprocessors import scala.reflect.macros.blackbox object MultitierTypes extends Preprocessor.Factory[MultitierTypes] { def apply[C <: blackbox.Context](c: C) = new MultitierTypes(c) } class MultitierTypes[C <: blackbox.Context](val c: C) extends Preprocessor[C] { import c.universe._ def process(tree: Tree): Tree = { val outer = tree object transformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) if !(mods hasFlag Flag.TRAIT) && tree != outer => super.transform(treeCopy.ClassDef( tree, mods, name, tparams, treeCopy.Template( impl, parents, self, placedValuesDef :: body))) case _ => super.transform(tree) } } transformer transform tree } private val placedValuesDef = q"${Flag.SYNTHETIC} protected[this] def `<placed values>`: Nothing = _root_.scala.Predef.???" }
Example 88
Source File: AbstractValues.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl package preprocessors import scala.reflect.macros.blackbox object AbstractValues extends Preprocessor.Factory[AbstractValues] { def apply[C <: blackbox.Context](c: C) = new AbstractValues(c) } class AbstractValues[C <: blackbox.Context](val c: C) extends Preprocessor[C] { import c.universe._ def process(tree: Tree): Tree = { def reducedFlags(mods: Modifiers) = Seq(Flag.ABSOVERRIDE, Flag.ARTIFACT, Flag.FINAL, Flag.IMPLICIT, Flag.LOCAL, Flag.MUTABLE, Flag.OVERRIDE, Flag.PRESUPER, Flag.PRIVATE, Flag.PROTECTED, Flag.STABLE, Flag.SYNTHETIC) .foldLeft(NoFlags) { (flagAcc, flag) => if (mods hasFlag flag) flagAcc | flag else flagAcc } def processMods(mods: Modifiers) = Modifiers(reducedFlags(mods), mods.privateWithin, annotation :: mods.annotations) def processStats(stats: List[Tree]) = stats map { case tree @ DefDef(mods, name, tparams, vparamss, tpt, EmptyTree) if (mods hasFlag Flag.DEFERRED) && !(mods hasFlag Flag.PRIVATE) => treeCopy.DefDef( tree, processMods(mods), name, tparams, vparamss, tpt, q"null.asInstanceOf[$tpt]") case tree @ ValDef(mods, name, tpt, EmptyTree) if (mods hasFlag Flag.DEFERRED) && !(mods hasFlag Flag.PRIVATE) => treeCopy.ValDef( tree, processMods(mods), name, tpt, q"null.asInstanceOf[$tpt]") case tree => tree } object transformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) if mods hasFlag Flag.FINAL => super.transform(treeCopy.ClassDef( tree, mods, name, tparams, treeCopy.Template( impl, parents, self, processStats(body)))) case ModuleDef(mods, name, impl @ Template(parents, self, body)) => super.transform(treeCopy.ModuleDef( tree, mods, name, treeCopy.Template( impl, parents, self, processStats(body)))) case _ => super.transform(tree) } } transformer transform tree } private val annotation = q"new ${termNames.ROOTPKG}.loci.runtime.AbstractValue" }
Example 89
Source File: Preprocessor.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl import scala.reflect.macros.blackbox trait Preprocessor[C <: blackbox.Context] { val c: C def process(tree: c.Tree): c.Tree } object Preprocessor { def run( c: blackbox.Context)( tree: c.Tree, factories: Seq[Preprocessor.Factory[Preprocessor]]) = { val logging = Logging(c) val preprocessors = factories.distinct map { factory => factory[c.type](c) } logging.debug("Multitier preprocessors") preprocessors foreach { preprocessor => logging.debug(s" ${name(preprocessor)}") } preprocessors.foldLeft(tree) { (tree, preprocessor) => logging.debug(s"Running multitier preprocessor ${name(preprocessor)}") preprocessor process tree } } private def name(ref: AnyRef) = { val name = ref.getClass.getSimpleName if (name endsWith "$") name.dropRight(1) else name } abstract class Factory[+Pre[C <: blackbox.Context] <: Preprocessor[C]] { def apply[C <: blackbox.Context](c: C): Pre[C] } }
Example 90
Source File: RuntimeAccess.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl package components import scala.reflect.macros.blackbox object RuntimeAccess extends Component.Factory[RuntimeAccess]( requires = Seq(Commons, Values)) { def apply[C <: blackbox.Context](engine: Engine[C]) = new RuntimeAccess(engine) def asInstance[C <: blackbox.Context] = { case c: RuntimeAccess[C] => c } } class RuntimeAccess[C <: blackbox.Context](val engine: Engine[C]) extends Component[C] { val phases = Seq( Phase("runtime:access", processRuntimeAccess, after = Set("values:collect"), before = Set("impls:lift"))) val commons = engine.require(Commons) val values = engine.require(Values) import engine.c.universe._ import commons._ import values._ def processRuntimeAccess(records: List[Any]): List[Any] = { var count = 0 val result = records process { case record @ PlacedValue(_, _, _, _) => object transformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case q"$_.$name[..$tpts](...$exprss)" if tree.symbol.owner == symbols.multitier && (name == names.running || name == names.terminate) => count += 1 q"$$loci$$sys.$name[..$tpts](...$exprss)" case _ => super.transform(tree) } } record.copy(tree = transformer transform record.tree) } logging.debug(s" Processed $count multitier runtime ${if (count == 1) "query" else "queries"}") result } }
Example 91
Source File: Subjectivity.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl package components import scala.reflect.macros.blackbox object Subjectivity extends Component.Factory[Subjectivity]( requires = Seq(Commons, Values)) { def apply[C <: blackbox.Context](engine: Engine[C]) = new Subjectivity(engine) def asInstance[C <: blackbox.Context] = { case c: Subjectivity[C] => c } } class Subjectivity[C <: blackbox.Context](val engine: Engine[C]) extends Component[C] { val phases = Seq( Phase("local:sbj", processLocalSubjectiveAccess, after = Set("values:collect"), before = Set("impls:lift"))) val commons = engine.require(Commons) val values = engine.require(Values) import engine.c.universe._ import commons._ import values._ def processLocalSubjectiveAccess(records: List[Any]): List[Any] = { var count = 0 val result = records process { case record @ PlacedValue(_, _, _, _) => object transformer extends Transformer { override def transform(tree: Tree): Tree = tree match { case q"$expr.$_[..$_]($_[..$_](...$exprss))" if tree.nonEmpty && tree.symbol == symbols.to => decomposePlacementType(expr.tpe.widen, EmptyTree, expr.symbol, expr.pos, moduleDefinition = false) match { case Placed(_, _, _, Modality.Subjective(_)) => count += 1 val value = transform(expr) val remote = transform(exprss.head.head) if (expr.symbol.isTerm && expr.symbol.asTerm.isStable) q"$$loci$$sys.subjectiveValue($value, $remote)" else q"$value($remote)" case _ => transform(expr) } case _ => super.transform(tree) } } record.copy(tree = transformer transform record.tree) } logging.debug(s" Processed $count local ${if (count == 1) "access" else "accesses"} to subjective values") result } }
Example 92
Source File: ModuleInfo.scala From scala-loci with Apache License 2.0 | 5 votes |
package loci package language package impl package components import scala.reflect.macros.blackbox object ModuleInfo extends Component.Factory[ModuleInfo]( requires = Seq(Commons)) { def apply[C <: blackbox.Context](engine: Engine[C]) = new ModuleInfo(engine) def asInstance[C <: blackbox.Context] = { case c: ModuleInfo[C] => c } } class ModuleInfo[C <: blackbox.Context](val engine: Engine[C]) extends Component[C] { val phases = Seq.empty val commons = engine.require(Commons) import engine.c.universe._ import commons._ object module { val tree = engine.multitierCode val name = tree.name val className = name.toTypeName val symbol = tree.symbol val classSymbol = if (symbol.isModule) symbol.asModule.moduleClass.asClass else symbol.asClass val self = uniqueRealisticTermName(engine.multitierCode.symbol) val outer = engine.outerMultitierName.headOption val path = engine.outerMultitierName.reverse map { case (value, _) => value } } private val underExpansion: Set[Symbol] = (engine.multitierCode collect { case tree: DefTree if tree.symbol != NoSymbol => tree.symbol }).toSet def underExpansion(symbol: Symbol): Boolean = underExpansion contains symbol private val underEnclosingExpansion: Set[Symbol] = (engine.outerMultitierCode collect { case tree: DefTree if tree.symbol != NoSymbol => tree.symbol }).toSet def underEnclosingExpansion(symbol: Symbol): Boolean = underEnclosingExpansion contains symbol }
Example 93
Source File: DerivingMacros.scala From scalaz-deriving with GNU Lesser General Public License v3.0 | 5 votes |
// Copyright: 2017 - 2020 Sam Halliday // License: http://www.gnu.org/licenses/lgpl-3.0.en.html package scalaz.macros import scala.Predef._ import scala.reflect.macros.blackbox final class DerivingMacrosImpl(val c: blackbox.Context) { import c.universe._ def deriving[F[_], A](implicit evF: c.WeakTypeTag[F[_]], evA: c.WeakTypeTag[A] ): Tree = { val F = evF.tpe val A = evA.tpe val fqn = F.dealias.typeSymbol.fullName readConfig().targets.get(fqn) match { case Some(target) => parseTerm(target) case None => q"_root_.scalaz.Deriving.gen[$F, $A]" } } def xderiving[F[_], A](implicit evF: c.WeakTypeTag[F[_]], evA: c.WeakTypeTag[A] ): Tree = { val F = evF.tpe val A = evA.tpe A.decls.collect { case m: MethodSymbol if m.isParamAccessor => m.asMethod }.toList match { case value :: Nil => val hasXmap = F.decls.find(_.name.toString == "xmap").isDefined val access = value.name val U = value.typeSignatureIn(A).resultType def invariant = q"""_root_.scalaz.InvariantFunctor[${F.typeSymbol}].xmap( _root_.scala.Predef.implicitly[${F.typeSymbol}[$U]], (u: $U) => new $A(u), (a: $A) => a.$access)""" def xmap = q"""_root_.scala.Predef.implicitly[${F.typeSymbol}[$U]].xmap( (u: $U) => new $A(u), (a: $A) => a.$access)""" if (hasXmap) xmap else invariant case _ => c.abort(c.enclosingPosition, "only supports classes with one parameter") } } private def readConfig(): DerivingConfig = DerivingConfig.targets .fold( error => { c.error(c.prefix.tree.pos, s"Failed to parse deriving config: $error") throw new IllegalStateException }, success => DerivingConfig(success) ) private def parseTerm(s: String): Tree = { def toSelect(parts: List[TermName]): Tree = parts match { case Nil => Ident(termNames.ROOTPKG) case head :: tail => Select(toSelect(tail), head) } toSelect(s.split("[.]").toList.map(TermName(_)).reverse) } } object DerivingMacros { def deriving[F[_], A]: F[A] = macro DerivingMacrosImpl.deriving[F, A] def xderiving[F[_], A]: F[A] = macro DerivingMacrosImpl.xderiving[F, A] }
Example 94
Source File: LoggerMacros.scala From almond with BSD 3-Clause "New" or "Revised" License | 5 votes |
package almond.logger.internal import scala.reflect.macros.blackbox object LoggerMacros { def error(c: blackbox.Context)(message: c.Expr[String]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.errorEnabled) ${c.prefix}.underlying.error($message)" } def warn(c: blackbox.Context)(message: c.Expr[String]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.warningEnabled) ${c.prefix}.underlying.warn($message)" } def info(c: blackbox.Context)(message: c.Expr[String]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.infoEnabled) ${c.prefix}.underlying.info($message)" } def debug(c: blackbox.Context)(message: c.Expr[String]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.debugEnabled) ${c.prefix}.underlying.debug($message)" } def errorEx(c: blackbox.Context)(message: c.Expr[String], throwable: c.Expr[Throwable]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.errorEnabled) ${c.prefix}.underlying.error($message, $throwable)" } def warnEx(c: blackbox.Context)(message: c.Expr[String], throwable: c.Expr[Throwable]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.warningEnabled) ${c.prefix}.underlying.warn($message, $throwable)" } def infoEx(c: blackbox.Context)(message: c.Expr[String], throwable: c.Expr[Throwable]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.infoEnabled) ${c.prefix}.underlying.info($message, $throwable)" } def debugEx(c: blackbox.Context)(message: c.Expr[String], throwable: c.Expr[Throwable]): c.universe.Tree = { import c.universe._ q"if (${c.prefix}.underlying.debugEnabled) ${c.prefix}.underlying.debug($message, $throwable)" } }
Example 95
Source File: Macros.scala From caliban with Apache License 2.0 | 5 votes |
package caliban import scala.language.experimental.macros import scala.reflect.macros.blackbox import caliban.parsing.Parser object Macros { def gqldoc(document: String): String = macro MacrosInternal.queryLiteral private class MacrosInternal(val c: blackbox.Context) { import c.universe._ def queryLiteral(document: c.Expr[String]): c.Expr[String] = document.tree match { case Literal(Constant(s: String)) => Parser.check(s).fold(document)(e => c.abort(c.enclosingPosition, s"GraphQL document is invalid: $e")) case _ => c.abort(c.enclosingPosition, s"This macro can only be used with string literals.") } } }
Example 96
Source File: CodeExampleImpl.scala From slinky with MIT License | 5 votes |
package slinky.docs import java.io.File import slinky.core.facade.ReactElement import scala.io.Source import scala.reflect.macros.blackbox object CodeExampleImpl { def text(c: blackbox.Context)(exampleLocation: c.Expr[String]): c.Expr[ReactElement] = { import c.universe._ val Literal(Constant(loc: String)) = exampleLocation.tree val inputFile = new File(s"docs/src/main/scala/${loc.split('.').mkString("/")}.scala") val enclosingPackage = loc.split('.').init.mkString(".") val fileContent = Source.fromFile(inputFile).mkString val innerCode = fileContent.split('\n') val textToDisplay = innerCode .map(_.replaceAllLiterally("//display:", "")) .filterNot(_.endsWith("//nodisplay")) .dropWhile(_.trim.isEmpty) .reverse.dropWhile(_.trim.isEmpty).reverse .mkString("\n") val codeToRun = innerCode.filter(_.startsWith("//run:")).map(_.replaceAllLiterally("//run:", "")).mkString("\n") c.Expr[ReactElement]( q"""{ import ${c.parse(enclosingPackage)}._ _root_.slinky.docs.CodeExampleInternal(codeText = ${Literal(Constant(textToDisplay))}, demoElement = {${c.parse(codeToRun)}}) }""") } }
Example 97
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 98
Source File: ShapelessMacros.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.macros import shapeless.ReprTypes import scala.annotation.tailrec import scala.reflect.macros.blackbox trait ShapelessMacros extends ReprTypes with MacroMessages with SymbolMacros { val c: blackbox.Context import c.universe._ def unfoldCompoundTpe(compoundTpe: Type, nil: Type, cons: Type): List[Type] = { @tailrec def loop(tpe: Type, acc: List[Type]): List[Type] = tpe.dealias match { case TypeRef(_, consSym, List(hd, tl)) if consSym.asType.toType.typeConstructor =:= cons => loop(tl, hd :: acc) case `nil` => acc case other => abort(s"Bad compound type $compoundTpe") } loop(compoundTpe, Nil).reverse } def hlistElements(tpe: Type): List[Type] = unfoldCompoundTpe(tpe, hnilTpe, hconsTpe) def extractRecord(tpe: Type): List[Option[(String, Type)]] = hlistElements(tpe).map { case FieldType(KeyName(name), value) => Some(name -> value) case _ => None } object FieldType { import internal._ def apply(kTpe: Type, vTpe: Type): Type = refinedType(List(vTpe, typeRef(keyTagTpe, keyTagTpe.typeSymbol, List(kTpe, vTpe))), NoSymbol) def unapply(fTpe: Type): Option[(Type, Type)] = { val KeyTagPre = keyTagTpe fTpe.dealias match { case RefinedType(List(v0, TypeRef(pre, sym, List(k, v1))), _) if sym.asType.toType.typeConstructor =:= KeyTagPre && v0 =:= v1 => Some((k, v0)) case _ => None } } } }
Example 99
Source File: Query1.scala From scio with Apache License 2.0 | 5 votes |
package com.spotify.scio.sql import com.spotify.scio.schemas._ import com.spotify.scio.values.SCollection import org.apache.beam.sdk.extensions.sql.SqlTransform import org.apache.beam.sdk.extensions.sql.impl.ParseException import org.apache.beam.sdk.values._ import scala.reflect.ClassTag final case class Query1[A, B]( query: String, tag: TupleTag[A] = Sql.defaultTag[A], udfs: List[Udf] = Nil ) object Query1 { import scala.reflect.macros.blackbox import QueryMacros._ def typecheck[A: Schema, B: Schema](q: Query1[A, B]): Either[String, Query1[A, B]] = Queries .typecheck( q.query, List((q.tag.getId, SchemaMaterializer.beamSchema[A])), SchemaMaterializer.beamSchema[B], q.udfs ) .right .map(_ => q) def typed[A: Schema, B: Schema](query: String): Query1[A, B] = macro typedImplDefaultTag[A, B] def typed[A: Schema, B: Schema](query: String, aTag: TupleTag[A]): Query1[A, B] = macro typedImpl[A, B] def typedImplDefaultTag[A: c.WeakTypeTag, B: c.WeakTypeTag](c: blackbox.Context)( query: c.Expr[String] )(iSchema: c.Expr[Schema[A]], oSchema: c.Expr[Schema[B]]): c.Expr[Query1[A, B]] = { val h = new { val ctx: c.type = c } with SchemaMacroHelpers import h._ import c.universe._ val tag = c.Expr[TupleTag[A]](q"${Sql.defaultTag[A]}") typedImpl(c)(query, tag)(iSchema, oSchema) } def typedImpl[A: c.WeakTypeTag, B: c.WeakTypeTag](c: blackbox.Context)( query: c.Expr[String], aTag: c.Expr[TupleTag[A]] )(iSchema: c.Expr[Schema[A]], oSchema: c.Expr[Schema[B]]): c.Expr[Query1[A, B]] = { val h = new { val ctx: c.type = c } with SchemaMacroHelpers import h._ import c.universe._ assertConcrete[A](c) assertConcrete[B](c) val (sIn, sOut) = c.eval(c.Expr[(Schema[A], Schema[B])](q"(${untyped(iSchema)}, ${untyped(oSchema)})")) val sq = Query1[A, B](cons(c)(query), tupleTag(c)(aTag)) typecheck(sq)(sIn, sOut) .fold( err => c.abort(c.enclosingPosition, err), _ => c.Expr[Query1[A, B]](q"_root_.com.spotify.scio.sql.Query1($query, $aTag)") ) } } final class SqlSCollection1[A: Schema: ClassTag](sc: SCollection[A]) { def query(q: String, udfs: Udf*): SCollection[Row] = query(Query1[A, Row](q, Sql.defaultTag, udfs = udfs.toList)) def query(q: Query1[A, Row]): SCollection[Row] = sc.context.wrap { val scWithSchema = Sql.setSchema(sc) val transform = SqlTransform .query(q.query) .withTableProvider(Sql.BeamProviderName, Sql.tableProvider(q.tag, scWithSchema)) val sqlTransform = Sql.registerUdf(transform, q.udfs: _*) scWithSchema.applyInternal(sqlTransform) } def queryAs[R: Schema: ClassTag](q: String, udfs: Udf*): SCollection[R] = queryAs(Query1[A, R](q, Sql.defaultTag, udfs = udfs.toList)) def queryAs[R: Schema: ClassTag](q: Query1[A, R]): SCollection[R] = try { query(Query1[A, Row](q.query, q.tag, q.udfs)).to(To.unchecked((_, i) => i)) } catch { case e: ParseException => Query1.typecheck(q).fold(err => throw new RuntimeException(err, e), _ => throw e) } }
Example 100
Source File: MacroSettings.scala From scio with Apache License 2.0 | 5 votes |
package com.spotify.scio import scala.reflect.macros.blackbox sealed private[scio] trait FeatureFlag private[scio] object FeatureFlag { case object Enable extends FeatureFlag case object Disable extends FeatureFlag } private[scio] object MacroSettings { private def getFlag(settings: List[String])(name: String, default: FeatureFlag): FeatureFlag = { val ss: Map[String, String] = settings .map(_.split("=")) .map { case Array(k, v) => (k.trim, v.trim) } .toMap ss.get(name) .map { case "true" => FeatureFlag.Enable case "false" => FeatureFlag.Disable case v => throw new IllegalArgumentException( s"""Invalid value for setting -Xmacro-settings:$name,""" + s"""expected "true" or "false", got $v""" ) } .getOrElse(default) } def cacheImplicitSchemas(c: blackbox.Context): FeatureFlag = getFlag(c.settings)("cache-implicit-schemas", FeatureFlag.Disable) }
Example 101
Source File: SysPropsMacros.scala From scio with Apache License 2.0 | 5 votes |
package com.spotify.scio import scala.annotation.{compileTimeOnly, StaticAnnotation} import scala.reflect.macros.blackbox @compileTimeOnly( "enable macro paradise (2.12) or -Ymacro-annotations (2.13) to expand macro annotations" ) final class registerSysProps extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro registerSysPropsMacro.impl } private object registerSysPropsMacro { def impl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { import c.universe._ val traitT = tq"_root_.com.spotify.scio.SysProps" annottees.map(_.tree) match { case List(q"$mod object $name extends ..$parents { ..$body }") => val vars = body.collect { case ValDef(_, _, _, rhs) => c.Expr(rhs) } val propertiesMethod = q"""override def properties: List[SysProp] = List(..$vars)""" c.Expr[Any](q""" $mod object $name extends ..$parents with $traitT { $propertiesMethod ..$body } """) case t => c.abort(c.enclosingPosition, s"Invalid annotation $t") } } }
Example 102
Source File: AvroCoderMacros.scala From scio with Apache License 2.0 | 5 votes |
package com.spotify.scio.coders import org.apache.avro.specific.SpecificRecordBase import scala.reflect.macros.blackbox private[coders] object AvroCoderMacros { def staticInvokeCoder[T <: SpecificRecordBase: c.WeakTypeTag](c: blackbox.Context): c.Tree = { import c.universe._ val wtt = weakTypeOf[T] val companioned = wtt.typeSymbol q""" _root_.com.spotify.scio.coders.Coder.beam( _root_.org.apache.beam.sdk.coders.AvroCoder.of[$companioned]( classOf[$companioned], new $companioned().getSchema ) ) """ } }
Example 103
Source File: SetProperty.scala From scio with Apache License 2.0 | 5 votes |
package com.spotify.scio.bigquery.validation import scala.annotation.{compileTimeOnly, StaticAnnotation} import scala.reflect.macros.blackbox // This shouldn't be necessary in most production use cases. However passing System properties from // Intellij can cause issues. The ideal place to set this system property is in your build.sbt file. private[validation] object SetProperty { @compileTimeOnly( "enable macro paradise (2.12) or -Ymacro-annotations (2.13) to expand macro annotations" ) class setProperty extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro setPropertyImpl } def setSystemProperty(): String = System.setProperty( "override.type.provider", "com.spotify.scio.bigquery.validation.SampleOverrideTypeProvider" ) def setPropertyImpl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { setSystemProperty() annottees.head } }
Example 104
Source File: Debug.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal object Debug { import scala.reflect.macros.blackbox private val macroDebugEnabled = System.getenv("TAPIR_LOG_GENERATED_CODE") == "true" def logGeneratedCode(c: blackbox.Context)(typeName: String, tree: c.universe.Tree): Unit = { import c.universe._ if (macroDebugEnabled) { println(s"""$typeName macro output start:""") println(showCode(tree)) println(s"""$typeName macro output end.""") } } }
Example 105
Source File: CaseClassUtil.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal import scala.reflect.macros.blackbox private[generic] class CaseClassUtil[C <: blackbox.Context, T: C#WeakTypeTag](val c: C) { import c.universe._ val t: Type = weakTypeOf[T] if (!t.typeSymbol.isClass || !t.typeSymbol.asClass.isCaseClass) { c.error(c.enclosingPosition, s"Multipart codec can only be generated for a case class, but got: $t.") } lazy val fields: List[Symbol] = t.decls .collectFirst { case m: MethodSymbol if m.isPrimaryConstructor => m } .get .paramLists .head private lazy val companion: Ident = Ident(TermName(t.typeSymbol.name.decodedName.toString)) lazy val instanceFromValues: Tree = if (fields.size == 1) { q"$companion.apply(values.head.asInstanceOf[${fields.head.typeSignature}])" } else { q"$companion.tupled.asInstanceOf[Any => $t].apply(sttp.tapir.internal.SeqToParams(values))" } lazy val schema: Tree = c.typecheck(q"implicitly[sttp.tapir.Schema[$t]]") }
Example 106
Source File: FormCodecDerivation.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal import sttp.tapir.generic.Configuration import sttp.tapir.{Codec, CodecFormat} import scala.reflect.macros.blackbox trait FormCodecDerivation { implicit def formCaseClassCodec[T <: Product with Serializable](implicit conf: Configuration ): Codec[String, T, CodecFormat.XWwwFormUrlencoded] = macro FormCodecMacros.generateForCaseClass[T] } object FormCodecMacros { // http://blog.echo.sh/2013/11/04/exploring-scala-macros-map-to-case-class-conversion.html def generateForCaseClass[T: c.WeakTypeTag]( c: blackbox.Context )(conf: c.Expr[Configuration]): c.Expr[Codec[String, T, CodecFormat.XWwwFormUrlencoded]] = { import c.universe._ val t = weakTypeOf[T] val util = new CaseClassUtil[c.type, T](c) val fields = util.fields val fieldsWithCodecs = fields.map { field => (field, c.typecheck(q"implicitly[sttp.tapir.Codec[List[String], ${field.typeSignature}, sttp.tapir.CodecFormat.TextPlain]]")) } val encodeParams: Iterable[Tree] = fieldsWithCodecs.map { case (field, codec) => val fieldName = field.name.asInstanceOf[TermName] val fieldNameAsString = fieldName.decodedName.toString q"""val transformedName = $conf.toLowLevelName($fieldNameAsString) $codec.encode(o.$fieldName).map(v => (transformedName, v))""" } val decodeParams = fieldsWithCodecs.map { case (field, codec) => val fieldName = field.name.decodedName.toString q"""val transformedName = $conf.toLowLevelName($fieldName) $codec.decode(paramsMap.get(transformedName).toList.flatten)""" } val codecTree = q""" { def decode(params: Seq[(String, String)]): sttp.tapir.DecodeResult[$t] = { val paramsMap: Map[String, Seq[String]] = params.groupBy(_._1).mapValues(_.map(_._2)).toMap val decodeResults = List(..$decodeParams) sttp.tapir.DecodeResult.sequence(decodeResults).map { values => ${util.instanceFromValues} } } def encode(o: $t): Seq[(String, String)] = List(..$encodeParams).flatten sttp.tapir.Codec.formSeqCodecUtf8 .mapDecode(decode _)(encode _) .schema(${util.schema}) .validate(implicitly[sttp.tapir.Validator[$t]]) } """ Debug.logGeneratedCode(c)(t.typeSymbol.fullName, codecTree) c.Expr[Codec[String, T, CodecFormat.XWwwFormUrlencoded]](codecTree) } }
Example 107
Source File: OneOfMacro.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal import sttp.tapir.Schema import scala.annotation.tailrec import scala.reflect.macros.blackbox object OneOfMacro { // http://onoffswitch.net/extracting-scala-method-names-objects-macros/ def oneOfMacro[E: c.WeakTypeTag, V: c.WeakTypeTag]( c: blackbox.Context )(extractor: c.Expr[E => V], asString: c.Expr[V => String])(mapping: c.Expr[(V, Schema[_])]*): c.Expr[Schema[E]] = { import c.universe._ @tailrec def resolveFunctionName(f: Function): String = { f.body match { // the function name case t: Select => t.name.decodedName.toString case t: Function => resolveFunctionName(t) // an application of a function and extracting the name case t: Apply if t.fun.isInstanceOf[Select @unchecked] => t.fun.asInstanceOf[Select].name.decodedName.toString // curried lambda case t: Block if t.expr.isInstanceOf[Function @unchecked] => val func = t.expr.asInstanceOf[Function] resolveFunctionName(func) case _ => throw new RuntimeException("Unable to resolve function name for expression: " + f.body) } } val weakTypeE = weakTypeOf[E] def extractTypeArguments(weakType: c.Type): List[String] = { def allTypeArguments(tn: c.Type): Seq[c.Type] = tn.typeArgs.flatMap(tn2 => tn2 +: allTypeArguments(tn2)) allTypeArguments(weakType).map(_.typeSymbol.name.decodedName.toString).toList } val name = resolveFunctionName(extractor.tree.asInstanceOf[Function]) val schemaForE = q"""{ import sttp.tapir.Schema._ import sttp.tapir.SchemaType._ val rawMapping = scala.collection.immutable.Map(..$mapping) val discriminator = Discriminator($name, rawMapping.map{case (k, sf)=> $asString.apply(k) -> SRef(sf.schemaType.asInstanceOf[SObject].info)}) Schema(SCoproduct(SObjectInfo(${weakTypeE.typeSymbol.fullName},${extractTypeArguments(weakTypeE)}), rawMapping.values.toList, Some(discriminator))) }""" Debug.logGeneratedCode(c)(weakTypeE.typeSymbol.fullName, schemaForE) c.Expr[Schema[E]](schemaForE) } }
Example 108
Source File: SchemaMapMacro.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal import sttp.tapir.Schema import scala.reflect.macros.blackbox object SchemaMapMacro { def schemaForMap[M: c.WeakTypeTag, V: c.WeakTypeTag]( c: blackbox.Context )(schemaForV: c.Expr[Schema[V]]): c.Expr[Schema[Map[String, V]]] = { import c.universe._ def extractTypeArguments(weakType: c.Type): List[String] = { def allTypeArguments(tn: c.Type): Seq[c.Type] = tn.typeArgs.flatMap(tn2 => tn2 +: allTypeArguments(tn2)) allTypeArguments(weakType).map(_.typeSymbol.name.decodedName.toString).toList } val weakTypeV = weakTypeOf[V] val genericTypeParametersM = List(weakTypeV.typeSymbol.name.decodedName.toString) ++ extractTypeArguments(weakTypeV) val schemaForMap = q"""sttp.tapir.Schema(sttp.tapir.SchemaType.SOpenProduct(sttp.tapir.SchemaType.SObjectInfo("Map", ${genericTypeParametersM}), ${schemaForV}))""" Debug.logGeneratedCode(c)(weakTypeV.typeSymbol.fullName, schemaForMap) c.Expr[Schema[Map[String, V]]](schemaForMap) } }
Example 109
Source File: ValidatorEnumMacro.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.generic.internal import sttp.tapir.Validator import scala.reflect.macros.blackbox // based on: https://stackoverflow.com/questions/13671734/iteration-over-a-sealed-trait-in-scala trait ValidatorEnumMacro { def validatorForEnum[E: c.WeakTypeTag](c: blackbox.Context): c.Expr[Validator.Enum[E]] = { import c.universe._ val t = weakTypeOf[E] val symbol = t.typeSymbol.asClass if (!symbol.isClass || !symbol.isSealed) { c.abort(c.enclosingPosition, "Can only enumerate values of a sealed trait or class.") } else { val subclasses = symbol.knownDirectSubclasses.toList.sortBy(_.name.encodedName.toString) if (!subclasses.forall(_.isModuleClass)) { c.abort(c.enclosingPosition, "All children must be objects.") } else { val instances = subclasses.map(x => Ident(x.asInstanceOf[scala.reflect.internal.Symbols#Symbol].sourceModule.asInstanceOf[Symbol])) val validatorEnum = q"sttp.tapir.Validator.enum($instances)" Debug.logGeneratedCode(c)(t.typeSymbol.fullName, validatorEnum) c.Expr[Validator.Enum[E]](validatorEnum) } } } }
Example 110
Source File: ModifySchemaMacro.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.internal import sttp.tapir.Schema import scala.annotation.tailrec import scala.reflect.macros.blackbox object ModifySchemaMacro { private val ShapeInfo = "Path must have shape: _.field1.field2.each.field3.(...)" def modifyMacro[T: c.WeakTypeTag, U: c.WeakTypeTag]( c: blackbox.Context )(path: c.Expr[T => U])(modification: c.Expr[Schema[U] => Schema[U]]): c.Tree = applyModification[T, U](c)(extractPathFromFunctionCall(c)(path), modification) def setDescriptionMacro[T: c.WeakTypeTag, U: c.WeakTypeTag]( c: blackbox.Context )(path: c.Expr[T => U], description: c.Expr[String]): c.Tree = addDescription[T, U](c)(extractPathFromFunctionCall(c)(path), description) private def addDescription[T: c.WeakTypeTag, U: c.WeakTypeTag](c: blackbox.Context)( path: c.Expr[List[String]], description: c.Expr[String] ): c.Tree = { import c.universe._ q"""{ ${c.prefix}.modifyUnsafe($path:_*)((v: sttp.tapir.Schema[${c.weakTypeOf[T]}]) => v.description($description)) }""" } private def applyModification[T: c.WeakTypeTag, U: c.WeakTypeTag](c: blackbox.Context)( path: c.Expr[List[String]], modification: c.Expr[Schema[U] => Schema[U]] ): c.Tree = { import c.universe._ q"""{ ${c.prefix}.modifyUnsafe($path:_*)($modification) }""" } @tailrec def collectPathElements(tree: c.Tree, acc: List[PathElement]): List[PathElement] = { def typeSupported(quicklensType: c.Tree) = Seq("ModifyEach", "ModifyEither", "ModifyEachMap") .exists(quicklensType.toString.endsWith) tree match { case q"$parent.$child " => collectPathElements(parent, TermPathElement(child) :: acc) case q"$tpname[..$_]($t)($f) " if typeSupported(tpname) => val newAcc = acc match { // replace the term controlled by quicklens case TermPathElement(term, xargs @ _*) :: rest => FunctorPathElement(f, term, xargs: _*) :: rest case pathEl :: _ => c.abort(c.enclosingPosition, s"Invalid use of path element $pathEl. $ShapeInfo, got: ${path.tree}") case Nil => c.abort(c.enclosingPosition, s"Invalid use of path element(Nil). $ShapeInfo, got: ${path.tree}") } collectPathElements(t, newAcc) case _: Ident => acc case _ => c.abort(c.enclosingPosition, s"Unsupported path element. $ShapeInfo, got: $tree") } } val pathEls = path.tree match { case q"($arg) => $pathBody " => collectPathElements(pathBody, Nil) case _ => c.abort(c.enclosingPosition, s"$ShapeInfo, got: ${path.tree}") } def isOptionalFunctor(tree: c.Tree): Boolean = { tree match { case TypeApply(Select(_, TermName("optionModifyFunctor")), _) => true case _ => false } } c.Expr[List[String]](q"${pathEls.collect { case TermPathElement(c) => c.decodedName.toString case FunctorPathElement(functor, method, _ @_*) if !isOptionalFunctor(functor) => method.decodedName.toString }}") } private[internal] def ignoredFromPath[T, U](path: T => U): List[String] = macro extractPathFromFunctionCall[T, U] }
Example 111
Source File: StatusMappingMacro.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.internal import sttp.model.StatusCode import sttp.tapir.EndpointOutput import sttp.tapir.EndpointOutput.StatusMapping import scala.reflect.ClassTag import scala.reflect.macros.blackbox object StatusMappingMacro { def classMatcherIfErasedSameAsType[O: c.WeakTypeTag](c: blackbox.Context)( statusCode: c.Expr[StatusCode], output: c.Expr[EndpointOutput[O]] )(ct: c.Expr[ClassTag[O]]): c.Expr[StatusMapping[O]] = { import c.universe._ val t = implicitly[c.WeakTypeTag[O]].tpe.dealias if (!(t =:= t.erasure) && !(t =:= typeOf[Unit])) { c.error( c.enclosingPosition, s"Constructing statusMapping of type $t is not allowed because of type erasure. Using a runtime-class-based check it isn't possible to verify " + s"that the input matches the desired class. Please use statusMappingClassMatcher, statusMappingValueMatcher or statusMappingFromMatchType instead" ) } c.Expr[StatusMapping[O]](q"sttp.tapir.statusMappingClassMatcher($statusCode, $output, $ct.runtimeClass)") } }
Example 112
Source File: SealedValues.scala From flamy with Apache License 2.0 | 5 votes |
package com.flaminem.flamy.utils.macros import scala.collection.immutable.Seq import scala.language.experimental.macros import scala.reflect.macros.blackbox //scalastyle:off object SealedValues { def values[A]: Seq[A] = macro values_impl[A] def values_impl[A: c.WeakTypeTag](c: blackbox.Context) : c.Expr[Seq[A]] = { import c.universe._ val symbol = weakTypeOf[A].typeSymbol if (!symbol.isClass) { c.abort( c.enclosingPosition, "Can only enumerate values of a sealed trait or class." )} else if (!symbol.asClass.isSealed) { c.abort( c.enclosingPosition, "Can only enumerate values of a sealed trait or class." ) } else { val siblingSubclasses: List[Symbol] = scala.util.Try { val enclosingModule = c.macroApplication enclosingModule.filter { x => scala.util.Try(x.symbol.asModule.moduleClass.asClass.baseClasses.contains(symbol)) .getOrElse(false) }.map(_.symbol) } getOrElse { Nil } val children = symbol.asClass.knownDirectSubclasses.toList.sortBy{_.pos.start} ::: siblingSubclasses if (!children.forall(x => x.isModuleClass || x.isModule)) { c.abort( c.enclosingPosition, "All children must be objects." ) } else c.Expr[Seq[A]] { def sourceModuleRef(sym: Symbol) = Ident( if (sym.isModule) { sym } else { sym.asInstanceOf[ scala.reflect.internal.Symbols#Symbol ].sourceModule.asInstanceOf[Symbol] } ) Apply( Select( reify(Seq).tree, TermName("apply") ), children.map(sourceModuleRef(_)) ) } } } } //scalastyle:on
Example 113
Source File: Macros.scala From jsonapi-scala with BSD 3-Clause "New" or "Revised" License | 5 votes |
package com.qvantel.jsonapi import scala.annotation.compileTimeOnly import com.qvantel.jsonapi.macrosupport.{JsonApiReaders, JsonApiWriters} import scala.reflect.macros.blackbox @compileTimeOnly("Macros can only be used at compile-time") final class Macros(val c: blackbox.Context) extends JsonApiWriters with JsonApiReaders { import c.universe._ private[this] def createFormat(t: c.Type): c.Tree = { val rootParamName = TermName(c.freshName("root")) val includedParamName = TermName(c.freshName("included")) val includePaths = TermName(c.freshName("includePaths")) val includePath = TermName(c.freshName("includePath")) q"""new _root_.com.qvantel.jsonapi.JsonApiFormat[$t] with _root_.spray.json.RootJsonFormat[$t] { import _root_.com.qvantel.jsonapi.PathJsonFormat override final def write($rootParamName: $t, sparseFields: Map[String, List[String]]): _root_.spray.json.JsValue = ${primaryDataWriter( t, rootParamName)} override final def included($rootParamName: $t, sparseFields: Map[String, List[String]]): _root_.scala.collection.immutable.Set[_root_.spray.json.JsObject] = ${includedWriter( t, rootParamName)} override final def read( $rootParamName: _root_.spray.json.JsValue, $includedParamName: _root_.scala.collection.immutable.Map[(String, String), _root_.spray.json.JsObject], $includePaths: _root_.scala.collection.immutable.Set[String], $includePath: String ): $t = ${reader(t, rootParamName, includedParamName, includePaths, includePath)} }""" } def createIncludes[A: c.WeakTypeTag]: c.Tree = { val t = weakTypeOf[A] val includeParamName = TermName(c.freshName()) val includeMapParamName = TermName(c.freshName()) q""" new _root_.com.qvantel.jsonapi.Includes[$t] { private[this] final lazy val $includeMapParamName: Map[String, _root_.com.qvantel.jsonapi.Includes[_]] = ${includesMap( t)} override def includeAllowed($includeParamName: String): Boolean = ${includeAllowed(t, includeParamName, includeMapParamName)} } """ } def jsonApiWriterWithNoNameManglingImpl[A: c.WeakTypeTag]: c.Tree = createWriter(weakTypeOf[A]) def jsonApiFormatWithNoNameManglingImpl[A: c.WeakTypeTag]: c.Tree = createFormat(weakTypeOf[A]) }
Example 114
Source File: CompileTimeState.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.derivation import scala.collection.mutable import scala.reflect.macros.blackbox private[derivation] object CompileTimeState { sealed abstract class TypePath(path: String) { override def toString = path } final case class CoproductType(typeName: String) extends TypePath(s"coproduct type $typeName") final case class ProductType(paramName: String, typeName: String) extends TypePath(s"parameter '$paramName' of product type $typeName") final case class ChainedImplicit(typeClassName: String, typeName: String) extends TypePath(s"chained implicit $typeClassName for type $typeName") final class Stack[C <: blackbox.Context with Singleton] { private var frames = List.empty[Frame] private val cache = mutable.Map.empty[C#Type, C#Tree] def isEmpty: Boolean = frames.isEmpty def nonEmpty: Boolean = frames.nonEmpty def top: Option[Frame] = frames.headOption def pop(): Unit = frames = frames drop 1 def push(frame: Frame): Unit = frames ::= frame def clear(): Unit = { frames = Nil cache.clear() } def find(searchType: C#Type): Option[C#TermName] = frames.collectFirst { case Frame(_, tpe, term) if tpe =:= searchType => term } def recurse[T <: C#Tree](frame: Frame, searchType: C#Type)(fn: => C#Tree): C#Tree = { push(frame) val result = cache.getOrElseUpdate(searchType, fn) pop() result } def trace: List[TypePath] = frames.drop(1).zip(frames).collect { case (Frame(path, tp1, _), Frame(_, tp2, _)) if !(tp1 =:= tp2) => path } override def toString: String = frames.mkString(" a stack:\n", "\n", "\n") final case class Frame(path: TypePath, searchType: C#Type, term: C#TermName) } object Stack { // Cheating to satisfy Singleton bound (which improves type inference). private val dummyContext: blackbox.Context = null private val global = new Stack[dummyContext.type] private val workSet = mutable.Set.empty[blackbox.Context#Symbol] def withContext(c: blackbox.Context)(fn: Stack[c.type] => c.Tree): c.Tree = { workSet += c.macroApplication.symbol val depth = c.enclosingMacros.count(m => workSet(m.macroApplication.symbol)) try fn(global.asInstanceOf[Stack[c.type]]) finally if (depth <= 1) { global.clear() workSet.clear() } } } }
Example 115
Source File: ExportMacro.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.derivation.auto import ru.tinkoff.phobos.encoding.ElementEncoder import ru.tinkoff.phobos.decoding.ElementDecoder import scala.reflect.macros.blackbox class ExportMacro(val c: blackbox.Context) { import c.universe._ def exportEncoder[A: WeakTypeTag]: Expr[Exported[ElementEncoder[A]]] = { c.Expr[Exported[ElementEncoder[A]]](q"""new _root_.ru.tinkoff.phobos.derivation.auto.Exported( _root_.ru.tinkoff.phobos.derivation.semiauto.deriveElementEncoder[${weakTypeOf[A]}] )""") } def exportDecoder[A: WeakTypeTag]: Expr[Exported[ElementDecoder[A]]] = { c.Expr[Exported[ElementDecoder[A]]](q"""new _root_.ru.tinkoff.phobos.derivation.auto.Exported( _root_.ru.tinkoff.phobos.derivation.semiauto.deriveElementDecoder[${weakTypeOf[A]}] )""") } }
Example 116
Source File: ElementCodec.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.annotations import ru.tinkoff.phobos.configured.ElementCodecConfig import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.reflect.macros.blackbox @compileTimeOnly("enable macro paradise to expand macro annotations") final class ElementCodec(config: ElementCodecConfig = ElementCodecConfig.default) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro ElementCodecImpl.impl } private final class ElementCodecImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) { import c.universe._ def instances(typ: Tree): Seq[Tree] = { val pkg = q"ru.tinkoff.phobos" val config = c.prefix.tree match { case q"new ElementCodec" => defaultConfig.tree case q"new ElementCodec($config)" => config } Seq( q""" implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] = $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config) """, q""" implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] = $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config) """ ) } }
Example 117
Source File: CodecAnnotation.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.annotations import ru.tinkoff.phobos.configured.ElementCodecConfig import scala.reflect.macros.blackbox private[phobos] abstract class CodecAnnotation(val c: blackbox.Context) { import c.universe._ def instances(typ: Tree): Seq[Tree] def impl(annottees: c.Tree*): c.Tree = { annottees match { case Seq(q"$mods object $obj extends { ..$earlydefns } with ..$parents { $self => ..$body }") => q""" $mods object $obj extends {..$earlydefns} with ..$parents { $self => ..${instances(tq"$obj.type") ++: body} } """ case Seq(cls: ClassDef) => q""" $cls object ${cls.name.toTermName} { ..${instances(tq"${cls.name}")} } """ case Seq(cls: ClassDef, q"$mods object $obj extends { ..$earlydefns } with ..$parents { $self => ..$body }") => q""" $cls $mods object $obj extends {..$earlydefns} with ..$parents { $self => ..${instances(tq"${cls.name}") ++: body} } """ case _ => c.abort(c.enclosingPosition, "Namespace must be represented with class or object") } } protected val defaultConfig = reify(ElementCodecConfig.default) }
Example 118
Source File: XmlCodecNs.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.annotations import ru.tinkoff.phobos.Namespace import ru.tinkoff.phobos.configured.ElementCodecConfig import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.reflect.macros.blackbox @compileTimeOnly("enable macro paradise to expand macro annotations") class XmlCodecNs[T: Namespace](localName: String, namespace: T, config: ElementCodecConfig = ElementCodecConfig.default) extends StaticAnnotation { def namespaceUri: String = Namespace[T].getNamespace def macroTransform(annottees: Any*): Any = macro XmlCodecNsImpl.impl } private final class XmlCodecNsImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) { import c.universe._ def instances(typ: Tree): Seq[Tree] = { val pkg = q"ru.tinkoff.phobos" val (nsInstance, localName, config) = c.prefix.tree match { case q"new XmlCodecNs($localName, $nsInstance)" => (nsInstance, localName, defaultConfig.tree) case q"new XmlCodecNs($localName, $nsInstance, $config)" => (nsInstance, localName, config) case q"new XmlCodecNs[$_]($localName, $nsInstance, $config)" => (nsInstance, localName, config) } Seq( q""" implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] = $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config) """, q""" implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] = $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config) """, q""" implicit val ${TermName(c.freshName("xmlEncoder"))}: $pkg.encoding.XmlEncoder[$typ] = $pkg.encoding.XmlEncoder.fromElementEncoderNs($localName, $nsInstance) """, q""" implicit val ${TermName(c.freshName("xmlDecoder"))}: $pkg.decoding.XmlDecoder[$typ] = $pkg.decoding.XmlDecoder.fromElementDecoderNs($localName, $nsInstance) """ ) } }
Example 119
Source File: XmlCodec.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.annotations import ru.tinkoff.phobos.configured.ElementCodecConfig import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.reflect.macros.blackbox @compileTimeOnly("enable macro paradise to expand macro annotations") class XmlCodec(localName: String, config: ElementCodecConfig = ElementCodecConfig.default) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro XmlCodecImpl.impl } private final class XmlCodecImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) { import c.universe._ def instances(typ: Tree): Seq[Tree] = { val pkg = q"ru.tinkoff.phobos" val (localName, config) = c.prefix.tree match { case q"new XmlCodec($localName)" => (localName, defaultConfig.tree) case q"new XmlCodec($localName, $config)" => (localName, config) } Seq( q""" implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] = $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config) """, q""" implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] = $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config) """, q""" implicit val ${TermName(c.freshName("xmlEncoder"))}: $pkg.encoding.XmlEncoder[$typ] = $pkg.encoding.XmlEncoder.fromElementEncoder[$typ]($localName) """, q""" implicit val ${TermName(c.freshName("xmlDecoder"))}: $pkg.decoding.XmlDecoder[$typ] = $pkg.decoding.XmlDecoder.fromElementDecoder[$typ]($localName) """ ) } }
Example 120
Source File: XmlnsDef.scala From phobos with Apache License 2.0 | 5 votes |
package ru.tinkoff.phobos.annotations import scala.annotation.{StaticAnnotation, compileTimeOnly} import scala.reflect.macros.blackbox @compileTimeOnly("enable macro paradise to expand macro annotations") final class XmlnsDef(uri: String) extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro XmlnsDefImpl.impl } private final class XmlnsDefImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) { import c.universe._ def instances(typ: Tree): Seq[Tree] = { val pkg = q"ru.tinkoff.phobos" val instanceName = TermName(c.freshName("namespaceInstance")) val uri = c.prefix.tree match { case q"new XmlnsDef($uri)" => uri } Seq(q"implicit val $instanceName: $pkg.Namespace[$typ] = $pkg.Namespace.mkInstance[$typ]($uri)") } }
Example 121
Source File: Model.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.macros import io.scalaland.chimney.internal.TransformerConfiguration import scala.reflect.macros.blackbox trait Model extends TransformerConfiguration { val c: blackbox.Context import c.universe._ case class Target(name: String, tpe: Type) object Target { def fromJavaBeanSetter(ms: MethodSymbol, site: Type): Target = Target(ms.canonicalName, ms.beanSetterParamTypeIn(site)) def fromField(ms: MethodSymbol, site: Type): Target = Target(ms.canonicalName, ms.resultTypeIn(site)) } case class TransformerBodyTree(tree: Tree, isWrapped: Boolean) sealed trait AccessorResolution extends Product with Serializable { def isResolved: Boolean } object AccessorResolution { case object NotFound extends AccessorResolution { override def isResolved: Boolean = false } case class Resolved(symbol: MethodSymbol, wasRenamed: Boolean) extends AccessorResolution { override def isResolved: Boolean = true } case object DefAvailable extends AccessorResolution { override def isResolved: Boolean = false } } }
Example 122
Source File: ChimneyBlackboxMacros.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.macros import io.scalaland.chimney import io.scalaland.chimney.internal.utils.{DerivationGuards, EitherUtils, MacroUtils} import io.scalaland.chimney.{Patcher, TransformerF, TransformerFSupport} import scala.reflect.macros.blackbox class ChimneyBlackboxMacros(val c: blackbox.Context) extends PatcherMacros with TransformerMacros with DerivationGuards with MacroUtils with EitherUtils { import c.universe._ def buildTransformerImpl[From: WeakTypeTag, To: WeakTypeTag, C: WeakTypeTag] : c.Expr[chimney.Transformer[From, To]] = { c.Expr[chimney.Transformer[From, To]](buildDefinedTransformer[From, To, C]()) } def buildTransformerFImpl[F[+_], From: WeakTypeTag, To: WeakTypeTag, C: WeakTypeTag]( tfs: c.Expr[TransformerFSupport[F]] ): c.Expr[TransformerF[F, From, To]] = { c.Expr[TransformerF[F, From, To]](buildDefinedTransformer[From, To, C](tfs.tree)) } def transformImpl[From: WeakTypeTag, To: WeakTypeTag, C: WeakTypeTag]: c.Expr[To] = { c.Expr[To](expandTransform[From, To, C]()) } def transformFImpl[F[+_], From: WeakTypeTag, To: WeakTypeTag, C: WeakTypeTag]( tfs: c.Expr[TransformerFSupport[F]] ): c.Expr[F[To]] = { c.Expr[F[To]](expandTransform[From, To, C](tfs.tree)) } def deriveTransformerImpl[From: WeakTypeTag, To: WeakTypeTag]: c.Expr[chimney.Transformer[From, To]] = { c.Expr[chimney.Transformer[From, To]]( genTransformer[From, To]( TransformerConfig( definitionScope = Some((weakTypeOf[From], weakTypeOf[To])) ) ) ) } def deriveTransformerFImpl[F[+_], From: WeakTypeTag, To: WeakTypeTag]( tfs: c.Expr[TransformerFSupport[F]] )( implicit F: WeakTypeTag[F[_]] ): c.Expr[TransformerF[F, From, To]] = { c.Expr[TransformerF[F, From, To]]( genTransformer[From, To]( TransformerConfig( definitionScope = Some((weakTypeOf[From], weakTypeOf[To])), wrapperType = Some(F.tpe), wrapperSupportInstance = tfs.tree ) ) ) } def patchImpl[T: WeakTypeTag, Patch: WeakTypeTag, C: WeakTypeTag]: c.Expr[T] = { c.Expr[T](expandPatch[T, Patch, C]) } def derivePatcherImpl[T: WeakTypeTag, Patch: WeakTypeTag]: c.Expr[Patcher[T, Patch]] = { genPatcher[T, Patch](PatcherConfig()) } }
Example 123
Source File: PatcherCfg.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal import scala.reflect.macros.blackbox sealed abstract class PatcherCfg object PatcherCfg { final class Empty extends PatcherCfg final class IgnoreRedundantPatcherFields[C <: PatcherCfg] extends PatcherCfg final class IgnoreNoneInPatch[C <: PatcherCfg] extends PatcherCfg } trait PatcherConfiguration { val c: blackbox.Context import c.universe._ case class PatcherConfig( ignoreNoneInPatch: Boolean = false, ignoreRedundantPatcherFields: Boolean = false ) def capturePatcherConfig(cfgTpe: Type, config: PatcherConfig = PatcherConfig()): PatcherConfig = { import PatcherCfg._ val emptyT = typeOf[Empty] val ignoreRedundantPatcherFields = typeOf[IgnoreRedundantPatcherFields[_]].typeConstructor val ignoreNoneInPatch = typeOf[IgnoreNoneInPatch[_]].typeConstructor if (cfgTpe =:= emptyT) { config } else if (cfgTpe.typeConstructor =:= ignoreRedundantPatcherFields) { capturePatcherConfig(cfgTpe.typeArgs.head, config.copy(ignoreRedundantPatcherFields = true)) } else if (cfgTpe.typeConstructor =:= ignoreNoneInPatch) { capturePatcherConfig(cfgTpe.typeArgs.head, config.copy(ignoreNoneInPatch = true)) } else { // $COVERAGE-OFF$ c.abort(c.enclosingPosition, "Bad internal patcher config type shape!") // $COVERAGE-ON$ } } }
Example 124
Source File: CompanionUtils.scala From chimney with Apache License 2.0 | 5 votes |
package io.scalaland.chimney.internal.utils import scala.reflect.macros.{blackbox, runtime} import scala.tools.nsc.Global trait CompanionUtils { val c: blackbox.Context // Copied from Magnolia: https://github.com/propensive/magnolia/blob/master/core/shared/src/main/scala/globalutil.scala // From Shapeless: https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/generic.scala#L698 // Cut-n-pasted (with most original comments) and slightly adapted from // https://github.com/scalamacros/paradise/blob/c14c634923313dd03f4f483be3d7782a9b56de0e/plugin/src/main/scala/org/scalamacros/paradise/typechecker/Namers.scala#L568-L613 def patchedCompanionRef(c: blackbox.Context)(tpe: c.Type): c.Tree = { // see https://github.com/scalamacros/paradise/issues/7 // also see https://github.com/scalamacros/paradise/issues/64 val global = c.universe.asInstanceOf[Global] val typer = c.asInstanceOf[runtime.Context].callsiteTyper.asInstanceOf[global.analyzer.Typer] val ctx = typer.context val globalType = tpe.asInstanceOf[global.Type] val original = globalType.typeSymbol val owner = original.owner val companion = original.companion.orElse { import global.{abort => aabort, _} implicit class PatchedContext(ctx: global.analyzer.Context) { trait PatchedLookupResult { def suchThat(criterion: Symbol => Boolean): Symbol } def patchedLookup(name: Name, expectedOwner: Symbol) = new PatchedLookupResult { override def suchThat(criterion: Symbol => Boolean): Symbol = { var res: Symbol = NoSymbol var ctx = PatchedContext.this.ctx while (res == NoSymbol && ctx.outer != ctx) { // NOTE: original implementation says `val s = ctx.scope lookup name` // but we can't use it, because Scope.lookup returns wrong results when the lookup is ambiguous // and that triggers https://github.com/scalamacros/paradise/issues/64 val s = { val lookupResult = ctx.scope.lookupAll(name).filter(criterion).toList lookupResult match { case Nil => NoSymbol case List(unique) => unique case _ => aabort(s"unexpected multiple results for a companion symbol lookup for $original#{$original.id}") } } if (s != NoSymbol && s.owner == expectedOwner) res = s else ctx = ctx.outer } res } } } ctx.patchedLookup(original.name.companionName, owner) suchThat { sym => (original.isTerm || sym.hasModuleFlag) && (sym isCoDefinedWith original) } } global.gen.mkAttributedRef(globalType.prefix, companion).asInstanceOf[c.Tree] } }