From 39f38d4fd354ec70d4dcaf52a8804c8143b1c3f0 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sun, 26 Nov 2017 09:20:14 -0800 Subject: Refactor `build.sc` to pull out common `ScalaModule` code into a separate trait Also workaround a few scala-reflect bugs in `Discovered` and `Router` that were making this not-work --- core/src/main/scala/mill/discover/Discovered.scala | 9 +++++---- core/src/main/scala/mill/discover/Router.scala | 2 ++ core/src/test/scala/mill/discover/DiscoveredTests.scala | 14 +++++++++++++- core/src/test/scala/mill/util/TestGraphs.scala | 11 +++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) (limited to 'core') diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala index e3939d5b..aef5f14f 100644 --- a/core/src/main/scala/mill/discover/Discovered.scala +++ b/core/src/main/scala/mill/discover/Discovered.scala @@ -36,7 +36,7 @@ object Discovered { def applyImpl[T: c.WeakTypeTag](c: Context): c.Expr[Discovered[T]] = { import c.universe._ - val tpe = c.weakTypeTag[T].tpe + val baseType = c.weakTypeTag[T].tpe def rec(segments: List[Option[String]], t: c.Type): Tree = { @@ -77,6 +77,7 @@ object Discovered { q"($name, ${rec(Some(name) :: segments, m.typeSignature.finalResultType)})" } + val crossName = q"${TermName(c.freshName())}" val hierarchySelector = { val base = q"${TermName(c.freshName())}" @@ -84,7 +85,7 @@ object Discovered { case (prefix, (Some(name), i)) => q"$prefix.${TermName(name)}" case (prefix, (None, i)) => q"$prefix.apply($crossName($i):_*)" } - q"($base: $tpe, $crossName: List[List[Any]]) => $ident" + q"($base: $baseType, $crossName: List[List[Any]]) => $ident.asInstanceOf[$t]" } val commands = @@ -92,7 +93,7 @@ object Discovered { .asInstanceOf[Seq[c.Tree]] .toList - q"""mill.discover.Mirror[$tpe, $t]( + q"""mill.discover.Mirror[$baseType, $t]( $hierarchySelector, $commands, $targets, @@ -101,7 +102,7 @@ object Discovered { )""" } - val res = q"new _root_.mill.discover.Discovered(${rec(Nil, tpe)})" + val res = q"new _root_.mill.discover.Discovered(${rec(Nil, baseType)})" // println(res) c.Expr[Discovered[T]](res) } diff --git a/core/src/main/scala/mill/discover/Router.scala b/core/src/main/scala/mill/discover/Router.scala index dda682b2..90e83430 100644 --- a/core/src/main/scala/mill/discover/Router.scala +++ b/core/src/main/scala/mill/discover/Router.scala @@ -264,7 +264,9 @@ class Router [C <: Context](val c: C) { if member.isTerm memTerm = member.asTerm if memTerm.isMethod + if !memTerm.isModule } yield memTerm.asMethod + extractableMembers flatMap { case memTerm => if (memTerm.isSetter || memTerm.isConstructor || memTerm.isGetter) Nil else Seq(memTerm) diff --git a/core/src/test/scala/mill/discover/DiscoveredTests.scala b/core/src/test/scala/mill/discover/DiscoveredTests.scala index e606b2a9..98a54759 100644 --- a/core/src/test/scala/mill/discover/DiscoveredTests.scala +++ b/core/src/test/scala/mill/discover/DiscoveredTests.scala @@ -6,7 +6,7 @@ import mill.discover.Router.{ArgSig, EntryPoint} import utest._ import mill.{Module, T} import mill.discover.Mirror.Segment.Label -import mill.util.TestGraphs.nestedModule +import mill.util.TestGraphs.{TraitWithModuleObject, nestedModule} object DiscoveredTests extends TestSuite{ val tests = Tests{ @@ -36,6 +36,18 @@ object DiscoveredTests extends TestSuite{ assert(mapped.toSet == expected.toSet) } + 'traitWithModule - { + val discovered = Discovered[TraitWithModuleObject.type] + val mapped = discovered.targets(TraitWithModuleObject).map(x => x.segments -> x.target) + val expected = Seq( + ( + List(Label("TraitModule"), Label("testFramework")), + TraitWithModuleObject.TraitModule.testFramework + ) + ) + assert(mapped == expected) + } + 'commands - { object outer { def hello() = T.command{ diff --git a/core/src/test/scala/mill/util/TestGraphs.scala b/core/src/test/scala/mill/util/TestGraphs.scala index edea69a4..a69221da 100644 --- a/core/src/test/scala/mill/util/TestGraphs.scala +++ b/core/src/test/scala/mill/util/TestGraphs.scala @@ -167,6 +167,17 @@ object TestGraphs{ } + trait TraitWithModule extends Module{ outer => + object TraitModule extends Module{ + def testFramework = T{ "mill.UTestFramework" } + def test() = T.command{ ()/*donothing*/ } + } + } + + + // Make sure nested objects inherited from traits work + object TraitWithModuleObject extends TraitWithModule + object singleCross{ val cross = -- cgit v1.2.3