Deprecate .value extension method from input tasks (#2709)

Calling the `.value` method on an input task returns `InputTask[A]`, which is completely unintuitive. I think it's basically a bug in `.value`. This change deprecates the `.value` call on input tasks, in preparation to the removal in sbt 1.0.

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

One of the motivation for doing this now is the deprecation of old operators `<<=`, which forces more users to convert to the `:=` style and potentially run into the `.value` behavior.
This commit is contained in:
eugene yokota 2016-08-26 14:44:49 -04:00 committed by GitHub
parent 239549617b
commit 6631456eff
5 changed files with 49 additions and 1 deletions

View File

@ -96,8 +96,13 @@ object InputWrapper {
val tpe = ts.tree.tpe
if (tpe <:< c.weakTypeOf[Initialize[Task[T]]])
InputWrapper.wrapInitTask[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[Initialize[T]])
else if (tpe <:< c.weakTypeOf[Initialize[T]]) {
if (c.weakTypeOf[T] <:< c.weakTypeOf[InputTask[_]]) {
c.warning(pos, """`value` is deprecated for an input task. Use `evaluated` or `inputTaskValue`.
|See http://www.scala-sbt.org/0.13/docs/Input-Tasks.html for more details.""".stripMargin)
}
InputWrapper.wrapInit[T](c)(ts, pos)
}
else if (tpe <:< c.weakTypeOf[Task[T]])
InputWrapper.wrapTask[T](c)(ts, pos)
else if (tpe <:< c.weakTypeOf[InputTask[T]])
@ -107,6 +112,10 @@ object InputWrapper {
else
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}")
}
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
@ -147,6 +156,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

@ -0,0 +1,10 @@
### Fixes with compatibility implications
- `.value` method is deprecated for input tasks. 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, `inputTaskValue` method is now provided. [#2709][2709] by [@eed3si9n][@eed3si9n]
[@eed3si9n]: https://github.com/eed3si9n
[2709]: https://github.com/sbt/sbt/pull/2709

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,2 @@
> check