scala.annotation.compileTimeOnly Scala Examples

The following examples show how to use scala.annotation.compileTimeOnly. 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: 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 2
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 3
Source File: PlacedValues.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package runtime

import scala.annotation.compileTimeOnly
import scala.util.{Failure, Try}

trait PlacedValues {
  final val $loci$sys: System = $loci$sys$create
  protected def $loci$sys$create: System

  def $loci$dispatch(
      request: MessageBuffer,
      signature: Value.Signature,
      reference: Value.Reference): Try[MessageBuffer] =
    Failure(new transmitter.RemoteAccessException(
      s"request for ${Value.Signature.serialize(signature)} could not be dispatched"))
}

object PlacedValues {
  @compileTimeOnly("Multitier type can only be instantiated in module in which it is defined")
  implicit def placedValues: Nothing =
    throw new NotImplementedError("Multitier type can only be instantiated in module in which it is defined")
} 
Example 4
Source File: Remote.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci
package runtime

import communicator.ProtocolCommon

import java.util.concurrent.atomic.AtomicBoolean

import scala.annotation.compileTimeOnly

object Remote {
  case class Reference(
    id: Long,
    signature: Peer.Signature)(
    val protocol: ProtocolCommon,
    private[runtime] val remoteConnections: RemoteConnections)
      extends loci.Remote.Reference[Nothing] {

    private[runtime] val isConnected = new AtomicBoolean(true)
    private[runtime] val isAuthenticated = new AtomicBoolean(protocol.authenticated)
    private[runtime] val doDisconnected = Notice.Steady[Unit]

    def asReference = this
    def authenticated = isAuthenticated.get
    def authenticate() = isAuthenticated.set(true)
    def connected = isConnected.get
    def disconnect() = remoteConnections.disconnect(this)
    val disconnected = doDisconnected.notice

    override def toString: String = s"remote#$id($signature[$protocol])"
  }

  @compileTimeOnly("Call only allowed in multitier code. Use `remote.asRemote[P]` instead.")
  def cast[P](reference: loci.Remote.Reference[_]): Option[Remote[P]] = ???
} 
Example 5
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 6
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 7
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 8
Source File: MessageBuffer.scala    From scala-loci   with Apache License 2.0 5 votes vote down vote up
package loci

import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets

import scala.annotation.compileTimeOnly
import scala.collection.mutable

final class MessageBuffer private (val backingArray: Array[Byte])
    extends mutable.IndexedSeq[Byte] {
  @compileTimeOnly("`backingArrayBuffer` only available in JS")
  def backingArrayBuffer: Any = ???

  @inline def length: Int = backingArray.length

  @inline def apply(index: Int) = {
    if (index < 0  || index >= length)
      throw new IndexOutOfBoundsException(s"index $index")

    backingArray(index)
  }

  @inline def update(index: Int, element: Byte) = {
    if (index < 0  || index >= length)
      throw new IndexOutOfBoundsException(s"index $index")

    backingArray(index) = element
  }

  @inline def update(offset: Int, buffer: MessageBuffer, bufferOffset: Int, count: Int) = {
    if (offset < 0 || bufferOffset < 0 || count < 0 ||
        offset > length - count || bufferOffset > buffer.length - count)
      throw new IndexOutOfBoundsException(
        s"offset $offset, length $length, " +
        s"buffer offset ${bufferOffset}, buffer length ${buffer.length}, count $count")

    System.arraycopy(buffer.backingArray, bufferOffset, backingArray, offset, count)
  }

  @inline def concat(buffer: MessageBuffer): MessageBuffer = {
    val array = new Array[Byte](length + buffer.length)
    System.arraycopy(backingArray, 0, array, 0, length)
    System.arraycopy(buffer.backingArray, 0, array, length, buffer.length)
    new MessageBuffer(array)
  }

  @inline def copy(offset: Int, count: Int): MessageBuffer = {
    if (offset < 0 || count < 0 || offset > length - count)
      throw new IndexOutOfBoundsException(s"offset $offset, count $count, length $length")

    val array = new Array[Byte](count)
    System.arraycopy(backingArray, offset, array, 0, count)
    new MessageBuffer(array)
  }

  @inline def decodeString(offset: Int, count: Int): String =
    new String(backingArray, offset, count, StandardCharsets.UTF_8)

  @inline def decodeString: String =
    decodeString(0, length)

  @inline def asByteBuffer: ByteBuffer =
    ByteBuffer wrap backingArray

  override def toString: String =
    MessageBufferEncoding.byteBufferToString(asByteBuffer, 0, length, fatal = true) getOrElse
      MessageBufferEncoding.messageBufferToHexString(this)
}

object MessageBuffer {
  def empty: MessageBuffer = new MessageBuffer(Array.emptyByteArray)

  def allocate(length: Int): MessageBuffer = new MessageBuffer(new Array(length))

  def encodeString(string: String): MessageBuffer =
    new MessageBuffer(string getBytes StandardCharsets.UTF_8)

  def wrapByteBuffer(buffer: ByteBuffer): MessageBuffer =
    if (!buffer.hasArray) {
      val duplicate = buffer.duplicate
      duplicate.position(0)
      duplicate.limit(buffer.capacity)
      val array = new Array[Byte](duplicate.remaining)
      duplicate.get(array)
      new MessageBuffer(array)
    }
    else
      new MessageBuffer(buffer.array)

  def wrapArray(array: Array[Byte]): MessageBuffer =
    new MessageBuffer(array)

  @compileTimeOnly("`wrapArrayBuffer` only available in JS")
  def wrapArrayBuffer(arrayBuffer: Any): MessageBuffer = ???
} 
Example 9
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 10
Source File: Decorator.scala    From Elysium   with MIT License 5 votes vote down vote up
package nz.daved.elysium.core

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import nz.daved.elysium.manipulate.DefManipulation._

import scala.meta.Defn.Def
import scala.meta._

@compileTimeOnly("@before not expanded")
class before(fun: () => Unit) extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    val q"new $_(${apply: Term.Apply})" = this
    defn.asInstanceOf[Def].prependStat(apply)
  }
}

@compileTimeOnly("@after not expanded")
class after(fun: () => Unit) extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    val q"new $_(${apply: Term.Apply})" = this
    defn.asInstanceOf[Def].appendStat(apply)
  }
} 
Example 11
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 12
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 13
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.Factory
import com.softwaremill.diffx.DiffxSupport._

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

  implicit class DiffxEachMap[F[_, _], K, T](t: F[K, T])(implicit fac: Factory[(K, T), F[K, T]]) {
    @compileTimeOnly(canOnlyBeUsedInsideIgnore("each"))
    def each: T = sys.error("")
  }
} 
Example 14
Source File: DiffxSupport.scala    From diffx   with Apache License 2.0 5 votes vote down vote up
package com.softwaremill.diffx
import acyclic.skipped

import scala.annotation.compileTimeOnly
import com.softwaremill.diffx.DiffxSupport._

trait DiffxSupport extends DiffxEitherSupport with DiffxConsoleSupport with DiffxOptionSupport {
  type FieldPath = List[String]

  def compare[T](left: T, right: T)(implicit d: Diff[T]): DiffResult = d.apply(left, right)
}

object DiffxSupport {
  private[diffx] def canOnlyBeUsedInsideIgnore(method: String) =
    s"$method can only be used inside ignore"
}

trait DiffxEitherSupport {
  implicit class DiffxEither[T[_, _], L, R](e: T[L, R])(implicit f: DiffxEitherFunctor[T, L, R]) {
    @compileTimeOnly(canOnlyBeUsedInsideIgnore("eachLeft"))
    def eachLeft: L = sys.error("")

    @compileTimeOnly(canOnlyBeUsedInsideIgnore("eachRight"))
    def eachRight: R = sys.error("")
  }

  trait DiffxEitherFunctor[T[_, _], L, R] {
    def eachLeft(e: T[L, R])(f: L => L): T[L, R] = sys.error("")
    def eachRight(e: T[L, R])(f: R => R): T[L, R] = sys.error("")
  }

  implicit def eitherDiffxFunctor[T[_, _], L, R]: DiffxEitherFunctor[Either, L, R] =
    new DiffxEitherFunctor[Either, L, R] {}
}

trait DiffxConsoleSupport {
  def leftColor(s: String)(implicit c: ConsoleColorConfig): String = c.left(s)
  def rightColor(s: String)(implicit c: ConsoleColorConfig): String = c.right(s)
  def defaultColor(s: String)(implicit c: ConsoleColorConfig): String = c.default(s)
  def arrowColor(s: String)(implicit c: ConsoleColorConfig): String = c.arrow(s)
  def showChange(l: String, r: String)(implicit c: ConsoleColorConfig): String =
    leftColor(l) + arrowColor(" -> ") + rightColor(r)
}

case class ConsoleColorConfig(
    left: String => String,
    right: String => String,
    default: String => String,
    arrow: String => String
)

object ConsoleColorConfig {
  val dark: ConsoleColorConfig = ConsoleColorConfig(left = magenta, right = green, default = cyan, arrow = red)
  val light: ConsoleColorConfig = ConsoleColorConfig(default = black, arrow = red, left = magenta, right = blue)
  val normal: ConsoleColorConfig =
    ConsoleColorConfig(default = identity, arrow = red, right = green, left = red)
  val envDriven: ConsoleColorConfig = Option(System.getenv("DIFFX_COLOR_THEME")) match {
    case Some("light") => light
    case Some("dark")  => dark
    case _             => normal
  }
  implicit val default: ConsoleColorConfig = envDriven

  def magenta: String => String = toColor(Console.MAGENTA)
  def green: String => String = toColor(Console.GREEN)
  def blue: String => String = toColor(Console.BLUE)
  def cyan: String => String = toColor(Console.CYAN)
  def red: String => String = toColor(Console.RED)
  def black: String => String = toColor(Console.BLACK)

  private def toColor(color: String) = { s: String => color + s + Console.RESET }
}

trait DiffxOptionSupport {
  implicit class DiffxEach[F[_], T](t: F[T])(implicit f: DiffxFunctor[F, T]) {
    @compileTimeOnly(canOnlyBeUsedInsideIgnore("each"))
    def each: T = sys.error("")
  }

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

  implicit def optionDiffxFunctor[A]: DiffxFunctor[Option, A] =
    new DiffxFunctor[Option, A] {}
} 
Example 15
Source File: InfixDsl.scala    From quill   with Apache License 2.0 5 votes vote down vote up
package io.getquill.dsl

import io.getquill.quotation.NonQuotedException
import scala.annotation.compileTimeOnly

private[dsl] trait InfixDsl {

  private[dsl] trait InfixValue {
    def as[T]: T
    def pure: InfixValue
  }

  implicit class InfixInterpolator(val sc: StringContext) {

    @compileTimeOnly(NonQuotedException.message)
    def infix(args: Any*): InfixValue = NonQuotedException()
  }
} 
Example 16
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 17
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 18
Source File: AliasWithLens.scala    From Vegas   with MIT License 5 votes vote down vote up
package vegas.macros

import language.experimental.macros
import scala.annotation.{ StaticAnnotation, compileTimeOnly }
import reflect.macros.blackbox.Context
import macrocompat.bundle
import monocle.Lens

class alias_with_lens(name: String, lens: Lens[_,_]) extends StaticAnnotation

@compileTimeOnly("You must enable the macro paradise plugin.")
class aliased extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro AliasMacros.lensAliasMacroImpl
}


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

  def paramsToArgs(params: List[ValDef]): List[Tree] = {
    params.map { case q"$a val $param: $b = $c" => q"$param" }
  }

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

    val result = annottees map (_.tree) match {

      // Match a trait
      case (traitDef @ q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }") :: _ => {

        // Loop through all functions with aliases, and great new defs for each using given name and lens
        val aliasedDefs = for {
          q"@..$annots private def $tname[..$tparams](...$paramss): $tpt = $expr" <- stats
          annot <- annots
          Apply(Select(New(Ident(TypeName(aName))), _), annotArgs) = annot if (aName == "alias_with_lens")
        } yield {
          val List(Literal(Constant(name: String)), lens) = annotArgs
          val aliasIdent = TermName(name)
          val args = paramss.tail.map(paramsToArgs)
          q"def $aliasIdent[..$tparams](...${ paramss.tail }): $tpt = $tname(..$lens)(...$args)"
        }

        // Now rewrite trait with additional methods
        if(aliasedDefs.nonEmpty) {
          q"""
            $mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self =>
              ..$stats
              ..$aliasedDefs
            }
          """
        } else traitDef

      }

      case _ => c.abort(c.enclosingPosition, "Invalid annotation target: not a trait")

    }

    c.Expr[Any](result)
  }

} 
Example 19
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 20
Source File: autoInvariant.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.meta._
import Util._

import collection.immutable.Seq


@compileTimeOnly("Cannot expand @autoFunctor")
class autoInvariant extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    enrichAlgebra(defn, higherKinded = false)(autoInvariant.invariantInst)
  }
}

object autoInvariant {
  private[mainecoon] def invariantInst(ad: AlgDefn): TypeDefinition = {
    import ad._
    import cls._

    class ParamParser(params: Seq[Term.Param]) {
      lazy val effParams: Seq[Term.Param] =
        params.collect {
          case p @ Term.Param(_, _, Some(Type.Name(`effectTypeName`)), _) => p
        }

      lazy val newArgs: Seq[Term] =
        params.map {
          case p if effParams.contains(p) => q"mapFunctionFrom(${Term.Name(p.name.value)})"
          case p => Term.Name(p.name.value)
        }

      lazy val newParams: Seq[Term.Param] =
        params.map { p =>
          effParams.find(_ == p).fold(p) { effP =>
            effP.copy(decltpe = Some(Type.Name("TTarget")))
          }
        }
    }

    val methods = templ.stats.toList.flatMap(_.collect {
      //abstract method with return type being effect type
      case q"def $methodName[..$mTParams](...$params): ${Type.Name(`effectTypeName`)}" =>
        val pps = params.map(new ParamParser(_))
        q"""def $methodName[..$mTParams](...${pps.map(_.newParams)}): TTarget =
           mapFunction(delegatee_.$methodName(...${pps.map(_.newArgs)}))"""

      //abstract method with other return type
      case q"def $methodName[..$mTParams](...$params): $targetType" =>
        val pps = params.map(new ParamParser(_))
        q"""def $methodName[..$mTParams](...${pps.map(_.newParams)}): $targetType =
           delegatee_.$methodName(...${pps.map(_.newArgs)})"""
    })

    val instanceDef = Seq(q"""
      implicit def ${Term.Name("invariantFor" + name.value)}[..$extraTParams]: _root_.cats.Invariant[$typeLambdaVaryingEffect] =
        new _root_.cats.Invariant[$typeLambdaVaryingEffect] {
          def imap[T, TTarget](delegatee_ : $name[..${tArgs("T")}])(mapFunction: T => TTarget)(mapFunctionFrom: TTarget => T): $name[..${tArgs("TTarget")}] =
            new ${Ctor.Ref.Name(name.value)}[..${tArgs("TTarget")}] {
              ..$methods
            }
        }""")

    cls.copy(companion = cls.companion.addStats(instanceDef))

  }
} 
Example 21
Source File: ModifyMacroFunctorSupport.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.internal

import scala.annotation.compileTimeOnly

trait ModifyMacroFunctorSupport {
  implicit class ModifyEach[F[_], T](t: F[T])(implicit f: ModifyFunctor[F, T]) {
    @compileTimeOnly(canOnlyBeUsedInsideModify("each"))
    def each: T = sys.error("")
  }

  trait ModifyFunctor[F[_], A] {
    @compileTimeOnly(canOnlyBeUsedInsideModify("each"))
    def each(fa: F[A])(f: A => A): F[A] = sys.error("")
  }

  implicit def optionModifyFunctor[A]: ModifyFunctor[Option, A] =
    new ModifyFunctor[Option, A] {}

  private[tapir] def canOnlyBeUsedInsideModify(method: String) =
    s"$method can only be used inside ignore"
} 
Example 22
Source File: XmlnsDef.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.annotations

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

@compileTimeOnly("enable macro paradise to expand macro annotations")
final class XmlnsDef(uri: String) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro XmlnsDefImpl.impl
}

private final class XmlnsDefImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) {
  import c.universe._

  def instances(typ: Tree): Seq[Tree] = {
    val pkg = q"ru.tinkoff.phobos"
    val instanceName = TermName(c.freshName("namespaceInstance"))
    val uri = c.prefix.tree match {
      case q"new XmlnsDef($uri)" => uri
    }
    Seq(q"implicit val $instanceName: $pkg.Namespace[$typ] = $pkg.Namespace.mkInstance[$typ]($uri)")
  }

} 
Example 23
Source File: XmlCodec.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.annotations

import ru.tinkoff.phobos.configured.ElementCodecConfig
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.reflect.macros.blackbox

@compileTimeOnly("enable macro paradise to expand macro annotations")
class XmlCodec(localName: String, config: ElementCodecConfig = ElementCodecConfig.default) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro XmlCodecImpl.impl
}

private final class XmlCodecImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) {
  import c.universe._

  def instances(typ: Tree): Seq[Tree] = {
    val pkg = q"ru.tinkoff.phobos"
    val (localName, config) = c.prefix.tree match {
      case q"new XmlCodec($localName)"          => (localName, defaultConfig.tree)
      case q"new XmlCodec($localName, $config)" => (localName, config)
    }

    Seq(
      q"""
          implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] =
            $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config)
       """,
      q"""
          implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] =
            $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config)
       """,
      q"""
          implicit val ${TermName(c.freshName("xmlEncoder"))}: $pkg.encoding.XmlEncoder[$typ] =
            $pkg.encoding.XmlEncoder.fromElementEncoder[$typ]($localName)
       """,
      q"""
          implicit val ${TermName(c.freshName("xmlDecoder"))}: $pkg.decoding.XmlDecoder[$typ] =
            $pkg.decoding.XmlDecoder.fromElementDecoder[$typ]($localName)
       """
    )
  }

} 
Example 24
Source File: XmlCodecNs.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.annotations

import ru.tinkoff.phobos.Namespace
import ru.tinkoff.phobos.configured.ElementCodecConfig
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.reflect.macros.blackbox

@compileTimeOnly("enable macro paradise to expand macro annotations")
class XmlCodecNs[T: Namespace](localName: String, namespace: T, config: ElementCodecConfig = ElementCodecConfig.default)
    extends StaticAnnotation {
  def namespaceUri: String = Namespace[T].getNamespace
  def macroTransform(annottees: Any*): Any = macro XmlCodecNsImpl.impl
}

private final class XmlCodecNsImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) {
  import c.universe._

  def instances(typ: Tree): Seq[Tree] = {
    val pkg = q"ru.tinkoff.phobos"
    val (nsInstance, localName, config) = c.prefix.tree match {
      case q"new XmlCodecNs($localName, $nsInstance)"              => (nsInstance, localName, defaultConfig.tree)
      case q"new XmlCodecNs($localName, $nsInstance, $config)"     => (nsInstance, localName, config)
      case q"new XmlCodecNs[$_]($localName, $nsInstance, $config)" => (nsInstance, localName, config)
    }

    Seq(
      q"""
          implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] =
            $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config)
       """,
      q"""
          implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] =
            $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config)
       """,
      q"""
          implicit val ${TermName(c.freshName("xmlEncoder"))}: $pkg.encoding.XmlEncoder[$typ] =
            $pkg.encoding.XmlEncoder.fromElementEncoderNs($localName, $nsInstance)
       """,
      q"""
          implicit val ${TermName(c.freshName("xmlDecoder"))}: $pkg.decoding.XmlDecoder[$typ] =
            $pkg.decoding.XmlDecoder.fromElementDecoderNs($localName, $nsInstance)
       """
    )
  }

} 
Example 25
Source File: ElementCodec.scala    From phobos   with Apache License 2.0 5 votes vote down vote up
package ru.tinkoff.phobos.annotations

import ru.tinkoff.phobos.configured.ElementCodecConfig
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.reflect.macros.blackbox

@compileTimeOnly("enable macro paradise to expand macro annotations")
final class ElementCodec(config: ElementCodecConfig = ElementCodecConfig.default) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro ElementCodecImpl.impl
}

private final class ElementCodecImpl(ctx: blackbox.Context) extends CodecAnnotation(ctx) {
  import c.universe._

  def instances(typ: Tree): Seq[Tree] = {
    val pkg = q"ru.tinkoff.phobos"

    val config = c.prefix.tree match {
      case q"new ElementCodec"          => defaultConfig.tree
      case q"new ElementCodec($config)" => config
    }

    Seq(
      q"""
          implicit val ${TermName(c.freshName("elementEncoder"))}: $pkg.encoding.ElementEncoder[$typ] =
            $pkg.derivation.semiauto.deriveElementEncoderConfigured[$typ]($config)
       """,
      q"""
          implicit val ${TermName(c.freshName("elementDecoder"))}: $pkg.decoding.ElementDecoder[$typ] =
            $pkg.derivation.semiauto.deriveElementDecoderConfigured[$typ]($config)
       """
    )
  }

} 
Example 26
Source File: Macros.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi

import scala.annotation.compileTimeOnly
import com.qvantel.jsonapi.macrosupport.{JsonApiReaders, JsonApiWriters}

import scala.reflect.macros.blackbox


@compileTimeOnly("Macros can only be used at compile-time")
final class Macros(val c: blackbox.Context) extends JsonApiWriters with JsonApiReaders {
  import c.universe._

  private[this] def createFormat(t: c.Type): c.Tree = {
    val rootParamName     = TermName(c.freshName("root"))
    val includedParamName = TermName(c.freshName("included"))
    val includePaths      = TermName(c.freshName("includePaths"))
    val includePath       = TermName(c.freshName("includePath"))
    q"""new _root_.com.qvantel.jsonapi.JsonApiFormat[$t] with _root_.spray.json.RootJsonFormat[$t] {
          import _root_.com.qvantel.jsonapi.PathJsonFormat
          override final def write($rootParamName: $t, sparseFields: Map[String, List[String]]): _root_.spray.json.JsValue = ${primaryDataWriter(
      t,
      rootParamName)}
          override final def included($rootParamName: $t, sparseFields: Map[String, List[String]]): _root_.scala.collection.immutable.Set[_root_.spray.json.JsObject] = ${includedWriter(
      t,
      rootParamName)}
          override final def read(
            $rootParamName: _root_.spray.json.JsValue,
            $includedParamName: _root_.scala.collection.immutable.Map[(String, String), _root_.spray.json.JsObject],
            $includePaths: _root_.scala.collection.immutable.Set[String],
            $includePath: String
          ): $t = ${reader(t, rootParamName, includedParamName, includePaths, includePath)}
        }"""
  }

  def createIncludes[A: c.WeakTypeTag]: c.Tree = {
    val t = weakTypeOf[A]

    val includeParamName    = TermName(c.freshName())
    val includeMapParamName = TermName(c.freshName())
    q"""
      new _root_.com.qvantel.jsonapi.Includes[$t] {
        private[this] final lazy val $includeMapParamName: Map[String, _root_.com.qvantel.jsonapi.Includes[_]] = ${includesMap(
      t)}
        override def includeAllowed($includeParamName: String): Boolean = ${includeAllowed(t,
                                                                                           includeParamName,
                                                                                           includeMapParamName)}
      }
      """
  }

  def jsonApiWriterWithNoNameManglingImpl[A: c.WeakTypeTag]: c.Tree = createWriter(weakTypeOf[A])
  def jsonApiFormatWithNoNameManglingImpl[A: c.WeakTypeTag]: c.Tree = createFormat(weakTypeOf[A])
} 
Example 27
Source File: Tools.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi.macrosupport

import scala.annotation.compileTimeOnly
import scala.reflect.macros.blackbox.Context
import shapeless.{CNil, Coproduct}

@compileTimeOnly("Macros can only be used at compile-time")
trait Tools {
  val c: Context
  import c.universe._

  private[this] val coproductType = typeOf[Coproduct]
  private[this] val coproductNil  = typeOf[CNil]

  private[this] def inl(name: TermName): c.Tree = {
    val bind = pq"$name"
    q"_root_.shapeless.Inl($bind)"
  }

  private[this] def inr(tree: c.Tree): c.Tree = q"_root_.shapeless.Inr($tree)"

  def coproductTypes(t: c.Type): List[c.Type] = {
    def go(ta: List[c.Type], acc: List[c.Type]): List[c.Type] =
      ta match {
        case Nil                                 => acc
        case l :: r :: Nil if r =:= coproductNil => acc :+ l
        case l :: r :: Nil                       => go(r.dealias.typeArgs, acc :+ l)
      }

    if (t <:< coproductType) {
      go(t.dealias.typeArgs, Nil)
    } else {
      c.abort(c.enclosingPosition, s"The type $t must be a shapeless.Coproduct")
    }
  }

  def coproductPattern(n: Int, name: TermName): c.Tree =
    (1 until n).foldLeft(inl(name))((tree, _) => inr(tree))

  def coproductPatterns(nTypes: Int, name: TermName): Seq[c.Tree] =
    (1 to nTypes).map(coproductPattern(_, name))
} 
Example 28
Source File: JsonApiCommon.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi.macrosupport

import scala.annotation.compileTimeOnly

import com.qvantel.jsonapi._

@compileTimeOnly("Macros can only be used at compile-time")
trait JsonApiCommon extends Tools {
  import c.universe._

  val toOneType: c.universe.Type                 = typeOf[ToOne[_]]
  val optionalToOneType: c.universe.Type         = typeOf[Option[ToOne[_]]]
  val jsonOptionalToOneType: c.universe.Type     = typeOf[JsonOption[ToOne[_]]]
  val toManyType: c.universe.Type                = typeOf[ToMany[_]]
  val polyToOneType: c.universe.Type             = typeOf[PolyToOne[_]]
  val optionalPolyToOneType: c.universe.Type     = typeOf[Option[PolyToOne[_]]]
  val jsonOptionalPolyToOneType: c.universe.Type = typeOf[JsonOption[PolyToOne[_]]]
  val polyToManyType: c.universe.Type            = typeOf[PolyToMany[_]]

  val optionType: c.universe.Type     = typeOf[Option[_]]
  val jsonOptionType: c.universe.Type = typeOf[JsonOption[_]]

  def camelToDashes(name: String): String =
    "[A-Z\\d]".r.replaceAllIn(name, m => "-" + m.group(0).toLowerCase())

  def resourceType(t: c.Type): c.Tree =
    q"_root_.scala.Predef.implicitly[_root_.com.qvantel.jsonapi.ResourceType[$t]].resourceType"

  def caseClassFields(t: c.Type): List[c.universe.TermSymbol] = {
    val primaryConstructor = t.typeSymbol.asClass.primaryConstructor.asMethod
    primaryConstructor.paramLists.headOption getOrElse {
      c.abort(c.enclosingPosition, s"Case class constructor does not have any fields")
    } map (_.asTerm) sortBy (_.name.toString)
  }

  def partitionedCaseClassFields(t: c.Type): (List[c.universe.TermSymbol], List[c.universe.TermSymbol]) =
    partitionRelations(t, caseClassFields(t))

  def relationFields(t: c.Type): List[c.universe.TermSymbol] =
    partitionedCaseClassFields(t)._1

  def resolveContainedType(t: c.Type): c.Type =
    if (t <:< toOneType || t <:< toManyType || t <:< polyToOneType || t <:< polyToManyType) {
      t.typeArgs.headOption.getOrElse(c.abort(c.enclosingPosition, s"$t typeArgs is empty"))
    } else if (t <:< optionalToOneType || t <:< jsonOptionalToOneType || t <:< optionalPolyToOneType || t <:< jsonOptionalPolyToOneType) {
      t.typeArgs.headOption
        .getOrElse(c.abort(c.enclosingPosition, s"$t typeArgs is empty"))
        .typeArgs
        .headOption
        .getOrElse(c.abort(c.enclosingPosition, s"$t typeArgs is empty"))
    } else {
      c.abort(c.enclosingPosition, s"Cannot determine contained type for $t")
    }

  def emptyForIterableType(t: c.Type): c.Tree =
    if (t <:< typeOf[Iterable[_]]) {
      q"${t.typeSymbol.companion}.empty[..${t.typeArgs}]"
    } else {
      c.abort(c.enclosingPosition, s"Type $t is not an Iterable")
    }

  def resolveContainedAttributeType(t: c.Type): c.Type =
    if (t <:< optionType || t <:< jsonOptionType) {
      t.typeArgs.headOption.getOrElse(c.abort(c.enclosingPosition, s"$t typeArgs is empty"))
    } else {
      c.abort(c.enclosingPosition, s"Cannot determine contained type for $t")
    }

  def relationshipTypes(t: c.Type): List[(c.universe.Type, String)] =
    relationFields(t) map { field =>
      (field.infoIn(t), field.name.toString)
    }

  def partitionRelations(
      t: c.Type,
      fields: List[c.universe.TermSymbol]): (List[c.universe.TermSymbol], List[c.universe.TermSymbol]) =
    fields partition { field =>
      val fieldType = field.infoIn(t)
      fieldType <:< toOneType ||
      fieldType <:< optionalToOneType ||
      fieldType <:< jsonOptionalToOneType ||
      fieldType <:< toManyType ||
      fieldType <:< polyToOneType ||
      fieldType <:< optionalPolyToOneType ||
      fieldType <:< jsonOptionalPolyToOneType ||
      fieldType <:< polyToManyType
    }
} 
Example 29
Source File: ModifyMacroSupport.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.internal

import scala.annotation.compileTimeOnly
import scala.collection.TraversableLike
import scala.collection.generic.CanBuildFrom

trait ModifyMacroSupport extends ModifyMacroFunctorSupport {
  implicit def traversableModifyFunctor[F[_], A](implicit
      cbf: CanBuildFrom[F[A], A, F[A]],
      ev: F[A] => TraversableLike[A, F[A]]
  ): ModifyFunctor[F, A] =
    new ModifyFunctor[F, A] {}

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

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

  implicit class ModifyEachMap[F[_, _], K, T](t: F[K, T])(implicit f: ModifyMapAtFunctor[F, K, T]) {
    @compileTimeOnly(canOnlyBeUsedInsideModify("each"))
    def each: T = sys.error("")
  }
} 
Example 30
Source File: ModifyMacroSupport.scala    From tapir   with Apache License 2.0 5 votes vote down vote up
package sttp.tapir.internal

import scala.annotation.compileTimeOnly
import scala.collection.Factory

trait ModifyMacroSupport extends ModifyMacroFunctorSupport {
  implicit def traversableModifyFunctor[F[_], A](
                                                  implicit fac: Factory[A, F[A]],
                                                  ev: F[A] => Iterable[A]
                                                ): ModifyFunctor[F, A] =
    new ModifyFunctor[F, A] {}

  implicit class ModifyEachMap[F[_, _], K, T](t: F[K, T])(implicit fac: Factory[(K, T), F[K, T]]) {
    @compileTimeOnly(canOnlyBeUsedInsideModify("each"))
    def each: T = sys.error("")
  }
} 
Example 31
Source File: autoFunctor.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import mainecoon.Util._

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._


@compileTimeOnly("Cannot expand @autoFunctor")
class autoFunctor extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    enrichAlgebra(defn, higherKinded = false)(autoFunctor.functorInst)
  }
}


object autoFunctor {
  private[mainecoon] def functorInst(ad: AlgDefn): TypeDefinition = {
    import ad._
    import cls._

    val instanceDef =
      q"""
    implicit def ${Term.Name("functorFor" + name.value)}[..$extraTParams]: _root_.cats.Functor[$typeLambdaVaryingEffect] =
      new _root_.cats.Functor[$typeLambdaVaryingEffect] {
        def map[T, TTarget](delegatee_ : $name[..${tArgs("T")}])(mapFunction: T => TTarget): $name[..${tArgs("TTarget")}] =
          new ${Ctor.Ref.Name(name.value)}[..${tArgs("TTarget")}] {
            ..${autoFlatMap.mapMethods(templ, effectTypeName)}
          }
      }"""

    cls.copy(companion = cls.companion.addStats(Seq(instanceDef)))
  }
} 
Example 32
Source File: SetProperty.scala    From scio   with Apache License 2.0 5 votes vote down vote up
package com.spotify.scio.bigquery.validation

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

// This shouldn't be necessary in most production use cases. However passing System properties from
// Intellij can cause issues. The ideal place to set this system property is in your build.sbt file.
private[validation] object SetProperty {
  @compileTimeOnly(
    "enable macro paradise (2.12) or -Ymacro-annotations (2.13) to expand macro annotations"
  )
  class setProperty extends StaticAnnotation {
    def macroTransform(annottees: Any*): Any = macro setPropertyImpl
  }

  def setSystemProperty(): String =
    System.setProperty(
      "override.type.provider",
      "com.spotify.scio.bigquery.validation.SampleOverrideTypeProvider"
    )

  def setPropertyImpl(c: blackbox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    setSystemProperty()
    annottees.head
  }
} 
Example 33
Source File: SysPropsMacros.scala    From scio   with Apache License 2.0 5 votes vote down vote up
package com.spotify.scio

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

@compileTimeOnly(
  "enable macro paradise (2.12) or -Ymacro-annotations (2.13) to expand macro annotations"
)
final class registerSysProps extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro registerSysPropsMacro.impl
}

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

    val traitT = tq"_root_.com.spotify.scio.SysProps"

    annottees.map(_.tree) match {
      case List(q"$mod object $name extends ..$parents { ..$body }") =>
        val vars = body.collect {
          case ValDef(_, _, _, rhs) => c.Expr(rhs)
        }

        val propertiesMethod =
          q"""override def properties: List[SysProp] = List(..$vars)"""

        c.Expr[Any](q"""
            $mod object $name extends ..$parents with $traitT {
              $propertiesMethod
              ..$body
            }
            """)
      case t => c.abort(c.enclosingPosition, s"Invalid annotation $t")
    }
  }
} 
Example 34
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 35
Source File: package.scala    From troy   with Apache License 2.0 5 votes vote down vote up
package troy

import com.datastax.driver.core._
import troy.macros._
import troy.schema.VersionedSchemaEngine

import scala.annotation.compileTimeOnly
import scala.concurrent.Future

package object dsl {

  // $COVERAGE-OFF$
  implicit class RichStringContext(val context: StringContext) extends AnyVal {
    @compileTimeOnly("cql Strings can be used only inside troy.dsl.withSchema block")
    def cql(args: Any*): MacroDSL.TroyCql = ???
  }

  trait WithSchema {
    def minVersion(v: VersionedSchemaEngine.Version) = new WithSchema {
      def maxVersion(v: VersionedSchemaEngine.Version) = withSchema
    }
    def apply[F](code: F): F = macro troyImpl[F]
  }
  // $COVERAGE-ON$
  object withSchema extends WithSchema

  implicit class MacroDsl_RichStatement(val statement: Statement) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureBoundStatement(val xxx: Future[Statement]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichResultSet(val xxx: ResultSet) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichFutureOfResultSet(val xxx: Future[ResultSet]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureOfSeqOfRow(val xxx: Future[Seq[Row]]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureOfOptionOfRow(val xxx: Future[Option[Row]]) extends ParsingOps {
    type ParseAs[R] = Future[Option[R]]
  }

  implicit class MacroDsl_RichSeqOfRow(val xxx: Seq[Row]) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichJavaListOfRow(val xxx: java.util.List[Row]) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichOptionOfRow(val xxx: Option[Row]) extends ParsingOps {
    type ParseAs[R] = Option[R]
  }
} 
Example 36
Source File: ParsingOps.scala    From troy   with Apache License 2.0 5 votes vote down vote up
package troy
package dsl

import scala.annotation.compileTimeOnly

trait ParsingOps {
  type ParseAs[R]
  // $COVERAGE-OFF$
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[R](mapper: () => R): ParseAs[R] = ???
  // (1 to 22).map(1 to _).map(_.map(i => s"T$i").mkString(", ")).map(tstr => s"def as[$tstr, R](mapper: ($tstr) => R): MacroDSL[M[R]]").foreach(println)
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, R](mapper: (T1) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, R](mapper: (T1, T2) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, R](mapper: (T1, T2, T3) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, R](mapper: (T1, T2, T3, T4) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, R](mapper: (T1, T2, T3, T4, T5) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, R](mapper: (T1, T2, T3, T4, T5, T6) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, R](mapper: (T1, T2, T3, T4, T5, T6, T7) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R): ParseAs[R] = ???
  // $COVERAGE-ON$
} 
Example 37
Source File: package.scala    From troy   with Apache License 2.0 5 votes vote down vote up
package troy

import com.datastax.driver.core.{ Row, ResultSet, Statement }

import scala.annotation.compileTimeOnly
import scala.concurrent.Future

package object meta {
  implicit class RichStringContext(val context: StringContext) extends AnyVal {
    @compileTimeOnly("cql Strings can be used only inside troy.dsl.withSchema block")
    def cql(args: Any*): MacroDSL.TroyCql = ???
  }

  implicit class MacroDsl_RichStatement(val statement: Statement) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureBoundStatement(val xxx: Future[Statement]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichResultSet(val xxx: ResultSet) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichFutureOfResultSet(val xxx: Future[ResultSet]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureOfSeqOfRow(val xxx: Future[Seq[Row]]) extends ParsingOps {
    type ParseAs[R] = Future[Seq[R]]
  }

  implicit class MacroDsl_RichFutureOfOptionOfRow(val xxx: Future[Option[Row]]) extends ParsingOps {
    type ParseAs[R] = Future[Option[R]]
  }

  implicit class MacroDsl_RichSeqOfRow(val xxx: Seq[Row]) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichJavaListOfRow(val xxx: java.util.List[Row]) extends ParsingOps {
    type ParseAs[R] = Seq[R]
  }

  implicit class MacroDsl_RichOptionOfRow(val xxx: Option[Row]) extends ParsingOps {
    type ParseAs[R] = Option[R]
  }
} 
Example 38
Source File: ParsingOps.scala    From troy   with Apache License 2.0 5 votes vote down vote up
package troy
package meta

import scala.annotation.compileTimeOnly

trait ParsingOps {
  type ParseAs[R]

  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[R](mapper: () => R): ParseAs[R] = ???
  // (1 to 22).map(1 to _).map(_.map(i => s"T$i").mkString(", ")).map(tstr => s"def as[$tstr, R](mapper: ($tstr) => R): MacroDSL[M[R]]").foreach(println)
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, R](mapper: (T1) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, R](mapper: (T1, T2) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, R](mapper: (T1, T2, T3) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, R](mapper: (T1, T2, T3, T4) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, R](mapper: (T1, T2, T3, T4, T5) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, R](mapper: (T1, T2, T3, T4, T5, T6) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, R](mapper: (T1, T2, T3, T4, T5, T6, T7) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R): ParseAs[R] = ???
  @compileTimeOnly("as can be called only inside troy.dsl.withSchema block")
  def as[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](mapper: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R): ParseAs[R] = ???
} 
Example 39
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 40
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 41
Source File: autoApply.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoApply")
class autoApply extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoApplyMacros.applyInst
}


private[tagless] class autoApplyMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateApplyFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("applyFor" + algebraName),
      typeParams,
      tq"_root_.cats.Apply[$algebraType]",
      q"_root_.cats.tagless.Derive.apply[$algebraType]"
    )

  def applyInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateApplyFor(algebra.name)) :: Nil
    }
} 
Example 42
Source File: autoApplyK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoApplyK")
class autoApplyK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoApplyKMacros.newDef
}

private [tagless] class autoApplyKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator {
  import c.universe._

  private def generateApplyKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("applyKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.ApplyK[$algebraType]",
      q"_root_.cats.tagless.Derive.applyK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateApplyKFor(algebra.name))

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: autoDerivationDef(algebra) :: Nil)
} 
Example 43
Source File: BerekeningReferentie.scala    From rule-engine   with MIT License 5 votes vote down vote up
package nl.rabobank.oss.rules.dsl.nl.grammar.meta

import scala.annotation.compileTimeOnly
import scala.meta._

//scalastyle:off


  def extractLijstBerekeningTParams(ctorcalls: Seq[Ctor.Call]): Option[(String, String)] = {
    ctorcalls.collect {
      case q"$expr(..$aexprssnel)" => {
        println(s"Matched constructor application for ${expr.syntax}")
        expr match {
          case ctor"$ctorref[..$atpesnel]" => (ctorref.syntax, atpesnel.head.syntax, atpesnel.last.syntax)
          case ctor"${ctorname: Ctor.Name}" => {
            // Crap, we couldn't match against explicitly defined type parameters, we'll have to deduce them from the first two expressions.
            // The required functionality is on the roadmap of Scala Meta, so perhaps with some new release in the future.

            (ctorname.syntax, "Any", "Any")
          }
        }
      }
    }
    .find( x => x._1 == "ElementBerekening" )
    .map( x => (x._2, x._3) )
  }
} 
Example 44
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 45
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 46
Source File: reifyInvocations.scala    From liberator   with MIT License 5 votes vote down vote up
package io.aecor.liberator.macros

import scala.annotation.compileTimeOnly
import scala.collection.immutable.Seq
import scala.meta._
import Common._

@compileTimeOnly("Cannot expand @reifyInvocations")
class reifyInvocations extends scala.annotation.StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    Common.parseTraitAndCompanion(defn) match {
      case Some((t, c)) =>
        ReifiedInvocationsMacro(t, c)
      case None =>
        defn
    }
  }
}

object ReifiedInvocationsMacro {

  def apply(base: Defn.Trait, companion: Defn.Object): Term.Block = {
    val t = Common.Trait.fromDefn(base)

    val unifiedInvocation = t"({type X[A] = _root_.io.aecor.liberator.Invocation[${t.unified}, A]})#X"

    val generatedStats: Seq[Stat] = Seq(
      q"""
        implicit def aecorLiberatorReifiedInvocations[..${t.params}]: _root_.io.aecor.liberator.ReifiedInvocations[${t.unified}] =
          new _root_.io.aecor.liberator.ReifiedInvocations[${t.unified}] {
            final def mapK[F[_], G[_]](mf: ${t.name}[..${t.paramTypes}, F], fg: _root_.cats.arrow.FunctionK[F, G]): ${t.name}[..${t.paramTypes}, G] =
               new ${Ctor.Name(t.name.value)}[..${t.paramTypes}, G] {
                 ..${
                   t.methods.map {
                     case Method(name, tps, params, out) =>
                       if (params.nonEmpty)
                         q"final def $name[..$tps](..$params): G[$out] = fg(mf.$name(..${params.map(_.name.value).map(Term.Name(_))}))"
                       else
                         q"final def $name[..$tps]: G[$out] = fg(mf.$name)"
                   }
                 }
               }

            final val invocations: ${t.name}[..${t.paramTypes}, $unifiedInvocation] = new ${Ctor.Name(t.name.value)}[..${t.paramTypes}, $unifiedInvocation] {
              ..${
                t.methods.map {
                  case Method(name, tps, params, out) =>
                    if (params.nonEmpty)
                      q"""final def $name[..$tps](..$params): _root_.io.aecor.liberator.Invocation[${t.unified}, $out] =
                         new _root_.io.aecor.liberator.Invocation[${t.unified}, $out] {
                           final def invoke[F[_]](mf: ${t.name}[..${t.paramTypes}, F]): F[$out] =
                             mf.$name(..${params.map(_.name.value).map(Term.Name(_))})
                         }
                       """
                    else
                      q"""final def $name[..$tps]: _root_.io.aecor.liberator.Invocation[${t.unified}, $out] =
                         new _root_.io.aecor.liberator.Invocation[${t.unified}, $out] {
                           final def invoke[F[_]](mf: ${t.name}[..${t.paramTypes}, F]): F[$out] =
                             mf.$name
                         }
                       """
                }
              }
            }

          }
    """
    )

    val newCompanion = {
      val currentStats = companion.templ.stats.getOrElse(Nil)
      companion.copy(templ = companion.templ.copy(stats = Some(currentStats ++ generatedStats)))
    }

    Term.Block(Seq(base, newCompanion))
  }
} 
Example 47
Source File: annotations.scala    From freestyle   with Apache License 2.0 5 votes vote down vote up
package freestyle
package free

import scala.annotation.{compileTimeOnly, StaticAnnotation}
import freestyle.free.internal.{freeImpl, moduleImpl}

@compileTimeOnly("enable macro paradise to expand @free macro annotations")
class free extends StaticAnnotation {
  import scala.meta._

  inline def apply(defn: Any): Any = meta { freeImpl.free(defn) }
}

@compileTimeOnly("enable macro paradise to expand @module macro annotations")
class module extends StaticAnnotation {
  import scala.meta._

  inline def apply(defn: Any): Any = meta { moduleImpl.module(defn) }
}

class debug extends StaticAnnotation 
Example 48
Source File: annotations.scala    From freestyle   with Apache License 2.0 5 votes vote down vote up
package freestyle
package tagless

import freestyle.tagless.internal._

import scala.meta._
import scala.annotation.{StaticAnnotation, compileTimeOnly}

@compileTimeOnly("enable macro paradise to expand @tagless macro annotations")
class tagless(val stacksafe: Boolean) extends StaticAnnotation {
  import scala.meta._

  inline def apply(defn: Any): Any = meta {
    val stacksafe: Boolean = this match {
      case q"new $_(${Lit.Boolean(ss)})" => ss
      case q"new $_(stacksafe = ${Lit.Boolean(ss)})" => ss
      case _ => false
    }
    taglessImpl.tagless(defn, stacksafe)
  }
}

@compileTimeOnly("enable macro paradise to expand @module macro annotations")
class module extends StaticAnnotation {
  import scala.meta._

  inline def apply(defn: Any): Any = meta { moduleImpl.module(defn) }
} 
Example 49
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 50
Source File: autoProductNK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoProductK")
class autoProductNK extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoProductNKMacros.productKInst
}

private [tagless] class autoProductNKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  def productMethod(typedef: TypeDefinition)(arity: Int): Tree = {
    def af(n: Int) = TermName("af" + n)

    val name = typedef.ident
    val range = 1 to arity

    // tparam"F1[_], F2[_], F3[_]"
    val effectTypeParams: List[TypeDef] =
      range.map(n => createTypeParam("F" + n, 1)).toList
    val effectTypeParamsNames = tArgs(effectTypeParams)

    //Tuple3K
    val productTypeName = tq"_root_.cats.tagless.${TypeName("Tuple" + arity + "K")}"

    val methods = typedef.impl.body.map {
      case q"def $method[..$typeParams](...$paramLists): ${_}[$resultType]" =>
        val returnItems = range.map(n => q"${af(n)}.$method(...${argumentLists(paramLists)})")
        q"""def $method[..$typeParams](...$paramLists): $productTypeName[..$effectTypeParamsNames]#λ[$resultType] =
           (..$returnItems)
        """

      case statement =>
        abort(s"autoProductK does not support algebra with such statement: $statement")
    }

    //af1: A[F1], af2: A[F2], af3: A[F3]
    val inboundInterpreters: Seq[ValDef] =
      (range zip effectTypeParamsNames).map {
        case (idx, fx) =>
          ValDef(
            Modifiers(Flag.PARAM),
            af(idx),
            typedef.applied(fx),
            EmptyTree
          )
      }

    q"""
        def ${TermName("product" + arity + "K")}[..$effectTypeParams](..$inboundInterpreters): $name[$productTypeName[..$effectTypeParamsNames]#λ] =
          new $name[$productTypeName[..$effectTypeParamsNames]#λ] {
            ..$methods
          }
      """

  }

  def productKInst(annottees: c.Tree*): c.Tree =
    enrich(annottees.toList) { td =>
      val productMethods = (3 to 9).map(productMethod(td))
      Seq(td.defn, addStats(td.companion, productMethods))
    }
} 
Example 51
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 52
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 53
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 54
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 55
Source File: valueclass.scala    From dilate   with Apache License 2.0 5 votes vote down vote up
package com.vitorsvieira.dilate

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._
import scala.util.Try

@compileTimeOnly("@valueclass macro expands only in compile time.")
final class valueclass extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq([email protected](_, name, _, ctor, _), companion: Defn.Object)) =>
        val result = Dilate.valueclassApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val templateStats: Option[Seq[Stat]] = Try(
          result.template.valueclasses ++:
            result.template.implicitDefs ++:
            companion.templ.stats.getOrElse(Nil)
        ).toOption
        val newCompanion: Defn.Object = companion.copy(templ = companion.templ.copy(stats = templateStats))

        Term.Block(Seq(newClass, newCompanion))
      case [email protected](_, name, _, ctor, _)                                          =>
        val result: ExtractionResult = Dilate.valueclassApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val newCompanion: Defn.Object =
          q"""object ${Term.Name(name.value)} {
            ..${result.template.valueclasses}
            ..${result.template.implicitDefs}
          }"""

        Term.Block(Seq(newClass, newCompanion))
      case _ =>
        println(defn.structure)
        abort("@valueclass must annotate a class.")
    }
  }
} 
Example 56
Source File: newtype.scala    From dilate   with Apache License 2.0 5 votes vote down vote up
package com.vitorsvieira.dilate

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.meta._
import scala.util.Try

@compileTimeOnly("@newtype macro expands only in compile time.")
final class newtype extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case Term.Block(Seq([email protected](_, name, _, ctor, _), companion: Defn.Object)) =>
        val result = Dilate.newtypeApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val templateStats: Option[Seq[Stat]] = Try(
          result.template.traits ++:
            result.template.types ++:
            result.template.implicitClasses ++:
            companion.templ.stats.getOrElse(Nil)
        ).toOption
        val newCompanion: Defn.Object = companion.copy(templ = companion.templ.copy(stats = templateStats))

        Term.Block(Seq(newClass, newCompanion))
      case [email protected](_, name, _, ctor, _) =>
        val result: ExtractionResult = Dilate.newtypeApply(name, ctor.paramss)
        val newClass: Defn.Class = cls.copy(
          ctor = Ctor.Primary.apply(ctor.mods, ctor.name, result.domain.finalArgs)
        )

        val newCompanion: Defn.Object =
          q"""object ${Term.Name(name.value)} {
            ..${result.template.traits}
            ..${result.template.types}
            ..${result.template.implicitClasses}
          }"""

        Term.Block(Seq(newClass, newCompanion))
      case _ =>
        println(defn.structure)
        abort("@newtype must annotate a class.")
    }
  }
} 
Example 57
Source File: Macros.scala    From scarango   with MIT License 5 votes vote down vote up
package com.outr.arango

import scala.annotation.compileTimeOnly
import scala.reflect.macros.blackbox

@compileTimeOnly("Enable macro paradise to expand compile-time macros")
object Macros {
  def serializationAuto[D](c: blackbox.Context)
                          (implicit d: c.WeakTypeTag[D]): c.Expr[Serialization[D]] = {
    import c.universe._

    c.Expr[Serialization[D]](
      q"""
         import _root_.com.outr.arango._
         import _root_.profig._
         import _root_.io.circe.Json

         Serialization[$d](
           doc2Json = (d: $d) => JsonUtil.toJson[$d](d),
           json2Doc = (j: Json) => JsonUtil.fromJson[$d](j)
         )
       """)
  }
} 
Example 58
Source File: GraphMacros.scala    From scarango   with MIT License 5 votes vote down vote up
package com.outr.arango

import scala.annotation.compileTimeOnly
import scala.reflect.macros.blackbox

@compileTimeOnly("Enable macro paradise to expand compile-time macros")
object GraphMacros {
  def store[T](c: blackbox.Context)
              (key: c.Expr[String])
              (implicit t: c.WeakTypeTag[T]): c.Expr[DatabaseStore[T]] = {
    import c.universe._

    val graph = c.prefix
    val tree =
      q"""
         DatabaseStore[$t]($key, $graph, Serialization.auto[$t])
       """
    c.Expr[DatabaseStore[T]](tree)
  }

  def queryBuilderAs[D](c: blackbox.Context)(implicit d: c.WeakTypeTag[D]): c.Expr[QueryBuilder[D]] = {
    import c.universe._

    val builder = c.prefix
    if (d.tpe <:< typeOf[Document[_]] && d.tpe.companion <:< typeOf[DocumentModel[_]]) {
      c.Expr[QueryBuilder[D]](q"$builder.as[$d](${d.tpe.typeSymbol.companion}.serialization)")
    } else {
      c.Expr[QueryBuilder[D]](q"$builder.as[$d](_root_.com.outr.arango.Serialization.auto[$d])")
    }
  }

  def vertex[D <: Document[D]](c: blackbox.Context)
                              (implicit d: c.WeakTypeTag[D]): c.Expr[Collection[D]] = {
    import c.universe._

    val graph = c.prefix
    val companion = d.tpe.typeSymbol.companion
    c.Expr[Collection[D]](
      q"""
         import com.outr.arango._

         new Collection[$d]($graph, $companion, CollectionType.Document, $companion.indexes, None)
       """)
  }

  def edge[D <: Document[D]](c: blackbox.Context)
                            (implicit d: c.WeakTypeTag[D]): c.Expr[Collection[D]] = {
    import c.universe._

    val graph = c.prefix
    val companion = d.tpe.typeSymbol.companion
    c.Expr[Collection[D]](
      q"""
         import com.outr.arango._

         new Collection[$d]($graph, $companion, CollectionType.Edge, $companion.indexes, None)
       """)
  }
} 
Example 59
Source File: autoInvariant.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInvariant")
class autoInvariant extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInvariantMacros.invariantInst
}

private[tagless] class autoInvariantMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateInvariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("invariantFor" + algebraName),
      typeParams,
      tq"_root_.cats.Invariant[$algebraType]",
      q"_root_.cats.tagless.Derive.invariant[$algebraType]"
    )

  def invariantInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateInvariantFor(algebra.name)) :: Nil
    }
} 
Example 60
Source File: finalAlg.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import Util._

import scala.meta._
import collection.immutable.Seq

@compileTimeOnly("Cannot expand @finalAlg")
class finalAlg extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {

    def enrich(ad: AlgDefn): TypeDefinition = {
      import ad._
      import cls._

     cls.copy(
        companion = companion.addStats( Seq[Stat](
          q"def apply[..${cls.tparams}](implicit inst: $name[..${tArgs()}]): $name[..${tArgs()}] = inst"
        ))
      )
    }
    enrichAlgebra(defn, false)(enrich)
  }
} 
Example 61
Source File: autoSemigroupalK.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.meta._
import autoSemigroupalK._
import Util._

import collection.immutable.Seq


@compileTimeOnly("Cannot expand @autoSemigroupalK")
class autoSemigroupalK extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    enrich(defn)(semigroupalKInst)
  }
}

object autoSemigroupalK {
  private[mainecoon] def semigroupalKInst(cls: TypeDefinition): TypeDefinition = {
    import cls._

    val instanceDef = Seq(q"""
      implicit def ${Term.Name("semigroupalKFor" + name.value)}: _root_.mainecoon.SemigroupalK[$name] =
        new _root_.mainecoon.SemigroupalK[$name] {
          ${semigroupalKMethods(cls)}
        }""")

    cls.copy(companion = cls.companion.addStats(instanceDef))
  }

  private[mainecoon] def semigroupalKMethods(cls: TypeDefinition): Defn = {
    import cls._

    val methods = templ.stats.map(_.map {
      case q"def $methodName[..$mTParams](..$params): $f[$resultType]" =>

        q"""def $methodName[..$mTParams](..$params): _root_.cats.data.Tuple2K[F, G, $resultType] =
           _root_.cats.data.Tuple2K(af.$methodName(..${arguments(params)}), ag.$methodName(..${arguments(params)}))"""
      case q"def $methodName[..$mTParams](..$params)(..$params2): $f[$resultType]" =>

        q"""def $methodName[..$mTParams](..$params)(..$params2): _root_.cats.data.Tuple2K[F, G, $resultType] =
           _root_.cats.data.Tuple2K(af.$methodName(..${arguments(params)})(..${arguments(params2)}), ag.$methodName(..${arguments(params)})(..${arguments(params2)}))"""
      case st => abort(s"autoSemigroupalK does not support algebra with such statement: $st")
    }).getOrElse(Nil)

    q"""
      def productK[F[_], G[_]](af: $name[F], ag: $name[G]): $name[({type λ[A]=_root_.cats.data.Tuple2K[F, G, A]})#λ] =
        new ${Ctor.Ref.Name(name.value)}[({type λ[A]=_root_.cats.data.Tuple2K[F, G, A]})#λ] {
          ..$methods
        }
    """


  }
} 
Example 62
Source File: autoProductNK.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.meta._
import autoProductNK._
import Util._

import collection.immutable.Seq


@compileTimeOnly("Cannot expand @autoProductK")
class autoProductNK extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    enrich(defn)(productKInst)
  }
}

object autoProductNK {
  private[mainecoon] def productKInst(cls: TypeDefinition): TypeDefinition = {
    import cls._

    def productMethod(arity: Int): Stat = {
      val range = (1 to arity).map(_.toString)

      // "F1, F2, F3"
      val effectTypeParamsNames = range.map(n => Type.Name("F" + n))

      //Tuple3K
      val productTypeName = Type.Name(s"_root_.mainecoon.Tuple${arity}K")

      val methods = templ.stats.map(_.map {
        case q"def $methodName[..$mTParams](..$params): $f[$resultType]" =>
          val returnItems = range.map { n =>
            q"${Term.Name("af" + n)}.$methodName(..${arguments(params)})"
          }
          q"""def $methodName[..$mTParams](..$params): $productTypeName[..$effectTypeParamsNames]#λ[$resultType] =
           (..$returnItems)"""
        //curried version
        case q"def $methodName[..$mTParams](..$params)(..$params2): $f[$resultType]" =>
          val returnItems = range.map { n =>
            q"${Term.Name("af" + n)}.$methodName(..${arguments(params)})(..${arguments(params2)})"
          }
          q"""def $methodName[..$mTParams](..$params)(..$params2): $productTypeName[..$effectTypeParamsNames]#λ[$resultType] =
           (..$returnItems)"""
        case st => abort(s"autoProductK does not support algebra with such statement: $st")
      }).getOrElse(Nil)

      // tparam"F1[_], F2[_], F3[_]"
      val effectTypeParams: Seq[Type.Param] = range.map(n => typeParam(s"F$n", 1))

      // param"af1: A[F1]"
      def inboundInterpreter(idx: String): Term.Param =
        Term.Param(Nil, Term.Name("af" + idx), Some(Type.Name(s"${name.value}[F"+idx + "]")), None)

      //af1: A[F1], af2: A[F2], af3: A[F3]
      val inboundInterpreters: Seq[Term.Param] = range.map(inboundInterpreter)

      q"""
        def ${Term.Name("product" + arity + "K")}[..$effectTypeParams](..$inboundInterpreters): $name[$productTypeName[..$effectTypeParamsNames]#λ] =
          new ${Ctor.Ref.Name(name.value)}[$productTypeName[..$effectTypeParamsNames]#λ] {
            ..$methods
          }
      """

    }

    val instanceDef = (3 to 9).map(productMethod)

    cls.copy(companion = cls.companion.addStats(instanceDef))
  }
} 
Example 63
Source File: autoApplyK.scala    From mainecoon   with Apache License 2.0 5 votes vote down vote up
package mainecoon

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.meta._
import Util._

import collection.immutable.Seq


@compileTimeOnly("Cannot expand @autoApplyK")
class autoApplyK(autoDerivation: Boolean) extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    val autoDerivation: Boolean = this match {
      case q"new $_(${Lit.Boolean(arg)})" => arg
      case q"new $_(autoDerivation = ${Lit.Boolean(arg)})" => arg
      case _  => true
    }
    enrichAlgebra(defn)(a => new ApplyKInstanceGenerator(a, autoDerivation).newDef)
  }
}


class ApplyKInstanceGenerator(algDefn: AlgDefn, autoDerivation: Boolean) extends CovariantKMethodsGenerator(algDefn) {
  import algDefn._
  import cls._
  lazy val instanceDef: Seq[Defn] = {
    Seq(
      companionMapKDef,
      q"""
        implicit def ${Term.Name("applyKFor" + name.value)}[..$extraTParams]: _root_.mainecoon.ApplyK[$typeLambdaVaryingHigherKindedEffect] =
          new _root_.mainecoon.ApplyK[$typeLambdaVaryingHigherKindedEffect] {
            $instanceMapKDef
            ${autoSemigroupalK.semigroupalKMethods(cls)}
          }
      """
    )
  }


  lazy val newDef: TypeDefinition = cls.copy(companion = cls.companion.addStats(instanceDef ++  {
    if(autoDerivation)
      Seq(autoDerivationDef)
    else Nil}))
} 
Example 64
Source File: ReaderBuilder.scala    From tethys   with Apache License 2.0 5 votes vote down vote up
package tethys.derivation.builder

import tethys.JsonReader

import scala.annotation.compileTimeOnly

sealed trait ReaderBuilder[A] {
  def extract[B](field: (A) => B): DependentFieldAs[A, B]
  def extractReader[B](field: (A) => B): DependentField0[A, JsonReader[_ <: B]]

  def fieldStyle(style: FieldStyle): ReaderBuilder[A]
  def strict: ReaderBuilder[A]
}

object ReaderBuilder {
  @compileTimeOnly("ReaderBuilder should be defined in describe block")
  def apply[A]: ReaderBuilder[A] = throw new NotDescribedException

  sealed trait AsSyntax[A, B, C] {
    def apply(fun: B => C): ReaderBuilder[A]
  }
} 
Example 65
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 66
Source File: autoInstrument.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInstrument")
class autoInstrument extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInstrumentMacros.instrumentInst
}

private[tagless] class autoInstrumentMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateInstrumentFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("instrumentFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.diagnosis.Instrument[$algebraType]",
      q"_root_.cats.tagless.Derive.instrument[$algebraType]"
    )

  def instrumentInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.FirstHigherKindedTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateInstrumentFor(algebra.name)) :: Nil
    }
} 
Example 67
Source File: autoBifunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoBifunctor")
class autoBifunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoBifunctorMacros.bifunctorInst
}

private[tagless] class autoBifunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateBifunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("bifunctorFor" + algebraName),
      typeParams,
      tq"_root_.cats.Bifunctor[$algebraType]",
      q"_root_.cats.tagless.Derive.bifunctor[$algebraType]"
    )

  def bifunctorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) {
      algebra =>
        algebra.forVaryingEffectType(generateBifunctorFor(algebra.name)) :: Nil
    }
} 
Example 68
Source File: autoProfunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoProfunctor")
class autoProfunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoProfunctorMacros.profunctorInst
}

private[tagless] class autoProfunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateProfunctorFor(
    algebraName: String
  )(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("profunctorFor" + algebraName),
      typeParams,
      tq"_root_.cats.arrow.Profunctor[$algebraType]",
      q"_root_.cats.tagless.Derive.profunctor[$algebraType]"
    )

  def profunctorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.TwoLastRegularTypeParams) {
      algebra =>
        algebra.forVaryingEffectType(generateProfunctorFor(algebra.name)) :: Nil
    }
} 
Example 69
Source File: TransactionMacros.scala    From scarango   with MIT License 5 votes vote down vote up
package com.outr.arango.transaction

import com.outr.arango.Graph

import scala.annotation.compileTimeOnly
import scala.concurrent.Future
import scala.reflect.macros.blackbox

@compileTimeOnly("Enable macro paradise to expand compile-time macros")
object TransactionMacros {
  def simple[G <: Graph, R](c: blackbox.Context)
                                (transaction: c.Expr[(G) => Future[R]])
                                (implicit g: c.WeakTypeTag[G]): c.Expr[Future[R]] = {
    import c.universe._

    c.Expr[Future[R]](
      q"""
        import com.outr.arango.transaction._
        import scribe.Execution.global


       """)

    ???
  }
} 
Example 70
Source File: autoFunctor.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctor")
class autoFunctor extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFunctorMacros.functorInst
}


private[tagless] class autoFunctorMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateFunctorFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("functorFor" + algebraName),
      typeParams,
      tq"_root_.cats.Functor[$algebraType]",
      q"_root_.cats.tagless.Derive.functor[$algebraType]"
    )

  def functorInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateFunctorFor(algebra.name)) :: Nil
    }
} 
Example 71
Source File: autoContravariantK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctorK")
class autoContravariantK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoContravariantKMacros.contravariantKInst
}

private [tagless] class autoContravariantKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateContravariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("contravariantKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.ContravariantK[$algebraType]",
      q"_root_.cats.tagless.Derive.contravariantK[$algebraType]"
    )

  def contravariantKInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList) { algebra =>
      algebra.forVaryingEffectType(generateContravariantKFor(algebra.name)) :: Nil
    }
} 
Example 72
Source File: autoFlatMap.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFlatMap")
class autoFlatMap extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFlatMapMacros.flatMapInst
}


private[tagless] class autoFlatMapMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateFlatMapFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("flatMapFor" + algebraName),
      typeParams,
      tq"_root_.cats.FlatMap[$algebraType]",
      q"_root_.cats.tagless.Derive.flatMap[$algebraType]"
    )

  def flatMapInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateFlatMapFor(algebra.name)) :: Nil
    }
} 
Example 73
Source File: autoSemigroupalK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoSemigroupalK")
class autoSemigroupalK extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoSemigroupalKMacros.semigroupalKInst
}

private[tagless] class autoSemigroupalKMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateSemigroupalKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("semigroupalKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.SemigroupalK[$algebraType]",
      q"_root_.cats.tagless.Derive.semigroupalK[$algebraType]"
    )

  def semigroupalKInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList) { algebra =>
      algebra.forVaryingEffectType(generateSemigroupalKFor(algebra.name)) :: Nil
    }
} 
Example 74
Source File: autoContravariant.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoContravariant")
class autoContravariant extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoContravariantMacros.contravariantInst
}

private[tagless] class autoContravariantMacros(override val c: whitebox.Context) extends MacroUtils  {
  import c.universe._

  private def generateContravariantFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("contravariantFor" + algebraName),
      typeParams,
      tq"_root_.cats.Contravariant[$algebraType]",
      q"_root_.cats.tagless.Derive.contravariant[$algebraType]"
    )

  def contravariantInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateContravariantFor(algebra.name)) :: Nil
    }
} 
Example 75
Source File: autoFunctorK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoFunctorK")
class autoFunctorK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoFunctorKMacros.newDef
}

private [tagless] class autoFunctorKMacros(override val c: whitebox.Context) extends MacroUtils with CovariantKMethodsGenerator {
  import c.universe._

  private def generateFunctorKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("functorKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.FunctorK[$algebraType]",
      q"_root_.cats.tagless.Derive.functorK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateFunctorKFor(algebra.name))

  def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = {
    algDefn.forVaryingEffectTypeFullyRefined {
      (algebraType, tparams) =>
        val impl = Seq(
          generateFunctorKFor("FullyRefined" + algDefn.name)(
            algebraType,
            tparams
          ),
          generateAutoDerive(algDefn.fullyRefinedTypeSig)(
            algebraType,
            tparams
          )
        )
        q"object fullyRefined { ..$impl }"
    }
  }

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(
      algebra => instanceDef(algebra) :: companionMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil)
}

private [tagless] trait CovariantKMethodsGenerator { self: MacroUtils =>
  import c.universe._

  def companionMapKDef(algDefn: AlgDefn.UnaryAlg) = {
    val from = TermName("af")
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = algDefn.newTypeSig(F)
    val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from)

    algDefn.forVaryingEffectType((algebraType, tparams) => q"""
      def mapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}]): $fullyRefinedAlgebraG =
        _root_.cats.tagless.FunctorK[$algebraType].mapK($from)(fk).asInstanceOf[$fullyRefinedAlgebraG]
    """)
  }

  def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = {
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = newTypeSig(F)
    val algebraG = newTypeSig(G)

    q"""
      object autoDerive {
        @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter"))
        implicit def fromFunctorK[$F, $G, ..$tparams](
          implicit fk: _root_.cats.~>[..${tArgs(F, G)}],
          FK: _root_.cats.tagless.FunctorK[$algebraType],
          af: $algebraF)
          : $algebraG = FK.mapK(af)(fk)
      }"""
  }

  def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) =
    if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree

} 
Example 76
Source File: autoSemigroupal.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoSemigroupal")
class autoSemigroupal extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoSemigroupalMacros.semigroupalInst
}


private[tagless] class autoSemigroupalMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateSemigroupalFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("semigroupalFor" + algebraName),
      typeParams,
      tq"_root_.cats.Semigroupal[$algebraType]",
      q"_root_.cats.tagless.Derive.semigroupal[$algebraType]"
    )

  def semigroupalInst(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList, AlgebraResolver.LastRegularTypeParam) { algebra =>
      algebra.forVaryingEffectType(generateSemigroupalFor(algebra.name)) :: Nil
    }
} 
Example 77
Source File: autoInvariantK.scala    From cats-tagless   with Apache License 2.0 5 votes vote down vote up
package cats.tagless

import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.collection.immutable.Seq
import scala.reflect.macros.whitebox


@compileTimeOnly("Cannot expand @autoInvariantK")
class autoInvariantK(autoDerivation: Boolean = true) extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro autoInvariantKMacros.newDef
}

private [tagless] class autoInvariantKMacros(override val c: whitebox.Context) extends MacroUtils {
  import c.universe._

  private def generateInvariantKFor(algebraName: String)(algebraType: Tree, typeParams: Seq[TypeDef]) =
    typeClassInstance(
      TermName("invariantKFor" + algebraName),
      typeParams,
      tq"_root_.cats.tagless.InvariantK[$algebraType]",
      q"_root_.cats.tagless.Derive.invariantK[$algebraType]"
    )

  def instanceDef(algebra: AlgDefn.UnaryAlg): Tree =
    algebra.forVaryingEffectType(generateInvariantKFor(algebra.name))

  def instanceDefFullyRefined(algDefn: AlgDefn.UnaryAlg): Tree = {
    algDefn.forVaryingEffectTypeFullyRefined {
      (algebraType, tparams) =>
        val impl = Seq(
          generateInvariantKFor("FullyRefined" + algDefn.name)(
            algebraType,
            tparams
          ),
          generateAutoDerive(algDefn.fullyRefinedTypeSig)(
            algebraType,
            tparams
          )
        )
        q"object fullyRefined { ..$impl }"
    }
  }

  def companionIMapKDef(algDefn: AlgDefn.UnaryAlg) = {
    val from = TermName("af")
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = algDefn.newTypeSig(F)
    val fullyRefinedAlgebraG = algDefn.dependentRefinedTypeSig(G, from)

    algDefn.forVaryingEffectType((algebraType, tparams) => q"""
      def imapK[$F, $G, ..$tparams]($from: $algebraF)(fk: _root_.cats.~>[..${tArgs(F, G)}])(gk: _root_.cats.~>[..${tArgs(G, F)}]): $fullyRefinedAlgebraG =
        _root_.cats.tagless.InvariantK[$algebraType].imapK($from)(fk)(gk).asInstanceOf[$fullyRefinedAlgebraG]
    """)
  }

  def generateAutoDerive(newTypeSig: TypeDef => TypTree)(algebraType: Tree, tparams: Seq[TypeDef]) = {
    val F = createFreshTypeParam("F", 1)
    val G = createFreshTypeParam("G", 1)
    val algebraF = newTypeSig(F)
    val algebraG = newTypeSig(G)

    q"""
      object autoDerive {
        @SuppressWarnings(Array("org.wartremover.warts.ImplicitParameter"))
        implicit def fromFunctorK[$F, $G, ..$tparams](
          implicit af: $algebraF,
          IK: _root_.cats.tagless.InvariantK[$algebraType],
          fk: _root_.cats.~>[..${tArgs(F, G)}],
          gk: _root_.cats.~>[..${tArgs(G, F)}])
          : $algebraG = IK.imapK(af)(fk)(gk)
      }"""
  }

  def autoDerivationDef(algDefn: AlgDefn.UnaryAlg) =
    if(autoDerive) algDefn.forVaryingEffectType(generateAutoDerive(algDefn.newTypeSig)) else EmptyTree

  def newDef(annottees: c.Tree*): c.Tree =
    enrichAlgebra(annottees.toList)(algebra => instanceDef(algebra) :: companionIMapKDef(algebra) :: instanceDefFullyRefined(algebra) :: autoDerivationDef(algebra) :: Nil)
}