[sbt 1.0] Remove .value extension method from input tasks (#2710)

* Remove .value from input tasks. Ref #2709

Calling `.value` method on an input task returns `InputTask[A]`, which
is completely unintuitive and often results to a bug.

In most cases `.evaluated` should be called, which returns `A` by
evaluating the task. Just in case `InputTask[A]` is needed,
`toInputTask` method is now provided.

* Fixed test

* Rename toInputTask to inputTaskValue
This commit is contained in:
eugene yokota 2016-08-29 15:11:32 -04:00 committed by Dale Wijnand
parent 57cc782db8
commit 9f21bb451d
5 changed files with 39 additions and 2 deletions

View File

@ -90,14 +90,23 @@ object InputWrapper {
def valueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] =
ContextUtil.selectMacroImpl[T](c) { (ts, pos) =>
ts.tree.tpe match {
case tpe if tpe <:< c.weakTypeOf[Initialize[T]] =>
if (c.weakTypeOf[T] <:< c.weakTypeOf[InputTask[_]]) {
c.abort(pos, """`value` is removed from input tasks. Use `evaluated` or `inputTaskValue`.
|See http://www.scala-sbt.org/1.0/docs/Input-Tasks.html for more details.""".stripMargin)
}
InputWrapper.wrapInit[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[Task[T]]] => InputWrapper.wrapInitTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[T]] => InputWrapper.wrapInit[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Task[T]] => InputWrapper.wrapTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[InputTask[T]] => InputWrapper.wrapInputTask[T](c)(ts, pos)
case tpe if tpe <:< c.weakTypeOf[Initialize[InputTask[T]]] => InputWrapper.wrapInitInputTask[T](c)(ts, pos)
case tpe => unexpectedType(c)(pos, tpe)
}
}
def inputTaskValueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[InputTask[T]] =
ContextUtil.selectMacroImpl[InputTask[T]](c) { (ts, pos) =>
InputWrapper.wrapInit[InputTask[T]](c)(ts, pos)
}
def taskValueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[Task[T]] =
ContextUtil.selectMacroImpl[Task[T]](c) { (ts, pos) =>
val tpe = ts.tree.tpe
@ -141,6 +150,8 @@ sealed abstract class ParserInput[T] {
sealed abstract class InputEvaluated[T] {
@compileTimeOnly("`evaluated` can only be used within an input task macro, such as := or Def.inputTask.")
def evaluated: T = macro InputWrapper.valueMacroImpl[T]
@compileTimeOnly("`inputTaskValue` can only be used within an input task macro, such as := or Def.inputTask.")
def inputTaskValue: InputTask[T] = macro InputWrapper.inputTaskValueMacroImpl[T]
}
sealed abstract class ParserInputTask[T] {
@compileTimeOnly("`parsed` can only be used within an input task macro, such as := or Def.inputTask.")

View File

@ -72,7 +72,7 @@ object Assign {
}
val it3: Initialize[InputTask[String]] = Def.inputTask[String] {
tsk.parsed.value + itsk.parsed.value.toString + isk.value
tsk.parsed.value + itsk.parsed.value.toString + isk.evaluated
}
// should not compile: cannot use a task to define the parser
/* val it4 = Def.inputTask {

View File

@ -0,0 +1,3 @@
object Hello extends App {
println("hello" + args.toList.toString)
}

View File

@ -0,0 +1,22 @@
import complete.Parser
// http://www.scala-sbt.org/0.13/docs/Input-Tasks.html
val run2 = inputKey[Unit](
"Runs the main class twice with different argument lists separated by --")
val check = taskKey[Unit]("")
val separator: Parser[String] = "--"
lazy val root = (project in file(".")).
settings(
name := "run-test",
run2 := {
val one = (run in Compile).evaluated
val sep = separator.parsed
val two = (run in Compile).evaluated
},
check := {
val x = run2.toTask(" a b -- c d").value
}
)

View File

@ -0,0 +1 @@
> check