Skip to content

Commit c87bb2f

Browse files
committed
Fix #98 by providing a clear compilation error when a case class has a primary constructor with multiple parameter lists.
1 parent 84225b8 commit c87bb2f

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

macros/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,16 @@ object JsonCodecMaker {
355355
case m: MethodSymbol if m.isPrimaryConstructor => m
356356
}.get // FIXME: while in Scala, every class has a primary constructor, but sometime it cannot be accessed
357357

358-
//FIXME: handling only default val params from the first list because subsequent might depend on previous params
359-
def getParams(tpe: Type): Seq[TermSymbol] = getPrimaryConstructor(tpe).paramLists.head.map(_.asTerm)
358+
def getParams(tpe: Type): Seq[TermSymbol] = getPrimaryConstructor(tpe).paramLists match {
359+
case paramList :: Nil => paramList.map(_.asTerm)
360+
case _ => fail(s"'$tpe' has a primary constructor with multiple parameter lists. " +
361+
"Please consider using a custom implicitly accessible codec for this type.")
362+
}
360363

361364
def getDefaults(tpe: Type): Map[String, Tree] = {
365+
val params = getParams(tpe)
362366
val module = getModule(tpe)
363-
getParams(tpe).zipWithIndex.collect { case (p, i) if p.isParamWithDefault =>
367+
params.zipWithIndex.collect { case (p, i) if p.isParamWithDefault =>
364368
(decodedName(p), q"$module.${TermName("$lessinit$greater$default$" + (i + 1))}")
365369
}(breakOut)
366370
}

macros/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMakerSpec.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,14 +1098,14 @@ class JsonCodecMakerSpec extends WordSpec with Matchers {
10981098
"serialize and deserialize case classes with private primary constructor if it can be accessed" in {
10991099
verifySerDeser(PrivatePrimaryConstructor.codec, PrivatePrimaryConstructor("1"), "{\"i\":1}".getBytes("UTF-8"))
11001100
}
1101-
"don't generate codec for unsupported classes" in {
1101+
"don't generate codecs for unsupported classes" in {
11021102
assert(intercept[TestFailedException](assertCompiles {
11031103
"""JsonCodecMaker.make[java.util.Date](CodecMakerConfig())"""
11041104
}).getMessage.contains {
11051105
"""No implicit 'com.github.plokhotnyuk.jsoniter_scala.core.JsonValueCodec[_]' defined for 'java.util.Date'."""
11061106
})
11071107
}
1108-
"don't generate codec for too deeply defined case classes" in {
1108+
"don't generate codecs for too deeply defined case classes" in {
11091109
assert(intercept[TestFailedException](assertCompiles {
11101110
"""val codecOfFoo = () => {
11111111
| case class Foo(i: Int)
@@ -1117,6 +1117,15 @@ class JsonCodecMakerSpec extends WordSpec with Matchers {
11171117
|it as a top-level object or directly inside of another class or object.""".stripMargin.replace('\n', ' ')
11181118
})
11191119
}
1120+
"don't generate codecs for case classes with multiple parameter lists in a primary constructor" in {
1121+
assert(intercept[TestFailedException](assertCompiles {
1122+
"""case class MultiListOfArgs(i: Int)(l: Long)
1123+
|JsonCodecMaker.make[MultiListOfArgs](CodecMakerConfig())""".stripMargin
1124+
}).getMessage.contains {
1125+
"""'MultiListOfArgs' has a primary constructor with multiple parameter lists.
1126+
|Please consider using a custom implicitly accessible codec for this type.""".stripMargin.replace('\n', ' ')
1127+
})
1128+
}
11201129
}
11211130
"JsonCodecMaker.enforceCamelCase" should {
11221131
"transform snake_case names to camelCase" in {

0 commit comments

Comments
 (0)