aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/scala/magnolia.scala
diff options
context:
space:
mode:
authorJon Pretty <jon.pretty@propensive.com>2017-10-30 19:25:07 +0100
committerJon Pretty <jon.pretty@propensive.com>2017-10-30 19:25:07 +0100
commit7b776425828d27b3112ad5bddafaa7564c326536 (patch)
treebe041b460d9fced354fa6a7dabd03d7ced185d5a /core/src/main/scala/magnolia.scala
parent86c66ba93b5dc15301ac305fa28e24952e232613 (diff)
downloadmagnolia-7b776425828d27b3112ad5bddafaa7564c326536.tar.gz
magnolia-7b776425828d27b3112ad5bddafaa7564c326536.tar.bz2
magnolia-7b776425828d27b3112ad5bddafaa7564c326536.zip
Support for case objects
Diffstat (limited to 'core/src/main/scala/magnolia.scala')
-rw-r--r--core/src/main/scala/magnolia.scala26
1 files changed, 22 insertions, 4 deletions
diff --git a/core/src/main/scala/magnolia.scala b/core/src/main/scala/magnolia.scala
index c4c8113..ae582e4 100644
--- a/core/src/main/scala/magnolia.scala
+++ b/core/src/main/scala/magnolia.scala
@@ -24,6 +24,7 @@ trait JoinContext[Tc[_], T] {
def construct[R](param: ((Param[Tc, T]) => Any)): T
def typeName: String
def parameters: List[Param[Tc, T]]
+ def isObject: Boolean
}
object Magnolia {
@@ -34,7 +35,7 @@ object Magnolia {
def generic[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
import scala.util.{Try, Success, Failure}
-
+
def javaClassName(sym: Symbol): String =
if(sym.owner.isPackage) sym.fullName
else if(sym.owner.isModuleClass) s"${javaClassName(sym.owner)}$$${sym.name}"
@@ -85,7 +86,6 @@ object Magnolia {
genericType: Type,
typeConstructor: Type,
assignedName: TermName): Tree = {
-
val searchType = appliedType(typeConstructor, genericType)
findType(genericType).map { methodName =>
val methodAsString = methodName.encodedName.toString
@@ -123,6 +123,7 @@ object Magnolia {
val typeSymbol = genericType.typeSymbol
val classType = if(typeSymbol.isClass) Some(typeSymbol.asClass) else None
val isCaseClass = classType.map(_.isCaseClass).getOrElse(false)
+ val isCaseObject = classType.map(_.isModuleClass).getOrElse(false)
val isSealedTrait = classType.map(_.isSealed).getOrElse(false)
val isValueClass = genericType <:< typeOf[AnyVal]
@@ -130,7 +131,24 @@ object Magnolia {
// FIXME: Handle AnyVals
- if(isCaseClass) {
+ if(isCaseObject) {
+ val termSym = genericType.typeSymbol.companionSymbol
+ val obj = termSym.asTerm
+ val className = obj.name.toString
+ val impl = q"""
+ ${c.prefix}.join(new _root_.magnolia.JoinContext[$typeConstructor, $genericType] {
+ def construct[R](fn: ((Param[${typeConstructor}, $genericType]) => Any)): $genericType = $obj
+ def typeName: _root_.java.lang.String = $className
+ def parameters: _root_.scala.List[Param[$typeConstructor, $genericType]] = _root_.scala.List()
+ def isObject = true
+ })
+ """
+
+ Some(q"""
+ def $assignedName: $resultType = $impl
+ $assignedName
+ """)
+ } else if(isCaseClass) {
val caseClassParameters = genericType.decls.collect {
case m: MethodSymbol if m.isCaseAccessor => m.asMethod
}
@@ -172,6 +190,7 @@ object Magnolia {
def typeName: _root_.java.lang.String = $className
def parameters: _root_.scala.List[Param[$typeConstructor, $genericType]] =
_root_.scala.List(..$callables)
+ def isObject = false
})
"""
@@ -181,7 +200,6 @@ object Magnolia {
"""
}
} else if(isSealedTrait) {
-
val subtypes = classType.get.knownDirectSubclasses.to[List]
if(subtypes.isEmpty) {