From 883c382d58ce3aabf5bd1c09c4f6a833932e8be4 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Tue, 7 Nov 2017 22:13:16 -0800 Subject: First full metacircular compile-build-execute workflow now works using the `build.sc` file in the root of the repo. Run using ``` sbt scalaplugin/compile "core/run build.sc ScalaPlugin.console" ``` --- core/src/main/scala/forge/Main.scala | 53 ++++++++++++++++++---- .../src/main/scala/forge/discover/Discovered.scala | 19 +++++--- core/src/main/scala/forge/eval/Evaluator.scala | 2 +- .../src/test/scala/forge/JavaCompileJarTests.scala | 4 +- 4 files changed, 59 insertions(+), 19 deletions(-) (limited to 'core') diff --git a/core/src/main/scala/forge/Main.scala b/core/src/main/scala/forge/Main.scala index e3b89f60..3820244b 100644 --- a/core/src/main/scala/forge/Main.scala +++ b/core/src/main/scala/forge/Main.scala @@ -2,25 +2,58 @@ package forge import ammonite.ops._ import ammonite.util.{Name, Res} -import forge.discover.Discovered +import forge.define.Target +import forge.discover.{Discovered, NestedEntry} import forge.eval.Evaluator import forge.util.OSet +import play.api.libs.json.Format object Main { def main(args: Array[String]): Unit = { + val List(buildFile, selector0, rest @_*) = args.toList + pprint.log((buildFile, selector0, rest)) + val selector = selector0.split('.').toList ammonite.Main().instantiateInterpreter() match{ + case Left(problems) => pprint.log(problems) case Right(interp) => - val result = ammonite.main.Scripts.runScript(pwd, Path(args(0), pwd), interp, Nil) - - val (obj, discovered) = result.asInstanceOf[Res.Success[(Any, Discovered[Any])]].s - val mapping = Discovered.mapping(obj)(discovered) - val workspacePath = pwd / 'target / 'javac - val evaluator = new Evaluator(workspacePath, mapping) - val evaluated = evaluator.evaluate(OSet.from(mapping.keys)).evaluated.filter(mapping.contains) - (result, interp.watchedFiles) - case Left(problems) => problems + val result = ammonite.main.Scripts.runScript(pwd, Path(buildFile, pwd), interp, Nil) + + if (!result.isSuccess) println(result) + else{ + + val (obj, discovered) = result.asInstanceOf[Res.Success[(Any, Discovered[Any])]].s + val mapping = Discovered.mapping(obj)(discovered) + val workspacePath = pwd / 'out + val evaluator = new Evaluator(workspacePath, mapping) + val mainRoutes = discovered.mains.map(x => (x.path :+ x.entryPoint.name, Left(x))) + val targetRoutes = discovered.targets.map(x => x._1 -> Right(x)) + val allRoutes = (mainRoutes ++ targetRoutes).toMap[ + Seq[String], + Either[NestedEntry[Any, _], (Seq[String], Format[_], Any => Target[_])] + ] + allRoutes.get(selector) match{ + case Some(Left(nestedEntryPoint)) => + nestedEntryPoint.invoke( + obj, + ammonite.main.Scripts.groupArgs(rest.toList) + ) match{ + case error: forge.discover.Router.Result.Error => + println("Failed to evaluate main method: " + error) + case forge.discover.Router.Result.Success(target) => + println("Found target! " + target) + val evaluated = evaluator.evaluate(OSet(target)) + pprint.log(evaluated) + } + + case None => println("Unknown selector: " + selector) + case Some(Right((_, _, targetFunc))) => + val target = targetFunc(obj) + val evaluated = evaluator.evaluate(OSet(target)) + pprint.log(evaluated) + } + } } } diff --git a/core/src/main/scala/forge/discover/Discovered.scala b/core/src/main/scala/forge/discover/Discovered.scala index fcf5ccbd..ae274fb3 100644 --- a/core/src/main/scala/forge/discover/Discovered.scala +++ b/core/src/main/scala/forge/discover/Discovered.scala @@ -1,7 +1,7 @@ package forge.discover import forge.define.Target -import forge.discover.Router.EntryPoint +import forge.discover.Router.{EntryPoint, Result} import play.api.libs.json.Format import scala.language.experimental.macros @@ -17,7 +17,11 @@ case class Labelled[T](target: Target[T], segments: Seq[String]) -case class NestedEntry[T, V](path: Seq[String], resolve: T => V, entryPoint: EntryPoint[V]) +case class NestedEntry[T, V](path: Seq[String], resolve: T => V, entryPoint: EntryPoint[V]){ + def invoke(target: T, groupedArgs: Seq[(String, Option[String])]): Result[Target[Any]] = { + entryPoint.invoke(resolve(target),groupedArgs) + } +} object NestedEntry{ def make[T, V](path: Seq[String], resolve: T => V) (entryPoint: EntryPoint[V]) = NestedEntry(path, resolve, entryPoint) @@ -47,6 +51,7 @@ object Discovered { import c.universe._ val tpe = c.weakTypeTag[T].tpe def rec(segments: List[String], t: c.Type): (Seq[(Seq[String], Tree)], Seq[Seq[String]]) = { + val r = new Router(c) val selfMains = for(tree <- r.getAllRoutesForClass(t.asInstanceOf[r.c.Type]).asInstanceOf[Seq[c.Tree]]) @@ -55,17 +60,17 @@ object Discovered { val items = for { m <- t.members.toSeq if - (m.isTerm && (m.asTerm.isGetter || m.asTerm.isLazy)) || + (m.isTerm && (m.asTerm.isGetter || m.asTerm.isLazy)) || m.isModule || (m.isMethod && m.typeSignature.paramLists.isEmpty && m.typeSignature.resultType <:< c.weakTypeOf[Target[_]]) - if !m.fullName.contains('$') + if !m.name.toString.contains('$') } yield { val extendedSegments = m.name.toString :: segments val self = if (m.typeSignature.resultType <:< c.weakTypeOf[Target[_]]) Seq(extendedSegments) else Nil - val (mains, children) = rec(extendedSegments, m.typeSignature) + val (mains, children) = rec(extendedSegments, m.typeSignature) (mains, self ++ children) } @@ -100,10 +105,12 @@ object Discovered { q"forge.discover.NestedEntry.make(Seq(..$segments), ($arg: $tpe) => $select)($entry)" } + pprint.log(result.length) + pprint.log(nested.length) c.Expr[Discovered[T]](q""" new _root_.forge.discover.Discovered( $result, - _root_.scala.Seq(..$nested) + ${nested.toList} ) """) } diff --git a/core/src/main/scala/forge/eval/Evaluator.scala b/core/src/main/scala/forge/eval/Evaluator.scala index b52a342c..6f2d43f0 100644 --- a/core/src/main/scala/forge/eval/Evaluator.scala +++ b/core/src/main/scala/forge/eval/Evaluator.scala @@ -130,7 +130,7 @@ class Evaluator(workspacePath: Path, object Evaluator{ class TopoSorted private[Evaluator] (val values: OSet[Target[_]]) - case class Results(values: Seq[Any], evaluated: OSet[Target[_]]) + case class Results(values: Seq[Any], targets: OSet[Target[_]]) def groupAroundNamedTargets(topoSortedTargets: TopoSorted, labeling: Map[Target[_], Labelled[_]]): MultiBiMap[Int, Target[_]] = { diff --git a/core/src/test/scala/forge/JavaCompileJarTests.scala b/core/src/test/scala/forge/JavaCompileJarTests.scala index 92e1d0e9..081290ca 100644 --- a/core/src/test/scala/forge/JavaCompileJarTests.scala +++ b/core/src/test/scala/forge/JavaCompileJarTests.scala @@ -56,12 +56,12 @@ object JavaCompileJarTests extends TestSuite{ def eval[T](t: Target[T]): (T, Int) = { val evaluator = new Evaluator(workspacePath, mapping) val evaluated = evaluator.evaluate(OSet(t)) - (evaluated.values(0).asInstanceOf[T], evaluated.evaluated.size) + (evaluated.values(0).asInstanceOf[T], evaluated.targets.size) } def check(targets: OSet[Target[_]], expected: OSet[Target[_]]) = { val evaluator = new Evaluator(workspacePath, mapping) - val evaluated = evaluator.evaluate(targets).evaluated.filter(mapping.contains) + val evaluated = evaluator.evaluate(targets).targets.filter(mapping.contains) assert(evaluated == expected) } -- cgit v1.2.3