Skip to content

Commit

Permalink
Fix for issue #27 which slipped through our tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MateuszKubuszok committed Jan 9, 2023
1 parent 4fc6cbc commit 590a0a2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,25 @@ private[internal] trait PlatformProductCaseGeneration[Pipe[_, _], In, Out]
)
private def extractGetters[Extracted: Type]: ListMap[String, Getter[Extracted, Any]] = {
val sym = TypeRepr.of[Extracted].typeSymbol
// apparently each case field is duplicated: "a" and "a ", "_1" and "_1 " o_0 - the first is method, the other val
// the exceptions are cases in Scala 3 enum: they only have vals
val caseFields = sym.caseFields.filter(if (sym.flags.is(Flags.Enum)) _.isValDef else _.isDefDef)
val javaGetters = sym.declaredMethods.filterNot(isGarbage).filter(isJavaGetter)
// case class fields appear once in sym.caseFields as vals and once in sym.declaredMethods as methods
// additionally sometimes they appear twice! once as "val name" and once as "method name " (notice space at the end
// of name). This breaks matching by order (tuples) but has to be fixed in a way that doesn't filter out fields
// for normal cases.
val caseFields = sym.caseFields.zipWithIndex
.groupBy(_._1.name.trim)
.view
.map {
case (_, Seq(fieldIdx, _)) if fieldIdx._1.isDefDef => fieldIdx
case (_, Seq(_, fieldIdx)) if fieldIdx._1.isDefDef => fieldIdx
case (_, fieldIdxs) => fieldIdxs.head
}
.toList
.sortBy(_._2)
.map(_._1)
.toList
val caseFieldNames = caseFields.map(_.name.trim).toSet
def isCaseFieldName(sym: Symbol) = caseFieldNames(sym.name)
val javaGetters = sym.declaredMethods.filterNot(isGarbage).filterNot(isCaseFieldName).filter(isJavaGetter)
(caseFields ++ javaGetters)
.map { method =>
val name = method.name
Expand Down
53 changes: 53 additions & 0 deletions pipez/src/test/scala/pipez/BugReportSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package pipez

class BugReportSpec extends munit.FunSuite {

test("Bug report https://github.com/MateuszKubuszok/pipez/issues/27") {
// Bug was related to weird behavior in Scala 3 macros where symbols for case class fields are doubled:
// - there is one "val fieldName"
// - and there is one "method fieldName " (with space at the end!)
// This behavior was breaking matching by position (where input/output is a Tuple) but the workaround used
// unreliable solution which sometimes filtered out _all_ case class fields.
case class OvpnConfigurationFile(
id: String,
createdAt: Long,
name: String,
notBefore: String,
notAfter: String,
contents: String
)

case class OvpnConfigurationFileResponse(
id: String,
createdAt: Long,
name: String,
notBefore: String,
notAfter: String
)
assertEquals(
ContextCodec
.derive[OvpnConfigurationFile, OvpnConfigurationFileResponse]
.decode(
OvpnConfigurationFile(
id = "foo",
createdAt = 0,
name = "bar",
notBefore = "x",
notAfter = "y",
contents = "z"
),
false,
""
),
Right(
OvpnConfigurationFileResponse(
id = "foo",
createdAt = 0,
name = "bar",
notBefore = "x",
notAfter = "y"
)
)
)
}
}

0 comments on commit 590a0a2

Please sign in to comment.