@@ -251,38 +251,66 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
251251 def anyParamHasTransientDefault : Boolean =
252252 params.exists(isTransientDefault)
253253
254+ def isOptionLike (p : ApplyParam ): Boolean =
255+ p.optionLike.nonEmpty
256+
254257 def mayBeTransient (p : ApplyParam ): Boolean =
255- p.optionLike.nonEmpty || isTransientDefault(p)
258+ isOptionLike(p) || isTransientDefault(p)
256259
257260 def transientValue (p : ApplyParam ): Tree = p.optionLike match {
258261 case Some (optionLike) => q " ${optionLike.reference(Nil )}.none "
259262 case None => p.defaultValue
260263 }
261264
262- def countTransientFields : Tree =
265+ // assumes usage in in size(value, output) method implementation
266+ def countTransientFields : Tree = {
267+ def checkIgnoreTransientDefaultMarker : Tree =
268+ q " output.isDefined && output.get.customEvent( $SerializationPkg.IgnoreTransientDefaultMarker, ()) "
269+
270+ def doCount (paramsToCount : List [ApplyParam ], accessor : ApplyParam => Tree ): Tree =
271+ paramsToCount.foldLeft[Tree ](q " 0 " ) {
272+ (acc, p) => q " $acc + (if( ${accessor(p)} == ${transientValue(p)}) 1 else 0) "
273+ }
274+
275+ def countOnlyOptionLike (accessor : ApplyParam => Tree ): Tree =
276+ doCount(params.filter(isOptionLike), accessor)
277+
278+ def countTransient (accessor : ApplyParam => Tree ): Tree =
279+ doCount(params.filter(mayBeTransient), accessor)
280+
281+ def countMultipleParams (accessor : ApplyParam => Tree ): Tree =
282+ if (anyParamHasTransientDefault)
283+ q " if( $checkIgnoreTransientDefaultMarker) ${countOnlyOptionLike(accessor)} else ${countTransient(accessor)}"
284+ else
285+ countTransient(accessor)
286+
287+ def countSingleParam (param : ApplyParam , value : Tree ): Tree =
288+ if (isTransientDefault(param))
289+ q " if(! $checkIgnoreTransientDefaultMarker && $value == ${transientValue(param)}) 1 else 0 "
290+ else
291+ q " if( $value == ${transientValue(param)}) 1 else 0 "
292+
263293 if (canUseFields)
264- params.filter(mayBeTransient).foldLeft[Tree ](q " 0 " ) {
265- (acc, p) => q " $acc + (if(value. ${p.sym.name} == ${transientValue(p)}) 1 else 0) "
294+ countMultipleParams(p => q " value. ${p.sym.name}" )
295+ else if (! params.exists(mayBeTransient))
296+ q " 0 "
297+ else
298+ params match {
299+ case List (p : ApplyParam ) =>
300+ q """
301+ val unapplyRes = $companion. $unapply[.. ${dtpe.typeArgs}](value)
302+ if(unapplyRes.isEmpty) unapplyFailed else { ${countSingleParam(p, q " unapplyRes.get " )} }
303+ """
304+ case _ =>
305+ q """
306+ val unapplyRes = $companion. $unapply[.. ${dtpe.typeArgs}](value)
307+ if(unapplyRes.isEmpty) unapplyFailed else {
308+ val t = unapplyRes.get
309+ ${countMultipleParams(p => q " t. ${tupleGet(p.idx)}" )}
310+ }
311+ """
266312 }
267- else if (! params.exists(mayBeTransient)) q " 0 "
268- else params match {
269- case List (p : ApplyParam ) =>
270- q """
271- val unapplyRes = $companion. $unapply[.. ${dtpe.typeArgs}](value)
272- if(unapplyRes.isEmpty) unapplyFailed else if(unapplyRes.get == ${transientValue(p)}) 1 else 0
273- """
274- case _ =>
275- val res = params.filter(mayBeTransient).foldLeft[Tree ](q " 0 " ) {
276- (acc, p) => q " $acc + (if(t. ${tupleGet(p.idx)} == ${transientValue(p)}) 1 else 0) "
277- }
278- q """
279- val unapplyRes = $companion. $unapply[.. ${dtpe.typeArgs}](value)
280- if(unapplyRes.isEmpty) unapplyFailed else {
281- val t = unapplyRes.get
282- $res
283- }
284- """
285- }
313+ }
286314
287315 if (isTransparent(dtpe.typeSymbol)) params match {
288316 case List (p : ApplyParam ) =>
@@ -331,7 +359,7 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
331359 val res =
332360 q """
333361 def size(value: $dtpe, output: $OptCls[ $SerializationPkg.SequentialOutput]): $IntCls =
334- ${params.size} + ${generated.size} - output.filter(_.customEvent( $SerializationPkg .IgnoreTransientDefaultMarker, ())).mapOr( $countTransientFields, _ => 0)
362+ ${params.size} + ${generated.size} - { $countTransientFields }
335363 """
336364 List (res)
337365 }
0 commit comments