diff options
Diffstat (limited to 'core/src/main/scala')
-rw-r--r-- | core/src/main/scala/mill/define/Cross.scala | 61 |
1 files changed, 24 insertions, 37 deletions
diff --git a/core/src/main/scala/mill/define/Cross.scala b/core/src/main/scala/mill/define/Cross.scala index 691c5691..6226590d 100644 --- a/core/src/main/scala/mill/define/Cross.scala +++ b/core/src/main/scala/mill/define/Cross.scala @@ -4,60 +4,47 @@ import scala.reflect.macros.blackbox object Cross{ - abstract class Implicit[T]{ - def make(v: Any, ctx: Module.Ctx): T - def crossValues(v: Any): List[Any] - } - object Implicit{ - implicit def make[T]: Implicit[T] = macro makeImpl[T] - def makeImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Implicit[T]] = { + case class Factory[T](make: (Product, Module.Ctx) => T) + + object Factory{ + implicit def make[T]: Factory[T] = macro makeImpl[T] + def makeImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Factory[T]] = { import c.universe._ val tpe = weakTypeOf[T] val primaryConstructorArgs = tpe.typeSymbol.asClass.primaryConstructor.typeSignature.paramLists.head - val tree = primaryConstructorArgs match{ - case List(arg) => - q""" - new mill.define.Cross.Implicit[$tpe]{ - def make(v: Any, ctx0: mill.define.Module.Ctx) = new $tpe(v.asInstanceOf[${arg.info}]){ - override def ctx = ctx0 - } - def crossValues(v: Any) = List(v) - } - """ - case args => - val argTupleValues = for((a, n) <- args.zipWithIndex) yield{ - q"v.asInstanceOf[scala.Product].productElement($n).asInstanceOf[${a.info}]" - } - q""" - new mill.define.Cross.Implicit[$tpe]{ - def make(v: Any, ctx0: mill.define.Module.Ctx) = new $tpe(..$argTupleValues){ - override def ctx = ctx0 - } - def crossValues(v: Any) = List(..$argTupleValues) - } - """ + val argTupleValues = + for((a, n) <- primaryConstructorArgs.zipWithIndex) + yield q"v.productElement($n).asInstanceOf[${a.info}]" + + val instance = c.Expr[(Product, Module.Ctx) => T]( + q"{ (v, ctx0) => new $tpe(..$argTupleValues){ override def ctx = ctx0 } }" + ) - } - c.Expr[Implicit[T]](tree) + reify { mill.define.Cross.Factory[T](instance.splice) } } } } class Cross[T](cases: Any*) - (implicit ci: Cross.Implicit[T], - val ctx: Module.Ctx){ - val items = for(c <- cases.toList) yield{ - val crossValues = ci.crossValues(c) + (implicit ci: Cross.Factory[T], + val ctx: Module.Ctx){ + + val items = for(c0 <- cases.toList) yield{ + val c = c0 match{ + case p: Product => p + case v => Tuple1(v) + } + val crossValues = c.productIterator.toList.reverse val sub = ci.make( c, ctx.copy( segments0 = ctx.segments0 ++ Seq(ctx.segment), - segment = Segment.Cross(crossValues.reverse) + segment = Segment.Cross(crossValues) ) ) - (crossValues.reverse, sub) + (crossValues, sub) } val itemMap = items.toMap def apply(args: Any*) = itemMap(args.toList) |