summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-01-08 01:46:17 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-01-08 01:46:17 -0800
commitb4cabadf8071d12749805cd7ea160b54b26e1b30 (patch)
tree58ed5394ff8ccb9453f1a410fc65a8beb6dbcf0a
parent51e565c519aedc5dc8494a44cc74c750f6a6e9cf (diff)
downloadmill-b4cabadf8071d12749805cd7ea160b54b26e1b30.tar.gz
mill-b4cabadf8071d12749805cd7ea160b54b26e1b30.tar.bz2
mill-b4cabadf8071d12749805cd7ea160b54b26e1b30.zip
Tidy up `Cross` implementation
-rw-r--r--core/src/main/scala/mill/define/Cross.scala61
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)