From 01bd4add3cdd96af5e7443dfbe021704ed815f69 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Aug 2016 23:08:27 -0400 Subject: [PATCH] Replace the old operators with Restligeist macros The old operators `<<=`, `<+=`, and `<++=` are now replaced with Restligeist macros that will always fail during compile-time but can display migration guide as the error message. This would provide better upgrade experience than simply removing the methods and displaying `<<= is not a member of sbt.TaskKey`. --- MIGRATION.md | 3 +- .../src/main/scala/sbt/Structure.scala | 17 +++---- .../src/main/scala/sbt/std/TaskMacro.scala | 49 +++++++++++++------ .../old-ops/changes/settingAppend1/build.sbt | 4 ++ .../old-ops/changes/settingAppendN/build.sbt | 4 ++ .../old-ops/changes/settingAssign/build.sbt | 4 ++ .../old-ops/changes/taskAppend1/build.sbt | 6 +++ .../old-ops/changes/taskAppendN/build.sbt | 6 +++ .../old-ops/changes/taskAssign/build.sbt | 4 ++ sbt/src/sbt-test/project/old-ops/test | 17 +++++++ 10 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 sbt/src/sbt-test/project/old-ops/changes/settingAppend1/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/changes/settingAppendN/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/changes/settingAssign/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/changes/taskAppend1/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/changes/taskAppendN/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/changes/taskAssign/build.sbt create mode 100644 sbt/src/sbt-test/project/old-ops/test diff --git a/MIGRATION.md b/MIGRATION.md index f5753e214..0278371cf 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -8,7 +8,8 @@ Migration notes - The incremental compiler, called Zinc, uses class-based name hashing. - Zinc drops support for Scala 2.8.x and 2.9.x. - Removed the pre-0.13.7 *.sbt file parser (previously available under `-Dsbt.parser.simple=true`) -- Removed old, hypher-separated key names (use `publishLocal` instead of `publish-local`) +- Removed old, hyphen-separated key names (use `publishLocal` instead of `publish-local`) +- Removes no-longer-documented old operators `<<=`, `<+=`, and `<++=`. #### Additional import required diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 93c18452d..9f74e983b 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -39,8 +39,8 @@ sealed abstract class SettingKey[T] extends ScopedTaskable[T] with KeyedInitiali final def :=(v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T] final def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[T] = macro std.TaskMacro.settingAppend1Impl[T, U] final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] = macro std.TaskMacro.settingAppendNImpl[T, U] - final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] = macro std.TaskMacro.settingAppend1Position[T, V] - final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] = macro std.TaskMacro.settingAppendNPosition[T, V] + final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] = macro std.TaskMacro.fakeSettingAppend1Position[T, V] + final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] = macro std.TaskMacro.fakeSettingAppendNPosition[T, V] final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[T] = macro std.TaskMacro.settingRemove1Impl[T, U] final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[T] = macro std.TaskMacro.settingRemoveNImpl[T, U] final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T] @@ -70,8 +70,8 @@ sealed abstract class TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[ def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskAppend1Impl[T, U] def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNImpl[T, U] - def <+=[V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppend1Position[T, V] - def <++=[V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNPosition[T, V] + def <+=[V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] = macro std.TaskMacro.fakeTaskAppend1Position[T, V] + def <++=[V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] = macro std.TaskMacro.fakeTaskAppendNPosition[T, V] final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskRemove1Impl[T, U] final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskRemoveNImpl[T, U] @@ -147,12 +147,7 @@ object Scoped { private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S] - /** - * Binds a single value to this. A new [Def.Setting] is defined using the value(s) of `app`. - * @param app value to bind to this key - * @return setting binding this key to the given value. - */ - final def <<=(app: Initialize[S]): Setting[S] = macro std.TaskMacro.settingAssignPosition[S] + final def <<=(app: Initialize[S]): Setting[S] = macro std.TaskMacro.fakeSettingAssignPosition[S] /** Internally used function for setting a value along with the `.sbt` file location where it is defined. */ final def set(app: Initialize[S], source: SourcePosition): Setting[S] = setting(scopedKey, app, source) @@ -198,7 +193,7 @@ object Scoped { def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S] def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S] - def <<=(app: Initialize[Task[S]]): Setting[Task[S]] = macro std.TaskMacro.itaskAssignPosition[S] + def <<=(app: Initialize[Task[S]]): Setting[Task[S]] = macro std.TaskMacro.fakeItaskAssignPosition[S] def set(app: Initialize[Task[S]], source: SourcePosition): Setting[Task[S]] = Def.setting(scopedKey, app, source) def transform(f: S => S, source: SourcePosition): Setting[Task[S]] = set(scopedKey(_ map f), source) diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index c98bbf704..0841a8601 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -72,6 +72,13 @@ object TaskMacro { final val TransformInitName = "transform" final val InputTaskCreateDynName = "createDyn" final val InputTaskCreateFreeName = "createFree" + final val append1Migration = "Use `lhs += { x.value }`." + final val appendNMigration = "Use `lhs ++= { x.value }`." + final val assignMigration = + """Use `key := { x.value }` or `key ~= (old => { newValue })`. + |The RHS of `<<=` takes an `Initialize[_]` expression, which can be converted to `:=` style + |by wrapping the expression in parenthesis, and calling `.value` at the end. + |For example, `key := (key.dependsOn(compile in Test)).value`.""".stripMargin def taskMacroImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Initialize[Task[T]]] = Instance.contImpl[T, Id](c, FullInstance, FullConvert, MixedBuilder)(Left(t), Instance.idTransform[c.type]) @@ -94,6 +101,34 @@ object TaskMacro { c.Expr[Setting[Task[T]]](assign) } + // Error macros (Restligeist) + // These macros are there just so we can fail old operators like `<<=` and provide useful migration information. + + def fakeSettingAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] = + ContextUtil.selectMacroImpl[Setting[T]](c) { (ts, pos) => + c.abort(pos, assignMigration) + } + def fakeSettingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[V]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[S]] = + ContextUtil.selectMacroImpl[Setting[S]](c) { (ts, pos) => + c.abort(pos, append1Migration) + } + def fakeSettingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[V]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[S]] = + ContextUtil.selectMacroImpl[Setting[S]](c) { (ts, pos) => + c.abort(pos, appendNMigration) + } + def fakeItaskAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] = + ContextUtil.selectMacroImpl[Setting[Task[T]]](c) { (ts, pos) => + c.abort(pos, assignMigration) + } + def fakeTaskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[Task[S]]] = + ContextUtil.selectMacroImpl[Setting[Task[S]]](c) { (ts, pos) => + c.abort(pos, append1Migration) + } + def fakeTaskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[Task[S]]] = + ContextUtil.selectMacroImpl[Setting[Task[S]]](c) { (ts, pos) => + c.abort(pos, appendNMigration) + } + /* Implementations of <<= macro variations for tasks and settings. These just get the source position of the call site.*/ def itaskAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] = @@ -102,26 +137,12 @@ object TaskMacro { itaskAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) }) def taskAssignPositionPure[T: c.WeakTypeTag](c: Context)(app: c.Expr[T]): c.Expr[Setting[Task[T]]] = taskAssignPositionT(c)(c.universe.reify { TaskExtra.constant(app.splice) }) - def taskTransformPosition[S: c.WeakTypeTag](c: Context)(f: c.Expr[S => S]): c.Expr[Setting[Task[S]]] = c.Expr[Setting[Task[S]]](transformMacroImpl(c)(f.tree)(TransformInitName)) def settingTransformPosition[S: c.WeakTypeTag](c: Context)(f: c.Expr[S => S]): c.Expr[Setting[S]] = c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName)) def itaskTransformPosition[S: c.WeakTypeTag](c: Context)(f: c.Expr[S => S]): c.Expr[Setting[S]] = c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName)) - - def taskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[Task[S]]] = - c.Expr[Setting[Task[S]]](appendMacroImpl(c)(vs.tree, a.tree)(AppendNInitName)) - - def settingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[V]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[S]] = - c.Expr[Setting[S]](appendMacroImpl(c)(vs.tree, a.tree)(AppendNInitName)) - - def taskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[Task[S]]] = - c.Expr[Setting[Task[S]]](appendMacroImpl(c)(v.tree, a.tree)(Append1InitName)) - - def settingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[V]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[S]] = - c.Expr[Setting[S]](appendMacroImpl(c)(v.tree, a.tree)(Append1InitName)) - def settingAssignPure[T: c.WeakTypeTag](c: Context)(app: c.Expr[T]): c.Expr[Setting[T]] = settingAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) }) def settingAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] = diff --git a/sbt/src/sbt-test/project/old-ops/changes/settingAppend1/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/settingAppend1/build.sbt new file mode 100644 index 000000000..902c68c45 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/settingAppend1/build.sbt @@ -0,0 +1,4 @@ +lazy val root = (project in file(".")). + settings( + crossScalaVersions <+= scalaVersion + ) diff --git a/sbt/src/sbt-test/project/old-ops/changes/settingAppendN/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/settingAppendN/build.sbt new file mode 100644 index 000000000..7f36df425 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/settingAppendN/build.sbt @@ -0,0 +1,4 @@ +lazy val root = (project in file(".")). + settings( + crossScalaVersions <++= (scalaVersion) { Seq(_) } + ) diff --git a/sbt/src/sbt-test/project/old-ops/changes/settingAssign/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/settingAssign/build.sbt new file mode 100644 index 000000000..fff07a0e5 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/settingAssign/build.sbt @@ -0,0 +1,4 @@ +lazy val root = (project in file(".")). + settings( + crossScalaVersions <<= crossScalaVersions + ) diff --git a/sbt/src/sbt-test/project/old-ops/changes/taskAppend1/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/taskAppend1/build.sbt new file mode 100644 index 000000000..8ab652466 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/taskAppend1/build.sbt @@ -0,0 +1,6 @@ +lazy val foo = taskKey[String]("") +lazy val root = (project in file(".")). + settings( + scalacOptions <+= foo, + foo := "-unchecked" + ) diff --git a/sbt/src/sbt-test/project/old-ops/changes/taskAppendN/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/taskAppendN/build.sbt new file mode 100644 index 000000000..d7d9c0629 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/taskAppendN/build.sbt @@ -0,0 +1,6 @@ +lazy val foo = taskKey[Seq[String]]("") +lazy val root = (project in file(".")). + settings( + scalacOptions <++= foo, + foo := Seq("-unchecked") + ) diff --git a/sbt/src/sbt-test/project/old-ops/changes/taskAssign/build.sbt b/sbt/src/sbt-test/project/old-ops/changes/taskAssign/build.sbt new file mode 100644 index 000000000..3bbe0922e --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/changes/taskAssign/build.sbt @@ -0,0 +1,4 @@ +lazy val root = (project in file(".")). + settings( + scalacOptions <<= scalacOptions + ) diff --git a/sbt/src/sbt-test/project/old-ops/test b/sbt/src/sbt-test/project/old-ops/test new file mode 100644 index 000000000..2eae3cfe4 --- /dev/null +++ b/sbt/src/sbt-test/project/old-ops/test @@ -0,0 +1,17 @@ +$ copy-file changes/settingAssign/build.sbt build.sbt +-> compile + +$ copy-file changes/settingAppend1/build.sbt build.sbt +-> compile + +$ copy-file changes/settingAppendN/build.sbt build.sbt +-> compile + +$ copy-file changes/taskAssign/build.sbt build.sbt +-> compile + +$ copy-file changes/taskAppend1/build.sbt build.sbt +-> compile + +$ copy-file changes/taskAppendN/build.sbt build.sbt +-> compile