From 53bbb996171e22475efb33604ffe25c4c6769462 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 5 Oct 2017 02:43:50 -0400 Subject: [PATCH 1/2] Fixes Zero / Zero / Zero / name handling Prior to this change `Zero / Zero / Zero / name` broke as folllows: ``` scala> Zero / Zero / Zero / name Zero / Zero / Zero / name :18: error: inferred type arguments [sbt.Zero.type] do not conform to method /'s type parameter bounds [K <: sbt.SlashSyntax.Key[K]] Zero / Zero / Zero / name ^ ``` --- main/src/main/scala/sbt/SlashSyntax.scala | 8 +++++++- sbt/src/sbt-test/project/unified/build.sbt | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index 14d6d476c..634a86b75 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -1,6 +1,7 @@ package sbt import sbt.librarymanagement.Configuration +import sbt.internal.util.AttributeKey /** * SlashSyntax implements the slash syntax to scope keys for build.sbt DSL. @@ -57,7 +58,12 @@ object SlashSyntax { } /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ - final class RichConfiguration(protected val scope: Scope) extends RichScopeLike + final class RichConfiguration(protected val scope: Scope) extends RichScopeLike { + + // This is for handling `Zero / Zero / Zero / name`. + def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope = + new RichScope(scope.copy(task = taskAxis)) + } /** Both `Scoped.ScopingSetting` and `Scoped` are parents of `SettingKey`, `TaskKey` and * `InputKey`. We'll need both, so this is a convenient type alias. */ diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt index 935e32855..7f9835fea 100644 --- a/sbt/src/sbt-test/project/unified/build.sbt +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -10,6 +10,7 @@ lazy val root = (project in file(".")) Compile / console / scalacOptions += "-Ywarn-numeric-widen", projA / Compile / console / scalacOptions += "-feature", Zero / Zero / name := "foo", + Zero / Zero / Zero / name := "foo", libraryDependencies += uTest % Test, testFrameworks += new TestFramework("utest.runner.Framework"), From 60f2498c0a9c9f097a65c560eb724dd4b7bf9b13 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 5 Oct 2017 02:46:09 -0400 Subject: [PATCH 2/2] Implement toString for keys toString added for REPL testing: ``` scala> Zero / Zero / Zero / name res0: sbt.SlashSyntax.ScopeAndKey[sbt.SettingKey[String]] = Zero / Zero / Zero / name ``` --- main-settings/src/main/scala/sbt/Scope.scala | 5 +++++ main-settings/src/main/scala/sbt/Structure.scala | 6 ++++++ main/src/main/scala/sbt/SlashSyntax.scala | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 80661eb6b..4ca49b94d 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -24,6 +24,11 @@ final case class Scope(project: ScopeAxis[Reference], def in(project: Reference): Scope = copy(project = Select(project)) def in(config: ConfigKey): Scope = copy(config = Select(config)) def in(task: AttributeKey[_]): Scope = copy(task = Select(task)) + + override def toString: String = { + if (extra == This) s"$project / $config / $task" + else s"Scope($project, $config, $task, $extra)" + } } object Scope { val ThisScope: Scope = Scope(This, This, This, This) diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 247b776d4..da963325e 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -34,6 +34,8 @@ sealed abstract class SettingKey[T] val key: AttributeKey[T] + override def toString: String = s"SettingKey($scope / $key)" + final def toTask: Initialize[Task[T]] = this apply inlineTask final def scopedKey: ScopedKey[T] = ScopedKey(scope, key) @@ -105,6 +107,8 @@ sealed abstract class TaskKey[T] val key: AttributeKey[Task[T]] + override def toString: String = s"TaskKey($scope / $key)" + def toTask: Initialize[Task[T]] = this def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key) @@ -172,6 +176,8 @@ sealed trait InputKey[T] val key: AttributeKey[InputTask[T]] + override def toString: String = s"InputKey($scope / $key)" + def scopedKey: ScopedKey[InputTask[T]] = ScopedKey(scope, key) def in(scope: Scope): InputKey[T] = diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index 634a86b75..bf353f0ae 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -97,6 +97,10 @@ object SlashSyntax { final class ScopeAndKey[K <: Key[K]](scope: Scope, key: K) { private[sbt] def materialize: K = key in scope private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key) + + override def toString: String = { + s"$scope / ${key.key}" + } } }