aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Pretty <jon.pretty@propensive.com>2017-06-12 11:55:13 +0200
committerJon Pretty <jon.pretty@propensive.com>2017-06-12 11:55:13 +0200
commitec3f9d345e8a30e4e8c0b5885c718deb6cacb88c (patch)
tree9f92722e14df376b9bb42b6d2118ed80cc6fad52
parent1ea072197cf8a992b37d7efe0636358a236b9d6d (diff)
downloadmagnolia-ec3f9d345e8a30e4e8c0b5885c718deb6cacb88c.tar.gz
magnolia-ec3f9d345e8a30e4e8c0b5885c718deb6cacb88c.tar.bz2
magnolia-ec3f9d345e8a30e4e8c0b5885c718deb6cacb88c.zip
Fixes for substitution of Lazy values
-rw-r--r--core/src/main/scala/magnolia.scala32
-rw-r--r--examples/src/main/scala/example.scala32
-rw-r--r--tests/shared/src/main/scala/magnolia/main.scala12
3 files changed, 49 insertions, 27 deletions
diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala
index f3b7691..7342c67 100644
--- a/core/src/main/scala/magnolia.scala
+++ b/core/src/main/scala/magnolia.scala
@@ -11,10 +11,10 @@ class Macros(val c: whitebox.Context) {
import c.universe._
import CompileTimeState._
- private def findType(key: c.universe.Type): Option[c.TermName] =
+ private def findType(key: Type): Option[TermName] =
recursionStack(c.enclosingPosition).frames.find(_.genericType == key).map(_.termName(c))
- private def recurse[T](path: TypePath, key: c.universe.Type, value: c.TermName)(fn: => T):
+ private def recurse[T](path: TypePath, key: Type, value: TermName)(fn: => T):
Option[T] = {
recursionStack = recursionStack.updated(
c.enclosingPosition,
@@ -31,7 +31,7 @@ class Macros(val c: whitebox.Context) {
private val removeLazy: Transformer = new Transformer {
override def transform(tree: Tree): Tree = tree match {
- case q"magnolia.Lazy.apply[$returnType](${Literal(Constant(method: String))})" =>
+ case q"_root_.magnolia.Lazy.apply[$returnType](${Literal(Constant(method: String))})" =>
q"${TermName(method)}"
case _ =>
super.transform(tree)
@@ -39,15 +39,15 @@ class Macros(val c: whitebox.Context) {
}
private def getImplicit(paramName: Option[String],
- genericType: c.universe.Type,
- typeConstructor: c.universe.Type,
- assignedName: c.TermName,
- derivationImplicit: Either[c.Tree, c.Tree]): c.Tree = {
+ genericType: Type,
+ typeConstructor: Type,
+ assignedName: TermName,
+ derivationImplicit: Either[Tree, Tree]): Tree = {
findType(genericType).map { methodName =>
val methodAsString = methodName.encodedName.toString
val searchType = appliedType(typeConstructor, genericType)
- q"_root_.magnolia.Lazy[$searchType]($methodAsString)"
+ q"_root_.magnolia.Lazy.apply[$searchType]($methodAsString)"
}.orElse {
val searchType = appliedType(typeConstructor, genericType)
findType(genericType).map { _ =>
@@ -77,9 +77,9 @@ class Macros(val c: whitebox.Context) {
}
}
- private def directInferImplicit(genericType: c.universe.Type,
- typeConstructor: c.universe.Type,
- derivationImplicit: Either[c.Tree, c.Tree]): Option[c.Tree] = {
+ private def directInferImplicit(genericType: Type,
+ typeConstructor: Type,
+ derivationImplicit: Either[Tree, Tree]): Option[Tree] = {
val genericTypeName: String = genericType.typeSymbol.name.encodedName.toString.toLowerCase
val assignedName: TermName = TermName(c.freshName(s"${genericTypeName}Typeclass"))
@@ -160,8 +160,7 @@ class Macros(val c: whitebox.Context) {
}
}
- def magnolia[T: c.WeakTypeTag, Typeclass: c.WeakTypeTag]: c.Tree = try {
- import c.universe._
+ def magnolia[T: WeakTypeTag, Typeclass: WeakTypeTag]: Tree = try {
val genericType: Type = weakTypeOf[T]
val currentStack: List[Frame] = recursionStack.get(c.enclosingPosition).map(_.frames).getOrElse(List())
@@ -182,7 +181,7 @@ class Macros(val c: whitebox.Context) {
if(directlyReentrant) throw DirectlyReentrantException()
- val result: Option[c.Tree] = if(!recursionStack.isEmpty) {
+ val result: Option[Tree] = if(!recursionStack.isEmpty) {
findType(genericType) match {
case None =>
directInferImplicit(genericType, typeConstructor, derivationImplicit)
@@ -199,7 +198,10 @@ class Macros(val c: whitebox.Context) {
if(currentStack.isEmpty) recursionStack = Map()
result.map { tree =>
- if(currentStack.isEmpty) c.untypecheck(removeLazy.transform(tree)) else tree
+ if(currentStack.isEmpty) {
+ val res = c.untypecheck(removeLazy.transform(tree))
+ res
+ } else tree
}.getOrElse {
c.abort(c.enclosingPosition, "could not infer typeclass for type $genericType")
}
diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/example.scala
index c719ad8..5dd1f47 100644
--- a/examples/src/main/scala/example.scala
+++ b/examples/src/main/scala/example.scala
@@ -1,11 +1,13 @@
-package magnolia
+package magnolia.examples
+
+import magnolia._
import language.experimental.macros
import language.higherKinds
-case class Thing(str: String) {
+/*case class Thing(str: String) {
def access(path: String): Thing = Thing(s"$str.$path")
}
@@ -81,3 +83,29 @@ trait Serializer_1 extends Serializer_2 {
trait Serializer_2 {
implicit def generic[T]: Serializer[T] = macro Macros.magnolia[T, Serializer[_]]
}
+*/
+
+object `package` {
+ implicit class Showable[T: Show](t: T) {
+ def show: String = implicitly[Show[T]].show(t)
+ }
+}
+
+sealed trait Tree
+case class Branch(left: Tree, right: Tree) extends Tree
+case class Leaf(value: Int) extends Tree
+
+trait Show[T] { def show(t: T): String }
+object Show extends Show_1 {
+ implicit val showInt: Show[Int] = _.toString
+ implicit val derivation = new ContravariantDerivation[Show] {
+ type Return = String
+ def call[T](show: Show[T], value: T): String = show.show(value)
+ def construct[T](body: T => String): Show[T] = body(_)
+ def join(xs: List[String]): String = xs.mkString("(", ", ", ")")
+ }
+}
+
+trait Show_1 {
+ implicit def generic[T]: Show[T] = macro Macros.magnolia[T, Show[_]]
+}
diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala
index 889757c..362a0fe 100644
--- a/tests/shared/src/main/scala/magnolia/main.scala
+++ b/tests/shared/src/main/scala/magnolia/main.scala
@@ -1,18 +1,10 @@
package magnolia
-sealed trait Tree
-
-case class Branch(left: List[Twig]) extends Tree
-case class Leaf(node: List[String], right: List[Branch], left2: List[Branch], another: List[Leaf], broken: Double) extends Tree
-case class Twig(alpha: List[Twig], beta: List[Leaf], gamma: Double, delta: List[Tree]) extends Tree
+import examples._
object Main {
-
-
def main(args: Array[String]): Unit = {
-
- println(implicitly[Serializer[List[Tree]]].serialize(List(Branch(List(Twig(Nil, Nil, 43, Nil))))))
- println(implicitly[Extractor[List[Tree]]].extract(Thing("42")))
+ println(Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)).show)
}
}