scala.language.experimental.macros Scala Examples

The following examples show how to use scala.language.experimental.macros. 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: RpcClient.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.network.rpc

import jbok.network.rpc.internal.RpcClientMacro

import scala.language.experimental.macros

final class RpcClient[F[_], P](
    val transport: RpcTransport[F, P],
    val logger: RpcLogHandler[F]
) {
  def use[API]: API = macro RpcClientMacro.impl[API, F, P]
}

object RpcClient {
  def noopLogHandler[F[_]]: RpcLogHandler[F] = new RpcLogHandler[F] {
    override def logRequest[A](path: List[String], arguments: Product, result: F[A]): F[A] = result
  }

  def apply[F[_], P](transport: RpcTransport[F, P]) = new RpcClient[F, P](transport, noopLogHandler)
} 
Example 2
Source File: RpcService.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.network.rpc

import cats.effect.Sync
import jbok.network.rpc.internal.RpcServiceMacro

import scala.language.experimental.macros

final class RpcService[F[_], P](val apiMap: RpcService.Map[F, P])(implicit F: Sync[F]) {
  def handle(request: RpcRequest[P]): F[RpcResponse[P]] = {
    def notFoundFailure(path: List[String]): F[RpcResponse[P]] =
      F.pure(RpcResponse.Failure[P](404, s"Path ${path.mkString("/")} not found"))

    request.path match {
      case apiName :: methodName :: Nil =>
        val function: Option[P => F[RpcResponse[P]]] = apiMap.get(apiName).flatMap(_.get(methodName))
        function.fold(notFoundFailure(apiName :: methodName :: Nil))(f => f(request.payload))

      case _ => notFoundFailure(request.path)
    }
  }

  def mount[API](impl: API)(implicit F: Sync[F]): RpcService[F, P] =
    macro RpcServiceMacro.impl[API, F, P]

  def orElse(name: String, value: RpcService.MapValue[F, P]): RpcService[F, P] =
    new RpcService(apiMap + (name -> value))
}

object RpcService {
  type MapValue[F[_], P] = collection.Map[String, P => F[RpcResponse[P]]]

  type Map[F[_], P] = collection.Map[String, MapValue[F, P]]

  def apply[F[_], P](implicit F: Sync[F]): RpcService[F, P] = new RpcService[F, P](collection.mutable.HashMap.empty)
} 
Example 3
Source File: Table.scala    From iotchain   with MIT License 5 votes vote down vote up
package jbok.app.service.store.doobie

import doobie._
import scala.language.experimental.macros
import magnolia._


trait Table[A] {
  def fieldNames: Vector[String]

  def tableName: String

  def insert(data: A)(implicit writer: Write[A]): Update0 = {
    val holes = Vector.fill(fieldNames.size)("?").mkString(",")

    val quotedFieldNames = fieldNames.map('"'.toString + _ + '"'.toString).mkString(",")

    Update(s"""INSERT INTO "$tableName" ($quotedFieldNames) VALUES ($holes)""")
      .toUpdate0(data)
  }

  def selectFields(table: String): Fragment =
    Fragment.const0(fieldNames.map(f => s""""$table"."$f" AS "$table.$f"""").mkString(", "))
}

object Table {
  type Typeclass[A] = Table[A]

  def combine[A](ctx: CaseClass[Table, A]): Table[A] = {
    val table = new Table[A] {
      override val fieldNames: Vector[String] = ctx.parameters.map(_.label).toVector
      override val tableName: String          = ctx.typeName.short
    }
    table
  }

  implicit def gen[A]: Table[A] = macro Magnolia.gen[A]
} 
Example 4
Source File: Serialization.scala    From scarango   with MIT License 5 votes vote down vote up
package com.outr.arango

import io.circe.Decoder.Result
import io.circe.{Decoder, Encoder, HCursor, Json}

import scala.language.experimental.macros

case class Serialization[D](private val doc2Json: D => Json, private val json2Doc: Json => D) {
  final def toJson(document: D): Json = Id.update(doc2Json(document))

  final def fromJson(json: Json): D = json2Doc(Id.update(json))

  lazy val decoder: Decoder[D] = new Decoder[D] {
    override def apply(c: HCursor): Result[D] = Right(fromJson(c.value))
  }
}

object Serialization {
  def auto[D]: Serialization[D] = macro Macros.serializationAuto[D]
  def create[D](encoder: Encoder[D], decoder: Decoder[D]): Serialization[D] = {
    val doc2Json = (d: D) => encoder(d)
    val json2Doc = (json: Json) => decoder.decodeJson(json) match {
      case Left(df) => throw df
      case Right(d) => d
    }
    Serialization[D](doc2Json, json2Doc)
  }
} 
Example 5
Source File: BlockingPool.scala    From chymyst-core   with Apache License 2.0 5 votes vote down vote up
package io.chymyst.jc

import scala.language.experimental.macros


final class BlockingPool(
  name: String,
  override val parallelism: Int = cpuCores,
  priority: Int = Thread.NORM_PRIORITY,
  reporter: EventReporting = ConsoleErrorReporter
) extends Pool(name, priority, reporter) {

  // Looks like we will die hard at about 2021 threads...
  val poolSizeLimit: Int = math.min(2000, 1000 + 2 * parallelism)

  def currentPoolSize: Int = workerExecutor.getCorePoolSize

  private[jc] def startedBlockingCall(selfBlocking: Boolean) = synchronized { // Need a lock to modify the pool sizes.
    val newPoolSize = math.min(currentPoolSize + 1, poolSizeLimit)
    if (newPoolSize > currentPoolSize) {
      workerExecutor.setMaximumPoolSize(newPoolSize)
      workerExecutor.setCorePoolSize(newPoolSize)
    } else {
      reporter.warnTooManyThreads(toString, currentPoolSize)
    }
  }

  private[jc] def finishedBlockingCall(selfBlocking: Boolean) = synchronized { // Need a lock to modify the pool sizes.
    val newPoolSize = math.max(parallelism, currentPoolSize - 1)
    workerExecutor.setCorePoolSize(newPoolSize) // Must set them in this order, so that the core pool size is never larger than the maximum pool size.
    workerExecutor.setMaximumPoolSize(newPoolSize)
  }

  def withReporter(r: EventReporting): BlockingPool = new BlockingPool(name, parallelism, priority, r)
}

object BlockingPool {
  def apply(): BlockingPool = macro PoolMacros.newBlockingPoolImpl0 // IntelliJ cannot resolve the symbol PoolMacros, but compilation works.
  def apply(parallelism: Int): BlockingPool = macro PoolMacros.newBlockingPoolImpl1 // IntelliJ cannot resolve the symbol PoolMacros, but compilation works.
} 
Example 6
Source File: FixedPool.scala    From chymyst-core   with Apache License 2.0 5 votes vote down vote up
package io.chymyst.jc

import java.util.concurrent.atomic.AtomicInteger

import scala.language.experimental.macros


final class FixedPool(
  name: String,
  override val parallelism: Int = cpuCores,
  priority: Int = Thread.NORM_PRIORITY,
  reporter: EventReporting = ConsoleErrorReporter
) extends Pool(name, priority, reporter) {
  private[jc] val blockingCalls = new AtomicInteger(0)

  private def deadlockCheck(): Unit =
    if (blockingCalls.get >= workerExecutor.getMaximumPoolSize)
      reporter.reportDeadlock(toString, workerExecutor.getMaximumPoolSize, blockingCalls.get, Core.getReactionInfo)

  override private[chymyst] def runReaction(name: String, closure: ⇒ Unit): Unit = {
    deadlockCheck()
    super.runReaction(name, closure)
  }

  private[jc] def startedBlockingCall(selfBlocking: Boolean) = if (selfBlocking) {
    blockingCalls.getAndIncrement()
    deadlockCheck()
  }

  private[jc] def finishedBlockingCall(selfBlocking: Boolean) = if (selfBlocking) {
    blockingCalls.getAndDecrement()
    deadlockCheck()
  }

  def withReporter(r: EventReporting): FixedPool = new FixedPool(name, parallelism, priority, r)
}

object FixedPool {
  def apply(): FixedPool = macro PoolMacros.newFixedPoolImpl0 // IntelliJ cannot resolve the symbol PoolMacros, but compilation works.
  def apply(parallelism: Int): FixedPool = macro PoolMacros.newFixedPoolImpl1
} 
Example 7
Source File: Interpolation.scala    From slick-jdbc-extension-scala   with MIT License 5 votes vote down vote up
package com.github.tarao
package slickjdbc
package interpolation

import scala.language.implicitConversions
import slick.jdbc.SQLActionBuilder
import slick.sql.SqlAction
import slick.dbio.{NoStream, Effect}

trait SQLInterpolation {
  implicit def interpolation(s: StringContext) = SQLInterpolationImpl(s)
}
object SQLInterpolation extends SQLInterpolation

case class SQLInterpolationImpl(s: StringContext) extends AnyVal {
  import scala.language.experimental.macros

  def sql(param: Any*): SQLActionBuilder =
    macro MacroTreeBuilder.sqlImpl
  def sqlu(param: Any*): SqlAction[Int, NoStream, Effect] =
    macro MacroTreeBuilder.sqluImpl
}

trait Literal
class SimpleString(value: String) extends Literal {
  override def toString = value
}
case class TableName(name: String) extends SimpleString(name) 
Example 8
Source File: Models.scala    From scala-json-rpc   with MIT License 5 votes vote down vote up
package io.github.shogowada.scala.jsonrpc

import io.github.shogowada.scala.jsonrpc.Types.Id

import scala.language.experimental.macros

object Models {

  case class JSONRPCMethod(jsonrpc: String, method: String)

  case class JSONRPCId(jsonrpc: String, id: Id)

  case class JSONRPCRequest[PARAMS]
  (
      jsonrpc: String,
      id: Id,
      method: String,
      params: PARAMS
  )

  case class JSONRPCNotification[PARAMS]
  (
      jsonrpc: String,
      method: String,
      params: PARAMS
  )

  case class JSONRPCResultResponse[RESULT]
  (
      jsonrpc: String,
      id: Id,
      result: RESULT
  )

  case class JSONRPCErrorResponse[+ERROR]
  (
      jsonrpc: String,
      id: Id,
      error: JSONRPCError[ERROR]
  )

  case class JSONRPCError[+ERROR]
  (
      code: Int,
      message: String,
      data: Option[ERROR]
  )

  object JSONRPCErrors {
    lazy val parseError = JSONRPCError(-32700, "Parse error", Option("Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text."))
    lazy val invalidRequest = JSONRPCError(-32600, "Invalid Request", Option("The JSON sent is not a valid Request object."))
    lazy val methodNotFound = JSONRPCError(-32601, "Method not found", Option("The method does not exist / is not available."))
    lazy val invalidParams = JSONRPCError(-32602, "Invalid params", Option("Invalid method parameter(s)."))
    lazy val internalError = JSONRPCError(-32603, "Internal error", Option("Internal JSON-RPC error."))
  }

  class JSONRPCException[+ERROR](val maybeResponse: Option[JSONRPCErrorResponse[ERROR]]) extends RuntimeException

} 
Example 9
Source File: UpickleJSONSerializer.scala    From scala-json-rpc   with MIT License 5 votes vote down vote up
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 vote down vote up
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: ExecuteScala.scala    From piflow   with BSD 2-Clause "Simplified" License 5 votes vote down vote up
package cn.piflow.bundle.script


import java.net.{MalformedURLException, URL}

import cn.piflow.conf.bean.PropertyDescriptor
import cn.piflow.conf.util.{ImageUtil, MapUtil, PluginClassLoader}
import cn.piflow.conf.{ConfigurableStop, Port, StopGroup}
import cn.piflow.{JobContext, JobInputStream, JobOutputStream, ProcessContext}

import scala.language.experimental.macros
import scala.reflect.runtime.{universe => ru}


class ExecuteScala extends ConfigurableStop{
  override val authorEmail: String = "[email protected]"
  override val description: String = "Execute scala script"
  override val inportList: List[String] = List(Port.DefaultPort)
  override val outportList: List[String] = List(Port.DefaultPort)

  var packageName : String = "cn.piflow.bundle.script"
  var script : String = _
  var plugin : String = _

  override def setProperties(map: Map[String, Any]): Unit = {

    script = MapUtil.get(map,"script").asInstanceOf[String]
    plugin = MapUtil.get(map,"plugin").asInstanceOf[String]
  }

  override def getPropertyDescriptor(): List[PropertyDescriptor] = {
    var descriptor : List[PropertyDescriptor] = List()

    val pluginName = new PropertyDescriptor()
      .name("plugin")
      .displayName("Plugin")
      .description("The class name of scala code. This field is generated automaticly.")
      .defaultValue("")
      .required(true)
    descriptor = pluginName :: descriptor

    val script = new PropertyDescriptor()
      .name("script")
      .displayName("script")
      .description("The code of scala. \nUse in.read() to get dataframe from upstream component. \nUse out.write() to write datafram to downstream component.")
      .defaultValue("")
      .required(true)
      .example("val df = in.read() \nval df1 = df.select(\"author\").filter($\"author\".like(\"%xjzhu%\")) \ndf1.show() \ndf.createOrReplaceTempView(\"person\") \nval df2 = spark.sql(\"select * from person where author like '%xjzhu%'\") \ndf2.show() \nout.write(df2)")

    descriptor = script :: descriptor
    descriptor
  }

  override def getIcon(): Array[Byte] = {
    ImageUtil.getImage("icon/script/scala.jpg")
  }

  override def getGroup(): List[String] = {
    List(StopGroup.ScriptGroup)
  }

  override def initialize(ctx: ProcessContext): Unit = {
    val flowName = ctx.getFlow().getFlowName()
  }

  override def perform(in: JobInputStream, out: JobOutputStream, pec: JobContext): Unit = {

    val execMethod = "perform"
    val loader = new PluginClassLoader

    //when local run, use these codes
    //val scalaDir = PropertyUtil.getScalaPath()
    //val pluginurl = s"jar:file:$scalaDir/$plugin.jar!/"

    val userDir = System.getProperty("user.dir")
    //FileUtil.getJarFile(new File(userDir)).foreach(println(_))

    val pluginurl = s"jar:file:$userDir/$plugin.jar!/"
    println(s"Scala Plugin url : $pluginurl")
    var url : URL = null
    try
      url = new URL(pluginurl)
    catch {
      case e: MalformedURLException =>
        e.printStackTrace()
    }
    loader.addURLFile(url)

    val className = plugin.split("/").last.split(".jar")(0)
    val classMirror = ru.runtimeMirror(loader)
    println("staticModule: " + s"$packageName.$className")
    val classTest = classMirror.staticModule(s"$packageName.$className")
    val methods = classMirror.reflectModule(classTest)
    val objectMirror = classMirror.reflect(methods.instance)
    val method = methods.symbol.typeSignature.member(ru.TermName(s"$execMethod")).asMethod
    val result = objectMirror.reflectMethod(method)(in,out,pec)

  }

} 
Example 12
Source File: TestSupport.scala    From monadless   with Apache License 2.0 5 votes vote down vote up
package io.monadless.impl

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import org.scalamacros.resetallattrs._
import language.higherKinds
import scala.reflect.macros.TypecheckException

private[monadless] trait TestSupport[M[_]] {
  def get[T](m: M[T]): T
  def showTree[T](t: T): Unit = macro TestSupportMacro.showTree
  def showRawTree[T](t: T): Unit = macro TestSupportMacro.showRawTree
  def forceLift[T](t: T): T = macro TestSupportMacro.forceLift
  def runLiftTest[T](expected: T)(body: T): Unit = macro TestSupportMacro.runLiftTest[M, T]
}

private[monadless] class TestSupportMacro(val c: Context) {
  import c.universe._

  def showTree(t: Tree): Tree = {
    c.warning(c.enclosingPosition, t.toString)
    q"()"
  }
  def showRawTree(t: Tree): Tree = {
    c.warning(c.enclosingPosition, showRaw(t))
    q"()"
  }

  def forceLift(t: Tree): Tree =
    c.resetAllAttrs {
      Trees.Transform(c)(t) {
        case q"$pack.unlift[$t]($v)" =>
          q"${c.prefix}.get($v)"
      }
    }

  def runLiftTest[M[_], T](expected: Tree)(body: Tree): Tree =
    c.resetAllAttrs {

      val lifted =
        q"${c.prefix}.get(${c.prefix}.lift($body))"

      val forceLifted = forceLift(body)

      q"""
        val expected = scala.util.Try($expected)
        assert(expected == ${typecheckToTry(lifted, "lifted")})
        assert(expected == ${typecheckToTry(forceLifted, "force lifted")})
        ()
      """
    }

  def typecheckToTry(tree: Tree, name: String): Tree = {
    try {
      val typeCheckedTree = c.typecheck(c.resetAllAttrs(tree))
      c.info(c.enclosingPosition, s"$name: $typeCheckedTree", force = false)
      q"scala.util.Try($typeCheckedTree)"
    } catch {
      case e: TypecheckException =>
        val msg = s"""
          |$name fails typechecking: $e
          |tree: $tree
          |""".stripMargin
        c.info(e.pos.asInstanceOf[Position], msg, force = true)
        q"""scala.util.Failure(new Exception($msg))"""
    }
  }
} 
Example 13
Source File: FunnelDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.guava.semiauto

import com.google.common.base.Charsets
import com.google.common.hash.{Funnel, Funnels, PrimitiveSink}
import magnolia._

import scala.language.experimental.macros

object FunnelDerivation {
  type Typeclass[T] = Funnel[T]

  def combine[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] = new Funnel[T] {
    override def funnel(from: T, into: PrimitiveSink): Unit =
      if (caseClass.parameters.isEmpty) {
        into.putString(caseClass.typeName.short, Charsets.UTF_8)
      } else {
        caseClass.parameters.foreach { p =>
          // inject index to distinguish cases like `(Some(1), None)` and `(None, Some(1))`
          into.putInt(p.index)
          p.typeclass.funnel(p.dereference(from), into)
        }
      }
  }

  def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = new Funnel[T] {
    override def funnel(from: T, into: PrimitiveSink): Unit =
      sealedTrait.dispatch(from)(sub => sub.typeclass.funnel(sub.cast(from), into))
  }

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]

  def by[T, S](f: T => S)(implicit fnl: Funnel[S]): Funnel[T] = new Funnel[T] {
    override def funnel(from: T, into: PrimitiveSink): Unit = fnl.funnel(f(from), into)
  }
}

trait FunnelImplicits {
  private def funnel[T](f: (PrimitiveSink, T) => Unit): Funnel[T] = new Funnel[T] {
    override def funnel(from: T, into: PrimitiveSink): Unit = f(into, from)
  }

  implicit val intFunnel: Funnel[Int] = Funnels.integerFunnel().asInstanceOf[Funnel[Int]]
  implicit val longFunnel: Funnel[Long] = Funnels.longFunnel().asInstanceOf[Funnel[Long]]
  implicit val bytesFunnel: Funnel[Array[Byte]] = Funnels.byteArrayFunnel()
  implicit val charSequenceFunnel: Funnel[CharSequence] = Funnels.unencodedCharsFunnel()

  implicit val booleanFunnel: Funnel[Boolean] = funnel[Boolean](_.putBoolean(_))
  implicit val stringFunnel: Funnel[String] = funnel[String](_.putString(_, Charsets.UTF_8))
  implicit val byteFunnel: Funnel[Byte] = funnel[Byte](_.putByte(_))
  implicit val charFunnel: Funnel[Char] = funnel[Char](_.putChar(_))
  implicit val shortFunnel: Funnel[Short] = funnel[Short](_.putShort(_))

  // There is an implicit Option[T] => Iterable[T]
  implicit def iterableFunnel[T, C[_]](implicit
    fnl: Funnel[T],
    ti: C[T] => Iterable[T]
  ): Funnel[C[T]] =
    funnel { (sink, from) =>
      var i = 0
      from.foreach { x =>
        fnl.funnel(x, sink)
        i += 1
      }
      // inject size to distinguish `None`, `Some("")`, and `List("", "", ...)`
      sink.putInt(i)
    }
} 
Example 14
Source File: ArbitraryDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.scalacheck.semiauto

import magnolia._
import magnolify.shims.Monadic
import org.scalacheck.{Arbitrary, Gen}

import scala.language.experimental.macros

object ArbitraryDerivation {
  type Typeclass[T] = Arbitrary[T]

  def combine[T: Fallback](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = Arbitrary {
    Gen.lzy(Gen.sized { size =>
      if (size >= 0) {
        Gen.resize(size - 1, caseClass.constructMonadic(_.typeclass.arbitrary)(monadicGen))
      } else {
        implicitly[Fallback[T]].get
      }
    })
  }

  def dispatch[T: Fallback](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = Arbitrary {
    Gen.sized { size =>
      if (size > 0) {
        Gen.resize(
          size - 1,
          Gen.oneOf(sealedTrait.subtypes.map(_.typeclass.arbitrary)).flatMap(identity)
        )
      } else {
        implicitly[Fallback[T]].get
      }
    }
  }

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]

  private val monadicGen: Monadic[Gen] = new Monadic[Gen] {
    override def point[A](value: A): Gen[A] = Gen.const(value)
    override def flatMapS[A, B](from: Gen[A])(fn: A => Gen[B]): Gen[B] = from.flatMap(fn)
    override def mapS[A, B](from: Gen[A])(fn: A => B): Gen[B] = from.map(fn)
  }

  sealed trait Fallback[+T] extends Serializable {
    def get: Gen[T]
  }

  object Fallback {
    def apply[T](g: Gen[T]): Fallback[T] = new Fallback[T] {
      override def get: Gen[T] = g
    }

    def apply[T](v: T): Fallback[T] = Fallback[T](Gen.const(v))
    def apply[T](implicit arb: Arbitrary[T]): Fallback[T] = Fallback[T](arb.arbitrary)

    implicit def defaultFallback[T]: Fallback[T] = Fallback[T](Gen.fail)
  }
} 
Example 15
Source File: CogenDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.scalacheck.semiauto

import magnolia._
import org.scalacheck.Cogen

import scala.language.experimental.macros

object CogenDerivation {
  type Typeclass[T] = Cogen[T]

  def combine[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] = Cogen { (seed, t) =>
    caseClass.parameters.foldLeft(seed) { (seed, p) =>
      // inject index to distinguish cases like `(Some(false), None)` and `(None, Some(0))`
      val s = Cogen.cogenInt.perturb(seed, p.index)
      p.typeclass.perturb(s, p.dereference(t))
    }
  }

  def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = Cogen { (seed, t: T) =>
    sealedTrait.dispatch(t) { sub =>
      // inject index to distinguish case objects instances
      val s = Cogen.cogenInt.perturb(seed, sub.index)
      sub.typeclass.perturb(s, sub.cast(t))
    }
  }

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 16
Source File: package.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.scalacheck

import org.scalacheck._

import scala.language.experimental.macros
import scala.reflect.macros._

package object auto {
  def genArbitraryMacro[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._
    val wtt = weakTypeTag[T]
    q"""_root_.magnolify.scalacheck.semiauto.ArbitraryDerivation.apply[$wtt]"""
  }

  def genCogenMacro[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._
    val wtt = weakTypeTag[T]
    q"""_root_.magnolify.scalacheck.semiauto.CogenDerivation.apply[$wtt]"""
  }

  implicit def genArbitrary[T]: Arbitrary[T] = macro genArbitraryMacro[T]
  implicit def genCogen[T]: Cogen[T] = macro genCogenMacro[T]
} 
Example 17
Source File: CommutativeSemigroupDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.kernel.CommutativeSemigroup
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object CommutativeSemigroupDerivation {
  type Typeclass[T] = CommutativeSemigroup[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = SemigroupMethods.combineN(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)

    new CommutativeSemigroup[T] {
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
    }
  }

  @implicitNotFound("Cannot derive CommutativeSemigroup for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 18
Source File: CommutativeGroupDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.kernel.CommutativeGroup
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object CommutativeGroupDerivation {
  type Typeclass[T] = CommutativeGroup[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val emptyImpl = MonoidMethods.empty(caseClass)
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = GroupMethods.combineN(caseClass)
    val combineAllImpl = MonoidMethods.combineAll(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)
    val inverseImpl = GroupMethods.inverse(caseClass)
    val removeImpl = GroupMethods.remove(caseClass)

    new CommutativeGroup[T] {
      override def empty: T = emptyImpl()
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAll(as: IterableOnce[T]): T = combineAllImpl(as)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
      override def inverse(a: T): T = inverseImpl(a)
      override def remove(a: T, b: T): T = removeImpl(a, b)
    }
  }

  @implicitNotFound("Cannot derive CommutativeGroup for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 19
Source File: SemigroupDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Semigroup
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object SemigroupDerivation {
  type Typeclass[T] = Semigroup[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = SemigroupMethods.combineN(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)

    new Semigroup[T] {
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
    }
  }

  @implicitNotFound("Cannot derive Semigroup for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
}

private object SemigroupMethods {
  def combine[T, Typeclass[T] <: Semigroup[T]](caseClass: CaseClass[Typeclass, T]): (T, T) => T =
    (x, y) => caseClass.construct(p => p.typeclass.combine(p.dereference(x), p.dereference(y)))

  def combineNBase[T, Typeclass[T] <: Semigroup[T]](
    caseClass: CaseClass[Typeclass, T]
  ): (T, Int) => T =
    (a: T, n: Int) => caseClass.construct(p => p.typeclass.combineN(p.dereference(a), n))

  def combineN[T, Typeclass[T] <: Semigroup[T]](
    caseClass: CaseClass[Typeclass, T]
  ): (T, Int) => T = {
    val f = combineNBase(caseClass)
    (a: T, n: Int) =>
      if (n <= 0) {
        throw new IllegalArgumentException("Repeated combining for semigroups must have n > 0")
      } else {
        f(a, n)
      }
  }

  def combineAllOption[T, Typeclass[T] <: Semigroup[T]](
    caseClass: CaseClass[Typeclass, T]
  ): IterableOnce[T] => Option[T] = {
    val combineImpl = combine(caseClass)
    as: IterableOnce[T] =>
      as match {
        case it: Iterable[T] if it.nonEmpty =>
          // input is re-iterable and non-empty, combineAllOption on each field
          val result = Array.fill[Any](caseClass.parameters.length)(null)
          var i = 0
          while (i < caseClass.parameters.length) {
            val p = caseClass.parameters(i)
            result(i) = p.typeclass.combineAllOption(it.iterator.map(p.dereference)).get
            i += 1
          }
          Some(caseClass.rawConstruct(result))
        case xs =>
          xs.reduceOption(combineImpl)
      }
  }
} 
Example 20
Source File: EqDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Eq
import magnolia._

import scala.language.experimental.macros

object EqDerivation {
  type Typeclass[T] = Eq[T]

  def combine[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] =
    Eq.instance(EqMethods.combine(caseClass))

  def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] =
    Eq.instance(EqMethods.dispatch(sealedTrait))

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
}

private object EqMethods {
  def combine[T, Typeclass[T] <: Eq[T]](
    caseClass: ReadOnlyCaseClass[Typeclass, T]
  ): (T, T) => Boolean =
    (x, y) => caseClass.parameters.forall(p => p.typeclass.eqv(p.dereference(x), p.dereference(y)))

  def dispatch[T, Typeclass[T] <: Eq[T]](
    sealedTrait: SealedTrait[Typeclass, T]
  ): (T, T) => Boolean =
    (x, y) =>
      sealedTrait.dispatch(x) { sub =>
        sub.cast.isDefinedAt(y) && sub.typeclass.eqv(sub.cast(x), sub.cast(y))
      }
} 
Example 21
Source File: HashDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Hash
import magnolia._
import magnolify.shims.MurmurHash3Compat

import scala.language.experimental.macros
import scala.util.hashing.MurmurHash3

object HashDerivation {
  type Typeclass[T] = Hash[T]

  def combine[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] = {
    val eqvImpl = EqMethods.combine(caseClass)

    new Hash[T] {
      override def hash(x: T): Int =
        if (caseClass.parameters.isEmpty) {
          caseClass.typeName.short.hashCode
        } else {
          val seed = MurmurHash3Compat.seed(caseClass.typeName.short.hashCode)
          val h = caseClass.parameters.foldLeft(seed) { (h, p) =>
            MurmurHash3.mix(h, p.typeclass.hash(p.dereference(x)))
          }
          MurmurHash3.finalizeHash(h, caseClass.parameters.size)
        }

      override def eqv(x: T, y: T): Boolean = eqvImpl(x, y)
    }
  }

  def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = {
    val eqvImpl = EqMethods.dispatch(sealedTrait)

    new Hash[T] {
      override def hash(x: T): Int = sealedTrait.dispatch(x) { sub =>
        sub.typeclass.hash(sub.cast(x))
      }

      override def eqv(x: T, y: T): Boolean = eqvImpl(x, y)
    }
  }

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 22
Source File: ShowDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Show
import magnolia._

import scala.language.experimental.macros

object ShowDerivation {
  type Typeclass[T] = Show[T]

  def combine[T](caseClass: ReadOnlyCaseClass[Typeclass, T]): Typeclass[T] = Show.show { x =>
    caseClass.parameters
      .map(p => s"${p.label} = ${p.typeclass.show(p.dereference(x))}")
      .mkString(s"${caseClass.typeName.full} {", ", ", "}")
  }

  def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = Show.show { x =>
    sealedTrait.dispatch(x)(sub => sub.typeclass.show(sub.cast(x)))
  }

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 23
Source File: BandDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.kernel.Band
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object BandDerivation {
  type Typeclass[T] = Band[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = SemigroupMethods.combineN(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)

    new Band[T] {
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
    }
  }

  @implicitNotFound("Cannot derive Band for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 24
Source File: GroupDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Group
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object GroupDerivation {
  type Typeclass[T] = Group[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val emptyImpl = MonoidMethods.empty(caseClass)
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = GroupMethods.combineN(caseClass)
    val combineAllImpl = MonoidMethods.combineAll(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)
    val inverseImpl = GroupMethods.inverse(caseClass)
    val removeImpl = GroupMethods.remove(caseClass)

    new Group[T] {
      override def empty: T = emptyImpl()
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAll(as: IterableOnce[T]): T = combineAllImpl(as)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
      override def inverse(a: T): T = inverseImpl(a)
      override def remove(a: T, b: T): T = removeImpl(a, b)
    }
  }

  @implicitNotFound("Cannot derive Group for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
}

private object GroupMethods {
  def combineN[T, Typeclass[T] <: Group[T]](caseClass: CaseClass[Typeclass, T]): (T, Int) => T = {
    val emptyImpl = MonoidMethods.empty(caseClass)
    val combineImpl = SemigroupMethods.combine(caseClass)
    val f = SemigroupMethods.combineNBase(caseClass)
    val inverseImpl = inverse(caseClass)
    val removeImpl = remove(caseClass)
    (a: T, n: Int) =>
      if (n > 0) {
        f(a, n)
      } else if (n == 0) {
        emptyImpl()
      } else if (n == Int.MinValue) {
        f(inverseImpl(combineImpl(a, a)), 1073741824)
      } else {
        f(inverseImpl(a), -n)
      }
  }

  def inverse[T, Typeclass[T] <: Group[T]](caseClass: CaseClass[Typeclass, T]): T => T =
    a => caseClass.construct(p => p.typeclass.inverse(p.dereference(a)))

  def remove[T, Typeclass[T] <: Group[T]](caseClass: CaseClass[Typeclass, T]): (T, T) => T =
    (a, b) => caseClass.construct(p => p.typeclass.remove(p.dereference(a), p.dereference(b)))
} 
Example 25
Source File: MonoidDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.Monoid
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object MonoidDerivation {
  type Typeclass[T] = Monoid[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val emptyImpl = MonoidMethods.empty(caseClass)
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = MonoidMethods.combineN(caseClass)
    val combineAllImpl = MonoidMethods.combineAll(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)

    new Monoid[T] {
      override def empty: T = emptyImpl()
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAll(as: IterableOnce[T]): T = combineAllImpl(as)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
    }
  }

  @implicitNotFound("Cannot derive Monoid for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
}

private object MonoidMethods {
  def empty[T, Typeclass[T] <: Monoid[T]](caseClass: CaseClass[Typeclass, T]): () => T =
    new Function0[T] with Serializable {
      @transient private lazy val value = caseClass.construct(_.typeclass.empty)
      override def apply(): T = value
    }

  def combineN[T, Typeclass[T] <: Monoid[T]](caseClass: CaseClass[Typeclass, T]): (T, Int) => T = {
    val emptyImpl = empty(caseClass)
    val f = SemigroupMethods.combineNBase(caseClass)
    (a: T, n: Int) =>
      if (n < 0) {
        throw new IllegalArgumentException("Repeated combining for monoids must have n >= 0")
      } else if (n == 0) {
        emptyImpl()
      } else {
        f(a, n)
      }
  }

  def combineAll[T, Typeclass[T] <: Monoid[T]](
    caseClass: CaseClass[Typeclass, T]
  ): IterableOnce[T] => T = {
    val combineImpl = SemigroupMethods.combine(caseClass)
    val emptyImpl = MonoidMethods.empty(caseClass)
    as: IterableOnce[T] =>
      as match {
        case it: Iterable[T] if it.nonEmpty =>
          // input is re-iterable and non-empty, combineAll on each field
          val result = Array.fill[Any](caseClass.parameters.length)(null)
          var i = 0
          while (i < caseClass.parameters.length) {
            val p = caseClass.parameters(i)
            result(i) = p.typeclass.combineAll(it.iterator.map(p.dereference))
            i += 1
          }
          caseClass.rawConstruct(result)
        case xs => xs.foldLeft(emptyImpl())(combineImpl)
      }
  }
} 
Example 26
Source File: CommutativeMonoidDerivation.scala    From magnolify   with Apache License 2.0 5 votes vote down vote up
package magnolify.cats.semiauto

import cats.kernel.CommutativeMonoid
import magnolia._

import scala.annotation.implicitNotFound
import scala.language.experimental.macros

object CommutativeMonoidDerivation {
  type Typeclass[T] = CommutativeMonoid[T]

  def combine[T](caseClass: CaseClass[Typeclass, T]): Typeclass[T] = {
    val emptyImpl = MonoidMethods.empty(caseClass)
    val combineImpl = SemigroupMethods.combine(caseClass)
    val combineNImpl = MonoidMethods.combineN(caseClass)
    val combineAllImpl = MonoidMethods.combineAll(caseClass)
    val combineAllOptionImpl = SemigroupMethods.combineAllOption(caseClass)

    new CommutativeMonoid[T] {
      override def empty: T = emptyImpl()
      override def combine(x: T, y: T): T = combineImpl(x, y)
      override def combineN(a: T, n: Int): T = combineNImpl(a, n)
      override def combineAll(as: IterableOnce[T]): T = combineAllImpl(as)
      override def combineAllOption(as: IterableOnce[T]): Option[T] = combineAllOptionImpl(as)
    }
  }

  @implicitNotFound("Cannot derive CommutativeMonoid for sealed trait")
  private sealed trait Dispatchable[T]
  def dispatch[T: Dispatchable](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???

  implicit def apply[T]: Typeclass[T] = macro Magnolia.gen[T]
} 
Example 27
Source File: OpsInlining.scala    From nexus   with MIT License 5 votes vote down vote up
package nexus.util

import scala.language.experimental.macros
import scala.reflect.macros.blackbox._


object OpsInlining {

  def opName(c: Context)(op: c.TermName): c.TermName = {
    import c.universe._
    op match {
      case TermName("unary_$minus")   => TermName("neg")
      case TermName("$plus")          => TermName("add")
      case TermName("$minus")         => TermName("sub")
      case TermName("$times")         => TermName("mul")
      case TermName("$div")           => TermName("div")
      case TermName("$colon$times")   => TermName("scale")
      case TermName("$times$colon")   => TermName("scale")
      case TermName("$bar$times$bar") => TermName("mul")
      case TermName("$bar$div$bar")   => TermName("div")
      case _                          => op
    }
  }

  def op1(c: Context): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method" =>
        q"$ev.${opName(c)(method)}($lhs)"
    }
  }

  def op2(c: Context)(y: c.Tree): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $rhs)"
      case q"$impConv($lhs)($ev).$method[..$t]($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $rhs)"
    }
  }

  def op2Float(c: Context)(y: c.Tree): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.fromFloat($rhs))"
      case q"$impConv($lhs)($ev).$method[..$t]($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.fromFloat($rhs))"
    }
  }

  def op2Double(c: Context)(y: c.Tree): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.fromDouble($rhs))"
      case q"$impConv($lhs)($ev).$method[..$t]($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.fromDouble($rhs))"
    }
  }

  def op2TRFloat(c: Context)(y: c.Tree): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.R.fromFloat($rhs))"
      case q"$impConv($lhs)($ev).$method[..$t]($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.R.fromFloat($rhs))"
    }
  }

  def op2TRDouble(c: Context)(y: c.Tree): c.Tree = {
    import c.universe._
    c.macroApplication match {
      case q"$impConv($lhs)($ev).$method($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.R.fromDouble($rhs))"
      case q"$impConv($lhs)($ev).$method[..$t]($rhs)" =>
        q"$ev.${opName(c)(method)}($lhs, $ev.R.fromDouble($rhs))"
    }
  }

} 
Example 28
Source File: rig.scala    From spatial   with MIT License 5 votes vote down vote up
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 29
Source File: rewrite.scala    From spatial   with MIT License 5 votes vote down vote up
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 30
Source File: stateful.scala    From spatial   with MIT License 5 votes vote down vote up
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 31
Source File: ctx.scala    From spatial   with MIT License 5 votes vote down vote up
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 32
Source File: mod.scala    From spatial   with MIT License 5 votes vote down vote up
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 33
Source File: flow.scala    From spatial   with MIT License 5 votes vote down vote up
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 34
Source File: globalRewrite.scala    From spatial   with MIT License 5 votes vote down vote up
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 35
Source File: SrcCtxMacro.scala    From spatial   with MIT License 5 votes vote down vote up
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 36
Source File: data.scala    From spatial   with MIT License 5 votes vote down vote up
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 37
Source File: api.scala    From spatial   with MIT License 5 votes vote down vote up
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 38
Source File: op.scala    From spatial   with MIT License 5 votes vote down vote up
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 39
Source File: instrument.scala    From spatial   with MIT License 5 votes vote down vote up
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 40
Source File: StreamStructs.scala    From spatial   with MIT License 5 votes vote down vote up
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 41
Source File: Bits.scala    From spatial   with MIT License 5 votes vote down vote up
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 42
Source File: Arith.scala    From spatial   with MIT License 5 votes vote down vote up
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 43
Source File: package.scala    From logging   with Apache License 2.0 5 votes vote down vote up
package com.persist

import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
import com.persist.JsonOps._


  def richToString(m: RichMsg): String = {
    m match {
      case s: String => s
      case x => Compact(x, safe = true)
    }
  }

  implicit def sourceLocation: () => SourceLocation = macro sourceLocationMacro

  def sourceLocationMacro(c: Context): c.Expr[() => SourceLocation] = {
    import c.universe._

    val p = c.macroApplication.pos
    val file = p.source.file.name
    val line = p.line

    def allOwners(s: c.Symbol): Seq[c.Symbol] = {
      if (s == `NoSymbol`) {
        Seq()
      } else {
        s +: allOwners(s.owner)
      }
    }
    val owners = allOwners(c.internal.enclosingOwner)

    val className = owners
      .filter(s => s.toString.startsWith("class") || s.toString.startsWith("object"))
      .map(s => s.asClass.name.toString())
      .reverse
      .mkString("$")
    val packageName = owners
      .filter(_.isPackage)
      .map(_.name.toString())
      .filter(_ != "<root>")
      .reverse
      .mkString(".")

    c.Expr[() => SourceLocation](q"() => SourceLocation($file,$packageName,$className,$line)")
  }
} 
Example 44
Source File: Common.scala    From spark-tsne   with Apache License 2.0 5 votes vote down vote up
import sbt._
import Keys._
import com.typesafe.sbt.GitPlugin.autoImport._

import scala.language.experimental.macros
import scala.reflect.macros.Context

object Common {
  val commonSettings = Seq(
    organization in ThisBuild := "com.github.saurfang",
    javacOptions ++= Seq("-source", "1.7", "-target", "1.7"),
    scalacOptions ++= Seq("-target:jvm-1.7", "-deprecation", "-feature"),
    //git.useGitDescribe := true,
    git.baseVersion := "0.0.1",
    parallelExecution in test := false,
    updateOptions := updateOptions.value.withCachedResolution(true)
  )

  def tsneProject(path: String): Project = macro tsneProjectMacroImpl

  def tsneProjectMacroImpl(c: Context)(path: c.Expr[String]) = {
    import c.universe._
    reify {
      (Project.projectMacroImpl(c).splice in file(path.splice)).
        settings(name := path.splice).
        settings(Dependencies.Versions).
        settings(commonSettings: _*)
    }
  }
} 
Example 45
Source File: VisualTrace.scala    From watr-works   with Apache License 2.0 5 votes vote down vote up
package edu.umass.cs.iesl.watr
package tracing

import tracemacros._
import scala.language.experimental.macros
import geometry._
import scala.collection.mutable
import VisualTraceLevel._

object VisualTracer {

  { // Set trace levels here to force recompile and macro re-eval
    // VisualTraceGlobals.addTraceLevel(VisualTraceLevel.JsonLogs)
  }

  def tracingEnabled(): Boolean = {
    VisualTraceGlobals.tracingEnabled()
  }

}

protected [tracing] object VisualTraceGlobals {

  val activeTraces = mutable.HashSet[VisualTraceLevel]()

  def tracingEnabled(): Boolean = {
    activeTraces.nonEmpty
  }

  def clearTraceLevels(): Unit = {
    activeTraces.clear()
  }

  def addTraceLevel(v: VisualTraceLevel): Unit = v match {
    case  EnterExit =>
      activeTraces += EnterExit
    case  Checkpoint =>
      activeTraces ++= Seq(EnterExit, Checkpoint)
    case  JsonLogs =>
      activeTraces ++= Seq(EnterExit, JsonLogs)
    case  PrintLogs =>
      activeTraces ++= Seq(EnterExit, PrintLogs)
  }


}

trait VisualTracer extends EnableTrace { self =>
  import VisualTraceGlobals._

  lazy val tracer = self

  def isEnabled(v: VisualTraceLevel): Boolean = {
    activeTraces.contains(v)
  }

  def traceLevels(): Seq[VisualTraceLevel] = activeTraces.toSeq

  def tracingEnabled(): Boolean = {
    activeTraces.nonEmpty
  }

  def ifTrace(vtl: VisualTraceLevel)(body: => Unit): Unit = macro VisualTraceMacros.runOnTraceLevel[TraceLog]

} 
Example 46
Source File: Logger.scala    From mango   with Apache License 2.0 5 votes vote down vote up
package com.kakao.mango.logging

import org.slf4j.helpers.BasicMarkerFactory
import org.slf4j.{Marker, Logger => Underlying}

import scala.language.experimental.macros

object Logger {
  val markerFactory = new BasicMarkerFactory
  def apply(underlying: Underlying) = new Logger(underlying)
}


final class Logger private (val underlying: Underlying) {

  val markerFactory = Logger.markerFactory
  def marker(name: String): Marker = markerFactory.getMarker(name)

  def error(message: String): Unit = macro Macro.errorMessage
  def error(message: String, cause: Throwable): Unit = macro Macro.errorMessageCause
  def error(message: String, args: AnyRef*): Unit = macro Macro.errorMessageArgs
  def error(message: String, args: Any*): Unit = error(message, args.asInstanceOf[Seq[AnyRef]]: _*)

  def warn(message: String): Unit = macro Macro.warnMessage
  def warn(message: String, cause: Throwable): Unit = macro Macro.warnMessageCause
  def warn(message: String, args: AnyRef*): Unit = macro Macro.warnMessageArgs
  def warn(message: String, args: Any*): Unit = warn(message, args.asInstanceOf[Seq[AnyRef]]:_*)

  def info(message: String): Unit = macro Macro.infoMessage
  def info(message: String, cause: Throwable): Unit = macro Macro.infoMessageCause
  def info(message: String, args: AnyRef*): Unit = macro Macro.infoMessageArgs
  def info(message: String, args: Any*): Unit = info(message, args.asInstanceOf[Seq[AnyRef]]:_*)

  def debug(message: String): Unit = macro Macro.debugMessage
  def debug(message: String, cause: Throwable): Unit = macro Macro.debugMessageCause
  def debug(message: String, args: AnyRef*): Unit = macro Macro.debugMessageArgs
  def debug(message: String, args: Any*): Unit = debug(message, args.asInstanceOf[Seq[AnyRef]]:_*)

  def trace(message: String): Unit = macro Macro.traceMessage
  def trace(message: String, cause: Throwable): Unit = macro Macro.traceMessageCause
  def trace(message: String, args: AnyRef*): Unit = macro Macro.traceMessageArgs
  def trace(message: String, args: Any*): Unit = trace(message, args.asInstanceOf[Seq[AnyRef]]:_*)

} 
Example 47
Source File: Surface.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airframe.surface

import scala.language.existentials
import scala.language.experimental.macros

object Surface {
  def of[A]: Surface = macro SurfaceMacros.surfaceOf[A]
  def methodsOf[A]: Seq[MethodSurface] = macro SurfaceMacros.methodSurfaceOf[A]
}

trait Surface extends Serializable {
  def rawType: Class[_]
  def typeArgs: Seq[Surface]
  def params: Seq[Parameter]
  def name: String
  def fullName: String

  def dealias: Surface = this

  def isOption: Boolean
  def isAlias: Boolean
  def isPrimitive: Boolean
  def isSeq: Boolean = classOf[Seq[_]].isAssignableFrom(rawType)

  def objectFactory: Option[ObjectFactory] = None
}

sealed trait ParameterBase extends Serializable {
  def name: String
  def surface: Surface

  def call(obj: Any, x: Any*): Any
}

trait Parameter extends ParameterBase {
  def index: Int
  def name: String

  
  def getMethodArgDefaultValue(methodOwner: Any): Option[Any] = getDefaultValue
}

trait MethodSurface extends ParameterBase {
  def mod: Int
  def owner: Surface
  def name: String
  def args: Seq[MethodParameter]
  def surface: Surface = returnType
  def returnType: Surface

  def isPublic: Boolean    = (mod & MethodModifier.PUBLIC) != 0
  def isPrivate: Boolean   = (mod & MethodModifier.PRIVATE) != 0
  def isProtected: Boolean = (mod & MethodModifier.PROTECTED) != 0
  def isStatic: Boolean    = (mod & MethodModifier.STATIC) != 0
  def isFinal: Boolean     = (mod & MethodModifier.FINAL) != 0
  def isAbstract: Boolean  = (mod & MethodModifier.ABSTRACT) != 0
} 
Example 48
Source File: Asserts.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airspec.spi

import wvlet.airframe.SourceCode
import wvlet.airspec.{AirSpecMacros, AirSpecSpi}

import scala.language.experimental.macros
import scala.reflect.ClassTag

object Asserts {
  private[airspec] sealed trait TestResult
  private[airspec] case object Ok     extends TestResult
  private[airspec] case object Failed extends TestResult

  private[airspec] def check(cond: Boolean): TestResult = {
    if (cond) {
      Ok
    } else {
      Failed
    }
  }
}


trait Asserts { this: AirSpecSpi =>
  protected def assert(cond: => Boolean)(implicit code: SourceCode) = {
    if (!cond) {
      throw AssertionFailure("assertion failed", code)
    }
  }

  protected def assert(cond: => Boolean, message: String)(implicit code: SourceCode) = {
    if (!cond) {
      throw AssertionFailure(message, code)
    }
  }

  protected def assertEquals(a: Float, b: Float, delta: Double)(implicit code: SourceCode): Unit = {
    assert((a - b).abs < delta, s"${a} should be ${b} +- ${delta}")(code)
  }

  protected def assertEquals(a: Double, b: Double, delta: Double)(implicit code: SourceCode): Unit = {
    assert((a - b).abs < delta, s"${a} should be ${b} +- ${delta}")(code)
  }

  protected def fail(reason: String = "failed")(implicit code: SourceCode): Unit = {
    throw AssertionFailure(reason, code)
  }

  protected def ignore(reason: String = "ignored")(implicit code: SourceCode): Unit = {
    throw Ignored(reason, code)
  }

  protected def pending: Unit = macro AirSpecMacros.pendingImpl

  protected def pendingUntil(reason: String = "pending")(implicit code: SourceCode): Unit = {
    throw Pending(reason, code)
  }

  protected def pending(reason: String = "pending")(implicit code: SourceCode): Unit = {
    throw Pending(reason, code)
  }

  protected def cancel(reason: String = "cancelled")(implicit code: SourceCode): Unit = {
    throw Cancelled(reason, code)
  }

  protected def skip(reason: String = "skipped")(implicit code: SourceCode): Unit = {
    throw Skipped(reason, code)
  }

  protected def intercept[E <: Throwable: ClassTag](block: => Unit)(implicit code: SourceCode): E = {
    val tpe = implicitly[ClassTag[E]]

    try {
      block
      val name = tpe.runtimeClass.getName
      throw InterceptException(s"Expected a ${name} to be thrown", code)
    } catch {
      case ex: InterceptException =>
        throw new AssertionFailure(ex.message, code)
      case ex: Throwable if tpe.runtimeClass.isInstance(ex) =>
        ex.asInstanceOf[E]
    }
  }
} 
Example 49
Source File: AirSpecContext.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airspec.spi

import wvlet.airframe.Session
import wvlet.airframe.surface.{MethodSurface, Surface}
import wvlet.airspec.{AirSpecBase, AirSpecDef, AirSpecMacros, AirSpecSpi}

import scala.language.experimental.macros


  def run[A <: AirSpecBase](spec: A): A = macro AirSpecMacros.runSpecImpl[A]

  protected[airspec] def runInternal(spec: AirSpecSpi, testDefs: Seq[AirSpecDef]): AirSpecSpi
  protected[airspec] def runSingle(testDef: AirSpecDef): Unit
  protected def newSpec(specSurface: Surface): AirSpecSpi
}

object AirSpecContext {
  implicit class AirSpecContextAccess(val context: AirSpecContext) extends AnyVal {
    def callRunInternal(spec: AirSpecSpi, specMethods: Seq[MethodSurface]): AirSpecSpi = {
      context.runInternal(spec, AirSpecSpi.collectTestMethods(specMethods))
    }
    def callNewSpec(specSurface: Surface): AirSpecSpi = context.newSpec(specSurface)
  }
} 
Example 50
Source File: AirSpecContextImpl.scala    From airframe   with Apache License 2.0 5 votes vote down vote up
package wvlet.airspec.runner

import java.util.concurrent.atomic.AtomicInteger

import wvlet.airframe.Session
import wvlet.airframe.surface.Surface
import wvlet.airspec.spi.AirSpecContext
import wvlet.airspec.{AirSpecDef, AirSpecSpi}
import wvlet.log.LogSupport

import scala.language.experimental.macros


private[airspec] class AirSpecContextImpl(
    taskExecutor: AirSpecTaskRunner,
    val parentContext: Option[AirSpecContext],
    val currentSpec: AirSpecSpi,
    val testName: String = "<init>",
    val currentSession: Session
) extends AirSpecContext
    with LogSupport {
  private val childTaskCount = new AtomicInteger(0)

  override def hasChildTask: Boolean = {
    childTaskCount.get > 0
  }

  override protected[airspec] def runInternal(spec: AirSpecSpi, testDefs: Seq[AirSpecDef]): AirSpecSpi = {
    childTaskCount.incrementAndGet()
    taskExecutor.run(Some(this), spec, testDefs)
    spec
  }
  override protected[airspec] def runSingle(testDef: AirSpecDef): Unit = {
    childTaskCount.incrementAndGet()
    taskExecutor.runSingle(Some(this), currentSession, currentSpec, testDef, isLocal = true, design = testDef.design)
  }

  override protected def newSpec(specSurface: Surface): AirSpecSpi = {
    val spec: AirSpecSpi = currentSession.get(specSurface)
    // When the spec instance is an anonymous class, we need to find the real class name from the specSurface
    spec.setSpecName(specSurface.fullName)
    spec
  }
} 
Example 51
Source File: typeclass.scala    From typeclassic   with Apache License 2.0 5 votes vote down vote up
package typeclassic

import scala.annotation.{ compileTimeOnly, StaticAnnotation }
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context

import macrocompat._

@compileTimeOnly("typeclass annotation should have been automatically removed but was not")
class typeclass(excludeParents: List[String] = Nil, generateAllOps: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro TypeClassMacros.generateTypeClass
}


@bundle
class TypeClassMacros(val c: Context) {
  import c.universe._

  def generateTypeClass(annottees: c.Expr[Any]*): c.Expr[Any] = {
    annottees.map(_.tree) match {
      case (typeClass: ClassDef) :: Nil => modify(typeClass, None)
      case (typeClass: ClassDef) :: (companion: ModuleDef) :: Nil => modify(typeClass, Some(companion))
      case other :: Nil =>
        c.abort(c.enclosingPosition, "@typeclass can only be applied to traits or abstract classes that take 1 type parameter which is either a proper type or a type constructor")
    }
  }

  private def modify(typeClass: ClassDef, companion: Option[ModuleDef]) = {
    val (tparam, proper) = typeClass.tparams match {
      case hd :: Nil =>
        hd.tparams.size match {
          case 0 => (hd, true)
          case 1 => (hd, false)
          case n => c.abort(c.enclosingPosition, "@typeclass may only be applied to types that take a single proper type or type constructor")
        }
      case other => c.abort(c.enclosingPosition, "@typeclass may only be applied to types that take a single type parameter")
    }

    val modifiedTypeClass = typeClass // TODO

    val modifiedCompanion = generateCompanion(typeClass, tparam, proper, companion match {
      case Some(c) => c
      case None => q"object ${typeClass.name.toTermName} {}"
    })

    val result = c.Expr(q"""
      $modifiedTypeClass
      $modifiedCompanion
    """)

    trace(s"Generated type class ${typeClass.name}:\n" + showCode(result.tree))

    result
  }

  private def generateCompanion(typeClass: ClassDef, tparam0: TypeDef, proper: Boolean, comp: Tree): Tree = {
    val tparam = eliminateVariance(tparam0)

    val q"$mods object $name extends ..$bases { ..$body }" = comp

    q"""
      $mods object $name extends ..$bases {
        import scala.language.experimental.macros
        ..$body
        ${generateInstanceSummoner(typeClass, tparam)}
      }
    """
  }

  private def generateInstanceSummoner(typeClass: ClassDef, tparam: TypeDef): Tree = {
    q"""
      @_root_.typeclassic.op("$$y {$$x}")
      def apply[$tparam](implicit x1: ${typeClass.name}[${tparam.name}]): ${typeClass.name}[${tparam.name}] =
        macro _root_.typeclassic.OpsMacros.op10
    """
  }

  // This method is from simulacrum, contributed by paulp, and is licensed under 3-Clause BSD
  private def eliminateVariance(tparam: TypeDef): TypeDef = {
    // If there's another way to do this I'm afraid I don't know it.
    val u        = c.universe.asInstanceOf[c.universe.type with scala.reflect.internal.SymbolTable]
    val tparam0  = tparam.asInstanceOf[u.TypeDef]
    val badFlags = (Flag.COVARIANT | Flag.CONTRAVARIANT).asInstanceOf[Long]
    val fixedMods = tparam0.mods & ~badFlags
    TypeDef(fixedMods.asInstanceOf[c.universe.Modifiers], tparam.name, tparam.tparams, tparam.rhs)
  }

  private def trace(s: => String) = {
    // Macro paradise seems to always output info statements, even without -verbose
    if (sys.props.get("typeclassic.trace").isDefined) c.info(c.enclosingPosition, s, false)
  }
} 
Example 52
Source File: ConfigLoader.scala    From shocon   with Apache License 2.0 5 votes vote down vote up
package org.akkajs.shocon

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object ConfigLoader {

  import org.akkajs.shocon.verboseLog

  /// Loads the content of all config files passed with -Xmacro-settings:
  private def loadExplicitConfigFiles(c: Context): Option[String] =
    // check if config files to be loaded are defined via macro setting -Xmacro-settings:shocon.files=file1.conf;file2.conf
    c.settings.find(_.startsWith("shocon.files="))
      // load these files
      .map( _.split("=") match {
      case Array(_,paths) =>
        val (found,notfound) = paths.split(";").toList
          .map( new java.io.File(_) )
          .partition( _.canRead )

        if(notfound.nonEmpty)
          c.warning(c.enclosingPosition, s"shocon - could not read configuration files: $notfound")

        c.info(c.enclosingPosition, s"shocon - statically reading configuration from $found", force=false)
        found
      case _ => Nil
    })
      // concat these files into a single string
      .map( _.map(scala.io.Source.fromFile(_).getLines.mkString("\n")).mkString("\n\n") )

  def loadDefault(c: Context) = {
    import c.universe._

    val configStr: String =
      // load explicitly defined config files vi -Xmacro-settings:file1.conf;file2.conf;...
      loadExplicitConfigFiles(c)
        // or else load application.conf
        .getOrElse{
          try {
            val confPath = new Object {}.getClass
              .getResource("/")
              .toString + "application.conf"

            c.info(c.enclosingPosition,
              s"shocon - statically reading configuration from $confPath", force=false)

            val stream =
              new Object {}.getClass.getResourceAsStream("/application.conf")

            scala.io.Source.fromInputStream(stream).getLines.mkString("\n")
          } catch {
            case e: Throwable =>
              // we use print instead of c.warning, since multiple warnings at the same c.enclosingPosition seem not to work (?)
              println(c.enclosingPosition, s"WARNING: could not load config file: $e")
              "{}"
          }
        }

    c.Expr[com.typesafe.config.Config](q"""{
        com.typesafe.config.Config(
          org.akkajs.shocon.Config.gen($configStr)
        )
      }""")
  }


  def loadDefaultImpl(c: Context)() = loadDefault(c)
  def loadDefaultImplCL(c: Context)(cl: c.Expr[ClassLoader]) = loadDefault(c)

  def loadFromString(c: Context)(s: c.Expr[String]) = {
    import c.universe._

    s.tree match {
      case q"""$strLit""" =>
        strLit match {
          case Literal(Constant(str)) =>
            if (verboseLog)
              c.info(c.enclosingPosition, "[shocon-facade] optimized at compile time", false)
            
            c.Expr[com.typesafe.config.Config](q"""{
              com.typesafe.config.Config(
                org.akkajs.shocon.Config.gen(${str.toString})
              )
            }""")
          case _ =>
            if (verboseLog)
              c.warning(c.enclosingPosition, "[shocon-facade] fallback to runtime parser")

            c.Expr[com.typesafe.config.Config](q"""{
              com.typesafe.config.Config(
                org.akkajs.shocon.Config($strLit)
              )
            }""")
        }
    }
  }
} 
Example 53
Source File: JsonDataInputFormat.scala    From milan   with Apache License 2.0 5 votes vote down vote up
package com.amazon.milan.dataformats

import java.io.InputStream

import com.amazon.milan.HashUtil
import com.amazon.milan.serialization.{DataFormatConfiguration, JavaTypeFactory, MilanObjectMapper}
import com.amazon.milan.typeutil.TypeDescriptor
import com.fasterxml.jackson.databind.annotation.{JsonDeserialize, JsonSerialize}

import scala.collection.JavaConverters._
import scala.language.experimental.macros



@JsonSerialize
@JsonDeserialize
class JsonDataInputFormat[T: TypeDescriptor](val config: DataFormatConfiguration)
  extends DataInputFormat[T] {

  @transient private lazy val objectMapper = new MilanObjectMapper(this.config)
  @transient private lazy val javaType = new JavaTypeFactory(this.objectMapper.getTypeFactory).makeJavaType(this.recordTypeDescriptor)
  @transient private lazy val hashCodeValue = HashUtil.combineHashCodes(this.recordTypeDescriptor.hashCode(), this.config.hashCode())

  private var recordTypeDescriptor = implicitly[TypeDescriptor[T]]

  def this() {
    this(DataFormatConfiguration.default)
  }

  override def getGenericArguments: List[TypeDescriptor[_]] =
    List(implicitly[TypeDescriptor[T]])

  override def setGenericArguments(genericArgs: List[TypeDescriptor[_]]): Unit = {
    this.recordTypeDescriptor = genericArgs.head.asInstanceOf[TypeDescriptor[T]]
  }

  override def readValue(bytes: Array[Byte], offset: Int, length: Int): Option[T] = {
    Some(this.objectMapper.readValue[T](bytes, offset, length, this.javaType))
  }

  override def readValues(stream: InputStream): TraversableOnce[T] = {
    this.objectMapper.readerFor(this.javaType).readValues[T](stream).asScala
  }

  override def hashCode(): Int = this.hashCodeValue

  override def equals(obj: Any): Boolean = {
    obj match {
      case o: JsonDataInputFormat[T] =>
        this.recordTypeDescriptor.equals(o.recordTypeDescriptor) &&
          this.config.equals(o.config)

      case _ =>
        false
    }
  }
} 
Example 54
Source File: unions.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
package shapeless

import scala.language.dynamics
import scala.language.experimental.macros

import scala.reflect.macros.whitebox

object union {
  import syntax.UnionOps

  implicit def unionOps[C <: Coproduct](u : C) : UnionOps[C] = new UnionOps(u)

  
  object Union extends Dynamic {
    def applyDynamicNamed[U <: Coproduct](method: String)(elems: Any*): U = macro UnionMacros.mkUnionNamedImpl[U]

    def selectDynamic(tpeSelector: String): Any = macro LabelledMacros.unionTypeImpl
  }
}

@macrocompat.bundle
class UnionMacros(val c: whitebox.Context) {
  import c.universe._
  import internal.constantType
  import labelled.FieldType

  val fieldTypeTpe = typeOf[FieldType[_, _]].typeConstructor
  val SymTpe = typeOf[scala.Symbol]
  val atatTpe = typeOf[tag.@@[_,_]].typeConstructor

  def mkUnionNamedImpl[U <: Coproduct : WeakTypeTag](method: Tree)(elems: Tree*): Tree = {
    def mkSingletonSymbolType(c: Constant): Type =
      appliedType(atatTpe, List(SymTpe, constantType(c)))

    def mkFieldTpe(keyTpe: Type, valueTpe: Type): Type =
      appliedType(fieldTypeTpe, List(keyTpe, valueTpe.widen))

    def mkElem(keyTpe: Type, value: Tree): Tree =
      q"$value.asInstanceOf[${mkFieldTpe(keyTpe, value.tpe)}]"

    def promoteElem(elem: Tree): Tree = elem match {
      case q""" $prefix(${Literal(k: Constant)}, $v) """ => mkElem(mkSingletonSymbolType(k), v)
      case _ =>
        c.abort(c.enclosingPosition, s"$elem has the wrong shape for a record field")
    }

    val q"${methodString: String}" = method
    if(methodString != "apply")
      c.abort(c.enclosingPosition, s"this method must be called as 'apply' not '$methodString'")

    val elem =
      elems match {
        case Seq(e) => e
        case _ =>
          c.abort(c.enclosingPosition, s"only one branch of a union may be inhabited")
      }

    q""" _root_.shapeless.Coproduct[${weakTypeOf[U]}](${promoteElem(elem)}) """
  }
} 
Example 55
Source File: typechecking.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
package shapeless.test

import scala.language.experimental.macros

import java.util.regex.Pattern

import scala.reflect.macros.{ whitebox, ParseException, TypecheckException }


object illTyped {
  def apply(code: String): Unit = macro IllTypedMacros.applyImplNoExp
  def apply(code: String, expected: String): Unit = macro IllTypedMacros.applyImpl
}

@macrocompat.bundle
class IllTypedMacros(val c: whitebox.Context) {
  import c.universe._

  def applyImplNoExp(code: Tree): Tree = applyImpl(code, null)

  def applyImpl(code: Tree, expected: Tree): Tree = {
    val Literal(Constant(codeStr: String)) = code
    val (expPat, expMsg) = expected match {
      case null => (null, "Expected some error.")
      case Literal(Constant(s: String)) =>
        (Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.DOTALL), "Expected error matching: "+s)
    }

    try {
      val dummy0 = TermName(c.freshName)
      val dummy1 = TermName(c.freshName)
      c.typecheck(c.parse(s"object $dummy0 { val $dummy1 = { $codeStr } }"))
      c.error(c.enclosingPosition, "Type-checking succeeded unexpectedly.\n"+expMsg)
    } catch {
      case e: TypecheckException =>
        val msg = e.getMessage
        if((expected ne null) && !(expPat.matcher(msg)).matches)
          c.error(c.enclosingPosition, "Type-checking failed in an unexpected way.\n"+expMsg+"\nActual error: "+msg)
      case e: ParseException =>
        c.error(c.enclosingPosition, s"Parsing failed.\n${e.getMessage}")
    }

    q"()"
  }
} 
Example 56
Source File: compiletime.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
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 57
Source File: nat.scala    From perf_tester   with Apache License 2.0 5 votes vote down vote up
package shapeless

import scala.language.experimental.macros

import scala.annotation.tailrec
import scala.reflect.macros.whitebox


  type _0 = shapeless._0
  val _0: _0 = new _0

  def toInt[N <: Nat](implicit toIntN : ToInt[N]) = toIntN()

  def toInt(n : Nat)(implicit toIntN : ToInt[n.N]) = toIntN()

  implicit def natOps[N <: Nat](n : N) : NatOps[N] = new NatOps(n)
}

@macrocompat.bundle
class NatMacros(val c: whitebox.Context) extends NatMacroDefns {
  import c.universe._

  def materializeWidened(i: Tree): Tree =
    i match {
      case NatLiteral(n) => mkNatValue(n)
      case _ =>
        c.abort(c.enclosingPosition, s"Expression $i does not evaluate to a non-negative Int literal")
    }
}

@macrocompat.bundle
trait NatMacroDefns {
  val c: whitebox.Context
  import c.universe._

  object NatLiteral {
    def unapply(i: Tree): Option[Int] =
      i match {
        case Literal(Constant(n: Int)) if n >= 0 => Some(n)
        case _ => None
      }
  }

  def mkNatTpt(i: Int): Tree = {
    val succSym = typeOf[Succ[_]].typeConstructor.typeSymbol
    val _0Sym = typeOf[_0].typeSymbol

    @tailrec
    def loop(i: Int, acc: Tree): Tree = {
      if(i == 0) acc
      else loop(i-1, AppliedTypeTree(Ident(succSym), List(acc)))
    }

    loop(i, Ident(_0Sym))
  }

  def mkNatTpe(i: Int): Type = {
    val succTpe = typeOf[Succ[_]].typeConstructor
    val _0Tpe = typeOf[_0]

    @tailrec
    def loop(i: Int, acc: Type): Type = {
      if(i == 0) acc
      else loop(i-1, appliedType(succTpe, acc))
    }

    loop(i, _0Tpe)
  }

  def mkNatValue(i: Int): Tree =
    q""" new ${mkNatTpt(i)} """
} 
Example 58
Source File: Injectable.scala    From angulate2   with MIT License 5 votes vote down vote up
//     Project: angulate2 (https://github.com/jokade/angulate2)
// Description: Angular2 @Injectable annotation.

// Copyright (c) 2016 Johannes.Kastner <[email protected]>
//               Distributed under the MIT License (see included LICENSE file)
package angulate2.core

import angulate2.internal.ClassDecorator

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport

@js.native
@JSImport("@angular/core","Injectable")
object InjectableFacade extends js.Object {
  def apply() : js.Object = js.native
  def apply(options: js.Object) : js.Object = js.native
}

// NOTE: keep the constructor parameter list and Injectable.Macro.annotationParamNames in sync!
@compileTimeOnly("enable macro paradise to expand macro annotations")
class Injectable extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro Injectable.Macro.impl
}


object Injectable {

  private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator {
    import c.universe._
    override val annotationName: String = "Injectable"

    override val annotationParamNames: Seq[String] = Seq()

    override def mainAnnotationObject = q"angulate2.core.InjectableFacade"
  }
} 
Example 59
Source File: NgModule.scala    From angulate2   with MIT License 5 votes vote down vote up
//     Project: angulate2
// Description: Angular2 @NgModule macro annotation

// Copyright (c) 2016 Johannes.Kastner <[email protected]>
//               Distributed under the MIT License (see included LICENSE file)
package angulate2.core

import angulate2.internal.ClassDecorator

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport

@js.native
@JSImport("@angular/core","NgModule")
object NgModuleFacade extends js.Object {
  def apply() : js.Object = js.native
  def apply(options: js.Object) : js.Object = js.native
}

// NOTE: keep the constructor parameter list and Component.Macro.annotationParamNames in sync!
@compileTimeOnly("enable macro paradise to expand macro annotations")
class NgModule(providers: js.Array[js.Any] = null,
               declarations: js.Array[js.Any] = null,
               imports: js.Array[js.Any] = null,
               exports: js.Array[js.Any] = null,
               entryComponents: js.Array[js.Any] = null,
               bootstrap: js.Array[js.Any] = null,
               schemas: js.Array[js.Any] = null,
               id: String = null) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro NgModule.Macro.impl
}

object NgModule {
  private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator {
    import c.universe._

    val annotationParamNames = Seq(
      "providers",
      "declarations",
      "imports",
      "exports",
      "entryComponents",
      "bootstrap",
      "schemas",
      "id"
    )

    override val annotationName: String = "NgModule"

    override def mainAnnotationObject = q"angulate2.core.NgModuleFacade"
  }

} 
Example 60
Source File: Pipe.scala    From angulate2   with MIT License 5 votes vote down vote up
//     Project: angulate2 (https://github.com/jokade/angulate2)
// Description:

// Copyright (c) 2017 Johannes.Kastner <[email protected]>
//               Distributed under the MIT License (see included LICENSE file)
package angulate2.core

import angulate2.internal.ClassDecorator
import de.surfice.smacrotools.createJS

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport

@js.native
@JSImport("@angular/core","Pipe")
object PipeFacade extends js.Object {
  def apply(options: js.Object) : js.Object = js.native
}

// NOTE: keep the constructor parameter list and Directive.Macro.annotationParamNames in sync!
@compileTimeOnly("enable macro paradise to expand macro annotations")
class Pipe(name: String, pure: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro Pipe.Macro.impl
}

object Pipe {

  private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator {
    import c.universe._
    val annotationParamNames = Seq(
      "name",
      "pure"
    )

    override val annotationName: String = "Pipe"

    override def mainAnnotationObject = q"angulate2.core.PipeFacade"
  }
}

@createJS
trait PipeTransform0[T,R] {
  def transform(value: T): R
}

@createJS
trait PipeTransform1[T,A1,R] {
  def transform(value: T, arg1: A1): R
}

@createJS
trait PipeTransform2[T,A1,A2,R] {
  def transform(value: T, arg1: A1, arg2: A2): R
}

@createJS
trait PipeTransform3[T,A1,A2,A3,R] {
  def transform(value: T, arg1: A1, arg2: A2, arg3: A3): R
} 
Example 61
Source File: Directive.scala    From angulate2   with MIT License 5 votes vote down vote up
//     Project: angulate2 (https://github.com/jokade/angulate2)
// Description: Angular2 @Directive macro annotation

// Copyright (c) 2016 Johannes.Kastner <[email protected]>
//               Distributed under the MIT License (see included LICENSE file)
package angulate2.core

import angulate2.internal.{ClassDecorator, FieldDecorator}

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport

@js.native
@JSImport("@angular/core","Directive")
object DirectiveFacade extends js.Object {
  def apply(options: js.Object) : js.Object = js.native
}

// NOTE: keep the constructor parameter list and Directive.Macro.annotationParamNames in sync!
@compileTimeOnly("enable macro paradise to expand macro annotations")
class Directive(selector: String = null,
                inputs: js.Array[String] = null,
                outputs: js.Array[String] = null,
                host: js.Dictionary[String] = null,
                template: String = null,
                providers: js.Array[js.Any] = null,
                exportAs: String = null,
                queries: js.Any = null) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro Directive.Macro.impl
}


object Directive {

  private[angulate2] abstract class BaseMacro extends ClassDecorator with FieldDecorator

  private[angulate2] class Macro(val c: whitebox.Context) extends BaseMacro {
    import c.universe._

    override def annotationName = "Directive"

    override def mainAnnotationObject: c.universe.Tree = q"angulate2.core.DirectiveFacade"

    override def annotationParamNames: Seq[String] = Seq(
      "selector",
      "inputs",
      "outputs",
      "host",
      "template",
      "providers",
      "exportAs",
      "queries"
    )
  }
} 
Example 62
Source File: Routes.scala    From angulate2   with MIT License 5 votes vote down vote up
//     Project: angulate2 (https://github.com/jokade/angulate2)
// Description: Angulate2 extension for simplified creation of routing modules

// Copyright (c) 2016 Johannes.Kastner <[email protected]>
//               Distributed under the MIT License (see included LICENSE file)
package angulate2.ext

import angulate2.internal.ClassDecorator
import angulate2.router.Route

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.scalajs.js

@compileTimeOnly("enable macro paradise to expand macro annotations")
class Routes(root: Boolean, routes: Route*) extends StaticAnnotation {
  def this(providers: js.Array[js.Any])(root: Boolean, routes: Route*) = this(root,routes:_*)
  def macroTransform(annottees: Any*): Any = macro Routes.Macro.impl
}

object Routes {
  private[angulate2] class Macro(val c: whitebox.Context) extends ClassDecorator {
    import c.universe._

    val annotationParamNames = Seq(
      "root",
      "routes*"
    )

    override val firstArglistParamNames = Seq(
      "providers"
    )

    override val annotationName: String = "Routes"

    override def mainAnnotationObject = q"angulate2.core.NgModuleFacade"

    private val routerModule = q"angulate2.ops.@@[angulate2.router.RouterModule]"

    override def analyze: Analysis = super.analyze andThen {
      case (cls: ClassParts, data) =>
        val cdd = ClassDecoratorData(data)
        val routes = q"scalajs.js.Array(..${cdd.annotParams("routes")})"
        val remainingParams = cdd.annotParams - "root" - "routes"

        val imports = cdd.annotParams("root") match {
          case Literal(Constant(true)) => q"scalajs.js.Array(angulate2.router.RouterModule.forRoot($routes))"
          case Literal(Constant(false)) => q"scalajs.js.Array(angulate2.router.RouterModule.forChild($routes))"
        }
        (cls, ClassDecoratorData.update(data,cdd.copy(annotParams = remainingParams ++ Map("imports" -> imports, "exports" -> routerModule))))
      case default => default
    }

  }
} 
Example 63
Source File: DefaultReaderMacro.scala    From grafter   with MIT License 5 votes vote down vote up
package org.zalando.grafter.macros

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import ReaderMacros._

object DefaultReaderMacro {

  val annotationName = "defaultReader"

  def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._

    val (classTree, companionTree): (Tree, Option[Tree]) =
      annotationInputs(c)(annotationName)(annottees)

    classTree match {
      case ClassDef(_, className, typeParams, _) =>
        val genericTypeName = internal.reificationSupport.freshTypeName("A")
        val typeParam = typeParameter(annotationName)(c)

        typeParams match {
          case _ :: Nil =>
            outputs(c)(classTree, className, companionTree) {
              q"""
         implicit def reader[$genericTypeName, F[_]](implicit defaultReader: cats.data.Reader[$genericTypeName, $typeParam[F]]): cats.data.Reader[$genericTypeName, $className[F]] =
           org.zalando.grafter.GenericReader.widenReader(defaultReader)
      """
            }

          case Nil =>
            outputs(c)(classTree, className, companionTree) {
              q"""
         implicit def reader[$genericTypeName](implicit defaultReader: cats.data.Reader[$genericTypeName, $typeParam]): cats.data.Reader[$genericTypeName, $className] =
           org.zalando.grafter.GenericReader.widenReader(defaultReader)
      """
            }

          case other =>
            c.abort(c.macroApplication.pos, s"the @$annotationName annotation must specify a type containing at most one type parameter, found $other")

        }

      case other =>
        c.abort(c.macroApplication.pos, s"the @$annotationName annotation must annotate a trait, found $other")
    }
  }

}

class defaultReader[A] extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro DefaultReaderMacro.impl
} 
Example 64
Source File: ReaderOfMacro.scala    From grafter   with MIT License 5 votes vote down vote up
package org.zalando.grafter.macros

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import ReaderMacros._


object ReaderOfMacro {

  val annotationName = "readerOf"

  def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._

    def name(t: Name) = t.decodedName.toString.trim

    val (classTree, companionTree): (Tree, Option[Tree]) =
      annotationInputs(c)(annotationName)(annottees)

    classTree match {

      case ClassDef(_, className, _, Template(_, _, fields)) =>
        val typeParam  = typeParameter(annotationName)(c)
        def params     = fieldsNamesAndTypes(c)(fields)
        val paramNames = params.map(_._1).distinct
        val implicits  = params.map { case (p, _type) => q"""private val ${TermName("_"+name(p))}: cats.data.Reader[$typeParam, ${_type}] = implicitly[cats.data.Reader[$typeParam, ${_type}]];""" }
        val readValues = paramNames.map { p => q"""val ${TermName("_"+name(p)+"Value")} = ${TermName("_"+name(p))}.apply(r);""" }
        val values     = paramNames.map { p => q"""${TermName("_"+name(p)+"Value")}""" }
        val klassName  = name(className)

        val reader =
          c.Expr[Any](
            q"""
             implicit val reader: cats.data.Reader[$typeParam, ${TypeName(klassName)}] = {
               cats.data.Reader { r =>
                 ..$readValues
                 new ${TypeName(klassName)}(...${List(values)})
               }
             }
             """)

        outputs(c)(classTree, className, companionTree) {
          q"""
         ..$implicits

         ..$reader
      """
        }

      case other =>
        c.abort(c.macroApplication.pos, s"the @$annotationName annotation must annotate a class, found $other")
    }

  }

}

class readerOf[A] extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro ReaderOfMacro.impl
} 
Example 65
Source File: Common.scala    From spark-knn   with Apache License 2.0 5 votes vote down vote up
import com.typesafe.sbt.GitVersioning
import sbt._
import Keys._
import com.typesafe.sbt.GitPlugin.autoImport._
import sbtsparkpackage.SparkPackagePlugin.autoImport._

import scala.language.experimental.macros
import scala.reflect.macros.Context

object Common {
  val commonSettings = Seq(
    organization in ThisBuild := "com.github.saurfang",
    javacOptions ++= Seq("-source", "1.8", "-target", "1.8"),
    scalacOptions ++= Seq("-target:jvm-1.8", "-deprecation", "-feature"),
    //git.useGitDescribe := true,
    git.baseVersion := "0.0.1",
    parallelExecution in test := false,
    updateOptions := updateOptions.value.withCachedResolution(true),
    sparkVersion := "2.4.4",
    sparkComponents += "mllib",
    spIgnoreProvided := true
  )

  def knnProject(path: String): Project = macro knnProjectMacroImpl

  def knnProjectMacroImpl(c: Context)(path: c.Expr[String]) = {
    import c.universe._
    reify {
      (Project.projectMacroImpl(c).splice in file(path.splice)).
        enablePlugins(GitVersioning).
        settings(name := path.splice).
        settings(Dependencies.Versions).
        settings(commonSettings)
    }
  }
} 
Example 66
Source File: ServiceMethod.scala    From typebus   with MIT License 5 votes vote down vote up
package io.surfkit.typebus.annotations

import java.nio.file.Files

import io.surfkit.typebus.ResourceDb
import play.api.libs.json.{Json, OFormat, Format}

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

@compileTimeOnly("enable macro to expand macro annotations")
class ServiceMethod extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro ServiceMethod.impl
}

object ServiceMethod extends ResourceDb{

  val databaseTableName = "_Service"

  sealed trait Store
  object Store{
    implicit val format: OFormat[Store] = Json.format[Store]
  }
  final case class ServiceMethod(in: String, out: String) extends Store
  object ServiceMethod{
    implicit val format: Format[ServiceMethod] = Json.format[ServiceMethod]
  }
  final case class ServiceStore(methods: Set[ServiceMethod]) extends Store
  object ServiceStore{
    implicit val format: Format[ServiceStore] = Json.format[ServiceStore]
  }

  var methods = Set.empty[ServiceMethod]

  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._
    val result =
      annottees.map(_.tree).toList match {
        case q"$mods def $methodName[..$tpes]($arg, meta: EventMeta): Future[$returnType] = { ..$body }" :: Nil =>
        //case q"$mods def $methodName[..$tpes]($arg, meta: EventMeta): Future[$returnType]{..$body}" :: Nil =>
          // https://stackoverflow.com/questions/19379436/cant-access-parents-members-while-dealing-with-macro-annotations
          val retTpe = c.typecheck(q"(??? : $returnType)").tpe
          val argChild = arg.children.head
          val argTpe = c.typecheck(q"(??? : $argChild)").tpe
          //println(s"retTpe:${retTpe}  ${retTpe.typeSymbol.fullName}")
          //println(s"argTpe:${argTpe}  ${argTpe.typeSymbol.fullName}")
          // FIXME: packaging a jar will fail when trying to access the resource files.  For now we can skip this.
          try {
            methods += ServiceMethod(argTpe.typeSymbol.fullName, retTpe.typeSymbol.fullName)
            val servicePath = databaseTablePath(databaseTableName)
            Files.write(servicePath, serialiseServiceStore(ServiceStore(methods)).getBytes)
          }catch{
            case _: Throwable =>
          }
          q"""$mods def $methodName[..$tpes]($arg, meta: EventMeta): Future[$returnType] = { ..$body }"""

        case _ => c.abort(c.enclosingPosition, s"Annotation @ServiceMethod can be used only with methods of the form (T, EventMeta) => Future[U] instead of: ${annottees.map(_.tree).toList}")
      }
    c.Expr[Any](result)
  }

  def serialiseServiceStore(value: ServiceStore): String = Json.toJson(value).toString()
    //Pickle.intoBytes(value).array

  def deSerialiseServiceStore(json: String): ServiceStore = Json.parse(json).as[ServiceStore]
    //Unpickle[ServiceStore].fromBytes(java.nio.ByteBuffer.wrap(bytes))
} 
Example 67
Source File: ScribeMacros.scala    From scribe   with MIT License 5 votes vote down vote up
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 68
Source File: LoggerSupport.scala    From scribe   with MIT License 5 votes vote down vote up
package scribe

import scala.language.experimental.macros

trait LoggerSupport {
  def log[M](record: LogRecord[M]): Unit

  def log[M](level: Level, message: => M, throwable: Option[Throwable])
            (implicit loggable: Loggable[M]): Unit = macro Macros.log[M]

  def trace(): Unit = macro Macros.autoLevel0
  def debug(): Unit = macro Macros.autoLevel0
  def info(): Unit = macro Macros.autoLevel0
  def warn(): Unit = macro Macros.autoLevel0
  def error(): Unit = macro Macros.autoLevel0

  def trace[M: Loggable](message: => M): Unit = macro Macros.autoLevel1[M]
  def debug[M: Loggable](message: => M): Unit = macro Macros.autoLevel1[M]
  def info[M: Loggable](message: => M): Unit = macro Macros.autoLevel1[M]
  def warn[M: Loggable](message: => M): Unit = macro Macros.autoLevel1[M]
  def error[M: Loggable](message: => M): Unit = macro Macros.autoLevel1[M]

  def trace[M : Loggable](message: => M, t: Throwable): Unit = macro Macros.autoLevel2[M]
  def debug[M : Loggable](message: => M, t: Throwable): Unit = macro Macros.autoLevel2[M]
  def info[M : Loggable](message: => M, t: Throwable): Unit = macro Macros.autoLevel2[M]
  def warn[M : Loggable](message: => M, t: Throwable): Unit = macro Macros.autoLevel2[M]
  def error[M : Loggable](message: => M, t: Throwable): Unit = macro Macros.autoLevel2[M]
} 
Example 69
Source File: Position.scala    From scribe   with MIT License 5 votes vote down vote up
package scribe

import scala.language.experimental.macros
import perfolation._

case class Position(className: String,
                    methodName: Option[String],
                    line: Option[Int],
                    column: Option[Int],
                    fileName: String) {
  def toTraceElement: StackTraceElement = {
    val fn = if (fileName.indexOf('/') != -1) {
      fileName.substring(fileName.lastIndexOf('/') + 1)
    } else {
      fileName
    }
    new StackTraceElement(className, methodName.getOrElse("unknown"), fn, line.getOrElse(-1))
  }

  override def toString: String = {
    val mn = methodName.map(m => p":$m").getOrElse("")
    val ln = line.map(l => p":$l").getOrElse("")
    val cn = column.map(c => p":$c").getOrElse("")
    val fn = if (fileName.indexOf('/') != -1) {
      fileName.substring(fileName.lastIndexOf('/') + 1)
    } else {
      fileName
    }
    p"$className$mn$ln$cn ($fn)"
  }
}

object Position {
  private lazy val threadLocal = new ThreadLocal[List[Position]] {
    override def initialValue(): List[Position] = Nil
  }

  def push(position: Position): Unit = threadLocal.set(position :: threadLocal.get())

  def push(): Unit = macro scribe.Macros.pushPosition

  def pop(): Option[Position] = {
    val stack = threadLocal.get()
    if (stack.nonEmpty) {
      threadLocal.set(stack.tail)
    }
    stack.headOption
  }

  def stack: List[Position] = threadLocal.get().distinct

  def stack_=(stack: List[Position]): Unit = threadLocal.set(stack)

  def fix[T <: Throwable](throwable: T): T = {
    val positionTrace = stack.reverse.map(_.toTraceElement).distinct
    val original = throwable.getStackTrace.toList.filterNot(positionTrace.contains)
    val trace = (original.head :: positionTrace ::: original.tail).distinct
    throwable.setStackTrace(trace.toArray)
    throwable
  }
} 
Example 70
Source File: package.scala    From scalapy   with MIT License 5 votes vote down vote up
package me.shadaj.scalapy

import scala.collection.mutable

import scala.concurrent.Future

package object py {
  def module(name: String) = Module(name)
  def module(name: String, subname: String) = Module(name, subname)

  @py.native trait None extends Any
  val None = Any.populateWith(CPythonInterpreter.noneValue).as[None]

  type NoneOr[T] = None | T

  def `with`[T <: py.Any, O](ref: T)(withValue: T => O): O = {
    ref.as[Dynamic](Reader.facadeReader[Dynamic](FacadeCreator.getCreator[Dynamic])).__enter__()
    val ret = withValue(ref)
    ref.as[Dynamic].__exit__(None, None, None)
    ret
  }

  def local[T](f: => T): T = {
    py.PyValue.allocatedValues = List.empty[PyValue] :: py.PyValue.allocatedValues
    py.VariableReference.allocatedReferences = List.empty[VariableReference] :: py.VariableReference.allocatedReferences

    try {
      f
    } finally {
      py.PyValue.allocatedValues.head.foreach { c =>
        c.cleanup()
      }

      py.VariableReference.allocatedReferences.head.foreach { c =>
        c.cleanup()
      }

      py.PyValue.allocatedValues = py.PyValue.allocatedValues.tail
      py.VariableReference.allocatedReferences = py.VariableReference.allocatedReferences.tail
    }
  }

  import py.{Dynamic => PyDynamic, Any => PyAny}
  trait PyQuotable {
    def stringToInsert: String
    def cleanup(): Unit
  }

  object PyQuotable {
    implicit def fromAny(any: py.Any): PyQuotable = new PyQuotable {
      private val expr = any.expr
      def stringToInsert: String = expr.toString
      def cleanup() = expr.cleanup()
    }

    implicit def fromValue[V](value: V)(implicit writer: Writer[V]): PyQuotable = new PyQuotable {
      private val expr = Any.populateWith(writer.write(value)).expr
      def stringToInsert: String = expr.toString
      def cleanup() = expr.cleanup()
    }
  }

  implicit class PyQuote(private val sc: StringContext) extends AnyVal {
    def py(values: PyQuotable*): PyDynamic = {
      val strings = sc.parts.iterator
      val expressions = values.iterator
      var buf = new StringBuffer(strings.next)
      val toCleanup = mutable.Queue[PyQuotable]()
      while (strings.hasNext) {
        val expr = expressions.next
        buf append expr.stringToInsert
        toCleanup += expr

        buf append strings.next
      }
      
      val ret = PyAny.populateWith(CPythonInterpreter.load(buf.toString)).as[Dynamic]
      toCleanup.foreach(_.cleanup())
      ret
    }
  }

  def eval(str: String): PyDynamic = {
    PyAny.populateWith(CPythonInterpreter.load(str)).as[Dynamic]
  }

  import scala.language.experimental.macros
  def native[T]: T = macro FacadeImpl.native_impl[T]
  def nativeNamed[T]: T = macro FacadeImpl.native_named_impl[T]
} 
Example 71
Source File: Facades.scala    From scalapy   with MIT License 5 votes vote down vote up
package me.shadaj.scalapy.py

import scala.reflect.macros.whitebox
import scala.language.experimental.macros

import scala.annotation.StaticAnnotation
class native extends StaticAnnotation

object FacadeImpl {
  def creator[T <: Any](c: whitebox.Context)(implicit tag: c.WeakTypeTag[T]): c.Tree = {
    import c.universe._

    if (!tag.tpe.typeSymbol.annotations.exists(_.tpe =:= typeOf[native])) {
      c.error(c.enclosingPosition, "Cannot derive a creator for a trait that is not annotated as @py.native")
    }
    
    q"""new _root_.me.shadaj.scalapy.py.FacadeCreator[${tag.tpe}] {
      def create(value: _root_.me.shadaj.scalapy.py.PyValue) = new _root_.me.shadaj.scalapy.py.FacadeValueProvider(value) with ${tag.tpe} {}
    }"""
  }

  def native_impl[T: c.WeakTypeTag](c: whitebox.Context): c.Expr[T] = {
    import c.universe._

    if (!c.enclosingClass.symbol.annotations.exists(_.tpe =:= typeOf[native])) {
      c.error(c.enclosingPosition, "py.native implemented functions can only be declared inside traits annotated as @py.native")
    }

    val method = c.internal.enclosingOwner.asMethod
    val methodName = method.name.toString
    val returnType = method.returnType
    val paramss = method.paramLists

    paramss.headOption match {
      case Some(params) =>
        val paramExprs = params.map(_.name)
        c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].applyDynamic($methodName)(..$paramExprs).as[$returnType]")
      case scala.None =>
        c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].selectDynamic($methodName).as[$returnType]")
    }
  }

  def native_named_impl[T: c.WeakTypeTag](c: whitebox.Context): c.Expr[T] = {
    import c.universe._

    if (!c.enclosingClass.symbol.annotations.exists(_.tpe =:= typeOf[native])) {
      c.error(c.enclosingPosition, "py.native implemented functions can only be declared inside traits annotated as @py.native")
    }

    val method = c.internal.enclosingOwner.asMethod
    val methodName = method.name.toString
    val returnType = method.returnType
    val paramss = method.paramLists

    paramss.headOption match {
      case Some(params) =>
        val paramExprs = params.map { p =>
          val paramName = q"${p.asTerm}".toString
          s"""("${p.name}", $paramName)"""
        }

        c.Expr[T](c.parse(s"""as[_root_.me.shadaj.scalapy.py.Dynamic].applyDynamicNamed("$methodName")(${paramExprs.mkString(",")}).as[$returnType]"""))

      case scala.None =>
        c.Expr[T](q"as[_root_.me.shadaj.scalapy.py.Dynamic].selectDynamic($methodName).as[$returnType]")
    }
  }
} 
Example 72
Source File: ShouldNotTypecheck.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
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 73
Source File: Glossary.scala    From rule-engine   with MIT License 5 votes vote down vote up
package nl.rabobank.oss.rules.dsl.core.glossaries

import nl.rabobank.oss.rules.facts.{Fact, ListFact, SingularFact}
import nl.rabobank.oss.rules.utils.FactMacros

import scala.language.experimental.macros


  lazy val facts: Map[String, Fact[Any]] = {
    this.getClass.getDeclaredFields
      .filter( field => classOf[Fact[Any]].isAssignableFrom( field.getType ) )
      .map( field => {
        field.setAccessible(true)
        val fact: Fact[Any] = field.get(this).asInstanceOf[Fact[Any]]
        (fact.name, fact)
      })
      .toMap
  }

} 
Example 74
Source File: SemiautoDerivation.scala    From tethys   with Apache License 2.0 5 votes vote down vote up
package tethys.derivation

import tethys.derivation.builder._
import tethys.derivation.impl.builder.{ReaderDescriptionMacro, WriterDescriptorMacro}
import tethys.derivation.impl.derivation.SemiautoDerivationMacro
import tethys.{JsonObjectWriter, JsonReader}

import scala.annotation.compileTimeOnly
import scala.language.experimental.macros

trait SemiautoDerivation {
  def jsonWriter[A]: JsonObjectWriter[A] = macro SemiautoDerivationMacro.simpleJsonWriter[A]
  def jsonWriter[A](description: WriterDescription[A]): JsonObjectWriter[A] = macro SemiautoDerivationMacro.describedJsonWriter[A]
  def jsonWriter[A](builder: WriterBuilder[A]): JsonObjectWriter[A] = macro SemiautoDerivationMacro.jsonWriterWithBuilder[A]
  def jsonWriter[A](config: WriterDerivationConfig): JsonObjectWriter[A] = macro SemiautoDerivationMacro.jsonWriterWithConfig[A]

  def describe[A](builder: WriterBuilder[A]): WriterDescription[A] = macro WriterDescriptorMacro.simpleDescription[A]

  def jsonReader[A]: JsonReader[A] = macro SemiautoDerivationMacro.simpleJsonReader[A]
  def jsonReader[A](description: ReaderDescription[A]): JsonReader[A] = macro SemiautoDerivationMacro.describedJsonReader[A]
  def jsonReader[A](builder: ReaderBuilder[A]): JsonReader[A] = macro SemiautoDerivationMacro.jsonReaderWithBuilder[A]
  def jsonReader[A](config: ReaderDerivationConfig): JsonReader[A] = macro SemiautoDerivationMacro.jsonReaderWithConfig[A]

  def describe[A](builder: ReaderBuilder[A]): ReaderDescription[A] = macro ReaderDescriptionMacro.readerDescription[A]

  implicit class ReaderFieldStringOps(val s: String) {

    @compileTimeOnly("ReaderFieldOps.as should be defined in describe block")
    def as[A]: ReaderField[A] = throw new NotDescribedException
  }

  implicit class ReaderFieldSymbolOps(val s: Symbol) {

    @compileTimeOnly("ReaderFieldOps.as should be defined in describe block")
    def as[A]: ReaderField[A] = throw new NotDescribedException
  }
} 
Example 75
Source File: MacroLogging.scala    From tethys   with Apache License 2.0 5 votes vote down vote up
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 76
Source File: CollectionBuilder.scala    From tethys   with Apache License 2.0 5 votes vote down vote up
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 77
Source File: ShouldNotTypecheck.scala    From scala-parallel-collections   with Apache License 2.0 5 votes vote down vote up
package testutil

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context
import scala.reflect.macros.TypecheckException
import java.util.regex.Pattern


object ShouldNotTypecheck {
  def apply(code: String): Unit = macro applyImplNoExp
  def apply(code: String, expected: String): Unit = macro applyImpl

  def applyImplNoExp(ctx: Context)(code: ctx.Expr[String]) = applyImpl(ctx)(code, null)

  def applyImpl(ctx: Context)(code: ctx.Expr[String], expected: ctx.Expr[String]): ctx.Expr[Unit] = {
    import ctx.universe._

    val Expr(Literal(Constant(codeStr: String))) = code
    val (expPat, expMsg) = expected match {
      case null => (null, "Expected some error.")
      case Expr(Literal(Constant(s: String))) =>
        (Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.DOTALL), "Expected error matching: "+s)
    }

    try ctx.typecheck(ctx.parse("{ "+codeStr+" }")) catch { case e: TypecheckException =>
      val msg = e.getMessage
      if((expected ne null) && !(expPat.matcher(msg)).matches)
        ctx.abort(ctx.enclosingPosition, "Type-checking failed in an unexpected way.\n"+
          expMsg+"\nActual error: "+msg)
      else return reify(())
    }

    ctx.abort(ctx.enclosingPosition, "Type-checking succeeded unexpectedly.\n"+expMsg)
  }
} 
Example 78
Source File: ProtoBinWrapper.scala    From aerospike-scala   with Apache License 2.0 5 votes vote down vote up
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 79
Source File: KeyWrapper.scala    From aerospike-scala   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.aerospikemacro.converters

import com.aerospike.client.Value._
import com.aerospike.client.{Key, Value}
import ru.tinkoff.aerospikemacro.domain.{DBCredentials, WrapperException}

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context


trait KeyWrapper[KT] {

  val dbName: String    = ""
  val tableName: String = ""

  def apply(k: KT): Key = new Key(dbName, tableName, toValue(k))

  def toValue(v: KT): Value = Value.get(v) match {
    case _: NullValue =>
      throw new WrapperException {
        val msg = "You need to write your own toValue function in KeyWrapper"
      }
    case other => other
  }
}

object KeyWrapper {
  import Utils._

  implicit def materializeK[T](implicit dbc: DBCredentials): KeyWrapper[T] = macro implK[T]

  def implK[T: c.WeakTypeTag](c: Context)(dbc: c.Expr[DBCredentials]): c.Expr[KeyWrapper[T]] = {
    import c.universe._
    val tpe = weakTypeOf[T]

    val db        = reify(dbc.splice.namespace)
    val tableName = reify(dbc.splice.setname)

    val toDBValue = pickValue(c)

    c.Expr[KeyWrapper[T]] {
      q"""
      import com.aerospike.client.{Key, Value}
      import com.aerospike.client.Value._
      import scala.collection.immutable.Seq
      import ru.tinkoff.aerospikescala.domain.ByteSegment
      import scala.util.{Failure, Success, Try}

      new KeyWrapper[$tpe] {
        override val dbName = $db
        override val tableName = $tableName
        override def toValue(v: $tpe): Value = $toDBValue
      }
     """
    }
  }

  def create[T](dbc: DBCredentials): KeyWrapper[T] = macro implK[T]

} 
Example 80
Source File: Printer.scala    From aerospike-scala   with Apache License 2.0 5 votes vote down vote up
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 81
Source File: Sanitiser.scala    From sansible   with MIT License 5 votes vote down vote up
package ansible

import scala.language.experimental.macros
import scala.reflect.macros.whitebox

class Sanitiser(c: whitebox.Context) {
  private def reSugar(sym: c.universe.Symbol): String =
    Seq(
      "\\$eq" -> "=",
      "\\$hash" -> "#",
      "\\$bang" -> "!",
      "\\$asInstanceOf" -> "asInstanceOf",
      "\\$isInstanceOf" -> "isInstanceOf"
    ).foldLeft(sym.name.toString) { case (s, (a, b)) => s.replaceAll(a, b) }

  private val objType = c.weakTypeOf[Object]
  private val prodType = c.weakTypeOf[Product]
  private val keywords = c.universe.asInstanceOf[scala.reflect.internal.SymbolTable].nme.keywords.map(_.decoded)
  private val reservedWords = keywords ++ objType.decls.map(reSugar) ++ prodType.decls.map(reSugar)

  def safeName(name: String) =
    if (reservedWords(name)) s"_$name" else name
} 
Example 82
Source File: Expand.scala    From sansible   with MIT License 5 votes vote down vote up
package ansible

import ansible.AnsibleModule._
import argonaut.Argonaut._
import better.files._

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

@compileTimeOnly("enable macro paradise to expand macro annotations")
class expand extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro Expander.expand_impl
}

object Expander {
  val tmpDir = System.getProperty("java.io.tmpdir")

  def expand_impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._
    val gen = new CodeGen(c)

    val files = (tmpDir / "parsed_modules").listRecursively.filter(_.extension.contains(".json")).toList
    val ansibleModules = files.map { f =>
      f.contentAsString.decodeValidation[AnsibleModule].fold(err =>
        throw new Exception(s"Failed reading the json representation of the Ansible module: ${f.path}, error: $err"),
        identity
      )
    }

    def generateModule(m: AnsibleModule): (ModuleDef, ClassDef) = {
      val moduleTypeName = TypeName(camelize(m.name))
      val moduleTermName = TermName(camelize(m.name))
      val sortedOptions  = m.options.sortBy(_.required)(Ordering[Boolean].reverse)

      val (enumTypes, enumValues, fields) =
        sortedOptions.foldLeft((List.empty[ClassDef], List.empty[ModuleDef], Vector.empty[ValDef])) { case ((enumTypes, enumValues, fields), option) =>
          option match {
            case o: BooleanOption =>
              (enumTypes, enumValues, fields :+ gen.boolVal(o).asInstanceOf[ValDef])
            case o: StringOption =>
              (enumTypes, enumValues, fields :+ gen.stringVal(o).asInstanceOf[ValDef])
            case o: EnumOption =>
              (gen.enumClassDef(o).asInstanceOf[ClassDef] :: enumTypes,
                gen.enumObjectDef(o).asInstanceOf[ModuleDef] :: enumValues,
                fields :+ gen.enumVal(o, m.name).asInstanceOf[ValDef])
          }
        }

      val jsonEncoderVal = gen.moduleObjectJsonEncoder(m).asInstanceOf[ValDef]

      val enumSetters = m.enumOptions.map(gen.enumSetterDef(m.name)).asInstanceOf[List[DefDef]]

      val objectDef = q"""
         object $moduleTermName {
           $jsonEncoderVal
           ..$enumTypes
           ..$enumValues
         }
      """.asInstanceOf[ModuleDef]


      val classDef = q"""
        case class $moduleTypeName(..$fields) extends ansible.Module {
          override def call = ModuleCall(this.asJson)
          ..$enumSetters
        }
       """.asInstanceOf[ClassDef]

      (objectDef, classDef)
    }

    annottees.map(_.tree) match {
      case List(q"trait $_") =>
        val (objectDefs, classDefs) = ansibleModules.map(m => generateModule(m)).unzip
        c.Expr[Any](
          q"""
             import argonaut._
             import Argonaut._

             ..$objectDefs
             ..$classDefs
          """)
      case _ =>
        c.abort(c.enclosingPosition, "@expand should annotate a trait")
    }
  }

  private def camelize(str: String): String =
    str.split('_').map { s =>
      if (s.isEmpty)
        ""
      else
        s.head.toUpper.toString + s.tail.toLowerCase
    }.mkString
} 
Example 83
Source File: LuceneCreate.scala    From lucene4s   with MIT License 5 votes vote down vote up
package com.outr.lucene4s

import com.outr.lucene4s.facet.FacetField
import com.outr.lucene4s.field.value.support.{StringifyValueSupport, ValueSupport}
import com.outr.lucene4s.field.{Field, FieldType}
import com.outr.lucene4s.mapper.{BaseSearchable, SearchableMacro}

import scala.language.experimental.macros

class LuceneCreate(val lucene: Lucene) {
  def field[T](name: String,
               fieldType: FieldType = FieldType.Stored,
               fullTextSearchable: Boolean = lucene.defaultFullTextSearchable,
               sortable: Boolean = true
              )(implicit support: ValueSupport[T]): Field[T] = {
    val field = new Field[T](name, fieldType, support, fullTextSearchable, sortable)
    lucene.synchronized {
      lucene._fields += field
    }
    field
  }
  def stringifiedField[T](name: String,
                          fieldType: FieldType = FieldType.Stored,
                          fullTextSearchable: Boolean = lucene.defaultFullTextSearchable,
                          sortable: Boolean = true)(implicit stringify: Stringify[T]): Field[T] = {
    field[T](name, fieldType, fullTextSearchable, sortable)(StringifyValueSupport(stringify))
  }
  def facet(name: String,
            hierarchical: Boolean = false,
            multiValued: Boolean = false,
            requireDimCount: Boolean = false): FacetField = {
    lucene.facetsConfig.setHierarchical(name, hierarchical)
    lucene.facetsConfig.setMultiValued(name, multiValued)
    lucene.facetsConfig.setRequireDimCount(name, requireDimCount)
    val field = FacetField(name, hierarchical, multiValued, requireDimCount)
    lucene.synchronized {
      lucene._facets += field
    }
    field
  }
  def searchable[S <: BaseSearchable]: S = macro SearchableMacro.generate[S]
} 
Example 84
Source File: package.scala    From ip4s   with Apache License 2.0 5 votes vote down vote up
package com.comcast

import scala.language.experimental.macros

package object ip4s {
  final implicit class IpLiteralSyntax(val sc: StringContext) extends AnyVal {
    def ip(args: Any*): IpAddress = macro LiteralSyntaxMacros.ipInterpolator
    def ipv4(args: Any*): Ipv4Address =
      macro LiteralSyntaxMacros.ipv4Interpolator
    def ipv6(args: Any*): Ipv6Address =
      macro LiteralSyntaxMacros.ipv6Interpolator

    def mip(args: Any*): Multicast[IpAddress] =
      macro LiteralSyntaxMacros.mipInterpolator
    def mipv4(args: Any*): Multicast[Ipv4Address] =
      macro LiteralSyntaxMacros.mipv4Interpolator
    def mipv6(args: Any*): Multicast[Ipv6Address] =
      macro LiteralSyntaxMacros.mipv6Interpolator

    def ssmip(args: Any*): SourceSpecificMulticast[IpAddress] =
      macro LiteralSyntaxMacros.ssmipInterpolator
    def ssmipv4(args: Any*): SourceSpecificMulticast[Ipv4Address] =
      macro LiteralSyntaxMacros.ssmipv4Interpolator
    def ssmipv6(args: Any*): SourceSpecificMulticast[Ipv6Address] =
      macro LiteralSyntaxMacros.ssmipv6Interpolator

    def port(args: Any*): Port =
      macro LiteralSyntaxMacros.portInterpolator
    def host(args: Any*): Hostname =
      macro LiteralSyntaxMacros.hostnameInterpolator
    def idn(args: Any*): IDN =
      macro LiteralSyntaxMacros.idnInterpolator
  }
} 
Example 85
Source File: QueryDsl.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.dsl

import scala.language.experimental.macros
import io.getquill.quotation.NonQuotedException
import io.getquill.EntityQuery

import scala.annotation.compileTimeOnly

private[getquill] trait QueryDsl {
  dsl: CoreDsl =>

  def query[T]: EntityQuery[T] = macro QueryDslMacro.expandEntity[T]

  @compileTimeOnly(NonQuotedException.message)
  def querySchema[T](entity: String, columns: (T => (Any, String))*): EntityQuery[T] = NonQuotedException()

  @compileTimeOnly(NonQuotedException.message)
  def impliedQuerySchema[T](entity: String, columns: (T => (Any, String))*): EntityQuery[T] = NonQuotedException()

  implicit class NullableColumnExtensions[A](o: Option[A]) {
    @compileTimeOnly(NonQuotedException.message)
    def getOrNull: A =
      throw new IllegalArgumentException(
        "Cannot use getOrNull outside of database queries since only database value-types (e.g. Int, Double, etc...) can be null."
      )
  }

  object extras extends LowPriorityExtras {
    implicit class NumericOptionOps[A: Numeric](a: Option[A]) {
      def ===[B: Numeric](b: Option[B]): Boolean = a.exists(av => b.exists(bv => av == bv))
      def ===[B: Numeric](b: B): Boolean = a.exists(av => av == b)
      def =!=[B: Numeric](b: Option[B]): Boolean = a.exists(av => b.exists(bv => av != bv))
      def =!=[B: Numeric](b: B): Boolean = a.exists(av => av != b)
    }
    implicit class NumericRegOps[A: Numeric](a: A) {
      def ===[B: Numeric](b: Option[B]): Boolean = b.exists(bv => bv == a)
      def ===[B: Numeric](b: B): Boolean = a == b
      def =!=[B: Numeric](b: Option[B]): Boolean = b.exists(bv => bv != a)
      def =!=[B: Numeric](b: B): Boolean = a != b
    }
  }

  trait LowPriorityExtras {
    implicit class OptionOps[T](a: Option[T]) {
      def ===(b: Option[T]): Boolean = a.exists(av => b.exists(bv => av == bv))
      def ===(b: T): Boolean = a.exists(av => av == b)
      def =!=(b: Option[T]): Boolean = a.exists(av => b.exists(bv => av != bv))
      def =!=(b: T): Boolean = a.exists(av => av != b)
    }
    implicit class RegOps[T](a: T) {
      def ===(b: Option[T]): Boolean = b.exists(bv => bv == a)
      def ===(b: T): Boolean = a == b
      def =!=(b: Option[T]): Boolean = b.exists(bv => bv != a)
      def =!=(b: T): Boolean = a != b
    }
  }
} 
Example 86
Source File: QuotationDsl.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.dsl

import scala.language.experimental.macros
import scala.language.implicitConversions
import scala.reflect.macros.whitebox.Context

import io.getquill.ast.Ast
import io.getquill.quotation.NonQuotedException
import io.getquill.quotation.Quotation
import scala.annotation.compileTimeOnly

private[dsl] trait QuotationDsl {
  this: CoreDsl =>

  trait Quoted[+T] {
    def ast: Ast
    override def toString = ast.toString
  }

  def quote[T](body: Quoted[T]): Quoted[T] = macro QuotationMacro.doubleQuote[T]
  def quote[T1, R](func: T1 => Quoted[R]): Quoted[T1 => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, R](func: (T1, T2) => Quoted[R]): Quoted[(T1, T2) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, R](func: (T1, T2, T3) => Quoted[R]): Quoted[(T1, T2, T3) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, R](func: (T1, T2, T3, T4) => Quoted[R]): Quoted[(T1, T2, T3, T4) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, R](func: (T1, T2, T3, T4, T5) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, T6, R](func: (T1, T2, T3, T4, T5, T6) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, T6, T7, R](func: (T1, T2, T3, T4, T5, T6, T7) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, T6, T7, T8, R](func: (T1, T2, T3, T4, T5, T6, T7, T8) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](func: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R] = macro QuotationMacro.quotedFunctionBody
  def quote[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](func: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => Quoted[R]): Quoted[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R] = macro QuotationMacro.quotedFunctionBody

  implicit def quote[T](body: T): Quoted[T] = macro QuotationMacro.quote[T]

  @compileTimeOnly(NonQuotedException.message)
  implicit def unquote[T](quoted: Quoted[T]): T = NonQuotedException()
}

private[dsl] class QuotationMacro(val c: Context) extends Quotation 
Example 87
Source File: MetaDsl.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.dsl

import scala.language.experimental.macros
import io.getquill.{ Query, EntityQuery, Update, Insert }

trait MetaDslLowPriorityImplicits {
  this: MetaDsl =>

  implicit def materializeQueryMeta[T]: QueryMeta[T] = macro MetaDslMacro.materializeQueryMeta[T]
  implicit def materializeUpdateMeta[T]: UpdateMeta[T] = macro MetaDslMacro.materializeUpdateMeta[T]
  implicit def materializeInsertMeta[T]: InsertMeta[T] = macro MetaDslMacro.materializeInsertMeta[T]
  implicit def materializeSchemaMeta[T]: SchemaMeta[T] = macro MetaDslMacro.materializeSchemaMeta[T]
}

trait MetaDsl extends MetaDslLowPriorityImplicits {
  this: CoreDsl =>

  type Embedded = io.getquill.Embedded

  def schemaMeta[T](entity: String, columns: (T => (Any, String))*): SchemaMeta[T] = macro MetaDslMacro.schemaMeta[T]
  def queryMeta[T, R](expand: Quoted[Query[T] => Query[R]])(extract: R => T): QueryMeta[T] = macro MetaDslMacro.queryMeta[T, R]
  def updateMeta[T](exclude: (T => Any)*): UpdateMeta[T] = macro MetaDslMacro.updateMeta[T]
  def insertMeta[T](exclude: (T => Any)*): InsertMeta[T] = macro MetaDslMacro.insertMeta[T]

  trait SchemaMeta[T] {
    def entity: Quoted[EntityQuery[T]]
  }

  trait QueryMeta[T] {
    def expand: Quoted[Query[T] => Query[_]]
    def extract: ResultRow => T
  }

  trait UpdateMeta[T] {
    def expand: Quoted[(EntityQuery[T], T) => Update[T]]
  }

  trait InsertMeta[T] {
    def expand: Quoted[(EntityQuery[T], T) => Insert[T]]
  }
} 
Example 88
Source File: ImplicitQuery.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill

import scala.language.experimental.macros
import scala.language.implicitConversions
import scala.reflect.macros.whitebox.{ Context => MacroContext }
import scala.runtime.AbstractFunction1
import scala.runtime.AbstractFunction10
import scala.runtime.AbstractFunction11
import scala.runtime.AbstractFunction12
import scala.runtime.AbstractFunction13
import scala.runtime.AbstractFunction14
import scala.runtime.AbstractFunction15
import scala.runtime.AbstractFunction16
import scala.runtime.AbstractFunction17
import scala.runtime.AbstractFunction18
import scala.runtime.AbstractFunction19
import scala.runtime.AbstractFunction2
import scala.runtime.AbstractFunction20
import scala.runtime.AbstractFunction21
import scala.runtime.AbstractFunction22
import scala.runtime.AbstractFunction3
import scala.runtime.AbstractFunction4
import scala.runtime.AbstractFunction5
import scala.runtime.AbstractFunction6
import scala.runtime.AbstractFunction7
import scala.runtime.AbstractFunction8
import scala.runtime.AbstractFunction9

import io.getquill.util.MacroContextExt._
import io.getquill.context.Context

trait ImplicitQuery {
  this: Context[_, _] =>

  implicit def toQuery[P <: Product](f: AbstractFunction1[_, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction2[_, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction3[_, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction4[_, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction5[_, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction6[_, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction7[_, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction8[_, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction9[_, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction10[_, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction11[_, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction12[_, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction13[_, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction14[_, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
  implicit def toQuery[P <: Product](f: AbstractFunction22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, P]): Query[P] = macro ImplicitQueryMacro.toQuery[P]
}

private[getquill] class ImplicitQueryMacro(val c: MacroContext) {
  import c.universe._

  def toQuery[P <: Product](f: Expr[Any])(implicit p: WeakTypeTag[P]): Tree = {
    if (!p.tpe.typeSymbol.asClass.isCaseClass || !f.actualType.typeSymbol.isModuleClass)
      c.fail("Can't query a non-case class")

    q"${c.prefix}.query[$p]"
  }
} 
Example 89
Source File: TranslateContext.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.context

import io.getquill.NamingStrategy
import io.getquill.idiom.Idiom

import scala.annotation.tailrec
import scala.language.experimental.macros
import scala.language.higherKinds
import io.getquill.{ Query, Action, BatchAction }

trait TranslateContext extends TranslateContextBase {
  this: Context[_ <: Idiom, _ <: NamingStrategy] =>

  override type TranslateResult[T] = T

  override private[getquill] val translateEffect: ContextEffect[TranslateResult] = new ContextEffect[TranslateResult] {
    override def wrap[T](t: => T): T = t
    override def push[A, B](result: A)(f: A => B): B = f(result)
    override def seq[A, B](list: List[A]): List[A] = list
  }
}

trait TranslateContextBase {
  this: Context[_ <: Idiom, _ <: NamingStrategy] =>

  type TranslateResult[T]

  private[getquill] val translateEffect: ContextEffect[TranslateResult]
  import translateEffect._

  def translate[T](quoted: Quoted[T]): TranslateResult[String] = macro QueryMacro.translateQuery[T]
  def translate[T](quoted: Quoted[Query[T]]): TranslateResult[String] = macro QueryMacro.translateQuery[T]
  def translate(quoted: Quoted[Action[_]]): TranslateResult[String] = macro ActionMacro.translateQuery
  def translate(quoted: Quoted[BatchAction[Action[_]]]): TranslateResult[List[String]] = macro ActionMacro.translateBatchQuery

  def translate[T](quoted: Quoted[T], prettyPrint: Boolean): TranslateResult[String] = macro QueryMacro.translateQueryPrettyPrint[T]
  def translate[T](quoted: Quoted[Query[T]], prettyPrint: Boolean): TranslateResult[String] = macro QueryMacro.translateQueryPrettyPrint[T]
  def translate(quoted: Quoted[Action[_]], prettyPrint: Boolean): TranslateResult[String] = macro ActionMacro.translateQueryPrettyPrint
  def translate(quoted: Quoted[BatchAction[Action[_]]], prettyPrint: Boolean): TranslateResult[List[String]] = macro ActionMacro.translateBatchQueryPrettyPrint

  def translateQuery[T](statement: String, prepare: Prepare = identityPrepare, extractor: Extractor[T] = identityExtractor, prettyPrint: Boolean = false): TranslateResult[String] =
    push(prepareParams(statement, prepare)) { params =>
      val query =
        if (params.nonEmpty) {
          params.foldLeft(statement) {
            case (expanded, param) => expanded.replaceFirst("\\?", param)
          }
        } else {
          statement
        }

      if (prettyPrint)
        idiom.format(query)
      else
        query
    }

  def translateBatchQuery(groups: List[BatchGroup], prettyPrint: Boolean = false): TranslateResult[List[String]] =
    seq {
      groups.flatMap { group =>
        group.prepare.map { prepare =>
          translateQuery(group.string, prepare, prettyPrint = prettyPrint)
        }
      }
    }

  private[getquill] def prepareParams(statement: String, prepare: Prepare): TranslateResult[Seq[String]]

  @tailrec
  final protected def prepareParam(param: Any): String = param match {
    case None | null => "null"
    case Some(x)     => prepareParam(x)
    case str: String => s"'$str'"
    case _           => param.toString
  }
} 
Example 90
Source File: Context.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.context

import scala.language.higherKinds
import scala.language.experimental.macros
import io.getquill.dsl.CoreDsl
import io.getquill.util.Messages.fail
import java.io.Closeable

import scala.util.Try
import io.getquill.{ Query, Action, NamingStrategy, BatchAction, ReturnAction, ActionReturning }

trait Context[Idiom <: io.getquill.idiom.Idiom, Naming <: NamingStrategy]
  extends Closeable
  with CoreDsl {

  type Result[T]
  type RunQuerySingleResult[T]
  type RunQueryResult[T]
  type RunActionResult
  type RunActionReturningResult[T]
  type RunBatchActionResult
  type RunBatchActionReturningResult[T]
  type Session

  type Prepare = PrepareRow => (List[Any], PrepareRow)
  type Extractor[T] = ResultRow => T

  case class BatchGroup(string: String, prepare: List[Prepare])
  case class BatchGroupReturning(string: String, returningBehavior: ReturnAction, prepare: List[Prepare])

  def probe(statement: String): Try[_]

  def idiom: Idiom
  def naming: Naming

  def run[T](quoted: Quoted[T]): Result[RunQuerySingleResult[T]] = macro QueryMacro.runQuerySingle[T]
  def run[T](quoted: Quoted[Query[T]]): Result[RunQueryResult[T]] = macro QueryMacro.runQuery[T]
  def prepare[T](quoted: Quoted[Query[T]]): Session => Result[PrepareRow] = macro QueryMacro.prepareQuery[T]

  def run(quoted: Quoted[Action[_]]): Result[RunActionResult] = macro ActionMacro.runAction
  def run[T](quoted: Quoted[ActionReturning[_, T]]): Result[RunActionReturningResult[T]] = macro ActionMacro.runActionReturning[T]
  def run(quoted: Quoted[BatchAction[Action[_]]]): Result[RunBatchActionResult] = macro ActionMacro.runBatchAction
  def run[T](quoted: Quoted[BatchAction[ActionReturning[_, T]]]): Result[RunBatchActionReturningResult[T]] = macro ActionMacro.runBatchActionReturning[T]
  def prepare(quoted: Quoted[Action[_]]): Session => Result[PrepareRow] = macro ActionMacro.prepareAction
  def prepare(quoted: Quoted[BatchAction[Action[_]]]): Session => Result[List[PrepareRow]] = macro ActionMacro.prepareBatchAction

  protected val identityPrepare: Prepare = (Nil, _)
  protected val identityExtractor = identity[ResultRow] _

  protected def handleSingleResult[T](list: List[T]) =
    list match {
      case value :: Nil => value
      case other        => fail(s"Expected a single result but got $other")
    }
} 
Example 91
Source File: DiffMagnoliaDerivation.scala    From diffx   with Apache License 2.0 5 votes vote down vote up
package com.softwaremill.diffx
import acyclic.skipped
import magnolia._

import scala.collection.immutable.ListMap
import scala.language.experimental.macros

trait DiffMagnoliaDerivation extends LowPriority {
  type Typeclass[T] = Derived[Diff[T]]

  def combine[T](ctx: ReadOnlyCaseClass[Typeclass, T]): Derived[Diff[T]] =
    Derived(new Diff[T] {
      override def apply(left: T, right: T, toIgnore: List[FieldPath]): DiffResult = {
        val map = ListMap(ctx.parameters.map { p =>
          val lType = p.dereference(left)
          val pType = p.dereference(right)
          if (toIgnore.contains(List(p.label))) {
            p.label -> Identical(lType)
          } else {
            val nestedIgnore =
              if (toIgnore.exists(_.headOption.exists(h => h == p.label))) toIgnore.map(_.drop(1)) else Nil
            p.label -> p.typeclass.value(lType, pType, nestedIgnore)
          }
        }: _*)
        if (map.values.forall(p => p.isIdentical)) {
          Identical(left)
        } else {
          DiffResultObject(ctx.typeName.short, map)
        }
      }
    })

  def dispatch[T](ctx: SealedTrait[Typeclass, T]): Derived[Diff[T]] =
    Derived({ (left: T, right: T, toIgnore: List[FieldPath]) =>
      {
        val lType = ctx.dispatch(left)(a => a)
        val rType = ctx.dispatch(right)(a => a)
        if (lType == rType) {
          lType.typeclass.value(lType.cast(left), lType.cast(right), toIgnore)
        } else {
          DiffResultValue(lType.typeName.full, rType.typeName.full)
        }
      }
    })

  implicit def gen[T]: Derived[Diff[T]] = macro Magnolia.gen[T]
}

trait LowPriority {
  def fallback[T]: Derived[Diff[T]] =
    Derived((left: T, right: T, toIgnore: List[FieldPath]) => {
      if (left != right) {
        DiffResultValue(left, right)
      } else {
        Identical(left)
      }
    })
} 
Example 92
Source File: package.scala    From diffx   with Apache License 2.0 5 votes vote down vote up
package com.softwaremill
import acyclic.skipped

import scala.annotation.compileTimeOnly
import scala.collection.TraversableLike
import scala.collection.generic.CanBuildFrom
import scala.language.experimental.macros
import scala.language.higherKinds
import com.softwaremill.diffx.DiffxSupport._

package object diffx extends DiffxSupport {
  implicit def traversableDiffxFunctor[F[_], A](implicit
      cbf: CanBuildFrom[F[A], A, F[A]],
      ev: F[A] => TraversableLike[A, F[A]]
  ): DiffxFunctor[F, A] =
    new DiffxFunctor[F, A] {}

  trait DiffxMapAtFunctor[F[_, _], K, T] {
    @compileTimeOnly(canOnlyBeUsedInsideIgnore("each"))
    def each(fa: F[K, T])(f: T => T): F[K, T] = sys.error("")
  }

  implicit def mapDiffxFunctor[M[KT, TT] <: Map[KT, TT], K, T](implicit
      cbf: CanBuildFrom[M[K, T], (K, T), M[K, T]]
  ): DiffxMapAtFunctor[M, K, T] = new DiffxMapAtFunctor[M, K, T] {}

  implicit class DiffxEachMap[F[_, _], K, T](t: F[K, T])(implicit f: DiffxMapAtFunctor[F, K, T]) {
    @compileTimeOnly(canOnlyBeUsedInsideIgnore("each"))
    def each: T = sys.error("")
  }
} 
Example 93
Source File: FeatureBuilderMacros.scala    From TransmogrifAI   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
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 94
Source File: macroExpandeeSuppression.scala    From silencer   with Apache License 2.0 5 votes vote down vote up
package testdata

import com.github.ghik.silencer.silent

import scala.language.experimental.macros

object macroExpandeeSuppression {
  def discard(expr: Any): Unit = macro com.github.ghik.silencer.MacroImpls.discard

  discard {
    123: Unit
    456: @silent
  }

  discard {
    123
  }: @silent
} 
Example 95
Source File: ConfiguredJsonCodec.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
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 96
Source File: ReprAsObjectEncoder.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.encoding
import io.circe.{ Encoder, Json, JsonObject }
import io.circe.generic.extras.ConfigurableDeriver
import scala.annotation.implicitNotFound
import scala.language.experimental.macros


@implicitNotFound(
  """Could not find ReprAsObjectEncoder for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
trait ReprAsObjectEncoder[A] extends Encoder.AsObject[A] {
  def configuredEncodeObject(a: A)(
    transformMemberNames: String => String,
    transformDiscriminator: String => String,
    discriminator: Option[String]
  ): JsonObject

  final protected[this] def addDiscriminator[B](
    encode: Encoder[B],
    value: B,
    name: String,
    discriminator: Option[String]
  ): JsonObject = discriminator match {
    case None => JsonObject.singleton(name, encode(value))
    case Some(disc) =>
      encode match {
        case oe: Encoder.AsObject[B] @unchecked => oe.encodeObject(value).add(disc, Json.fromString(name))
        case _                                  => JsonObject.singleton(name, encode(value))
      }
  }

  final def encodeObject(a: A): JsonObject = configuredEncodeObject(a)(Predef.identity, Predef.identity, None)
}

object ReprAsObjectEncoder {
  implicit def deriveReprAsObjectEncoder[R]: ReprAsObjectEncoder[R] =
    macro ConfigurableDeriver.deriveConfiguredEncoder[R]
} 
Example 97
Source File: ReprAsObjectCodec.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.codec

import cats.data.Validated
import io.circe.{ Decoder, DecodingFailure, HCursor, JsonObject }
import io.circe.generic.extras.ConfigurableDeriver
import io.circe.generic.extras.decoding.ReprDecoder
import io.circe.generic.extras.encoding.ReprAsObjectEncoder
import scala.annotation.implicitNotFound
import scala.collection.immutable.Map
import scala.language.experimental.macros
import shapeless.HNil


@implicitNotFound(
  """Could not find ReprAsObjectCodec for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class ReprAsObjectCodec[A] extends ReprDecoder[A] with ReprAsObjectEncoder[A]

object ReprAsObjectCodec {
  implicit def deriveReprAsObjectCodec[R]: ReprAsObjectCodec[R] = macro ConfigurableDeriver.deriveConfiguredCodec[R]

  val hnilReprCodec: ReprAsObjectCodec[HNil] = new ReprAsObjectCodec[HNil] {
    def configuredDecode(c: HCursor)(
      transformMemberNames: String => String,
      transformConstructorNames: String => String,
      defaults: Map[String, Any],
      discriminator: Option[String]
    ): Decoder.Result[HNil] =
      if (c.value.isObject) Right(HNil) else Left(DecodingFailure("HNil", c.history))

    def configuredDecodeAccumulating(c: HCursor)(
      transformMemberNames: String => String,
      transformConstructorNames: String => String,
      defaults: Map[String, Any],
      discriminator: Option[String]
    ): Decoder.AccumulatingResult[HNil] =
      if (c.value.isObject) Validated.valid(HNil) else Validated.invalidNel(DecodingFailure("HNil", c.history))

    def configuredEncodeObject(a: HNil)(
      transformMemberNames: String => String,
      transformDiscriminator: String => String,
      discriminator: Option[String]
    ): JsonObject = JsonObject.empty
  }
} 
Example 98
Source File: Macros.scala    From seed   with Apache License 2.0 5 votes vote down vote up
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 99
Source File: Macros.scala    From seed   with Apache License 2.0 5 votes vote down vote up
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 100
Source File: Macros.scala    From seed   with Apache License 2.0 5 votes vote down vote up
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 101
Source File: MagnoliaDerived.scala    From avro4s   with Apache License 2.0 5 votes vote down vote up
package com.sksamuel.avro4s

import magnolia._

import scala.language.experimental.macros
import scala.reflect.runtime.universe._

trait MagnoliaDerivedSchemaFors {
  type Typeclass[T] = SchemaFor[T]

  implicit def gen[T]: SchemaFor[T] = macro Magnolia.gen[T]

  def dispatch[T: WeakTypeTag](ctx: SealedTrait[SchemaFor, T]): SchemaFor[T] = new ResolvableSchemaFor[T] {
    def schemaFor(env: DefinitionEnvironment[SchemaFor], update: SchemaUpdate): SchemaFor[T] = {
      env.get[T].getOrElse {
        DatatypeShape.of[T] match {
          case SealedTraitShape.TypeUnion => TypeUnions.schema(ctx, env, update)
          case SealedTraitShape.ScalaEnum => SchemaFor[T](ScalaEnums.schema(ctx), DefaultFieldMapper)
        }
      }
    }
  }

  def combine[T: WeakTypeTag](ctx: CaseClass[SchemaFor, T])(implicit fieldMapper: FieldMapper = DefaultFieldMapper): SchemaFor[T] = {
    val fm = fieldMapper
    new ResolvableSchemaFor[T] {
      def schemaFor(env: DefinitionEnvironment[SchemaFor], update: SchemaUpdate): SchemaFor[T] = {
        env.get[T].getOrElse {
          DatatypeShape.of(ctx) match {
            case CaseClassShape.Record    => Records.schema(ctx, env, update, fm)
            case CaseClassShape.ValueType => ValueTypes.schema(ctx, env, update)
          }
        }
      }
    }
  }
}

trait MagnoliaDerivedEncoders {
  type Typeclass[T] = Encoder[T]

  implicit def gen[T]: Encoder[T] = macro Magnolia.gen[T]

  def dispatch[T: WeakTypeTag](ctx: SealedTrait[Encoder, T]): Encoder[T] = new ResolvableEncoder[T] {
    def encoder(env: DefinitionEnvironment[Typeclass], update: SchemaUpdate): Typeclass[T] =
      env.get[T].getOrElse {
        DatatypeShape.of[T] match {
          case SealedTraitShape.TypeUnion => TypeUnions.encoder(ctx, env, update)
          case SealedTraitShape.ScalaEnum => ScalaEnums.encoder(ctx)
        }
      }
  }

  def combine[T: WeakTypeTag](ctx: CaseClass[Encoder, T])(implicit fieldMapper: FieldMapper = DefaultFieldMapper): Encoder[T] = new ResolvableEncoder[T] {
    def encoder(env: DefinitionEnvironment[Typeclass], update: SchemaUpdate): Typeclass[T] =
      env.get[T].getOrElse {
        DatatypeShape.of(ctx) match {
          case CaseClassShape.Record    => Records.encoder(ctx, env, update, fieldMapper)
          case CaseClassShape.ValueType => ValueTypes.encoder(ctx, env, update)
        }
      }
  }
}

trait MagnoliaDerivedDecoders {
  type Typeclass[T] = Decoder[T]

  implicit def gen[T]: Decoder[T] = macro Magnolia.gen[T]

  def dispatch[T: WeakTypeTag](ctx: SealedTrait[Decoder, T]): Decoder[T] = new ResolvableDecoder[T] {
    def decoder(env: DefinitionEnvironment[Typeclass], update: SchemaUpdate): Typeclass[T] =
      env.get[T].getOrElse {
        DatatypeShape.of[T] match {
          case SealedTraitShape.TypeUnion => TypeUnions.decoder(ctx, env, update)
          case SealedTraitShape.ScalaEnum => ScalaEnums.decoder(ctx)
        }
      }
  }

  def combine[T: WeakTypeTag](ctx: CaseClass[Decoder, T])(implicit fieldMapper: FieldMapper = DefaultFieldMapper): Decoder[T] = new ResolvableDecoder[T] {
    def decoder(env: DefinitionEnvironment[Typeclass], update: SchemaUpdate): Typeclass[T] =
      env.get[T].getOrElse {
        DatatypeShape.of(ctx) match {
          case CaseClassShape.Record    => Records.decoder(ctx, env, update, fieldMapper)
          case CaseClassShape.ValueType => ValueTypes.decoder(ctx, env, update)
        }
      }
  }
} 
Example 102
Source File: LambdaHTTPApiAnnotation.scala    From quaich   with Apache License 2.0 5 votes vote down vote up
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 103
Source File: delegate.scala    From macro-compat   with Apache License 2.0 5 votes vote down vote up
package delegate

import scala.language.experimental.macros

import scala.reflect.macros.whitebox

import macrocompat.bundle

class Delegate {
  def delegate: Unit = macro DelegateMacro.delegate
}

@bundle
class DelegateMacro(val c: whitebox.Context) { outer =>
  import c.universe._

  class D(override val c: outer.c.type) extends Delegatee(c)
  def delegate: Tree = (new D(c)).delegate
}

@bundle
class Delegatee(val c: whitebox.Context) {
  import c.universe._

  def delegate: Tree = {
    q"()"
  }
} 
Example 104
Source File: Macros.scala    From perfolation   with MIT License 5 votes vote down vote up
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 105
Source File: package.scala    From perfolation   with MIT License 5 votes vote down vote up
import scala.language.experimental.macros
import scala.language.implicitConversions
import scala.util.Try

package object perfolation {
  implicit def long2Implicits(l: Long): LongImplicits = new LongImplicits(l)
  implicit def double2Implicits(d: Double): DoubleImplicits = new DoubleImplicits(d)
  implicit def bigDecimal2Implicits(d: BigDecimal): BigDecimalImplicits = new BigDecimalImplicits(d)

  implicit class Perfolation(val sc: StringContext) extends AnyVal {
    def p(args: Any*): String = macro Macros.p
    def raw(args: Any*): String = macro Macros.raw
  }

  def stringBuilder(): java.lang.StringBuilder = pool.get()

  private[this] final val size = Try(sys.props.getOrElse("perfolation.buffer.size", "").toInt).getOrElse(16384)

  private[this] final val pool = new ThreadLocal[java.lang.StringBuilder] {
    override def initialValue(): java.lang.StringBuilder = new java.lang.StringBuilder(size)

    override def get(): java.lang.StringBuilder = {
      var sb = super.get()
      if (sb.capacity > size) {
        sb = initialValue()
        set(sb)
      } else sb.setLength(0)
      sb
    }
  }
} 
Example 106
Source File: I18n.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua.play

import play.api.http.HeaderNames
import play.api.mvc.RequestHeader
import play.twirl.api.Html
import ru.makkarpov.scalingua
import ru.makkarpov.scalingua._

import scala.language.experimental.macros
import scala.language.implicitConversions

trait I18n extends scalingua.I18n {
  type LHtml = LValue[Html]

  implicit val htmlOutputFormat = new OutputFormat[Html] {
    override def convert(s: String): Html = Html(s)

    override def escape(s: String): String = {
      val ret = new StringBuilder
      var i = 0
      ret.sizeHint(s.length)
      while (i < s.length) {
        s.charAt(i) match {
          case '<' => ret.append("&lt;")
          case '>' => ret.append("&gt;")
          case '"' => ret.append("&quot;")
          case '\'' => ret.append("&#x27;")
          case '&' => ret.append("&amp;")
          case c => ret += c
        }
        i += 1
      }
      ret.result()
    }
  }

  // The conversion from `RequestHeader` to `LanguageId` will imply information loss:
  // Suppose browser sent the following language precedence list `xx_YY`, `zz_WW`, `en_US`.
  // This conversion will have no information about available languages, so it will result in
  // `LanguageId("xx", "YY")` even if this language is absent. By supplying implicit `Messages`
  // too, we will have enough information to skip unsupported languages and return supported
  // one with respect to priority.

  implicit def requestHeader2Language(implicit rq: RequestHeader, msg: Messages): Language =
    rq.headers.get(HeaderNames.ACCEPT_LANGUAGE).map(PlayUtils.languageFromAccept).getOrElse(Language.English)

  implicit def stringContext2Interpolator1(sc: StringContext): PlayUtils.StringInterpolator =
    new PlayUtils.StringInterpolator(sc)

  def th(msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.singular[Html]

  def lth(msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazySingular[Html]

  def tch(ctx: String, msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.singularCtx[Html]

  def ltch(ctx: String, msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazySingularCtx[Html]

  def p(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
       (implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.plural[Html]

  def lp(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazyPlural[Html]

  def pc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
    macro Macros.pluralCtx[Html]

  def lpc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
         (implicit outputFormat: OutputFormat[Html]): LHtml =
    macro Macros.lazyPluralCtx[Html]
}

object I18n extends I18n 
Example 107
Source File: PlayUtils.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua.play

import play.api.mvc.RequestHeader
import play.twirl.api.Html
import ru.makkarpov.scalingua._

import scala.language.experimental.macros

object PlayUtils {
  class StringInterpolator(val sc: StringContext) extends AnyVal {
    def h(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
      macro Macros.interpolate[Html]

    def lh(args: Any*)(implicit outputFormat: OutputFormat[Html]): LValue[Html] =
      macro Macros.lazyInterpolate[Html]

    def ph(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[Html]): Html =
      macro Macros.pluralInterpolate[Html]

    def lph(args: Any*)(outputFormat: OutputFormat[Html]): LValue[Html] =
      macro Macros.lazyPluralInterpolate[Html]
  }

  // Modified to match only correct doubles
  private val qPattern = ";\\s*q=((?:[0-9]+\\.)?[0-9]+)".r

  def languageFromAccept(accept: String)(implicit msg: Messages): Language = {
    val langs = (for {
      value0 <- accept.split(',')
      value = value0.trim
    } yield {
      qPattern.findFirstMatchIn(value) match {
        case Some(m) => (BigDecimal(m.group(1)), m.before.toString)
        case None => (BigDecimal(1.0), value) // “The default value is q=1.”
      }
    }).sortBy(-_._1).iterator

    while (langs.hasNext) {
      val (_, id) = langs.next()
      val lng = LanguageId.get(id)

      if (lng.isDefined && msg.contains(lng.get))
        return msg(lng.get)
    }

    Language.English
  }
} 
Example 108
Source File: I18n.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua

import ru.makkarpov.scalingua.plural.Suffix

import scala.language.experimental.macros
import scala.language.implicitConversions
import scala.reflect.internal.annotations.compileTimeOnly

trait I18n {
  type LString = LValue[String]

  val S = Suffix

  // Since I want to keep StringInterpolator AnyVal, I will extract it to a place where there is no path-dependency
  // and provide here only implicit conversion function.
  implicit def stringContext2Interpolator(sc: StringContext): I18n.StringInterpolator =
    new I18n.StringInterpolator(sc)

  implicit def long2MacroExtension(v: Long): I18n.PluralMacroExtensions =
    new I18n.PluralMacroExtensions(v)

  implicit def int2MacroExtension(i: Int): I18n.PluralMacroExtensions =
    new I18n.PluralMacroExtensions(i)

  implicit def string2SuffixExtension(s: String): Suffix.GenericSuffixExtension =
    new Suffix.GenericSuffixExtension(s)

  def t(msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.singular[String]

  def lt(msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[String]): LString =
    macro Macros.lazySingular[String]

  def tc(ctx: String, msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.singularCtx[String]

  def ltc(ctx: String, msg: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[String]): LString =
    macro Macros.lazySingularCtx[String]

  def p(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
       (implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.plural[String]

  def lp(msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit outputFormat: OutputFormat[String]): LString =
    macro Macros.lazyPlural[String]

  def pc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
       (implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.pluralCtx[String]

  def lpc(ctx: String, msg: String, msgPlural: String, n: Long, args: (String, Any)*)
        (implicit outputFormat: OutputFormat[String]): LString =
    macro Macros.lazyPluralCtx[String]

  // Tagged:

  def tag(tag: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.singularTag[String]

  def ltag(tag: String, args: (String, Any)*)(implicit outputFormat: OutputFormat[String]): LValue[String] =
    macro Macros.lazySingularTag[String]

  def ptag(tag: String, n: Long, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
    macro Macros.pluralTag[String]

  def lptag(tag: String, n: Long, args: (String, Any)*)(implicit outputFormat: OutputFormat[String]): LValue[String] =
    macro Macros.lazyPluralTag[String]
}

object I18n extends I18n {
  class StringInterpolator(val sc: StringContext) extends AnyVal {
    def t(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
      macro Macros.interpolate[String]

    def lt(args: Any*)(implicit outputFormat: OutputFormat[String]): LString =
      macro Macros.lazyInterpolate[String]

    def p(args: Any*)(implicit lang: Language, outputFormat: OutputFormat[String]): String =
      macro Macros.pluralInterpolate[String]

    def lp(args: Any*)(implicit outputFormat: OutputFormat[String]): LString =
      macro Macros.lazyPluralInterpolate[String]
  }

  class PluralMacroExtensions(val l: Long) extends AnyVal {
    def nVar: Long = throw new IllegalStateException(".nVars should not remain after macro expansion")
  }
} 
Example 109
Source File: CustomI18nTest.scala    From scalingua   with Apache License 2.0 5 votes vote down vote up
package ru.makkarpov.scalingua.test

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import ru.makkarpov.scalingua.{I18n, Language, Macros, OutputFormat}

import scala.language.experimental.macros

class CustomI18nTest extends AnyFlatSpec with Matchers {
  case class CStr(s: String)

  implicit val CStrFormat = new OutputFormat[CStr] {
    override def convert(s: String): CStr = CStr(s"C{$s}")
    override def escape(s: String): String = s"[$s]"
  }

  object CustomI18n extends I18n {
    def ct(msg: String, args: (String, Any)*)(implicit lang: Language, outputFormat: OutputFormat[CStr]): CStr =
      macro Macros.singular[CStr]
  }

  implicit val mockLang = new MockLang("")

  import CustomI18n._

  it should "handle custom I18n classes via traits" in {
    t"Hello, world!" shouldBe "{s:Hello, world!}"
  }

  it should "handle custom methods in I18n classes" in {
    ct("Hello, world!").s shouldBe "C{{s:Hello, world!}}"
    ct("Hello, %(what)!", "what" -> "world").s shouldBe "C{{s:Hello, %(what)[[world]]!}}"

    """ ct("Hello, %(x)!", "y" -> 1) """ shouldNot compile
  }
} 
Example 110
Source File: DummyImplicit.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package transmitter

import scala.language.experimental.macros
import scala.reflect.macros.whitebox

object DummyImplicit {
  class Resolvable private[DummyImplicit]

  object Resolvable {
    implicit def dummy: Resolvable = new Resolvable
    implicit def noDummy: Resolvable = macro NoDummyImplicit.skip
  }

  class Unresolvable private[DummyImplicit]

  object Unresolvable {
    implicit def noDummy: Unresolvable = macro NoDummyImplicit.skip
  }
}

object NoDummyImplicit {
  def skip(c: whitebox.Context): c.Tree =
    c.abort(c.enclosingPosition, "Skipping dummy macro")
} 
Example 111
Source File: Serializable.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package transmitter

import scala.annotation.{compileTimeOnly, implicitNotFound}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.util.Try

@implicitNotFound("${T} is not serializable")
trait Serializable[T] {
  def serialize(value: T): MessageBuffer
  def deserialize(value: MessageBuffer): Try[T]
}

object Serializable {
  @inline def apply[T](implicit serializable: Serializable[T]): Serializable[T] =
    serializable

  @compileTimeOnly("Value is not serializable")
  final implicit def resolutionFailure[T](implicit ev: DummyImplicit.Resolvable): Serializable[T] =
    macro SerializableResolutionFailure[T]

  @compileTimeOnly("Value is not serializable")
  final def dummy[T]: Serializable[T] = throw new NotImplementedError
}

object SerializableResolutionFailure {
  def apply[T: c.WeakTypeTag](c: whitebox.Context)(ev: c.Tree): c.Tree = {
    import c.universe._

    // the current macro expansion always appears twice
    // see: http://stackoverflow.com/a/20466423
    val recursionCount = c.openMacros.count { other =>
      c.enclosingPosition == other.enclosingPosition &&
        c.macroApplication.toString == other.macroApplication.toString
    }
    if (recursionCount > 2)
      c.abort(c.enclosingPosition, "Skipping serializable resolution failure macro for recursive invocation")

    val serializableType = weakTypeOf[Serializable[T]]

    if ((c inferImplicitValue serializableType).nonEmpty)
      c.abort(c.enclosingPosition, "Skipping serializable resolution failure macro to prioritize other implicit")

    val tpe = weakTypeOf[T]
    val message = s"$tpe is not serializable"

    q"""{
      @${termNames.ROOTPKG}.scala.annotation.compileTimeOnly($message) def resolutionFailure() = ()
      resolutionFailure()
      ${termNames.ROOTPKG}.loci.transmitter.Serializable.dummy[$tpe]
    }"""
  }
} 
Example 112
Source File: TransmittableDummy.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package transmitter

import scala.annotation.compileTimeOnly
import scala.concurrent.Future
import scala.language.experimental.macros
import scala.reflect.macros.whitebox

trait TransmittableDummy {
  this: Transmittable.type =>

  @compileTimeOnly("Value is not transmittable")
  final implicit def resolutionFailure[T](implicit ev: DummyImplicit.Resolvable): Transmittable[T, T, T] {
    type Proxy = Future[T]
    type Transmittables = Transmittables.None
  } = macro TransmittableResolutionFailure[T]

  @compileTimeOnly("Value is not transmittable")
  final def dummy[T]: Transmittable[T, T, T] {
    type Proxy = Future[T]
    type Transmittables = Transmittables.None
  } = IdenticallyTransmittable()
}

object TransmittableResolutionFailure {
  def apply[T: c.WeakTypeTag](c: whitebox.Context)(ev: c.Tree): c.Tree = {
    import c.universe._

    // the current macro expansion always appears twice
    // see: http://stackoverflow.com/a/20466423
    val recursionCount = c.openMacros.count { other =>
      c.enclosingPosition == other.enclosingPosition &&
      c.macroApplication.toString == other.macroApplication.toString
    }
    if (recursionCount > 2)
      c.abort(c.enclosingPosition, "Skipping transmittable resolution failure macro for recursive invocation")

    val resolutionType = weakTypeOf[Transmittable.Aux.Resolution[T, _, _, _, _]]

    if ((c inferImplicitValue resolutionType).nonEmpty)
      c.abort(c.enclosingPosition, "Skipping transmittable resolution failure macro to prioritize other implicit")

    val tpe = weakTypeOf[T]
    val message = s"$tpe is not transmittable"

    q"""{
      @${termNames.ROOTPKG}.scala.annotation.compileTimeOnly($message) def resolutionFailure() = ()
      resolutionFailure()
      ${termNames.ROOTPKG}.loci.transmitter.Transmittable.dummy[$tpe]
    }"""
  }
} 
Example 113
Source File: package.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci

import contexts.Immediate.Implicits.global

import scribe.{Level, LogRecord, Logger, LoggerSupport, Position}

import scala.concurrent.{ExecutionContext, Future}
import scala.language.experimental.macros
import scala.util.Try
import scala.util.control.NonFatal

package object logging extends LoggerSupport {
  root.orphan().withHandler(minimumLevel = Some(Level.Info)).replace()

  def root = Logger("scala-loci")

  val reportException: Throwable => Unit = exception =>
    error("unhandled exception", tracing(exception))

  def log[M](record: LogRecord[M]): Unit = {
    val logRecord =
      if (record.className startsWith "loci.logging")
        record.copy(className = "scala-loci", methodName = None, line = None, column = None)
      else
        record.copy(className = record.className.replaceAll("\\.\\$anon[^.]*", "").replaceAll("\\.<.*>", ""))

    val logger = Logger.get(logRecord.className) getOrElse {
      Logger().withParent(root).replace(Some(logRecord.className))
    }

    logger.log(logRecord)
  }

  implicit def tracingExecutionContext: TracingExecutionContext =
    macro ImplicitTracingExecutionContext.resolve

  object tracing {
    def apply(context: ExecutionContext): ExecutionContext =
      macro ExplicitTracingExecutionContext.instrument

    def apply[T <: Throwable](throwable: T): T = {
      val stack = throwable.getStackTrace
      val trace =
        ((Position.stack.reverse map {
           pos => pos.copy(className = s"[trace] ${pos.className}").toTraceElement
         }).distinct
         filterNot stack.contains).toArray

      if (trace.nonEmpty) {
        val index = stack lastIndexWhere { element =>
          !(element.getClassName startsWith "java.") &&
          !(element.getClassName startsWith "scala.") &&
          !(element.getClassName startsWith "scribe.") &&
          !(element.getClassName startsWith "loci.logging.") &&
          !(element.getClassName startsWith "loci.contexts.")
        }

        if (index != -1) {
          val (prefix, suffix) = stack splitAt (index + 1)
          throwable.setStackTrace(prefix ++ trace ++ suffix)
        }
        else
          throwable.setStackTrace(stack ++ trace)
      }

      throwable
    }

    def apply[T[U] <: Try[U], U](value: T[U]): T[U] = {
      value.failed foreach { tracing(_) }
      value
    }

    def apply[T](value: Future[T]): Future[T] =
      value recover { case exception => throw tracing(exception) }

    def run[T](body: => T): T =
      try body match {
        case value: Throwable => tracing(value).asInstanceOf[T]
        case value: Try[_] => tracing(value).asInstanceOf[T]
        case value: Future[_] => tracing(value).asInstanceOf[T]
        case value => value
      }
      catch {
        case NonFatal(exception) => throw tracing(exception)
      }
  }
} 
Example 114
Source File: package.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
import loci.communicator._
import loci.language._
import loci.messaging._

import scala.annotation.{StaticAnnotation, compileTimeOnly, showAsInfix}
import scala.language.experimental.macros

package loci {
  @compileTimeOnly("enable macro paradise to use multitier code")
  final class multitier extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro impl.Multitier.annotation
  }

  object multitier {
    def start[P, Inst[P] <: Instance[P]](instance: Inst[P]): Runtime[P] =
      macro impl.Instance.start

    @compileTimeOnly("method can only be invoked in multitier code")
    def running: Boolean = erased

    @compileTimeOnly("method can only be invoked in multitier code")
    def terminate(): Unit = erased
  }

  final class peer extends StaticAnnotation

  sealed trait Single[P] extends Multiple[P]
  sealed trait Optional[P] extends Multiple[P]
  sealed trait Multiple[+P]

  trait Remote[+P] extends Equals
  object Remote extends transmitter.RemoteReference
}

package object loci {
  type Local[T] = T

  @showAsInfix type on[T, P] = Placed[T, P] with T
  @showAsInfix type per[T, P] = Placed.Subjective[T, P]

  def connect[P](setup: Connector[ConnectionsBase.Protocol]): Connections =
    macro impl.Connections.setup
  def connect[P](factory: ConnectionSetupFactory[ConnectionsBase.Protocol])(
       args: Any*): Connections =
    macro impl.Connections.factory

  def placed: Placement.Placed = erased
  def on: Placement.Select[Placement.Run] = erased
  def on[P]: Placement.On[P] with Placement.Run[P, from] = erased
  def remote: Placement.Narrow with Placement.Select[Placement.Call] with Placement.Call[Nothing, from] with Gateway[Nothing] = erased
  def remote[P]: Placement.Call[P, from] with Gateway[P] = erased
} 
Example 115
Source File: RemoteReference.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package transmitter

import scala.language.experimental.macros
import scala.language.implicitConversions

trait RemoteReference { this: Remote.type =>
  trait Reference[+P] extends loci.Remote[P] with RemoteRef {
    def asRemote[R]: Option[loci.Remote[R]] =
      macro language.impl.Remote.asRemote[R]

    def asReference: Reference[P]
    def authenticated: Boolean
    def authenticate(): Unit
  }

  implicit def reference[P](remote: loci.Remote[P]): Remote.Reference[P] = remote match {
    case remote: Remote.Reference[P] => remote
    case _ => throw new runtime.PeerImplementationError
  }
} 
Example 116
Source File: Instance.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci

import language._

import scala.annotation.compileTimeOnly
import scala.concurrent.ExecutionContext
import scala.language.experimental.macros
import scala.language.implicitConversions

class Instance[P] private[loci] (dummy: Int) {
  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this() = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(connect: Connections) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(context: ExecutionContext) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(separateMainThread: Boolean) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(context: ExecutionContext, connect: Connections) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(separateMainThread: Boolean, connect: Connections) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(context: ExecutionContext, separateMainThread: Boolean) = this(0)

  @compileTimeOnly("Multitier peer instantiation must be of the form: multitier start new Instance[P]")
  def this(context: ExecutionContext, separateMainThread: Boolean, connect: Connections) = this(0)
}

object Instance {
  final implicit class Ops[P](instance: Instance[P]) {
    def retrieve[T](retrievable: Retrievable[T]): T =
      macro language.impl.Instance.retrieve

    def terminate(): Unit = instance match {
      case instance: runtime.Instance[P] => instance.terminate()
      case _ => throw new runtime.PeerImplementationError
    }

    def terminated: Notice.Steady[Unit] = instance match {
      case instance: runtime.Instance[P] => instance.terminated
      case _ => throw new runtime.PeerImplementationError
    }
  }


  trait SubjectiveValue[T, R] {
    def to(remote: Remote[R]): T
  }


  sealed trait Retrievable[T]

  sealed trait RetrievableDefault {
    implicit def default[T](v: T): Retrievable[T] = erased
  }

  sealed trait RetrievablePlaced extends RetrievableDefault {
    implicit def placed[T, P](v: T on P): Retrievable[T] = erased
  }

  sealed trait RetrievableLocal extends RetrievablePlaced {
    implicit def local[T, P, _Local_[T] <: Local[T]](v: _Local_[T] on P): Retrievable[T] = erased
  }

  object Retrievable extends RetrievableLocal {
    implicit def subjective[T, R, P](v: T per R on P): Retrievable[SubjectiveValue[T, P]] = erased
  }
} 
Example 117
Source File: package.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
import loci.communicator._
import loci.language._
import loci.messaging._

import scala.annotation.{StaticAnnotation, compileTimeOnly, showAsInfix}
import scala.language.experimental.macros

package loci {
  @compileTimeOnly("enable macro paradise to use multitier code")
  final class multitier extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro impl.Multitier.annotation
  }

  object multitier {
    def start[P, Inst[P] <: Instance[P]](instance: Inst[P]): Runtime[P] =
      macro impl.Instance.start

    @compileTimeOnly("method can only be invoked in multitier code")
    def running: Boolean = erased

    @compileTimeOnly("method can only be invoked in multitier code")
    def terminate(): Unit = erased
  }

  final class peer extends StaticAnnotation

  sealed trait Single[P] extends Multiple[P]
  sealed trait Optional[P] extends Multiple[P]
  sealed trait Multiple[+P]

  trait Remote[+P] extends Equals
  object Remote extends transmitter.RemoteReference
}

package object loci {
  type Local[T] = T

  @showAsInfix type on[T, P] = Placed[T, P] with T
  @showAsInfix type per[T, P] = Placed.Subjective[T, P]

  def connect[P](setup: Connector[ConnectionsBase.Protocol]): Connections =
    macro impl.Connections.setup
  def connect[P](factory: ConnectionSetupFactory[ConnectionsBase.Protocol])(
       args: Any*): Connections =
    macro impl.Connections.factory

  def placed: Placement.Placed = erased
  def on: Placement.Select[Placement.Run] = erased
  def on[P]: Placement.On[P] with Placement.Run[P, from] = erased
  def remote: Placement.Narrow with Placement.Select[Placement.Call] with Placement.Call[Nothing, from] with Gateway[Nothing] = erased
  def remote[P]: Placement.Call[P, from] with Gateway[P] = erased
} 
Example 118
Source File: package.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
import loci.communicator._
import loci.language._
import loci.messaging._

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros

package loci {
  @compileTimeOnly("enable macro paradise to use multitier code")
  final class multitier extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro impl.Multitier.annotation
  }

  object multitier {
    def start[P, Inst[P] <: Instance[P]](instance: Inst[P]): Runtime[P] =
      macro impl.Instance.start

    @compileTimeOnly("method can only be invoked in multitier code")
    def running: Boolean = erased

    @compileTimeOnly("method can only be invoked in multitier code")
    def terminate(): Unit = erased
  }

  final class peer extends StaticAnnotation

  sealed trait Single[P] extends Multiple[P]
  sealed trait Optional[P] extends Multiple[P]
  sealed trait Multiple[+P]

  trait Remote[+P] extends Equals
  object Remote extends transmitter.RemoteReference
}

package object loci {
  type Local[T] = T

  type on[T, P] = Placed[T, P] with T
  type per[T, P] = Placed.Subjective[T, P]

  def connect[P](setup: Connector[ConnectionsBase.Protocol]): Connections =
    macro impl.Connections.setup
  def connect[P](factory: ConnectionSetupFactory[ConnectionsBase.Protocol])(
       args: Any*): Connections =
    macro impl.Connections.factory

  def placed: Placement.Placed = erased
  def on: Placement.Select[Placement.Run] = erased
  def on[P]: Placement.On[P] with Placement.Run[P, from] = erased
  def remote: Placement.Narrow with Placement.Select[Placement.Call] with Placement.Call[Nothing, from] with Gateway[Nothing] = erased
  def remote[P]: Placement.Call[P, from] with Gateway[P] = erased
} 
Example 119
Source File: ByTreeTyper.scala    From coroutines   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package org.coroutines.common



import scala.collection._
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context



private[coroutines] class ByTreeTyper[C <: Context](val c: C)(val treeValue: Any) {
  import c.universe._
  private val tree = treeValue.asInstanceOf[Tree]
  private val treeMapping = mutable.Map[Tree, Tree]()
  private val traverser = new TraverserUtil[c.type](c)
  val untypedTree = c.untypecheck(tree)
  traverser.traverseByShape(untypedTree, tree)((t, pt) => treeMapping(t) = pt)

  object typeOf {
    private val augmentedTypes = mutable.Map[Tree, Type]()
    def apply(t: Tree) = {
      if (augmentedTypes.contains(t)) augmentedTypes(t)
      else if (treeMapping.contains(t)) treeMapping(t).tpe
      else t.tpe
    }
    def update(t: Tree, tpe: Type) = augmentedTypes(t) = tpe
  }
} 
Example 120
Source File: Profiler.scala    From lift   with MIT License 5 votes vote down vote up
package lift.profiler

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

class Profile(extraContext: String = "") extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro Profile.impl
}

object Profile {
  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._

    val ctx: String = c.prefix.tree match {
      case q"new Profile($extraContext)" =>
        c.eval[String](c.Expr[String](extraContext))
      // match for when we have no explicit context (i.e. this allows us to
      // write `@Profile def ...` rather than `@Profile() def ...` which is
      // (in some ways) slightly cleaner
      case _⇒ "nocontext"
    }

    val result = {
      annottees.map(_.tree).toList match {
        case q"$mods def $methodName[..$tpes](...$args): $returnType = { ..$body }" :: Nil => {
          q"""$mods def $methodName[..$tpes](...$args): $returnType =  {
            val start = System.nanoTime()
            val profSpliceResultValueNoConflict = {..$body}
            val end = System.nanoTime()
            println("PROFILING_DATUM: (\""+${methodName.toString}+"\", \"" + ${ctx.toString} + "\", " + (end-start).toDouble/1000000 + ", \"Scala\")")
            profSpliceResultValueNoConflict
          }"""
        }
        case _ => c.abort(c.enclosingPosition, "Annotation @Profile can be used only with methods")
      }
    }
    c.Expr[Any](result)
  }

  def profile[T](name: String, context: String, f: () => T) : T = {
    val start = System.nanoTime()
    val r: T = f()
    val end = System.nanoTime()
    println("PROFILING_DATUM: (\"" + name + "\", \"" + context + "\"," + (end-start).toDouble/1000000 + ", \"Scala\")")
    r
  }
} 
Example 121
Source File: Macros.scala    From caliban   with Apache License 2.0 5 votes vote down vote up
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 122
Source File: CodeExample.scala    From slinky   with MIT License 5 votes vote down vote up
package slinky.docs

import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.ReactElement
import slinky.web.html._

import scala.scalajs.js
import scala.scalajs.js.Dynamic.literal
import scala.language.experimental.macros

@react object CodeExampleInternal {
  case class Props(codeText: String, demoElement: ReactElement)

  // from the reactjs.org theme
  val prismColors = js.Dictionary[js.Object](
    "hljs-comment" -> literal(color = "#999999"),
    "hljs-keyword" -> literal(color = "#c5a5c5"),
    "hljs-built_in" -> literal(color = "#5a9bcf"),
    "hljs-string" -> literal(color = "#8dc891"),
    "hljs-variable" -> literal(color = "#d7deea"),
    "hljs-title" -> literal(color = "#79b6f2"),
    "hljs-type" -> literal(color = "#FAC863"),
    "hljs-meta" -> literal(color = "#FAC863"),
    "hljs-strong" -> literal(fontWeight = 700),
    "hljs-emphasis" -> literal(fontStyle = "italic"),
    "hljs" -> literal(
      backgroundColor = "#282c34",
      color = "#ffffff",
      fontSize = "15px",
      lineHeight = "20px"
    ),
    "code[class*=\"language-\"]" -> literal(
      backgroundColor = "#282c34",
      color = "#ffffff"
    )
  )

  val component = FunctionalComponent[Props] { props =>
    div(style := literal(
      width = "100%",
      display = "flex",
      borderRadius = "10px",
      overflow = "hidden",
      border = "1px solid rgb(236, 236, 236)",
      height = "100%"
    ))(
      div(style := literal(
        width = "65%",
        height = "100%"
      ))(
        div(style := literal(
          width = "100%",
          display = "block",
          backgroundColor = "rgb(32, 35, 42)",
          padding = "10px",
          boxSizing = "border-box"
        ))(
          b(style := literal(color = "#999"))("SCALA CODE")
        ),
        div(style := literal(
          width = "100%",
          display = "block",
          padding = "10px",
          backgroundColor = "#282c34",
          boxSizing = "border-box",
          height = "calc(100% - 36px)",
          overflow = "auto"
        ))(
          SyntaxHighlighter(language = "scala", style = prismColors)(
            props.codeText
          )
        )
      ),
      div(style := literal(
        width = "35%",
        boxSizing = "border-box",
        borderLeft = "1px solid rgb(236, 236, 236)"
      ))(
        div(style := literal(
          backgroundColor = "rgb(236, 236, 236)",
          padding = "10px",
          boxSizing = "border-box"
        ))(
          b(style := literal(color = "rgb(109, 109, 109)"))("RESULT")
        ),
        div(style := literal(
          overflow = "auto",
          padding = "10px",
          boxSizing = "border-box"
        ))(props.demoElement)
      )
    )
  }
}

object CodeExample {
  def apply(exampleLocation: String): ReactElement = macro CodeExampleImpl.text
} 
Example 123
Source File: ToStringObfuscate.scala    From firebase4s   with MIT License 5 votes vote down vote up
package firebase4s.macros

import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
import scala.annotation.compileTimeOnly

@compileTimeOnly("enable macro paradise to expand macro annotations")
class ToStringObfuscate(fieldsToObfuscate: String*) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro ToStringObfuscateImpl.impl
}

object ToStringObfuscateImpl {

  def obfuscateValue(value: String) = "*" * value.length

  def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._

    def extractAnnotationParameters(tree: Tree): List[c.universe.Tree] = tree match {
      case q"new $name( ..$params )" => params
      case _                         => throw new Exception("ToStringObfuscate annotation must be have at least one parameter.")
    }

    def extractCaseClassesParts(classDecl: ClassDef) = classDecl match {
      case q"case class $className(..$fields) extends ..$parents { ..$body }" =>
        (className, fields, parents, body)
    }

    def replaceCaseClassSensitiveValues(tree: Tree) = tree match {
      case Literal(Constant(field: String)) =>
        q"""
            ${TermName(field)} = firebase4s.macros.ToStringObfuscateImpl.obfuscateValue(this.${TermName(field)})
          """
      case _ => c.abort(c.enclosingPosition, s"[replaceCaseClassSensitiveValues] Match error with $tree")
    }

    val sensitiveFields = extractAnnotationParameters(c.prefix.tree)
    
    val fieldReplacements = sensitiveFields.map(replaceCaseClassSensitiveValues(_))

    def extractNewToString(sensitiveFields: List[Tree]) = q"""
         override def toString: ${typeOf[String]} = {
          scala.runtime.ScalaRunTime._toString(this.copy(..$fieldReplacements))
         }
      """

    def modifiedDeclaration(classDecl: ClassDef) = {
      val (className, fields, parents, body) = extractCaseClassesParts(classDecl)
      val newToString = extractNewToString(sensitiveFields)

      val params = fields.asInstanceOf[List[ValDef]].map { p =>
        p.duplicate
      }

      c.Expr[Any](
        q"""
        case class $className ( ..$params ) extends ..$parents {
          $newToString
          ..$body
        }
      """
      )
    }

    annottees.map(_.tree) toList match {
      case (classDecl: ClassDef) :: Nil => modifiedDeclaration(classDecl)
      case _                            => c.abort(c.enclosingPosition, "Invalid annottee")
    }
  }
} 
Example 124
Source File: package.scala    From scalajs-react-bridge   with MIT License 5 votes vote down vote up
package com.payalabs.scalajs.react

import scala.concurrent.{ExecutionContext, Future}
import scala.language.experimental.macros
import scala.reflect.ClassTag
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.{Object, |}

import japgolly.scalajs.react.component.Js
import japgolly.scalajs.react.vdom.{TagMod, VdomElement, VdomNode}
import japgolly.scalajs.react.{CallbackTo, Children, CtorType}
import japgolly.scalajs.react.vdom.Implicits._

package object bridge extends GeneratedImplicits {
  def writerFromConversion[A](implicit conv: A => js.Any): JsWriter[A] = JsWriter(x => x)
  implicit def stringWriter: JsWriter[String] = writerFromConversion[String]

  implicit def boolWriter: JsWriter[Boolean] = writerFromConversion[Boolean]

  // Note: Char and Long not supported here, since in Scala.js they map to opaque types, which
  // may not map well to the underlying components expectations.
  implicit def byteWriter: JsWriter[Byte] = writerFromConversion[Byte]
  implicit def shortWriter: JsWriter[Short] = writerFromConversion[Short]
  implicit def intWriter: JsWriter[Int] = writerFromConversion[Int]

  implicit def floatWriter: JsWriter[Float] = writerFromConversion[Float]
  implicit def doubleWriter: JsWriter[Double] = writerFromConversion[Double]

  implicit def unitWriter: JsWriter[Unit] = writerFromConversion[Unit]
  implicit def jsAnyWriter[A <: js.Any]: JsWriter[A] = JsWriter(identity)

  implicit def callbackToWriter[T](implicit writerT: JsWriter[T]): JsWriter[CallbackTo[T]] =
    JsWriter(value => value.map(writerT.toJs).runNow())

  implicit def undefOrWriter[A](implicit writerA: JsWriter[A]): JsWriter[js.UndefOr[A]] =
    JsWriter(_.map(writerA.toJs))

  implicit def optionWriter[A](implicit writerA: JsWriter[A]): JsWriter[Option[A]] =
    JsWriter(_.map(writerA.toJs).orUndefined)

  implicit def unionWriter[A, B](implicit A: ClassTag[A],
                                 writerA: JsWriter[A],
                                 B: ClassTag[B],
                                 writerB: JsWriter[B]): JsWriter[A | B] =
    JsWriter { value =>
      A.unapply(value).map(writerA.toJs)
        .orElse(B.unapply(value).map(writerB.toJs))
        .getOrElse(throw new RuntimeException(s"Value $value of type ($A | $B) matched neither}"))
    }

  implicit def enumerationWriter[T <: Enumeration#Value]: JsWriter[T] =
    JsWriter(_.toString)

  implicit def baseSeqWriter[T: JsWriter]: JsWriter[scala.collection.Seq[T]] = {
    val elementWriter = implicitly[JsWriter[T]]

    JsWriter(_.map(elementWriter.toJs).toJSArray)
  }

  implicit def immutableSeqWriter[T : JsWriter]: JsWriter[scala.collection.immutable.Seq[T]] = {
    val elementWriter = implicitly[JsWriter[T]]

    JsWriter((value: scala.collection.immutable.Seq[T]) => js.Array(value.map(e => elementWriter.toJs(e)): _*))
  }

  implicit def mapWriter[T : JsWriter]: JsWriter[Map[String, T]] = {
    val elementWriter = implicitly[JsWriter[T]]

    JsWriter(
      (value: Map[String, T]) => {
        val converted = value.map { case (k, v) => (k, elementWriter.toJs(v)) }
        js.Dictionary(converted.toSeq: _*)
      }
    )
  }

  implicit def futureWriter[A](implicit writeA: JsWriter[A], executionContext: ExecutionContext): JsWriter[Future[A]] =
    JsWriter(_.map(writeA.toJs).toJSPromise)

  implicit def vdomElementWriter: JsWriter[VdomElement] = JsWriter(_.rawElement)

  type JsComponentType = Js.ComponentSimple[Object, CtorType.Summoner.Aux[Object, Children.Varargs, CtorType.PropsAndChildren]#CT, Js.UnmountedWithRawType[Object, Null, Js.RawMounted[Object, Null]]]

  def extractPropsAndChildren(attrAndChildren: Seq[TagMod]): (js.Object, List[VdomNode]) = {
    val b = new japgolly.scalajs.react.vdom.Builder.ToJs {}
    attrAndChildren.toTagMod.applyTo(b)
    b.addClassNameToProps()
    b.addStyleToProps()

    (b.props, b.childrenAsVdomNodes)
  }


} 
Example 125
Source File: ParamMaker.scala    From typed-schema   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.tschema.macros
import ru.tinkoff.tschema.macros.ParamMaker.Applyer
import ru.tinkoff.tschema.typeDSL
import ru.tinkoff.tschema.typeDSL.{Capture, DSLAtom, FormField, Header, QueryParam}

import scala.language.{dynamics, higherKinds}
import scala.language.experimental.macros
import shapeless.Witness

import scala.reflect.macros.whitebox

class ParamMaker[T[_, _]] extends Dynamic {
  def params[A]: Applyer = macro ParamMakerMacro.paramsImpl[A, T[_, _]]
}

object ParamMaker {
  type Applyer = { def apply[A](x: => A): DSLAtom }
  def apply[T[_, _]]: ParamMaker[T] = new ParamMaker[T]

  object query   extends ParamMaker[QueryParam]
  object path    extends ParamMaker[Capture]
  object headers extends ParamMaker[Header]
  object form    extends ParamMaker[FormField]
}

class ParamMakerMacro(val c: whitebox.Context) extends SymbolMacros {
  import c.universe._

  val consTpe = typeOf[typeDSL.:>[_, _]].typeConstructor

  def paramsImpl[A: WeakTypeTag, T: WeakTypeTag] = {
    val const = weakTypeTag[T].tpe.typeConstructor

    val result = extractNamesTypes(weakTypeOf[A]).map { case (name, tpe) => appliedType(const, KeyName(name), tpe) }
      .reduce((a, b) => appliedType(consTpe, a, b))

    q"""
    new {
      import ru.tinkoff.tschema.typeDSL.{:>}
      def apply[A](x: => A): :>[$result, A] = new :>
    }"""
  }

  def extractNamesTypes(ref: Type): List[(String, Type)] = ref match {
    case RefinedType(tpes, scope) =>
      info(tpes)
      scope.collect {
        case m: MethodSymbol =>
          info(m)
          m.name.decodedName.toString -> m.returnType
      }.toList
    case _                        => List.empty
  }

  def info[A](mess: A) = c.info(c.enclosingPosition, mess.toString, force = false)
} 
Example 126
Source File: TypeName.scala    From zio-config   with Apache License 2.0 5 votes vote down vote up
package zio.config.shapeless

import scala.language.experimental.macros
import scala.reflect.macros.whitebox

trait TypeName[T] {
  def apply(): String
}

object TypeName {
  implicit def materializeTypeName[T]: TypeName[T] = macro typeNameImpl[T]

  def typeNameImpl[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
    import c.universe._

    val T    = c.weakTypeOf[T]
    val name = T.typeSymbol.name.toString
    q" new _root_.zio.config.shapeless.TypeName[$T]{ def apply(): String = $name } "
  }
} 
Example 127
Source File: print.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
package magnolia.examples

import magnolia.{Magnolia, ReadOnlyCaseClass, SealedTrait}

import scala.language.experimental.macros

// Prints a type, only requires read access to fields
trait Print[T] {
  def print(t: T): String
}

trait GenericPrint {
  type Typeclass[T] = Print[T]

  def combine[T](ctx: ReadOnlyCaseClass[Typeclass, T]): Print[T] = { value =>
  if (ctx.isValueClass) {
    val param = ctx.parameters.head
    param.typeclass.print(param.dereference(value))
  }
  else {
    ctx.parameters.map { param =>
      param.typeclass.print(param.dereference(value))
    }.mkString(s"${ctx.typeName.short}(", ",", ")")
  }
  }


  def dispatch[T](ctx: SealedTrait[Print, T])(): Print[T] = { value =>
    ctx.dispatch(value) { sub =>
      sub.typeclass.print(sub.cast(value))
    }
  }

  implicit def gen[T]: Print[T] = macro Magnolia.gen[T]

}

object Print extends GenericPrint {
  implicit val string: Print[String] = identity
  implicit val int: Print[Int] = _.toString

  implicit def seq[T](implicit printT: Print[T]): Print[Seq[T]] = { values =>
    values.map(printT.print).mkString("[", ",", "]")
  }
} 
Example 128
Source File: patch.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
package magnolia.examples

import scala.language.experimental.macros
import magnolia._


  def patch(value: T, fieldValues: Seq[Any]): T
}

object Patcher extends LowerPriorityPatcher {

  type Typeclass[T] = Patcher[T]

  def combine[T](ctx: CaseClass[Patcher, T]): Patcher[T] =
    new Patcher[T] {
      def patch(value: T, fieldValues: Seq[Any]): T = {
        if (fieldValues.lengthCompare(ctx.parameters.size) != 0) {
          throw new IllegalArgumentException(
            s"Cannot patch value `$value`, expected ${ctx.parameters.size} fields but got ${fieldValues.size}"
          )
        }
        val effectiveFields = ctx.parameters.zip(fieldValues).map {
          case (param, x) => if (x.asInstanceOf[AnyRef] ne null) x else param dereference value
        }
        ctx.rawConstruct(effectiveFields)
      }
    }

  def dispatch[T](ctx: SealedTrait[Patcher, T]): Patcher[T] =
    new Patcher[T] {
      def patch(value: T, fieldValues: Seq[Any]): T =
        ctx.dispatch(value)(sub => sub.typeclass.patch(sub cast value, fieldValues))
    }

  implicit def gen[T]: Patcher[T] = macro Magnolia.gen[T]
}

sealed abstract class LowerPriorityPatcher {

  private[this] val _forSingleValue =
    new Patcher[Any] {
      def patch(value: Any, fieldValues: Seq[Any]): Any = {
        if (fieldValues.lengthCompare(1) != 0)
          throw new IllegalArgumentException(
            s"Cannot patch single value `$value` with patch sequence of size ${fieldValues.size}"
          )
        val head = fieldValues.head
        if (head.getClass != value.getClass)
          throw new IllegalArgumentException(
            s"Illegal patch value type. Expected `${value.getClass}` but got `${head.getClass}`"
          )
        head
      }
    }

  // once https://github.com/propensive/magnolia/issues/58 is fixed this can be marked `implicit`
  def forSingleValue[T]: Patcher[T] = _forSingleValue.asInstanceOf[Patcher[T]]
} 
Example 129
Source File: decodeSafe.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
import magnolia._
import scala.language.experimental.macros


  private def parse(value: String): (String, Map[String, String]) = {
    val end = value.indexOf('(')
    val name = value.substring(0, end)

    def parts(value: String,
              idx: Int = 0,
              depth: Int = 0,
              collected: List[String] = List("")): List[String] = {
      def plus(char: Char): List[String] = collected.head + char :: collected.tail

      if (idx == value.length) collected
      else
        value(idx) match {
          case '(' =>
            parts(value, idx + 1, depth + 1, plus('('))
          case ')' =>
            if (depth == 1) plus(')')
            else parts(value, idx + 1, depth - 1, plus(')'))
          case ',' =>
            if (depth == 0) parts(value, idx + 1, depth, "" :: collected)
            else parts(value, idx + 1, depth, plus(','))
          case char =>
            parts(value, idx + 1, depth, plus(char))
        }
    }

    def keyValue(str: String): (String, String) = {
      val List(label, value) = str.split("=", 2).toList
      (label, value)
    }

    (name, parts(value.substring(end + 1, value.length - 1)).map(keyValue).toMap)
  }
} 
Example 130
Source File: semiauto.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
package magnolia.examples

import scala.language.experimental.macros
import magnolia._

trait SemiDefault[A] {
  def default: A
}
object SemiDefault {
  @inline def apply[A](implicit A: SemiDefault[A]): SemiDefault[A] = A

  type Typeclass[T] = SemiDefault[T]

  def combine[T](ctx: CaseClass[SemiDefault, T]): SemiDefault[T] = new SemiDefault[T] {
    def default = ctx.construct(p => p.default.getOrElse(p.typeclass.default))
  }
  def dispatch[T](ctx: SealedTrait[SemiDefault, T])(): SemiDefault[T] = new SemiDefault[T] {
    def default = ctx.subtypes.head.typeclass.default
  }
  implicit val string: SemiDefault[String] = new SemiDefault[String] { def default = "" }
  implicit val int: SemiDefault[Int] = new SemiDefault[Int] { def default = 0 }

  // NOT IMPLICIT
  def gen[T]: SemiDefault[T] = macro Magnolia.gen[T]
} 
Example 131
Source File: csv.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
package magnolia.examples

import magnolia._
import scala.language.experimental.macros

trait Csv[A] {
  def apply(a: A): List[String]
}

object Csv {
  type Typeclass[A] = Csv[A]

  def combine[A](ctx: CaseClass[Csv, A]): Csv[A] = new Csv[A] {
    def apply(a: A): List[String] =
      ctx.parameters.foldLeft(List[String]()) {
        (acc, p) => acc ++ p.typeclass(p.dereference(a))
      }
  }

  def dispatch[A](ctx: SealedTrait[Csv, A]): Csv[A] = new Csv[A] {
    def apply(a: A): List[String] = ctx.dispatch(a)(sub => sub.typeclass(sub.cast(a)))
  }

  implicit def deriveCsv[A]: Csv[A] = macro Magnolia.gen[A]

  implicit val csvStr: Csv[String] = new Csv[String] {
    def apply(a: String): List[String] = List(a)
  }
} 
Example 132
Source File: decode.scala    From magnolia   with Apache License 2.0 5 votes vote down vote up
package magnolia.examples

import magnolia._
import scala.language.experimental.macros


  private def parse(value: String): (String, Map[String, String]) = {
    val end = value.indexOf('(')
    val name = value.substring(0, end)

    def parts(value: String,
              idx: Int = 0,
              depth: Int = 0,
              collected: List[String] = List("")): List[String] = {
      def plus(char: Char): List[String] = collected.head + char :: collected.tail

      if (idx == value.length) collected
      else
        value(idx) match {
          case '(' =>
            parts(value, idx + 1, depth + 1, plus('('))
          case ')' =>
            if (depth == 1) plus(')')
            else parts(value, idx + 1, depth - 1, plus(')'))
          case ',' =>
            if (depth == 0) parts(value, idx + 1, depth, "" :: collected)
            else parts(value, idx + 1, depth, plus(','))
          case char =>
            parts(value, idx + 1, depth, plus(char))
        }
    }

    def keyValue(str: String): (String, String) = {
      val List(label, value) = str.split("=", 2).toList
      (label, value)
    }

    (name, parts(value.substring(end + 1, value.length - 1)).map(keyValue).toMap)
  }
} 
Example 133
Source File: SchemaMagnoliaDerivation.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.generic.internal

import com.github.ghik.silencer.silent
import magnolia._
import sttp.tapir.SchemaType._
import sttp.tapir.generic.{Configuration, Derived}
import sttp.tapir.{Schema, SchemaType}
import SchemaMagnoliaDerivation.deriveInProgress

import scala.collection.mutable
import scala.language.experimental.macros

trait SchemaMagnoliaDerivation {
  type Typeclass[T] = Schema[T]

  @silent("discarded")
  def combine[T](ctx: ReadOnlyCaseClass[Schema, T])(implicit genericDerivationConfig: Configuration): Schema[T] = {
    withProgressCache { cache =>
      val cacheKey = ctx.typeName.full
      if (cache.contains(cacheKey)) {
        Schema[T](SRef(typeNameToObjectInfo(ctx.typeName)))
      } else {
        try {
          cache.add(cacheKey)
          if (ctx.isValueClass) {
            Schema[T](ctx.parameters.head.typeclass.schemaType)
          } else {
            Schema[T](
              SProduct(
                typeNameToObjectInfo(ctx.typeName),
                ctx.parameters.map(p => (genericDerivationConfig.toLowLevelName(p.label), p.typeclass)).toList
              )
            )
          }
        } finally {
          cache.remove(cacheKey)
        }
      }
    }
  }

  private def typeNameToObjectInfo(typeName: TypeName): SchemaType.SObjectInfo = {
    def allTypeArguments(tn: TypeName): Seq[TypeName] = tn.typeArguments.flatMap(tn2 => tn2 +: allTypeArguments(tn2))
    SObjectInfo(typeName.full, allTypeArguments(typeName).map(_.short).toList)
  }

  private def withProgressCache[T](f: mutable.Set[String] => Schema[T]): Schema[T] = {
    var cache = deriveInProgress.get()
    val newCache = cache == null
    if (newCache) {
      cache = mutable.Set[String]()
      deriveInProgress.set(cache)
    }

    try f(cache)
    finally {
      if (newCache) {
        deriveInProgress.remove()
      }
    }
  }

  def dispatch[T](ctx: SealedTrait[Schema, T]): Schema[T] = {
    Schema(SCoproduct(typeNameToObjectInfo(ctx.typeName), ctx.subtypes.map(_.typeclass).toList, None))
  }

  implicit def schemaForCaseClass[T]: Derived[Schema[T]] = macro MagnoliaDerivedMacro.derivedGen[T]
}

object SchemaMagnoliaDerivation {
  private[internal] val deriveInProgress: ThreadLocal[mutable.Set[String]] = new ThreadLocal()
} 
Example 134
Source File: SealedValues.scala    From flamy   with Apache License 2.0 5 votes vote down vote up
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 135
Source File: package.scala    From libisabelle   with Apache License 2.0 5 votes vote down vote up
package info.hupel.isabelle

import scala.language.experimental.macros


package object pure {

  type Indexname = (String, BigInt)
  type Sort = List[String]

  implicit class ExprStringContext(ctx: StringContext) {
    object term {
      def apply[T](args: T*): Program[String] = macro internal.Macros.term
    }
  }

  object Theory {
    val get: ml.Expr[String => Theory] =
      ml.Expr.uncheckedLiteral("get_theory")

    implicit val thyOpaque: ml.Opaque[Theory] = ml.Opaque.make("Refs.Thy")
  }
  type Theory = Theory.type

  object Context {
    val initGlobal: ml.Expr[Theory => Context] =
      ml.Expr.uncheckedLiteral("Proof_Context.init_global")

    implicit val ctxtOpaque: ml.Opaque[Context] = ml.Opaque.make("Refs.Ctxt")
  }
  type Context = Context.type

  type Conv = Cterm => Thm

  object Cterm {
    val eval: ml.Expr[Context => Conv] =
      ml.Expr.uncheckedLiteral("Code_Simp.dynamic_conv")

    implicit val ctermOpaque: ml.Opaque[Cterm] = ml.Opaque.make("Refs.Cterm")
  }
  type Cterm = Cterm.type

  object Thm {
    val mkTerm: ml.Expr[Cterm => Thm] =
      ml.Expr.uncheckedLiteral("Drule.mk_term")

    implicit val thmOpaque: ml.Opaque[Thm] = ml.Opaque.make("Refs.Thm")
  }
  type Thm = Thm.type

}