mirror of https://github.com/sbt/sbt.git
Merge pull request #2943 from eed3si9n/backport/generators
[sbt 0.13] Support sourceGenerators += Def.task { ... }
This commit is contained in:
commit
b6466624a8
|
|
@ -1,8 +1,9 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Def.Classpath
|
import Def.{ Classpath, Initialize }
|
||||||
import scala.annotation.implicitNotFound
|
import scala.annotation.implicitNotFound
|
||||||
|
import reflect.internal.annotations.compileTimeOnly
|
||||||
|
|
||||||
object Append {
|
object Append {
|
||||||
@implicitNotFound(msg = "No implicit for Append.Value[${A}, ${B}] found,\n so ${B} cannot be appended to ${A}")
|
@implicitNotFound(msg = "No implicit for Append.Value[${A}, ${B}] found,\n so ${B} cannot be appended to ${A}")
|
||||||
|
|
@ -23,6 +24,14 @@ object Append {
|
||||||
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ (b map { x => (x: T) })
|
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ (b map { x => (x: T) })
|
||||||
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
||||||
}
|
}
|
||||||
|
@compileTimeOnly("This can be used in += only.")
|
||||||
|
implicit def appendTaskValueSeq[T, V <: T]: Value[Seq[Task[T]], Initialize[Task[V]]] = new Value[Seq[Task[T]], Initialize[Task[V]]] {
|
||||||
|
def appendValue(a: Seq[Task[T]], b: Initialize[Task[V]]): Seq[Task[T]] = ???
|
||||||
|
}
|
||||||
|
@compileTimeOnly("This can be used in += only.")
|
||||||
|
implicit def appendTaskKeySeq[T, V <: T]: Value[Seq[Task[T]], TaskKey[V]] = new Value[Seq[Task[T]], TaskKey[V]] {
|
||||||
|
def appendValue(a: Seq[Task[T]], b: TaskKey[V]): Seq[Task[T]] = ???
|
||||||
|
}
|
||||||
implicit def appendList[T, V <: T]: Sequence[List[T], List[V], V] = new Sequence[List[T], List[V], V] {
|
implicit def appendList[T, V <: T]: Sequence[List[T], List[V], V] = new Sequence[List[T], List[V], V] {
|
||||||
def appendValues(a: List[T], b: List[V]): List[T] = a ::: b
|
def appendValues(a: List[T], b: List[V]): List[T] = a ::: b
|
||||||
def appendValue(a: List[T], b: V): List[T] = a :+ b
|
def appendValue(a: List[T], b: V): List[T] = a :+ b
|
||||||
|
|
|
||||||
|
|
@ -168,10 +168,25 @@ object TaskMacro {
|
||||||
/** Implementation of += macro for settings. */
|
/** Implementation of += macro for settings. */
|
||||||
def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] =
|
def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] =
|
||||||
{
|
{
|
||||||
|
import c.universe._
|
||||||
|
val util = ContextUtil[c.type](c)
|
||||||
|
val ttpe = c.weakTypeOf[T]
|
||||||
|
val typeArgs = util.typeArgs(ttpe)
|
||||||
|
v.tree.tpe match {
|
||||||
|
// To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically.
|
||||||
|
case tpe if typeArgs.nonEmpty && (tpe weak_<:< c.weakTypeOf[Initialize[_]]) =>
|
||||||
|
c.macroApplication match {
|
||||||
|
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), _) =>
|
||||||
|
val tree = Apply(TypeApply(Select(preT, newTermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil), Select(v.tree, newTermName("taskValue").encodedName) :: Nil)
|
||||||
|
c.Expr[Setting[T]](tree)
|
||||||
|
case x => ContextUtil.unexpectedTree(x)
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||||
c.Expr[Setting[T]](append)
|
c.Expr[Setting[T]](append)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/** Implementation of ++= macro for tasks. */
|
/** Implementation of ++= macro for tasks. */
|
||||||
def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] =
|
def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] =
|
||||||
{
|
{
|
||||||
|
|
@ -186,7 +201,6 @@ object TaskMacro {
|
||||||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||||
c.Expr[Setting[T]](append)
|
c.Expr[Setting[T]](append)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Implementation of -= macro for tasks. */
|
/** Implementation of -= macro for tasks. */
|
||||||
def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] =
|
def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] =
|
||||||
{
|
{
|
||||||
|
|
@ -221,7 +235,7 @@ object TaskMacro {
|
||||||
import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag, TypeApply, TypeApplyTag }
|
import c.universe.{ Apply, ApplyTag, newTermName, Select, SelectTag, TypeApply, TypeApplyTag }
|
||||||
c.macroApplication match {
|
c.macroApplication match {
|
||||||
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), a) =>
|
case Apply(Apply(TypeApply(Select(preT, nmeT), targs), _), a) =>
|
||||||
Apply(Apply(TypeApply(Select(preT, newTermName(newName).encodedName), targs), init :: sourcePosition(c).tree :: Nil), a)
|
Apply(Apply(TypeApply(Select(preT, newTermName(newName).encodedName), targs), init :: sourcePosition(c).tree :: Nil), append :: Nil)
|
||||||
case x => ContextUtil.unexpectedTree(x)
|
case x => ContextUtil.unexpectedTree(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ object Defaults extends BuildCommon {
|
||||||
unmanagedResources := collectFiles(unmanagedResourceDirectories, includeFilter in unmanagedResources, excludeFilter in unmanagedResources).value,
|
unmanagedResources := collectFiles(unmanagedResourceDirectories, includeFilter in unmanagedResources, excludeFilter in unmanagedResources).value,
|
||||||
watchSources in ConfigGlobal ++= unmanagedResources.value,
|
watchSources in ConfigGlobal ++= unmanagedResources.value,
|
||||||
resourceGenerators :== Nil,
|
resourceGenerators :== Nil,
|
||||||
resourceGenerators += ((discoveredSbtPlugins, resourceManaged) map PluginDiscovery.writeDescriptors).taskValue,
|
resourceGenerators += Def.task { PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value) },
|
||||||
managedResources := generate(resourceGenerators).value,
|
managedResources := generate(resourceGenerators).value,
|
||||||
resources := Classpaths.concat(managedResources, unmanagedResources).value
|
resources := Classpaths.concat(managedResources, unmanagedResources).value
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
lazy val buildInfo = taskKey[Seq[File]]("The task that generates the build info.")
|
||||||
|
|
||||||
|
lazy val root = (project in file("."))
|
||||||
|
.settings(
|
||||||
|
scalaVersion := "2.11.8",
|
||||||
|
buildInfo := {
|
||||||
|
val x = sourceManaged.value / "BuildInfo.scala"
|
||||||
|
IO.write(x, """object BuildInfo""")
|
||||||
|
x :: Nil
|
||||||
|
},
|
||||||
|
sourceGenerators in Compile += buildInfo,
|
||||||
|
sourceGenerators in Compile += Def.task { Nil }
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
> compile
|
||||||
|
$ exists target/scala-2.11/src_managed/BuildInfo.scala
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
val test123 = project in file(".") enablePlugins TestP settings(
|
val test123 = project in file(".") enablePlugins TestP settings(
|
||||||
resourceGenerators in Compile += (Def.task {
|
resourceGenerators in Compile += Def.task {
|
||||||
streams.value.log info "resource generated in settings"
|
streams.value.log info "resource generated in settings"
|
||||||
Nil
|
Nil
|
||||||
}).taskValue
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
TaskKey[Unit]("check") := {
|
TaskKey[Unit]("check") := {
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,9 @@ final class ContextUtil[C <: Context](val ctx: C) {
|
||||||
def freshMethodParameter(tpe: Type): ValDef =
|
def freshMethodParameter(tpe: Type): ValDef =
|
||||||
ValDef(parameterModifiers, freshTermName("p"), TypeTree(tpe), EmptyTree)
|
ValDef(parameterModifiers, freshTermName("p"), TypeTree(tpe), EmptyTree)
|
||||||
|
|
||||||
|
def typeArgs(tpe: Type): List[Type] =
|
||||||
|
tpe.asInstanceOf[global.Type].typeArgs map { _.asInstanceOf[Type] }
|
||||||
|
|
||||||
/** Constructs a ValDef with local modifiers and a unique name. */
|
/** Constructs a ValDef with local modifiers and a unique name. */
|
||||||
def localValDef(tpt: Tree, rhs: Tree): ValDef =
|
def localValDef(tpt: Tree, rhs: Tree): ValDef =
|
||||||
ValDef(localModifiers, freshTermName("q"), tpt, rhs)
|
ValDef(localModifiers, freshTermName("q"), tpt, rhs)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue