diff --git a/build.sbt b/build.sbt index 7b6e380..cf9b2ed 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,7 @@ import xerial.sbt.Sonatype._ lazy val commonSettings = Seq( + //scalaVersion := "2.12.12-bin-SNAPSHOT", scalaVersion := "2.12.12", organization := "io.github.dos65", version := "0.0.31-SNAPSHOT", diff --git a/modules/core/src/main/scala/make/Dep.scala b/modules/core/src/main/scala/make/Dep.scala new file mode 100644 index 0000000..054e302 --- /dev/null +++ b/modules/core/src/main/scala/make/Dep.scala @@ -0,0 +1,15 @@ +package make + +import make.internal.DepMacro + +/** + * This class is used to workaround wrong `divergency implicit error` on scala 2.12 + * Macros uses similar trick as `shapeless.Lazy` but do not allows recursive references + */ +case class Dep[F[_], A](value: Make[F, A]) + +object Dep { + + implicit def materialize[F[_], A]: Dep[F, A] = + macro DepMacro.materialize[F, A] +} \ No newline at end of file diff --git a/modules/core/src/main/scala/make/Make.scala b/modules/core/src/main/scala/make/Make.scala index 9faa9fc..457dc4b 100644 --- a/modules/core/src/main/scala/make/Make.scala +++ b/modules/core/src/main/scala/make/Make.scala @@ -5,6 +5,7 @@ import make.internal.MakeOps import cats.Applicative import scala.reflect.runtime.universe.TypeTag import make.internal.MakeBasicOps +import make.internal.DepMacro sealed abstract class Make[F[_], A] { def tag: Tag[A] @@ -12,7 +13,7 @@ sealed abstract class Make[F[_], A] { object Make extends ContraMakeInstances with MakeTupleInstances with LowPrioMake { - def of[F[_], A](implicit m: Make[F, A]): Make[F, A] = m + def of[F[_], A](implicit m: Dep[F, A]): Make[F, A] = m.value final private[make] case class Value[F[_], A]( v: () => F[A], @@ -42,15 +43,16 @@ object Make extends ContraMakeInstances with MakeTupleInstances with LowPrioMake def contramap[A, B](f: B => A): Contra[A, B] = new Contra[A, B](f) final class Contra[A, B](private[make] val f: B => A) + } trait ContraMakeInstances { implicit def contraMakeInstance[F[_]: Applicative, A, B](implicit contra: Make.Contra[A, B], - m: Make[F, B], + m: Dep[F, B], tagB: Tag[A] - ): Make[F, A] = MakeOps.map(m)(contra.f) + ): Make[F, A] = MakeOps.map(m.value)(contra.f) } trait LowPrioMake { diff --git a/modules/core/src/main/scala/make/internal/DepMacro.scala b/modules/core/src/main/scala/make/internal/DepMacro.scala new file mode 100644 index 0000000..996f0d5 --- /dev/null +++ b/modules/core/src/main/scala/make/internal/DepMacro.scala @@ -0,0 +1,47 @@ +package make.internal + +import scala.reflect.macros.whitebox +import scala.collection.mutable +import make.Dep +import make.Make + +class DepMacro(val c: whitebox.Context) { + + import c.universe._ + + def materialize[F[_], A](implicit + ftpe: WeakTypeTag[F[X] forSome { type X }], + atpe: WeakTypeTag[A] + ): c.Expr[Dep[F, A]] = { + val state = getOrCreateState + state.infer[F](ftpe.tpe, atpe.tpe) match { + case EmptyTree => + c.abort(c.enclosingPosition, "failed") + case tree => + c.Expr[Dep[F, A]](q"_root_.make.Dep[${ftpe.tpe}, ${atpe.tpe}]($tree)") + } + } + + private def getOrCreateState: State = { + val existing = + c.openMacros.find(c => c.internal.attachments(c.macroApplication).contains[State]) + .flatMap(c => c.internal.attachments(c.macroApplication).get[State]) + existing match { + case None => + val st = new State(mutable.HashSet.empty) + c.internal.updateAttachment(c.macroApplication, st) + st + case Some(st) => st + } + } + + + class State(val seen: mutable.HashSet[Type]) { + + def infer[F[_]](ftpe: c.Type, atpe: c.Type): c.Tree = { + val makeTc = c.universe.weakTypeOf[Make[F, _]].typeConstructor + val searchType = c.universe.appliedType(makeTc, ftpe, atpe) + c.inferImplicitValue(searchType) + } + } +} \ No newline at end of file diff --git a/modules/core/src/main/scala/make/internal/MakeAnnotationMacro.scala b/modules/core/src/main/scala/make/internal/MakeAnnotationMacro.scala index 32cb31a..47f387f 100644 --- a/modules/core/src/main/scala/make/internal/MakeAnnotationMacro.scala +++ b/modules/core/src/main/scala/make/internal/MakeAnnotationMacro.scala @@ -52,7 +52,7 @@ class MakeAnnotationMacro(val c: blackbox.Context) { val dependencies: List[(TermName, c.Tree)] = params.zipWithIndex.map{case (dp, i) => val name = TermName(c.freshName(s"dep$i")) - val tree = q"$name: _root_.make.Make[$effTpe, ${dp.tpt}]" + val tree = q"$name: _root_.make.Dep[$effTpe, ${dp.tpt}]" (name, tree) } val implicitDependencies = dependencies.map(_._2) @@ -68,8 +68,8 @@ class MakeAnnotationMacro(val c: blackbox.Context) { q"_root_.make.Make.pure[$effTpe, ${targetTpe}]($create)" } else { dependencies.reverse.map(_._1).foldLeft(EmptyTree){ - case (EmptyTree, name) => q"_root_.make.internal.MakeOps.map(${name})($create)" - case (tree, name) => q"_root_.make.internal.MakeOps.ap(${name})($tree)" + case (EmptyTree, name) => q"_root_.make.internal.MakeOps.map(${name}.value)($create)" + case (tree, name) => q"_root_.make.internal.MakeOps.ap(${name}.value)($tree)" } } @@ -118,7 +118,7 @@ class MakeAnnotationMacro(val c: blackbox.Context) { case Apply(Select(New(annoSelect), _), _) => annoSelect case _ => - c.abort(c.enclosingPosition, "Annotation descontruction failed") + c.abort(c.enclosingPosition, "Annotation decontruction failed") } } } diff --git a/modules/core/src/main/scala/make/internal/MakeMacro.scala b/modules/core/src/main/scala/make/internal/MakeMacro.scala index 8109a30..4cbcb60 100644 --- a/modules/core/src/main/scala/make/internal/MakeMacro.scala +++ b/modules/core/src/main/scala/make/internal/MakeMacro.scala @@ -25,6 +25,7 @@ class MakeMacro(val c: whitebox.Context) { out match { case EmptyTree => val st = extractInstanceSt(atpe.tpe, state.reverseTraces) + println(st) val message = renderInstanceSt(st) c.abort(c.enclosingPosition, s"Make for ${atpe.tpe} not found\n" + message) case tree => diff --git a/modules/core/src/main/scala/make/internal/MakeOps.scala b/modules/core/src/main/scala/make/internal/MakeOps.scala index 4f85863..65ef473 100644 --- a/modules/core/src/main/scala/make/internal/MakeOps.scala +++ b/modules/core/src/main/scala/make/internal/MakeOps.scala @@ -1,4 +1,4 @@ package make.internal -trait MakeOps extends MakeProductNOps +trait MakeOps extends MakeProductNOps with MakeBasicOps object MakeOps extends MakeOps diff --git a/modules/core/src/main/scala/make/internal/TpeTagMacro.scala b/modules/core/src/main/scala/make/internal/TpeTagMacro.scala index 2eb49a1..71ede24 100644 --- a/modules/core/src/main/scala/make/internal/TpeTagMacro.scala +++ b/modules/core/src/main/scala/make/internal/TpeTagMacro.scala @@ -3,7 +3,6 @@ package make.internal import scala.reflect.macros.blackbox import make.Tag.TpeTag import make.Tag -import scala.reflect.internal.Constants class TpeTagMacro(val c: blackbox.Context) { @@ -11,10 +10,8 @@ class TpeTagMacro(val c: blackbox.Context) { def materializeTpeTag[A : WeakTypeTag]: c.Expr[TpeTag[A]] = { val tpe = weakTypeOf[A] - println(s"CALL MATERIALIZE: $tpe ${tpe.typeSymbol.isParameter}") val value = transformTpe3(tpe) val tree = q"_root_.make.Tag.TpeTag[${tpe}]($value)" - println(s"OK!! $tree") c.Expr[TpeTag[A]](tree) } @@ -34,14 +31,6 @@ class TpeTagMacro(val c: blackbox.Context) { private def processTypeParameters(symbolName: c.Tree, t: c.Type): c.Tree = { val inner = t.dealias.typeArgs.map(transformTpe3) q"_root_.make.Tag.TpeTag.Type($symbolName, $inner)" - // t.dealias match { - // case ref: TypeRef => - // val inner = ref.args.map(transformTpe3) - // q"_root_.make.Tag.TpeTag.Type($symbolName, $inner)" - // case x => - // c.info(c.enclosingPosition, s"TpeTag not implemented for $x: ${x.getClass}", true) - // c.abort(c.enclosingPosition, "Not implemented") - // } } private def transformTpeParameter(t: c.Type): c.Tree = { @@ -53,22 +42,6 @@ class TpeTagMacro(val c: blackbox.Context) { } case _ => searchTPTag(t) } - // val kind = t.dealias.typeArgs - // println(s"TYPE ARGS for $t : $kind") - // kind.size match { - // case 0 => searchTPTag(t) - // case 1 => processTypeParameters(searchTCTag(t), t) - // case n => c.abort(c.enclosingPosition, "Not implemented") - // } - - // t.dealias match { - // case tpe: TypeRef => - // val inner = tpe.args.map(transformTpe3) - // q"_root_.make.Tag.TpeTag.Type(${symbolTree}, $inner)" - // case x => - // c.info(c.enclosingPosition, s"TpeTag(parameter) not implemented for $x: ${x.getClass}", true) - // c.abort(c.enclosingPosition, "Not implemented") - // } } @@ -86,106 +59,6 @@ class TpeTagMacro(val c: blackbox.Context) { .getOrElse(c.abort(c.enclosingPosition, "Not implemented")) } - // private def transformTpe2(t: c.Type): c.Tree = { - // println(s"transform $t ${t.typeSymbol.isParameter} ${t.getClass}") - // val normalized = t - // if (t.typeSymbol.isParameter) { - // t.dealias match { - // case ref: PolyType => - // println(s"IS POLY ${ref.typeParams} ${ref.typeArgs}") - // val kind = math.max(ref.typeParams.size, ref.typeArgs.size) - // ref.typeParams.size match { - // case 0 => - // val inner = ref.typeArgs.map(transformTpe2) - // q"_root_.make.Tag.TpeTag.Type(${ref.typeSymbol.fullName}, $inner)" - // case 1 => - // val tcTagTpe = appliedType(weakTypeOf[Tag.TCTag[X] forSome {type X[_]}].typeConstructor, t.typeConstructor) - // optionFromImplicitTree(c.inferImplicitValue(tcTagTpe)) - // .map(t => q"$t.tpe") - // .getOrElse(c.abort(c.enclosingPosition, "Not implemented")) - // case n => - // c.abort(c.enclosingPosition, "Not implemented") - // } - // case ref: TypeRef => - // ref.typeParams.size match { - // case 0 => - // val inner = ref.typeArgs.map(transformTpe2) - // q"_root_.make.Tag.TpeTag.Type(${ref.typeSymbol.fullName}, $inner)" - // case 1 => - // val tcTagTpe = appliedType(weakTypeOf[Tag.TCTag[X] forSome {type X[_]}].typeConstructor, t.typeConstructor) - // optionFromImplicitTree(c.inferImplicitValue(tcTagTpe)) - // .map(t => q"$t.tpe") - // .getOrElse(c.abort(c.enclosingPosition, "Not implemented")) - // case n => - // c.abort(c.enclosingPosition, "Not implemented") - // } - - // // case PolyType(typeParams, _) => - // // println(s"POLY TYPE: $typeParams") - // // typeParams.size match { - // // case 1 => - // // val tcTagTpe = appliedType(weakTypeOf[Tag.TCTag[X] forSome {type X[_]}].typeConstructor, t.typeConstructor) - // // optionFromImplicitTree(c.inferImplicitValue(tcTagTpe)) - // // .map(t => q"$t.tpe") - // // .getOrElse(c.abort(c.enclosingPosition, "Not implemented")) - // // case n => - // // c.abort(c.enclosingPosition, "Not implemented") - // // } - // // case x if x.typeSymbol.isParameter => - // // val tagTpe = appliedType(weakTypeOf[Tag.TPTag[X] forSome {type X}].typeConstructor, t) - // // optionFromImplicitTree(c.inferImplicitValue(tagTpe)) - // // .map{t => q"$t.tpe"} - // // .getOrElse(c.abort(c.enclosingPosition, "Not implemented")) - // case x => - // c.abort(c.enclosingPosition, "Not implemented") - // } - // } else { - // t match { - // case ref: TypeRef => - // val inner = ref.args.map(transformTpe2) - // q"_root_.make.Tag.TpeTag.Type(${ref.typeSymbol.fullName}, $inner)" - // case x => - // c.info(c.enclosingPosition, s"TpeTag not implemented for $x: ${x.getClass}", true) - // c.abort(c.enclosingPosition, "Not implemented") - // } - // } - // } - - // private def transformTpe(t: c.Type): c.Tree = { - // val normalized = t.dealias.etaExpand - // println(normalized + " " + normalized.getClass) - // val resolved = - // if (normalized.typeSymbol.isParameter) { - // normalized match { - // case PolyType(typeParams, _) => - // println(s"POLY TYPE: $typeParams") - // typeParams.size match { - // case 1 => - // val tcTagTpe = appliedType(weakTypeOf[Tag.TCTag[X] forSome {type X[_]}].typeConstructor, t.typeConstructor) - // optionFromImplicitTree(c.inferImplicitValue(tcTagTpe)) - // .map(t => q"$t.tpe") - // case n => - // None - // } - // case x if x.typeSymbol.isParameter => - // val tagTpe = appliedType(weakTypeOf[Tag.TPTag[X] forSome {type X}].typeConstructor, t) - // optionFromImplicitTree(c.inferImplicitValue(tagTpe)) - // .map{t => q"$t.tpe"} - // case x => None - // } - // } else { - // Some(q"${normalized.typeSymbol.fullName}") - // } - - // resolved match { - // case None => c.abort(c.enclosingPosition, s"Not found Tag for $t") - // case Some(tree) => - // tree - // // val arguments = t.typeArgs.map(transformTpe) - // // q"_root_.make.Tag.TpeTag.Type($tree, List(..$arguments))" - // } - // } - private def optionFromImplicitTree(tree: c.Tree): Option[c.Tree] = tree match { case EmptyTree => None @@ -197,7 +70,6 @@ class TpeTagMacro(val c: blackbox.Context) { ): c.Expr[Tag.TCTag[F]] = { val tpe = weakTypeTag.tpe - println(s"TCTAG: ${tpe} ${tpe.getClass}") tpe match { case tpe: PolyType => val symbol = c.internal.fullyInitialize(tpe.resultType.typeSymbol) @@ -236,12 +108,10 @@ class TpeTagMacro(val c: blackbox.Context) { // see test case with cats.Id val skip = name.startsWith(" X(z, y)) + implicit def xMake[G[_]: Applicative: Tag.TCTag](implicit deps: Make[G, (Z[G], Y[G])]): Make[G, X[G]] = + deps.mapN((z, y) => X(z, y)) - // implicit def wMake[F[_]: Applicative: Tag.TCTag](implicit deps: Make[F, (Y[F], X[F])]): Make[F, W[F]] = - // deps.mapN((y, x) => W(y, x)) + implicit def wMake[F[_]: Applicative: Tag.TCTag](implicit deps: Make[F, (Y[F], X[F])]): Make[F, W[F]] = + deps.mapN((y, x) => W(y, x)) - // val resolve = Make.of[IO, (W[IO], X[IO], Foo)] + val resolve = Make.of[IO, (W[IO], X[IO], Foo)] - // val (w, x, foo) = resolve.make.unsafeRunSync() + val (w, x, foo) = resolve.make.unsafeRunSync() - // assert(w.x == x) - // assert(foo.w == w) - // assert(foo.z == w.x.z) - // } + assert(w.x == x) + assert(foo.w == w) + assert(foo.z == w.x.z) + } - // test("higher kind tags 1") { + test("higher kind tags 1") { - // case class A[F[_]](value: F[String]) - // case class C[F[_]](a: A[F]) - // case class D[F[_], G[_]](b: C[F], c: C[G]) + case class A[F[_]](value: F[String]) + case class C[F[_]](a: A[F]) + case class D[F[_], G[_]](b: C[F], c: C[G]) - // implicit def aMake[F[_]: Applicative, Z[_]: Applicative: Tag.TCTag]: Make[F, A[Z]] = Make.pure(A(Applicative[Z].pure("42"))) + implicit def aMake[F[_]: Applicative, Z[_]: Applicative: Tag.TCTag]: Make[F, A[Z]] = Make.pure(A(Applicative[Z].pure("42"))) - // implicit def cMake[F[_]: Applicative, G[_]: Applicative: Tag.TCTag]( - // implicit a: Make[F, A[G]] - // ): Make[F, C[G]] = - // a.map(a => C(a)) + implicit def cMake[F[_]: Applicative, G[_]: Applicative: Tag.TCTag]( + implicit a: Make[F, A[G]] + ): Make[F, C[G]] = + a.map(a => C(a)) - // implicit def dMake[F[_]: Applicative, G[_]: Applicative: Tag.TCTag, H[_]: Applicative: Tag.TCTag]( - // implicit deps: Make[F, (C[G], C[H])] - // ): Make[F, D[G, H]] = - // deps.mapN(D(_, _)) + implicit def dMake[F[_]: Applicative, G[_]: Applicative: Tag.TCTag, H[_]: Applicative: Tag.TCTag]( + implicit deps: Make[F, (C[G], C[H])] + ): Make[F, D[G, H]] = + deps.mapN(D(_, _)) - // // import enableDebug._ + // import enableDebug._ - // val resolved = Make.of[IO, D[Option, IO]] - // val d = resolved.make.unsafeRunSync() - // assertEquals(d.b, C(A("42".some))) - // assertEquals(d.c.a.value.unsafeRunSync(), "42") - // } + val resolved = Make.of[IO, D[Option, IO]] + val d = resolved.make.unsafeRunSync() + assertEquals(d.b, C(A("42".some))) + assertEquals(d.c.a.value.unsafeRunSync(), "42") + } - // test("higher kind tags 2") { + test("higher kind tags 2") { - // case class A[F[_]](value: F[String]) - // case class B(a: String) + case class A[F[_]](value: F[String]) + case class B(a: String) - // implicit def aMake[F[_]: Applicative, Z[_]: Applicative: Tag.TCTag]: Make[F, A[Z]] = Make.pure(A(Applicative[Z].pure("42"))) + implicit def aMake[F[_]: Applicative, Z[_]: Applicative: Tag.TCTag]: Make[F, A[Z]] = Make.pure(A(Applicative[Z].pure("42"))) - // implicit def bMake[F[_]: Applicative: Tag.TCTag]( - // implicit a: Make[F, A[F]] - // ): Make[F, B] = - // a.mapF(a => a.value.map(v => B(v))) + implicit def bMake[F[_]: Applicative: Tag.TCTag]( + implicit a: Make[F, A[F]] + ): Make[F, B] = + a.mapF(a => a.value.map(v => B(v))) - // // import enableDebug._ + // import enableDebug._ - // val resolved = Make.of[IO, B] - // assertEquals(resolved.make.unsafeRunSync(), B("42")) - // } + val resolved = Make.of[IO, B] + assertEquals(resolved.make.unsafeRunSync(), B("42")) + } test("diverging implicit(tuples)") { + case class A[F[_]](value: F[String]) case class B(a: String, i: Int) @autoMake case class C(b: B) + implicit def cMake[F[_]: Applicative]( + implicit dep: Dep[F, B] + ): Make[F, C] = dep.value.map(C(_)) + implicit def bMake[F[_]: Applicative]( implicit - deps: Make[F, (Int, A[F])], + deps: Dep[F, (Int, A[F])], ): Make[F, B] = - deps.mapFN((i, a) => a.value.map(v => B(v, i))) + deps.value.mapFN((i, a) => a.value.map(v => B(v, i))) import enableDebug._ @@ -132,7 +137,7 @@ class MakeTest extends FunSuite { implicit val intMake = Make.pure[IO, Int](42) - val resolved = Make.of[IO, (C, B)] + val resolved = Make.debugOf[IO, (C, B)] assertEquals(resolved.make.unsafeRunSync(), (C(B("42", 42)), B("42", 42))) } diff --git a/modules/core/src/test/scala/make/TagTest.scala b/modules/core/src/test/scala/make/TagTest.scala index b507484..b2ee750 100644 --- a/modules/core/src/test/scala/make/TagTest.scala +++ b/modules/core/src/test/scala/make/TagTest.scala @@ -6,22 +6,22 @@ import make.Tag.TpeTag class TagTest extends FunSuite { - // test("tags") { - // assertEquals(Tag.TpeTag[Int].tpe.render, "scala.Int") - // assertEquals(Tag.TpeTag[List[String]].tpe.render, "scala.collection.immutable.List[java.lang.String]") - // assertEquals(func[IO].tpe.render, "make.TagTest.ABC[cats.effect.IO]") - // assertEquals(func2[IO].tpe.render, "cats.effect.IO[scala.Int]") - // assertEquals(func3[String].tpe.render, "scala.collection.immutable.List[java.lang.String]") - // assertEquals(func[cats.Id].tpe.render, "make.TagTest.ABC[cats.Id]") - // assertEquals(func2[cats.Id].tpe.render, "cats.Id[scala.Int]") - // assertEquals(func4[String, IO[List[Int]]].tpe.render, "scala.Tuple2[java.lang.String, cats.effect.IO[scala.collection.immutable.List[scala.Int]]]") - // } + test("tags") { + assertEquals(Tag.TpeTag[Int].tpe.render, "scala.Int") + assertEquals(Tag.TpeTag[List[String]].tpe.render, "scala.collection.immutable.List[java.lang.String]") + assertEquals(func[IO].tpe.render, "make.TagTest.ABC[cats.effect.IO]") + assertEquals(func2[IO].tpe.render, "cats.effect.IO[scala.Int]") + assertEquals(func3[String].tpe.render, "scala.collection.immutable.List[java.lang.String]") + assertEquals(func[cats.Id].tpe.render, "make.TagTest.ABC[cats.Id]") + assertEquals(func2[cats.Id].tpe.render, "cats.Id[scala.Int]") + assertEquals(func4[String, IO[List[Int]]].tpe.render, "scala.Tuple2[java.lang.String, cats.effect.IO[scala.collection.immutable.List[scala.Int]]]") + } - // class ABC[F[_]] - // def func[F[_]: Tag.TCTag]: Tag.TpeTag[ABC[F]] = Tag.TpeTag[ABC[F]] + class ABC[F[_]] + def func[F[_]: Tag.TCTag]: Tag.TpeTag[ABC[F]] = Tag.TpeTag[ABC[F]] - // def func2[G[_]: Tag.TCTag]: Tag.TpeTag[G[Int]] = Tag.TpeTag[G[Int]] - // def func3[A: Tag.TPTag]: Tag.TpeTag[List[A]] = Tag.TpeTag[List[A]] - // def func4[A, B](implicit tag: TpeTag[(A, B)]): Tag.TpeTag[(A, B)] = Tag.TpeTag[(A, B)] + def func2[G[_]: Tag.TCTag]: Tag.TpeTag[G[Int]] = Tag.TpeTag[G[Int]] + def func3[A: Tag.TPTag]: Tag.TpeTag[List[A]] = Tag.TpeTag[List[A]] + def func4[A, B](implicit tag: TpeTag[(A, B)]): Tag.TpeTag[(A, B)] = Tag.TpeTag[(A, B)] } \ No newline at end of file diff --git a/modules/core/src/test/scala/make/itCompiles.scala b/modules/core/src/test/scala/make/itCompiles.scala index 52b6cd6..fd6d1f8 100644 --- a/modules/core/src/test/scala/make/itCompiles.scala +++ b/modules/core/src/test/scala/make/itCompiles.scala @@ -10,77 +10,77 @@ import cats.effect.Sync */ object itCompiles { - // object annotations { + object annotations { - // @autoMake - // case class Smth1(a: Int) - // object Smth1Test { - // implicit val intMake = Make.pure[IO, Int](42) - // Make.of[IO, Smth1] - // } + @autoMake + case class Smth1(a: Int) + object Smth1Test { + implicit val intMake = Make.pure[IO, Int](42) + Make.of[IO, Smth1] + } - // @autoMake - // case class Smth2(a: Int, b: String) - // object Smth2Test { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // Make.of[IO, Smth2] - // } + @autoMake + case class Smth2(a: Int, b: String) + object Smth2Test { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + Make.of[IO, Smth2] + } - // @autoMake - // case class Smth3(a: Int, b: String, c: Double) - // object Smth3Test { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // implicit val doubleMake = Make.pure[IO, Double](42) - // Make.of[IO, Smth3] - // } + @autoMake + case class Smth3(a: Int, b: String, c: Double) + object Smth3Test { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + implicit val doubleMake = Make.pure[IO, Double](42) + Make.of[IO, Smth3] + } - // @autoMake - // case class Smth2Implicit[F[_]](a: Int, b: String)(implicit val F: Sync[F]) - // object Smth2ImplicitTest { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // Make.of[IO, Smth2Implicit[IO]] - // } + @autoMake + case class Smth2Implicit[F[_]](a: Int, b: String)(implicit val F: Sync[F]) + object Smth2ImplicitTest { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + Make.of[IO, Smth2Implicit[IO]] + } - // @autoMake - // class NonCase1(a: Int) - // object NonCase1Test { - // implicit val intMake = Make.pure[IO, Int](42) - // Make.of[IO, NonCase1] - // } + @autoMake + class NonCase1(a: Int) + object NonCase1Test { + implicit val intMake = Make.pure[IO, Int](42) + Make.of[IO, NonCase1] + } - // @autoMake - // class NonCase2(a: Int, b: String) - // object NonCase2Test { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // Make.of[IO, NonCase2] - // } + @autoMake + class NonCase2(a: Int, b: String) + object NonCase2Test { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + Make.of[IO, NonCase2] + } - // @autoMake - // class NonCaseImplicit[F[_]](a: Int, b: String)(implicit val F: Sync[F]) - // object NonCaseImplicitTest { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // Make.of[IO, NonCaseImplicit[IO]] - // } + @autoMake + class NonCaseImplicit[F[_]](a: Int, b: String)(implicit val F: Sync[F]) + object NonCaseImplicitTest { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + Make.of[IO, NonCaseImplicit[IO]] + } - // @autoMake - // class NonCaseImplicit2[F[_]: Sync](a: Int, b: String) - // object NonCaseImplicit2Test { - // implicit val intMake = Make.pure[IO, Int](42) - // implicit val stringMake = Make.pure[IO, String]("42") - // Make.of[IO, NonCaseImplicit2[IO]] - // } + @autoMake + class NonCaseImplicit2[F[_]: Sync](a: Int, b: String) + object NonCaseImplicit2Test { + implicit val intMake = Make.pure[IO, Int](42) + implicit val stringMake = Make.pure[IO, String]("42") + Make.of[IO, NonCaseImplicit2[IO]] + } - // @autoMake - // class HasTpeParam[X](a: X) - // object HasTpeParam { - // implicit val intMake = Make.pure[IO, Int](42) - // Make.of[IO, HasTpeParam[Int]] - // } - // } + @autoMake + class HasTpeParam[X](a: X) + object HasTpeParam { + implicit val intMake = Make.pure[IO, Int](42) + Make.of[IO, HasTpeParam[Int]] + } + } } diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala index d590615..04c63f2 100644 --- a/project/Boilerplate.scala +++ b/project/Boilerplate.scala @@ -56,8 +56,8 @@ object Boilerplate { val apArgs = synVals.reverse.dropRight(1) val impl = synVals.foldLeft(""){ - case ("" , c) => s"map($c)(${synVals.mkString("", " => ", " => ")} ${`(a..n)`})" - case (acc, c) => s"ap($c)($acc)" + case ("" , c) => s"MakeBasicOps.map($c)(${synVals.mkString("", " => ", " => ")} ${`(a..n)`})" + case (acc, c) => s"MakeBasicOps.ap($c)($acc)" } val toArity = arity - 1 val funcTags = @@ -79,7 +79,7 @@ object Boilerplate { |import make.Tag |import cats.Applicative | - |trait MakeProductNOps extends MakeBasicOps { + |trait MakeProductNOps { | - def productN[FF[_]: Applicative, ${`A..N`}](${`MakeA..MakeN`})(implicit $implictTags): Make[FF, ${`(A..N)`}] = - $impl @@ -111,9 +111,9 @@ object Boilerplate { val deps = (0 until arity).map(n => { val tpe = (n+'A').toChar val arg = (n+'a').toChar - s"$arg: Make[FF, $tpe]" + s"$arg: Dep[FF, $tpe]" }) - val args = synVals.map(s => s"$s").mkString(",") + val args = synVals.map(s => s"$s.value").mkString(",") val implicitValues = (implicitTags ++ deps).mkString(",")