File tree Expand file tree Collapse file tree 3 files changed +38
-9
lines changed
main/scala/com/avsystem/commons/meta
test/scala/com/avsystem/commons/meta
commons-macros/src/main/scala/com/avsystem/commons/macros/misc Expand file tree Collapse file tree 3 files changed +38
-9
lines changed Original file line number Diff line number Diff line change @@ -11,17 +11,17 @@ package meta
1111 * macro-materialization of typeclasses aggregated by `Instances` trait.
1212 *
1313 * `Instances` is a trait that aggregates multiple macro materialized typeclass instances.
14- * There is no fixed interface for `Instances`, its members are inspected by `MacroInstances.materialize`
15- * macro and implemented automatically. `Instances` trait must have only parameterless abstract methods.
16- * Return type of each method must have a companion object which contains `materialize` macro.
17- * That macro will be used to implement that method.
14+ * There is no fixed interface for `Instances`, its abstract methods are inspected by
15+ * `MacroInstances.materialize` macro and implemented automatically as `<methodReturnTypeCompanion>.materialize`
16+ * Therefore, return type type of each method must have a companion object which contains `materialize` macro.
1817 *
1918 * Example of `Instances`: [[com.avsystem.commons.rest.ClientInstances ClientInstances ]]
2019 *
2120 * The `Implicits` type is typically a trait with a collection of implicit definitions whose companion object
2221 * implements that trait, e.g. [[com.avsystem.commons.rest.DefaultRestImplicits DefaultRestImplicits ]].
2322 * When the macro implements `apply` method of `MacroInstances` contents of `Implicits` are imported into the
2423 * body of `apply` and visible further by macros that materialize `InstancesTrait`.
24+ * If you don't want to inject additional implicits, declare `Implicits` as `Unit`.
2525 *
2626 * If `MacroInstances` is accepted as implicit super constructor parameter of a companion object
2727 * (which is the typical situation) then `this` reference should be passed as `companion`.
Original file line number Diff line number Diff line change 1+ package com .avsystem .commons
2+ package meta
3+
4+ import com .avsystem .commons .serialization .GenCodec
5+
6+ case class Dep (int : Int )
7+ case class Klass [T ](value : T )
8+
9+ object DependencyImplicits {
10+ implicit val depCodec : GenCodec [Dep ] = GenCodec .materialize
11+ }
12+
13+ trait ComplexInstances [T ] {
14+ def plainCodec : GenCodec [Klass [Int ]]
15+ def codecWithGeneric : GenCodec [Klass [T ]]
16+ def dependencyUsingCodec : GenCodec [Klass [Dep ]]
17+ def parameterizedCodec [A : GenCodec ]: GenCodec [Klass [A ]]
18+ }
19+
20+ abstract class HasComplexInstances [T ](
21+ implicit macroInstances : MacroInstances [DependencyImplicits .type , ComplexInstances [T ]]
22+ ) {
23+ val instances : ComplexInstances [T ] = macroInstances(DependencyImplicits , this )
24+ }
25+
26+ object MacroInstancesTest extends HasComplexInstances [String ] {
27+ def main (args : Array [String ]): Unit = {
28+ println(instances.parameterizedCodec[Double ])
29+ }
30+ }
Original file line number Diff line number Diff line change @@ -355,23 +355,22 @@ class MiscMacros(ctx: blackbox.Context) extends AbstractMacroCommons(ctx) {
355355 }
356356
357357 val instancesMethods = instancesTpe.members.iterator
358- .filter(m => m.isAbstract && m.isMethod).toList.reverse
358+ .filter(m => m.isAbstract && m.isMethod).map(_.asMethod). toList.reverse
359359
360360 def impl (singleMethod : Option [Symbol ]): Tree = {
361361 val impls = instancesMethods.map { m =>
362362 val sig = m.typeSignatureIn(instancesTpe)
363363 val resultTpe = sig.finalResultType.dealias
364- if (sig.typeParams.nonEmpty || sig.paramLists.nonEmpty) {
365- abort(s " Problem with $m of $instancesTpe: expected non-generic, parameterless method " )
366- }
367364 val resultCompanion = typedCompanionOf(resultTpe)
368365 .getOrElse(abort(s " $resultTpe has no companion object with `materialize` macro " ))
369366
370367 val body =
371368 if (singleMethod.exists(_ != m)) q " $PredefObj.??? "
372369 else q " $resultCompanion.materialize "
373370
374- q " def ${m.name.toTermName} = $body"
371+ val tparamDefs = sig.typeParams.map(typeSymbolToTypeDef(_, forMethod = true ))
372+ val paramDefs = sig.paramLists.map(_.map(paramSymbolToValDef))
373+ q " def ${m.name}[.. $tparamDefs](... $paramDefs): ${treeForType(sig.finalResultType)} = $body"
375374 }
376375
377376 val implicitsName = c.freshName(TermName (" implicits" ))
You can’t perform that action at this time.
0 commit comments