From 091788d0ad6f94c91cc20d6074c3403934702325 Mon Sep 17 00:00:00 2001 From: Jon Pretty Date: Wed, 6 Jun 2018 21:27:28 +0100 Subject: Permit derivations of products when `dispatch` not defined --- core/shared/src/main/scala/magnolia.scala | 3 +-- examples/shared/src/main/scala/hash.scala | 37 +++++++++++++++++++++++++++++++ tests/src/main/scala/tests.scala | 15 ++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 examples/shared/src/main/scala/hash.scala diff --git a/core/shared/src/main/scala/magnolia.scala b/core/shared/src/main/scala/magnolia.scala index 6001977..dd1e0e8 100644 --- a/core/shared/src/main/scala/magnolia.scala +++ b/core/shared/src/main/scala/magnolia.scala @@ -127,9 +127,7 @@ object Magnolia { error(s"magnolia: the method `combine` should take a single parameter of type $expected") } - // FIXME: Only run these methods if they're used, particularly `dispatch` checkMethod("combine", "case classes", "CaseClass[Typeclass, _]") - checkMethod("dispatch", "sealed traits", "SealedTrait[Typeclass, _]") val expandDeferred = new Transformer { override def transform(tree: Tree) = tree match { @@ -333,6 +331,7 @@ object Magnolia { }})})) }""") } else if (isSealedTrait) { + checkMethod("dispatch", "sealed traits", "SealedTrait[Typeclass, _]") val genericSubtypes = knownSubclasses(classType.get) val subtypes = genericSubtypes.map { sub => val subType = sub.asType.toType // FIXME: Broken for path dependent types diff --git a/examples/shared/src/main/scala/hash.scala b/examples/shared/src/main/scala/hash.scala new file mode 100644 index 0000000..2c284c5 --- /dev/null +++ b/examples/shared/src/main/scala/hash.scala @@ -0,0 +1,37 @@ +/* Magnolia, version 0.7.1. Copyright 2018 Jon Pretty, Propensive Ltd. + * + * The primary distribution site is: http://co.ntextu.al/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +package magnolia.examples + +import magnolia._ +import scala.language.experimental.macros + +trait WeakHash[T] { def hash(value: T): Int } + +object WeakHash { + + type Typeclass[T] = WeakHash[T] + + def combine[T](ctx: CaseClass[WeakHash, T]): WeakHash[T] = new WeakHash[T] { + def hash(value: T): Int = ctx.parameters.map { param => + param.typeclass.hash(param.dereference(value)) + }.foldLeft(0)(_ ^ _) + } + + implicit val string: WeakHash[String] = _.map(_.toInt).sum + implicit val int: WeakHash[Int] = identity + implicit val double: WeakHash[Double] = _.toInt + + implicit def gen[T]: WeakHash[T] = macro Magnolia.gen[T] +} diff --git a/tests/src/main/scala/tests.scala b/tests/src/main/scala/tests.scala index c3b90cc..f408253 100644 --- a/tests/src/main/scala/tests.scala +++ b/tests/src/main/scala/tests.scala @@ -55,7 +55,6 @@ case object Red extends Color case object Green extends Color case object Blue extends Color - case class MyAnnotation(order: Int) extends StaticAnnotation @MyAnnotation(0) case class Attributed( @@ -382,5 +381,19 @@ object Tests extends TestApp { Show.gen[Attributed].show(Attributed("xyz", 100)) }.assert(_ == "Attributed{MyAnnotation(0)}(p1{MyAnnotation(1)}=xyz,p2{MyAnnotation(2)}=100)") + test("allow no-coproduct derivation definitions") { + scalac""" + WeakHash.gen[Person] + """ + }.assert(_ == Returns(fqt"magnolia.examples.WeakHash.Typeclass[magnolia.tests.Person]")) + + test("disallow coproduct derivations without dispatch method") { + scalac""" + WeakHash.gen[Entity] + """ + }.assert(_ == TypecheckError("magnolia: the method `dispatch` must be defined on the derivation object WeakHash to derive typeclasses for sealed traits")) + + + } } -- cgit v1.2.3