From d7f923bfe18b43da011afa2bf4e5fde447a99ce4 Mon Sep 17 00:00:00 2001 From: reimai Date: Wed, 5 Jun 2024 13:06:53 +0300 Subject: [PATCH] make format generation idempotent (cherry picked from commit 27c2a350fee86475d237e7dd377aabb5d5c63e1c) --- .../play/api/libs/json/JsMacroImpl.scala | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/play-json/shared/src/main/scala-2/play/api/libs/json/JsMacroImpl.scala b/play-json/shared/src/main/scala-2/play/api/libs/json/JsMacroImpl.scala index 384ee50b5..98ce49397 100644 --- a/play-json/shared/src/main/scala-2/play/api/libs/json/JsMacroImpl.scala +++ b/play-json/shared/src/main/scala-2/play/api/libs/json/JsMacroImpl.scala @@ -5,6 +5,7 @@ package play.api.libs.json import scala.annotation.tailrec +import scala.collection.mutable import scala.reflect.macros.blackbox /** @@ -555,25 +556,26 @@ class JsMacroImpl(val c: blackbox.Context) { val tpeSym = atag.tpe.typeSymbol.asClass @tailrec - def allSubclasses(path: List[Symbol], subclasses: Set[Type]): Set[Type] = path match { - case (cls: ClassSymbol) :: tail if tpeSym != cls && cls.selfType.baseClasses.contains(tpeSym) => { - if (cls.typeParams.nonEmpty) - c.warning(c.enclosingPosition, s"cannot handle class ${cls.fullName}: type parameter not supported") - val newSub = if (cls.typeParams.isEmpty) Set(cls.selfType) else Set.empty - allSubclasses(tail, subclasses ++ newSub) - } + def allSubclasses(path: List[Symbol], subclasses: mutable.LinkedHashSet[Type]): mutable.LinkedHashSet[Type] = + path match { + case (cls: ClassSymbol) :: tail if tpeSym != cls && cls.selfType.baseClasses.contains(tpeSym) => { + if (cls.typeParams.nonEmpty) + c.warning(c.enclosingPosition, s"cannot handle class ${cls.fullName}: type parameter not supported") + val newSub = if (cls.typeParams.isEmpty) Set(cls.selfType) else Set.empty + allSubclasses(tail, subclasses ++ newSub) + } - case (o: ModuleSymbol) :: tail - if o.companion == NoSymbol // not a companion object - && o.typeSignature.baseClasses.contains(tpeSym) => - allSubclasses(tail, subclasses ++ Set(o.typeSignature)) + case (o: ModuleSymbol) :: tail + if o.companion == NoSymbol // not a companion object + && o.typeSignature.baseClasses.contains(tpeSym) => + allSubclasses(tail, subclasses ++ Set(o.typeSignature)) - case _ :: tail => allSubclasses(tail, subclasses) - case _ => subclasses - } + case _ :: tail => allSubclasses(tail, subclasses) + case _ => subclasses + } if (tpeSym.isSealed && tpeSym.isAbstract) { - Some(allSubclasses(tpeSym.owner.typeSignature.decls.sorted, Set.empty).toList) + Some(allSubclasses(tpeSym.owner.typeSignature.decls.sorted, mutable.LinkedHashSet[Type]()).toList) } else None }