summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-11-01 23:22:32 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2017-11-01 23:22:32 -0700
commitbfbbe450d4ac330f83fb28334e57789f3130a51c (patch)
treefb7e43d942c59481afbf0e3824db1fbfa29ba65e /src
parent8637fffa264065b4bbc10b686102f5c36334cd6b (diff)
downloadmill-bfbbe450d4ac330f83fb28334e57789f3130a51c.tar.gz
mill-bfbbe450d4ac330f83fb28334e57789f3130a51c.tar.bz2
mill-bfbbe450d4ac330f83fb28334e57789f3130a51c.zip
First pass at idiom-bracket macro works
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/forge/Target.scala40
-rw-r--r--src/main/scala/forge/package.scala1
-rw-r--r--src/main/scala/forge/scalaplugin/Compile.scala109
-rw-r--r--src/test/scala/forge/MetacircularTests.scala22
4 files changed, 52 insertions, 120 deletions
diff --git a/src/main/scala/forge/Target.scala b/src/main/scala/forge/Target.scala
index c0b85f2a..a6a8eda7 100644
--- a/src/main/scala/forge/Target.scala
+++ b/src/main/scala/forge/Target.scala
@@ -6,6 +6,10 @@ import forge.util.{Args, PathRef}
import play.api.libs.json.{Format, JsValue, Json}
import scala.annotation.compileTimeOnly
+import language.experimental.macros
+import reflect.macros.blackbox.Context
+import scala.collection.mutable
+
abstract class Target[T] extends Target.Ops[T]{
/**
* What other Targets does this Target depend on?
@@ -40,6 +44,42 @@ object Target{
}
implicit def toTarget[T](t: T): Target[T] = new Target0(t)
implicit def apply[T](t: => Target[T]): Target[T] = new Target1(t)
+ def raw[T](t: T): Target[T] = macro impl[T]
+ def impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Target[T]] = {
+ import c.universe._
+ val bound = collection.mutable.Buffer.empty[(c.Tree, c.TermName)]
+
+ object transformer extends c.universe.Transformer{
+ override def transform(tree: c.Tree): c.Tree = tree match{
+ case q"$fun.apply()" if fun.tpe <:< weakTypeOf[Target[_]] =>
+ val newTerm = TermName(c.freshName())
+ bound.append((fun, newTerm))
+ val ident = Ident(newTerm)
+ ident
+ case _ => super.transform(tree)
+ }
+ }
+
+ val transformed = transformer.transform(t.tree)
+ val (exprs, names) = bound.unzip
+ val embedded = bound.length match{
+ case 0 => transformed
+ case 1 => q"zip(..$exprs).map{ case ${names(0)} => $transformed }"
+ case n =>
+
+ // For some reason, pq"(..$names)" doesn't work...
+ val pq = n match{
+ case 2 => pq"(${names(0)}, ${names(1)})"
+ case 3 => pq"(${names(0)}, ${names(1)}, ${names(2)})"
+ case 4 => pq"(${names(0)}, ${names(1)}, ${names(2)}, ${names(3)})"
+ case 5 => pq"(${names(0)}, ${names(1)}, ${names(2)}, ${names(3)}, ${names(4)})"
+ }
+ q"zip(..$exprs).map{ case $pq => $transformed }"
+ }
+
+
+ c.Expr[Target[T]](c.untypecheck(embedded))
+ }
abstract class Ops[T]{ this: Target[T] =>
def map[V](f: T => V) = new Target.Mapped(this, f)
diff --git a/src/main/scala/forge/package.scala b/src/main/scala/forge/package.scala
index 00562a85..f7635b9b 100644
--- a/src/main/scala/forge/package.scala
+++ b/src/main/scala/forge/package.scala
@@ -6,6 +6,7 @@ package object forge {
val T = Target
type T[T] = Target[T]
+ def zip[A](a: T[A]) = a
def zip[A, B](a: T[A], b: T[B]) = a.zip(b)
def zip[A, B, C](a: T[A], b: T[B], c: T[C]) = new Target[(A, B, C)]{
val inputs = Seq(a, b, c)
diff --git a/src/main/scala/forge/scalaplugin/Compile.scala b/src/main/scala/forge/scalaplugin/Compile.scala
deleted file mode 100644
index 77ff3a5e..00000000
--- a/src/main/scala/forge/scalaplugin/Compile.scala
+++ /dev/null
@@ -1,109 +0,0 @@
-package forge.scalaplugin
-import ammonite.ops._
-import java.io.File
-
-import coursier._
-import forge.Target
-import forge.util.OSet
-import sbt.internal.inc.{FreshCompilerCache, ScalaInstance, ZincUtil}
-import sbt.internal.util.{ConsoleOut, MainAppender}
-import sbt.util.LogExchange
-import xsbti.api.{ClassLike, DependencyContext}
-import xsbti.compile._
-
-import scalaz.concurrent.Task
-object Compile {
-
- def apply(scalaVersion: Target[String],
- dependencies: Target[OSet[Dependency]]) = {
- for((s, d) <- scalaVersion.zip(dependencies))
- yield underlying(s, d)
-
- }
- def underlying(scalaVersion: String,
- dependencies: OSet[Dependency]) = {
-
- val binaryScalaVersion = scalaVersion.split('.').dropRight(1).mkString(".")
- val start = Resolution(
- Set(
- Dependency(Module("org.scala-lang", "scala-compiler"), scalaVersion),
- Dependency(Module("org.scala-lang", "scala-library"), scalaVersion),
- Dependency(Module("org.scala-sbt", s"compiler-bridge_$binaryScalaVersion"), "1.0.3"),
- Dependency(Module("com.typesafe.play", s"play-json_$binaryScalaVersion"), "2.6.6")
- )
- )
- val repositories = Seq(
- Cache.ivy2Local,
- MavenRepository("https://repo1.maven.org/maven2")
- )
-
- val fetch = Fetch.from(repositories, Cache.fetch())
- val resolution = start.process.run(fetch).unsafePerformSync
-
-
- val localArtifacts: Seq[File] = Task.gatherUnordered(
- resolution.artifacts.map(Cache.file(_).run)
- ).unsafePerformSync.flatMap(_.toOption)
-
- pprint.log(localArtifacts)
- def grepJar(s: String) = localArtifacts.find(_.toString.endsWith(s)).get
-
- val scalac = ZincUtil.scalaCompiler(
- new ScalaInstance(
- version = scalaVersion,
- loader = getClass.getClassLoader,
- libraryJar = grepJar(s"scala-library-$scalaVersion.jar"),
- compilerJar = grepJar(s"scala-compiler-$scalaVersion.jar"),
- allJars = localArtifacts.toArray,
- explicitActual = None
- ),
- grepJar(s"compiler-bridge_$binaryScalaVersion-1.0.3.jar")
- )
-
- val outputDir = pwd/'target/'zinc
- mkdir(outputDir)
-
- val scalaFiles = Array(pwd/"Test.scala")
-
-
- scalac.apply(
- sources = scalaFiles.map(_.toIO),
- changes = new DependencyChanges {
- def isEmpty = true
- def modifiedBinaries() = Array[File]()
- def modifiedClasses() = Array[String]()
- },
- classpath = localArtifacts.toArray,
- singleOutput = outputDir.toIO,
- options = Array(),
- callback = new xsbti.AnalysisCallback {
- def startSource(source: File) = ()
- def apiPhaseCompleted() = ()
- def enabled() = true
- def binaryDependency(onBinaryEntry: File, onBinaryClassName: String, fromClassName: String, fromSourceFile: File, context: DependencyContext) = ()
- def generatedNonLocalClass(source: File, classFile: File, binaryClassName: String, srcClassName: String) = ()
- def problem(what: String, pos: xsbti.Position, msg: String, severity: xsbti.Severity, reported: Boolean) = ()
- def dependencyPhaseCompleted() = ()
- def classDependency(onClassName: String, sourceClassName: String, context: DependencyContext) = ()
- def generatedLocalClass(source: File, classFile: File) = ()
- def api(sourceFile: File, classApi: ClassLike) = ()
-
- def mainClass(sourceFile: File, className: String) = ()
- def usedName(className: String, name: String, useScopes: java.util.EnumSet[xsbti.UseScope]) = ()
- },
- maximumErrors = 10,
- cache = new FreshCompilerCache(),
- log = {
- val console = ConsoleOut.systemOut
- val consoleAppender = MainAppender.defaultScreen(console)
- val l = LogExchange.logger("Hello")
- LogExchange.unbindLoggerAppenders("Hello")
- LogExchange.bindLoggerAppenders("Hello", (consoleAppender -> sbt.util.Level.Warn) :: Nil)
- l
- }
- )
-
- %('java,"-cp", localArtifacts.mkString(":") + ":.", "Test")(pwd/'target/'zinc)
-
- }
-}
diff --git a/src/test/scala/forge/MetacircularTests.scala b/src/test/scala/forge/MetacircularTests.scala
index 6f7a51d2..f11b4af5 100644
--- a/src/test/scala/forge/MetacircularTests.scala
+++ b/src/test/scala/forge/MetacircularTests.scala
@@ -8,22 +8,22 @@ import utest._
object MetacircularTests extends TestSuite{
object Self extends scalaplugin.Subproject {
val scalaVersion = T{ "2.12.4" }
- override val compileDeps = T{
- for(scalaVersion <- scalaVersion) yield Seq(
- Dep(Mod("org.scala-lang", "scala-reflect"), scalaVersion, configuration = "provided"),
- )
+ override val compileDeps = T.raw{
+ Seq(Dep(Mod("org.scala-lang", "scala-reflect"), scalaVersion(), configuration = "provided"))
}
- override val deps = T{
- for((scalaVersion, scalaBinaryVersion) <- zip(scalaVersion, scalaBinaryVersion)) yield Seq(
- Dep(Mod("com.lihaoyi", "sourcecode_" + scalaBinaryVersion), "0.1.4"),
- Dep(Mod("com.lihaoyi", "pprint_" + scalaBinaryVersion), "0.5.3"),
- Dep(Mod("com.lihaoyi", "ammonite_" + scalaVersion), "1.0.3"),
- Dep(Mod("com.typesafe.play", "play-json_" + scalaBinaryVersion), "2.6.6"),
- Dep(Mod("org.scala-sbt", "zinc_" + scalaBinaryVersion), "1.0.3")
+
+ override val deps = T.raw{
+ Seq(
+ Dep(Mod("com.lihaoyi", "sourcecode_" + scalaBinaryVersion()), "0.1.4"),
+ Dep(Mod("com.lihaoyi", "pprint_" + scalaBinaryVersion()), "0.5.3"),
+ Dep(Mod("com.lihaoyi", "ammonite_" + scalaVersion()), "1.0.3"),
+ Dep(Mod("com.typesafe.play", "play-json_" + scalaBinaryVersion()), "2.6.6"),
+ Dep(Mod("org.scala-sbt", "zinc_" + scalaBinaryVersion()), "1.0.3")
)
}
+
val basePath = T{ pwd }
override val sources = T{ PathRef(pwd/'src/'main/'scala) }
override val resources = T{ PathRef(pwd/'src/'main/'resources) }