diff options
-rw-r--r-- | core/src/main/scala/magnolia.scala | 19 | ||||
-rw-r--r-- | examples/src/main/scala/cats.scala | 23 | ||||
-rw-r--r-- | examples/src/main/scala/eq.scala (renamed from examples/src/main/scala/example.scala) | 48 | ||||
-rw-r--r-- | tests/shared/src/main/scala/magnolia/cats.scala | 17 | ||||
-rw-r--r-- | tests/shared/src/main/scala/magnolia/main.scala | 17 |
5 files changed, 33 insertions, 91 deletions
diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala index 66d59d0..e2d1341 100644 --- a/core/src/main/scala/magnolia.scala +++ b/core/src/main/scala/magnolia.scala @@ -221,8 +221,8 @@ class Macros(val c: whitebox.Context) { val contraDerivationType = appliedType(contraDerivationTypeclass, List(typeConstructor)) val contraDerivation2Type = appliedType(contraDerivation2Typeclass, List(typeConstructor)) - def findDerivationImplicit[T <: DerivationImplicit](tpe: c.Type, cons: Tree => T): Try[DerivationImplicit] = - Try(cons(c.untypecheck(c.inferImplicitValue(tpe, false, false)))) + def findDerivationImplicit[T <: DerivationImplicit](derivationType: c.Type, wrap: Tree => T): Try[DerivationImplicit] = + Try(wrap(c.untypecheck(c.inferImplicitValue(derivationType, false, false)))) val derivationImplicit = findDerivationImplicit(coDerivationType, CovariantDerivationImplicit) @@ -258,17 +258,12 @@ class Macros(val c: whitebox.Context) { val searchType = appliedType(typeConstructor, genericType) Some(q"_root_.magnolia.Lazy[$searchType]($methodAsString)") } - } else { - directInferImplicit(genericType, typeConstructor, derivationImplicit) - } + } else directInferImplicit(genericType, typeConstructor, derivationImplicit) - if(currentStack.frames.isEmpty) recursionStack = Map() + if(currentStack.frames.isEmpty) recursionStack = ListMap() result.map { tree => - if(currentStack.frames.isEmpty) { - val res = c.untypecheck(removeLazy.transform(tree)) - res - } else tree + if(currentStack.frames.isEmpty) c.untypecheck(removeLazy.transform(tree)) else tree }.getOrElse { c.abort(c.enclosingPosition, "could not infer typeclass for type $genericType") } @@ -312,8 +307,8 @@ private[magnolia] object CompileTimeState { def termName(c: whitebox.Context): c.TermName = term.asInstanceOf[c.TermName] } - private[magnolia] var recursionStack: Map[api.Position, Stack] = - Map() + private[magnolia] var recursionStack: ListMap[api.Position, Stack] = + ListMap() private[magnolia] var emittedErrors: Set[ImplicitNotFound] = Set() } diff --git a/examples/src/main/scala/cats.scala b/examples/src/main/scala/cats.scala index 08690c2..8d33a0f 100644 --- a/examples/src/main/scala/cats.scala +++ b/examples/src/main/scala/cats.scala @@ -1,23 +1,22 @@ -package magnolia.examples.cats +package magnolia.examples import scala.collection.immutable.ListMap import scala.language.experimental.macros -import scala.language.higherKinds import cats.Show import magnolia.ContravariantDerivation import magnolia.Macros -object instances extends instances1 { +object catsShowDerivation { - implicit val showDerivation = 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: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") - } -} - -trait instances1 { + implicit val showDerivation: ContravariantDerivation[Show] = + 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: ListMap[String, String]): String = + xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") + } + implicit def genericShow[T]: Show[T] = macro Macros.magnolia[T, Show[_]] } diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/eq.scala index 6c289cb..30e7869 100644 --- a/examples/src/main/scala/example.scala +++ b/examples/src/main/scala/eq.scala @@ -3,26 +3,19 @@ package magnolia.examples import magnolia._ import language.experimental.macros -import language.higherKinds import collection.immutable.ListMap - object `package` { - implicit class Showable[T: Show](t: T) { - def show: String = implicitly[Show[T]].show(t) - } - implicit val showString: Show[String] = identity - implicit val showBool: Show[Boolean] = _.toString - implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") - implicit def showSet[T: Show]: Show[Set[T]] = s => "set" - implicit class Equable[T: Eq](t: T) { def isEqualTo(other: T): Boolean = implicitly[Eq[T]].isEqual(t, other) } + implicit val eqString: Eq[String] = _ == _ implicit val eqBool: Eq[Boolean] = _ == _ + implicit def eqList[T: Eq]: Eq[List[T]] = (l1, l2) => l1.size == l2.size && (l1 zip l2).forall { case (e1, e2) => e1 isEqualTo e2 } + implicit def eqSet[T: Eq]: Eq[Set[T]] = (s1, s2) => s1.size == s2.size && (s1 zip s2).forall { case (e1, e2) => e1 isEqualTo e2 } } @@ -37,46 +30,21 @@ case class Organization(name: String, contacts: Set[Person]) extends Entity case class Address(lines: List[String], country: Country) case class Country(name: String, code: String, salesTax: Boolean) -trait Show[T] { def show(t: T): String } -object Show extends Show_1 { - implicit val showInt: Show[Int] = _.toString - implicit val showString: Show[String] = identity - implicit val showBool: Show[Boolean] = _.toString - implicit def showList[T: Show]: Show[List[T]] = xs => xs.map { x => s"list:${implicitly[Show[T]].show(x)}" }.mkString(";") - implicit def showSet[T: Show]: Show[Set[T]] = s => "set" - - 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: ListMap[String, String]): String = xs.map { case (k, v) => s"$k=$v" }.mkString("{", ", ", "}") - } - - implicit class Showable[T: Show](t: T) { - def show: String = implicitly[Show[T]].show(t) - } -} - -trait Show_1 { - implicit def generic[T]: Show[T] = macro Macros.magnolia[T, Show[_]] -} - trait Eq[T] { def isEqual(a: T, b: T): Boolean } -object Eq extends Eq_1 { +object Eq { implicit val eqInt: Eq[Int] = _ == _ - implicit val derivation = new ContravariantDerivation2[Eq] { + implicit val derivation: ContravariantDerivation2[Eq] = new ContravariantDerivation2[Eq] { type Return = Boolean + def call[T](eq: Eq[T], value1: T, value2: T): Boolean = if(value1.getClass == value2.getClass) eq.isEqual(value1, value2) else false + def construct[T](body: (T, T) => Boolean): Eq[T] = body(_, _) def join(elements: ListMap[String, Boolean]): Boolean = elements.forall(_._2) } -} - -trait Eq_1 { + implicit def generic[T]: Eq[T] = macro Macros.magnolia[T, Eq[_]] } - diff --git a/tests/shared/src/main/scala/magnolia/cats.scala b/tests/shared/src/main/scala/magnolia/cats.scala deleted file mode 100644 index 4a1c096..0000000 --- a/tests/shared/src/main/scala/magnolia/cats.scala +++ /dev/null @@ -1,17 +0,0 @@ -package magnolia - -import examples.{Address, Branch, Country, Entity, Leaf, Person} -import cats.instances.all._ -import cats.syntax.all._ -import examples.cats.instances._ -import language.experimental.macros - -object CatsMain { - - def main(args: Array[String]): Unit = { - println(Branch(Branch(Leaf(1, "a"), Leaf(2, "b")), Leaf(3, "c")).show) - println(List[Entity](Person("John Smith", - Address(List("1 High Street", "London", "SW1A 1AA"), - Country("UK", "GBR", false)))).show) - } -} diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala index 4a9347a..c6cd9bc 100644 --- a/tests/shared/src/main/scala/magnolia/main.scala +++ b/tests/shared/src/main/scala/magnolia/main.scala @@ -1,24 +1,21 @@ package magnolia -import examples._ -import examples.Show._ +import examples.{Address, Branch, Country, Entity, Leaf, Person} +import cats.instances.all._ +import cats.syntax.all._ +import examples.catsShowDerivation._ +import language.experimental.macros object Main { - def main(args: Array[String]): Unit = { - val tree1: Tree = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)) - val tree2: Tree = Branch(Leaf(1), Leaf(2)) + def main(args: Array[String]): Unit = { + val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)) println(tree1.show) println(tree1 isEqualTo tree1) - println(tree1 isEqualTo tree2) - println(Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)).show) - println(List[Entity](Person("John Smith", Address(List("1 High Street", "London", "SW1A 1AA"), Country("UK", "GBR", false)))).show) - } } - |