diff options
-rw-r--r-- | core/src/main/scala/magnolia.scala | 32 | ||||
-rw-r--r-- | examples/src/main/scala/example.scala | 32 | ||||
-rw-r--r-- | tests/shared/src/main/scala/magnolia/main.scala | 12 |
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) } } |