aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Pretty <jon.pretty@propensive.com>2017-06-23 15:00:45 +0200
committerJon Pretty <jon.pretty@propensive.com>2017-06-23 15:00:45 +0200
commitf108a9e18bbe23f12ac86bdc2bf795995b3a424c (patch)
tree684189d3418398fa67590b3e7e7c8723b0a451a4
parenta8bab561a1e7f43783c3536a7a68e8a27f34084a (diff)
downloadmagnolia-f108a9e18bbe23f12ac86bdc2bf795995b3a424c.tar.gz
magnolia-f108a9e18bbe23f12ac86bdc2bf795995b3a424c.tar.bz2
magnolia-f108a9e18bbe23f12ac86bdc2bf795995b3a424c.zip
Include class name in `join` method
-rw-r--r--core/src/main/scala/magnolia.scala39
-rw-r--r--examples/src/main/scala/cats.scala4
-rw-r--r--examples/src/main/scala/eq.scala3
3 files changed, 31 insertions, 15 deletions
diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala
index e2d1341..2ed6bf3 100644
--- a/core/src/main/scala/magnolia.scala
+++ b/core/src/main/scala/magnolia.scala
@@ -11,14 +11,12 @@ class Macros(val c: whitebox.Context) {
import c.universe._
import CompileTimeState._
-
sealed trait DerivationImplicit { def tree: Tree }
case class CovariantDerivationImplicit(tree: Tree) extends DerivationImplicit
sealed trait ContravariantDerivationImplicit extends DerivationImplicit
case class ContravariantDerivation1Implicit(tree: Tree) extends ContravariantDerivationImplicit
case class ContravariantDerivation2Implicit(tree: Tree) extends ContravariantDerivationImplicit
-
private def findType(key: Type): Option[TermName] =
recursionStack(c.enclosingPosition).frames.find(_.genericType == key).map(_.termName(c))
@@ -98,6 +96,7 @@ class Macros(val c: whitebox.Context) {
val caseClassParameters = genericType.decls.collect {
case m: MethodSymbol if m.isCaseAccessor => m.asMethod
}
+ val className = genericType.toString
val implicits = caseClassParameters.map { param =>
val paramName = param.name.encodedName.toString
@@ -136,7 +135,10 @@ class Macros(val c: whitebox.Context) {
q"(${param.name.encodedName.toString}, $tree)"
}
- Some(q"${contra.tree}.join(_root_.scala.collection.immutable.ListMap(..$namedImplicits))")
+ Some(q"""${contra.tree}.join(
+ $className,
+ _root_.scala.collection.immutable.ListMap(..$namedImplicits)
+ )""")
}
} else if(isSealedTrait) {
@@ -164,12 +166,18 @@ class Macros(val c: whitebox.Context) {
case ContravariantDerivation2Implicit(impl) =>
val parts = subtypes.tail.zip(components.tail)
val base = q"""
- $impl.call(${components.head}, sourceParameter1.asInstanceOf[${subtypes.head}], sourceParameter2.asInstanceOf[${subtypes.head}])
+ $impl.call(
+ ${components.head},
+ sourceParameter1.asInstanceOf[${subtypes.head}],
+ sourceParameter2.asInstanceOf[${subtypes.head}]
+ )
"""
parts.foldLeft(base) { case (aggregated, (componentType, derivedImplicit)) =>
q"""
- if(sourceParameter1.isInstanceOf[$componentType] && sourceParameter2.isInstanceOf[$componentType])
- $impl.call($derivedImplicit, sourceParameter1.asInstanceOf[$componentType], sourceParameter2.asInstanceOf[$componentType])
+ if(sourceParameter1.isInstanceOf[$componentType] &&
+ sourceParameter2.isInstanceOf[$componentType])
+ $impl.call($derivedImplicit, sourceParameter1.asInstanceOf[$componentType],
+ sourceParameter2.asInstanceOf[$componentType])
else $aggregated"""
}
case ContravariantDerivation1Implicit(impl) =>
@@ -198,7 +206,9 @@ class Macros(val c: whitebox.Context) {
}"""
case ContravariantDerivation2Implicit(impl) =>
q"""{
- def $assignedName: $resultType = $impl.construct { case (sourceParameter1, sourceParameter2) => $const }
+ def $assignedName: $resultType = $impl.construct {
+ case (sourceParameter1, sourceParameter2) => $const
+ }
$assignedName
}"""
}
@@ -209,7 +219,10 @@ class Macros(val c: whitebox.Context) {
import scala.util.{Try, Success, Failure}
val genericType: Type = weakTypeOf[T]
- val currentStack: Stack = recursionStack.get(c.enclosingPosition).getOrElse(Stack(List(), List()))
+
+ val currentStack: Stack =
+ recursionStack.get(c.enclosingPosition).getOrElse(Stack(List(), List()))
+
val directlyReentrant = Some(genericType) == currentStack.frames.headOption.map(_.genericType)
val typeConstructor: Type = weakTypeOf[Typeclass].typeConstructor
@@ -221,13 +234,15 @@ class Macros(val c: whitebox.Context) {
val contraDerivationType = appliedType(contraDerivationTypeclass, List(typeConstructor))
val contraDerivation2Type = appliedType(contraDerivation2Typeclass, List(typeConstructor))
- def findDerivationImplicit[T <: DerivationImplicit](derivationType: c.Type, wrap: Tree => T): Try[DerivationImplicit] =
+ 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)
.orElse(findDerivationImplicit(contraDerivationType, ContravariantDerivation1Implicit))
- .orElse(findDerivationImplicit(contraDerivation2Type, ContravariantDerivation2Implicit)) match {
+ .orElse(findDerivationImplicit(contraDerivation2Type,
+ ContravariantDerivation2Implicit)) match {
case Failure(e) =>
c.info(c.enclosingPosition, s"could not find an implicit instance of "+
s"CovariantDerivation[$typeConstructor] or "+
@@ -327,13 +342,13 @@ trait ContravariantDerivation[Typeclass[_]] {
type Return
def call[T](typeclass: Typeclass[T], value: T): Return
def construct[T](body: T => Return): Typeclass[T]
- def join(elements: ListMap[String, Return]): Return
+ def join(name: String, elements: ListMap[String, Return]): Return
}
trait ContravariantDerivation2[Typeclass[_]] {
type Return
def call[T](typeclass: Typeclass[T], value1: T, value2: T): Return
def construct[T](body: (T, T) => Return): Typeclass[T]
- def join(elements: ListMap[String, Return]): Return
+ def join(name: String, elements: ListMap[String, Return]): Return
}
diff --git a/examples/src/main/scala/cats.scala b/examples/src/main/scala/cats.scala
index 8d33a0f..e881bca 100644
--- a/examples/src/main/scala/cats.scala
+++ b/examples/src/main/scala/cats.scala
@@ -14,8 +14,8 @@ object catsShowDerivation {
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("{", ", ", "}")
+ def join(name: String, xs: ListMap[String, String]): String =
+ xs.map { case (k, v) => s"$k=$v" }.mkString(s"$name(", ", ", ")")
}
implicit def genericShow[T]: Show[T] = macro Macros.magnolia[T, Show[_]]
diff --git a/examples/src/main/scala/eq.scala b/examples/src/main/scala/eq.scala
index 30e7869..1f4168e 100644
--- a/examples/src/main/scala/eq.scala
+++ b/examples/src/main/scala/eq.scala
@@ -43,7 +43,8 @@ object Eq {
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)
+ def join(className: String, elements: ListMap[String, Boolean]): Boolean =
+ elements.forall(_._2)
}
implicit def generic[T]: Eq[T] = macro Macros.magnolia[T, Eq[_]]