diff options
-rw-r--r-- | core/shared/src/main/scala/interface.scala | 11 | ||||
-rw-r--r-- | core/shared/src/main/scala/magnolia.scala | 21 | ||||
-rw-r--r-- | examples/shared/src/main/scala/show.scala | 2 | ||||
-rw-r--r-- | examples/shared/src/main/scala/typename.scala | 16 | ||||
-rw-r--r-- | tests/src/main/scala/tests.scala | 10 |
5 files changed, 38 insertions, 22 deletions
diff --git a/core/shared/src/main/scala/interface.scala b/core/shared/src/main/scala/interface.scala index b06f350..f0f104c 100644 --- a/core/shared/src/main/scala/interface.scala +++ b/core/shared/src/main/scala/interface.scala @@ -104,7 +104,7 @@ trait Param[Typeclass[_], Type] { * @tparam Typeclass type constructor for the typeclass being derived * @tparam Type generic type of this parameter */ abstract class CaseClass[Typeclass[_], Type] private[magnolia] ( - val typeName: String, + val typeName: TypeName, val isObject: Boolean, val isValueClass: Boolean, parametersArray: Array[Param[Typeclass, Type]] @@ -157,7 +157,7 @@ abstract class CaseClass[Typeclass[_], Type] private[magnolia] ( * @param subtypesArray an array of [[Subtype]] instances for each subtype in the sealed trait * @tparam Typeclass type constructor for the typeclass being derived * @tparam Type generic type of this parameter */ -final class SealedTrait[Typeclass[_], Type](val typeName: String, +final class SealedTrait[Typeclass[_], Type](val typeName: TypeName, subtypesArray: Array[Subtype[Typeclass, Type]]) { /** a sequence of all the subtypes of this sealed trait */ @@ -182,3 +182,10 @@ final class SealedTrait[Typeclass[_], Type](val typeName: String, rec(0) } } + +/** + * Provides the different parts of a type's class name. + */ +final case class TypeName(ownerName: String, short: String) { + def full: String = s"$ownerName.$short" +}
\ No newline at end of file diff --git a/core/shared/src/main/scala/magnolia.scala b/core/shared/src/main/scala/magnolia.scala index 200d38e..b4179f9 100644 --- a/core/shared/src/main/scala/magnolia.scala +++ b/core/shared/src/main/scala/magnolia.scala @@ -218,13 +218,18 @@ object Magnolia { val resultType = appliedType(typeConstructor, genericType) - val className = s"${genericType.typeSymbol.owner.fullName}.${genericType.typeSymbol.name.decodedName}" + val typeName = TermName(c.freshName("typeName")) + val typeNameDef = { + val ts = genericType.typeSymbol + q"val $typeName = $magnoliaPkg.TypeName(${ts.owner.fullName}, ${ts.name.decodedName.toString})" + } val result = if (isCaseObject) { val obj = GlobalUtil.patchedCompanionRef(c)(genericType) val impl = q""" + $typeNameDef ${c.prefix}.combine($magnoliaPkg.Magnolia.caseClass[$typeConstructor, $genericType]( - $className, true, false, new $scalaPkg.Array(0), _ => $obj) + $typeName, true, false, new $scalaPkg.Array(0), _ => $obj) ) """ Some(Typeclass(genericType, impl)) @@ -318,15 +323,17 @@ object Magnolia { val $paramsVal: $scalaPkg.Array[$magnoliaPkg.Param[$typeConstructor, $genericType]] = new $scalaPkg.Array(${assignments.length}) ..$assignments + + $typeNameDef ${c.prefix}.combine($magnoliaPkg.Magnolia.caseClass[$typeConstructor, $genericType]( - $className, + $typeName, false, $isValueClass, $paramsVal, ($fieldValues: $scalaPkg.Seq[Any]) => { if ($fieldValues.lengthCompare($paramsVal.length) != 0) { - val msg = "`" + $className + "` has " + $paramsVal.length + " fields, not " + $fieldValues.size + val msg = "`" + $typeName.full + "` has " + $paramsVal.length + " fields, not " + $fieldValues.size throw new java.lang.IllegalArgumentException(msg) } new $genericType(..${ @@ -385,9 +392,11 @@ object Magnolia { new $scalaPkg.Array(${assignments.size}) ..$assignments + + $typeNameDef ${c.prefix}.dispatch(new $magnoliaPkg.SealedTrait( - $className, + $typeName, $subtypesVal: $scalaPkg.Array[$magnoliaPkg.Subtype[$typeConstructor, $genericType]]) ): $resultType }""" @@ -482,7 +491,7 @@ object Magnolia { * * This method is intended to be called only from code generated by the Magnolia macro, and * should not be called directly from users' code. */ - def caseClass[Tc[_], T](name: String, + def caseClass[Tc[_], T](name: TypeName, obj: Boolean, valClass: Boolean, params: Array[Param[Tc, T]], diff --git a/examples/shared/src/main/scala/show.scala b/examples/shared/src/main/scala/show.scala index 9f634ba..6f5838b 100644 --- a/examples/shared/src/main/scala/show.scala +++ b/examples/shared/src/main/scala/show.scala @@ -30,7 +30,7 @@ trait GenericShow[Out] { s"${param.label}=${param.typeclass.show(param.dereference(value))}" } - join(ctx.typeName.split("\\.").last, paramStrings) + join(ctx.typeName.short, paramStrings) } } diff --git a/examples/shared/src/main/scala/typename.scala b/examples/shared/src/main/scala/typename.scala index c1e1fd2..61fab1d 100644 --- a/examples/shared/src/main/scala/typename.scala +++ b/examples/shared/src/main/scala/typename.scala @@ -4,16 +4,16 @@ import language.experimental.macros import magnolia._ -trait TypeName[T] { def name: String } +trait TypeNameInfo[T] { def name: TypeName } -object TypeName { - type Typeclass[T] = TypeName[T] - def combine[T](ctx: CaseClass[TypeName, T]): TypeName[T] = - new TypeName[T] { def name: String = ctx.typeName } +object TypeNameInfo { + type Typeclass[T] = TypeNameInfo[T] + def combine[T](ctx: CaseClass[TypeNameInfo, T]): TypeNameInfo[T] = + new TypeNameInfo[T] { def name: TypeName = ctx.typeName } - def dispatch[T](ctx: SealedTrait[TypeName, T]): TypeName[T] = - new TypeName[T] { def name: String = ctx.typeName } + def dispatch[T](ctx: SealedTrait[TypeNameInfo, T]): TypeNameInfo[T] = + new TypeNameInfo[T] { def name: TypeName = ctx.typeName } - implicit def gen[T]: TypeName[T] = macro Magnolia.gen[T] + implicit def gen[T]: TypeNameInfo[T] = macro Magnolia.gen[T] } diff --git a/tests/src/main/scala/tests.scala b/tests/src/main/scala/tests.scala index 254a516..5b47627 100644 --- a/tests/src/main/scala/tests.scala +++ b/tests/src/main/scala/tests.scala @@ -320,12 +320,12 @@ object Tests extends TestApp { }.assert(_ == "Portfolio(companies=[Company(name=Alice Inc),Company(name=Bob & Co)])") test("sealed trait typeName should be complete and unchanged") { - TypeName.gen[Color].name - }.assert(_ == "magnolia.tests.Color") + TypeNameInfo.gen[Color].name + }.assert(_.full == "magnolia.tests.Color") test("case class typeName should be complete and unchanged") { - implicit val stringTypeName: TypeName[String] = new TypeName[String] { def name = "" } - TypeName.gen[Fruit].name - }.assert(_ == "magnolia.tests.Fruit") + implicit val stringTypeName: TypeNameInfo[String] = new TypeNameInfo[String] { def name = ??? } + TypeNameInfo.gen[Fruit].name + }.assert(_.full == "magnolia.tests.Fruit") } } |