From 6e702a5a5fb9f9d508e0a9ddbbbfc2cb64267971 Mon Sep 17 00:00:00 2001 From: Jon Pretty Date: Thu, 22 Jun 2017 18:47:32 +0200 Subject: Use case clauses and switch statement instead of is/asInstanceOf --- core/src/main/scala/magnolia.scala | 22 ++++++++++------------ examples/src/main/scala/example.scala | 4 +--- tests/shared/src/main/scala/magnolia/main.scala | 6 ++++-- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala index 27172d3..66d59d0 100644 --- a/core/src/main/scala/magnolia.scala +++ b/core/src/main/scala/magnolia.scala @@ -161,18 +161,6 @@ class Macros(val c: whitebox.Context) { val reduction = components.reduce { (left, right) => q"$impl.combine($left, $right)" } q"$impl.call($reduction, sourceParameter)" - case ContravariantDerivation1Implicit(impl) => - val parts = subtypes.tail.zip(components.tail) - val base = q""" - $impl.call(${components.head}, sourceParameter.asInstanceOf[${subtypes.head}]) - """ - parts.foldLeft(base) { case (aggregated, (componentType, derivedImplicit)) => - q""" - if(sourceParameter.isInstanceOf[$componentType]) - $impl.call($derivedImplicit, sourceParameter.asInstanceOf[$componentType]) - else $aggregated""" - } - case ContravariantDerivation2Implicit(impl) => val parts = subtypes.tail.zip(components.tail) val base = q""" @@ -184,6 +172,16 @@ class Macros(val c: whitebox.Context) { $impl.call($derivedImplicit, sourceParameter1.asInstanceOf[$componentType], sourceParameter2.asInstanceOf[$componentType]) else $aggregated""" } + case ContravariantDerivation1Implicit(impl) => + val parts = subtypes.zip(components) + + val caseClauses = parts.map { case (subtype, component) => + cq"(value: $subtype) => $impl.call($component, value)" + } + + q"""(sourceParameter: @_root_.scala.annotation.switch) match { + case ..$caseClauses + }""" } } } else None diff --git a/examples/src/main/scala/example.scala b/examples/src/main/scala/example.scala index c649fba..543fa3d 100644 --- a/examples/src/main/scala/example.scala +++ b/examples/src/main/scala/example.scala @@ -26,11 +26,9 @@ object `package` { (s1, s2) => s1.size == s2.size && (s1 zip s2).forall { case (e1, e2) => e1 isEqualTo e2 } } -sealed trait EmptyType - sealed trait Tree case class Branch(left: Tree, right: Tree) extends Tree -case class Leaf(value: Int, no: String) extends Tree +case class Leaf(value: Int) extends Tree sealed trait Entity case class Person(name: String, address: Address) extends Entity diff --git a/tests/shared/src/main/scala/magnolia/main.scala b/tests/shared/src/main/scala/magnolia/main.scala index 9449f8d..3ac3fb6 100644 --- a/tests/shared/src/main/scala/magnolia/main.scala +++ b/tests/shared/src/main/scala/magnolia/main.scala @@ -5,13 +5,15 @@ import examples._ object Main { def main(args: Array[String]): Unit = { - val tree1: Tree = Branch(Branch(Leaf(1, "abc"), Leaf(2, "def")), Leaf(3, "ghi")) - val tree2: Tree = Branch(Leaf(1, "abc"), Leaf(2, "def")) + val tree1: Tree = Branch(Branch(Leaf(1), Leaf(2)), Leaf(3)) + val tree2: Tree = Branch(Leaf(1), Leaf(2)) 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) -- cgit v1.2.3