diff --git a/upickle/implicits/src-2/upickle/implicits/internal/Macros.scala b/upickle/implicits/src-2/upickle/implicits/internal/Macros.scala index 67d3942c1..4db982416 100644 --- a/upickle/implicits/src-2/upickle/implicits/internal/Macros.scala +++ b/upickle/implicits/src-2/upickle/implicits/internal/Macros.scala @@ -219,12 +219,14 @@ object Macros { fail(tpe, _), ) - + val sealedClassSymbol: Option[Symbol] = sealedParents.find(_ == tpe.typeSymbol) val segments = - sealedParents + sealedClassSymbol.toList.map(_.fullName.split('.')) ++ + sealedParents .flatMap(_.asClass.knownDirectSubclasses) .map(_.fullName.split('.')) + // -1 because even if there is only one subclass, and so no name segments // are needed to differentiate between them, we want to keep at least // the rightmost name segment diff --git a/upickle/implicits/src-3/upickle/implicits/macros.scala b/upickle/implicits/src-3/upickle/implicits/macros.scala index 9cc0b2d29..50d50ee9d 100644 --- a/upickle/implicits/src-3/upickle/implicits/macros.scala +++ b/upickle/implicits/src-3/upickle/implicits/macros.scala @@ -309,12 +309,15 @@ def tagNameImpl0[T](transform: String => String)(using Quotes, Type[T]): Expr[St inline def shortTagName[T]: String = ${ shortTagNameImpl[T] } def shortTagNameImpl[T](using Quotes, Type[T]): Expr[String] = import quotes.reflect._ - val sym = TypeTree.of[T].symbol + val sealedClassSymbol = if (TypeRepr.of[T].baseClasses.contains(TypeRepr.of[T].typeSymbol)) + Some(TypeRepr.of[T].typeSymbol.fullName.split('.')) + else None val segments = TypeRepr.of[T].baseClasses .filter(_.flags.is(Flags.Sealed)) .flatMap(_.children) .filter(_.flags.is(Flags.Case)) - .map(_.fullName.split('.')) + .map(_.fullName.split('.')) ++ + sealedClassSymbol.toList val identicalSegmentCount = Range(0, segments.map(_.length).max - 1) .takeWhile(i => segments.map(_.lift(i)).distinct.size == 1) diff --git a/upickle/test/src/upickle/MacroTests.scala b/upickle/test/src/upickle/MacroTests.scala index 2936ae1f1..c135073ec 100644 --- a/upickle/test/src/upickle/MacroTests.scala +++ b/upickle/test/src/upickle/MacroTests.scala @@ -6,6 +6,11 @@ import upickle.default.{read, write, ReadWriter => RW} case class Trivial(a: Int = 1) +sealed case class SealedClass(i: Int, s: String) +object SealedClass { + implicit val rw: RW[SealedClass] = upickle.default.macroRW +} + case class KeyedPerson( @upickle.implicits.key("first_name") firstName: String = "N/A", @upickle.implicits.key("last_name") lastName: String) @@ -872,5 +877,9 @@ object MacroTests extends TestSuite { ) } + + test("sealedClass"){ + assert(write(SealedClass(3, "Hello")) == """{"$type":"SealedClass","i":3,"s":"Hello"}""") + } } }