diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index 33591506c..5cf6fb65b 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -5,6 +5,7 @@ package sbt.internal.util import Types._ import scala.reflect.Manifest +import sbt.util.OptJsonWriter // T must be invariant to work properly. // Because it is sealed and the only instances go through AttributeKey.apply, @@ -39,6 +40,8 @@ sealed trait AttributeKey[T] { /** Identifies the relative importance of a key among other keys.*/ def rank: Int + + def optJsonWriter: OptJsonWriter[T] } private[sbt] abstract class SharedAttributeKey[T] extends AttributeKey[T] { override final def toString = label @@ -50,32 +53,33 @@ private[sbt] abstract class SharedAttributeKey[T] extends AttributeKey[T] { final def isLocal: Boolean = false } object AttributeKey { - def apply[T](name: String)(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = make(name, None, Nil, Int.MaxValue) - def apply[T](name: String, rank: Int)(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String, rank: Int)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = make(name, None, Nil, rank) - def apply[T](name: String, description: String)(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String, description: String)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = apply(name, description, Nil) - def apply[T](name: String, description: String, rank: Int)(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String, description: String, rank: Int)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = apply(name, description, Nil, rank) - def apply[T](name: String, description: String, extend: Seq[AttributeKey[_]])(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String, description: String, extend: Seq[AttributeKey[_]])(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = apply(name, description, extend, Int.MaxValue) - def apply[T](name: String, description: String, extend: Seq[AttributeKey[_]], rank: Int)(implicit mf: Manifest[T]): AttributeKey[T] = + def apply[T](name: String, description: String, extend: Seq[AttributeKey[_]], rank: Int)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = make(name, Some(description), extend, rank) - private[this] def make[T](name: String, description0: Option[String], extend0: Seq[AttributeKey[_]], rank0: Int)(implicit mf: Manifest[T]): AttributeKey[T] = new SharedAttributeKey[T] { + private[this] def make[T](name: String, description0: Option[String], extend0: Seq[AttributeKey[_]], rank0: Int)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = new SharedAttributeKey[T] { def manifest = mf val label = Util.hyphenToCamel(name) def description = description0 def extend = extend0 def rank = rank0 + def optJsonWriter = ojw } - private[sbt] def local[T](implicit mf: Manifest[T]): AttributeKey[T] = new AttributeKey[T] { + private[sbt] def local[T](implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = new AttributeKey[T] { def manifest = mf def label = LocalLabel def description = None @@ -83,6 +87,7 @@ object AttributeKey { override def toString = label def isLocal: Boolean = true def rank = Int.MaxValue + val optJsonWriter = ojw } private[sbt] final val LocalLabel = "$" + "local" } diff --git a/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala b/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala new file mode 100644 index 000000000..e840bc689 --- /dev/null +++ b/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala @@ -0,0 +1,22 @@ +package sbt.util + +import sjsonnew.JsonWriter + +sealed trait OptJsonWriter[A] +final case class NoJsonWriter[A]() extends OptJsonWriter[A] +final case class SomeJsonWriter[A](value: JsonWriter[A]) extends OptJsonWriter[A] + +trait OptJsonWriter0 { + implicit def fallback[A]: NoJsonWriter[A] = NoJsonWriter() +} +object OptJsonWriter extends OptJsonWriter0 { + implicit def lift[A](implicit z: JsonWriter[A]): SomeJsonWriter[A] = SomeJsonWriter(z) + + trait StrictMode0 { + implicit def conflictingFallback1[A]: NoJsonWriter[A] = NoJsonWriter() + implicit def conflictingFallback2[A]: NoJsonWriter[A] = NoJsonWriter() + } + object StrictMode extends StrictMode0 { + implicit def lift[A](implicit z: JsonWriter[A]): SomeJsonWriter[A] = SomeJsonWriter(z) + } +}