Skip to content
This repository has been archived by the owner on Dec 13, 2020. It is now read-only.

Commit

Permalink
Fixed the default values macro to use constructor instead of apply
Browse files Browse the repository at this point in the history
Fixes #1
  • Loading branch information
netvl committed Apr 20, 2015
1 parent 3db1ac9 commit da3da8a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
11 changes: 5 additions & 6 deletions core/src/main/scala/io/github/netvl/picopickle/defaults.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,19 @@ trait DefaultValueMacros extends ContextExtensions with SingletonTypeMacrosExten

val tTpe = weakTypeOf[T]
val tCompanionSym = companion(tTpe.typeSymbol)

if (tCompanionSym == NoSymbol)
c.abort(c.enclosingPosition, s"No companion symbol is available for type $tTpe")

val applySym = decl(tCompanionSym.typeSignature, termName("apply")).asMethod
if (applySym == NoSymbol)
c.abort(c.enclosingPosition, s"Companion symbol for type $tTpe does not have apply method")
val ctorSym = decl(tTpe, names.CONSTRUCTOR).asTerm.alternatives.collectFirst {
case ctor: MethodSymbol if ctor.isPrimaryConstructor => ctor
}.getOrElse(c.abort(c.enclosingPosition, s"Could not find the primary constructor for type $tTpe"))

val vTpe = weakTypeOf[V]

val defaultMethodName = paramLists(applySym).headOption.flatMap { argSyms =>
val defaultMethodName = paramLists(ctorSym).headOption.flatMap { argSyms =>
argSyms.map(_.asTerm).zipWithIndex.collect {
case (p, i) if p.isParamWithDefault && p.name.toString == fieldName && p.typeSignature =:= vTpe =>
termName(s"apply$$default$$${i+1}")
termName(s"$$lessinit$$greater$$default$$${i+1}") // TODO: not sure if this couldn't be made more correct
}.headOption
}

Expand Down
14 changes: 14 additions & 0 deletions core/src/test/scala/io/github/netvl/picopickle/Fixtures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,18 @@ object Fixtures {
sealed trait Root
case class A(x: Int, name: String = "me", enabled: Boolean = false) extends Root
}

object WithOverloadedApplyMethod {
case class A(x: Int, y: String, z: Double = 12.3)

object A {
def apply(s: String): A = A(s.toInt, s, s.toDouble)
}
}

object WithOverloadedConstructor {
case class A(x: Int, y: String, z: Double = 12.3) {
def this(s: String) = this(s.toInt, s, s.toDouble)
}
}
}
14 changes: 14 additions & 0 deletions project/tests/Pickler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,18 @@ cases:
- - 'A(10, null)'
- 'Map("x" -> 10, "y" -> null)'
- '"""{"x":10,"y":null}"""'
- name: case classes with an overloaded apply method in their companions
prepend: |
import WithOverloadedApplyMethod._
rw:
- - 'A(1, "2", 3.4)'
- 'Map("x" -> 1, "y" -> "2", "z" -> 3.4)'
- '"""{"x":1,"y":"2","z":3.4}"""'
- name: case classes with an overloaded constructor
prepend: |
import WithOverloadedConstructor._
rw:
- - 'A(1, "2", 3.4)'
- 'Map("x" -> 1, "y" -> "2", "z" -> 3.4)'
- '"""{"x":1,"y":"2","z":3.4}"""'

0 comments on commit da3da8a

Please sign in to comment.