diff --git a/.gitignore b/.gitignore index 1f81020b9..08ab853dc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ node_modules vscode-sbt-scala/client/server npm-debug.log *.vsix +*_pid*.log !sbt/src/server-test/completions/target .big .idea diff --git a/build.sbt b/build.sbt index 81cde481a..cc100d090 100644 --- a/build.sbt +++ b/build.sbt @@ -182,8 +182,6 @@ val scriptedSbtReduxMimaSettings = Def.settings(mimaPreviousArtifacts := Set()) lazy val sbtRoot: Project = (project in file(".")) .aggregate( (allProjects diff Seq( - actionsProj, - mainSettingsProj, scriptedSbtReduxProj, scriptedSbtOldProj, scriptedPluginProj, diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala index b619cab90..2c5b6bf4a 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala @@ -99,7 +99,10 @@ trait Cont: case Right(r) => (r, faTpe) // we can extract i out of i.type - val instanceExpr = Expr.summon[Applicative[F]].get + val instanceExpr = + Expr + .summon[Applicative[F]] + .getOrElse(sys.error(s"Applicative[F] not found for ${fTypeCon.typeSymbol}")) val inputBuf = ListBuffer[Input]() def makeApp(body: Term, inputs: List[Input]): Expr[F[Effect[A]]] = inputs match @@ -111,7 +114,7 @@ trait Cont: def pure(body: Term): Expr[F[Effect[A]]] = def pure0[A1: Type](body: Expr[A1]): Expr[F[A1]] = '{ - $instanceExpr.pure[A1] { $body } + $instanceExpr.pure[A1] { () => $body } } eitherTree match case Left(_) => pure0[Effect[A]](body.asExprOf[Effect[A]]) diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala index 9d6639134..f18a86466 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala @@ -14,20 +14,20 @@ import sbt.internal.util.Util.{ makeList, separate } /** * A String parser that provides semi-automatic tab completion. A successful parse results in a - * value of type `T`. The methods in this trait are what must be implemented to define a new Parser + * value of type `A`. The methods in this trait are what must be implemented to define a new Parser * implementation, but are not typically useful for common usage. Instead, most useful methods for * combining smaller parsers into larger parsers are implicitly added by the [[RichParser]] type. */ -trait Parser[+T] { - def derive(i: Char): Parser[T] - def resultEmpty: Result[T] - def result: Option[T] +trait Parser[+A1]: + def derive(i: Char): Parser[A1] + def resultEmpty: Result[A1] + def result: Option[A1] def completions(level: Int): Completions def failure: Option[Failure] def isTokenStart = false - def ifValid[S](p: => Parser[S]): Parser[S] + def ifValid[A2](p: => Parser[A2]): Parser[A2] def valid: Boolean -} +end Parser sealed trait RichParser[A] { @@ -154,7 +154,7 @@ sealed trait RichParser[A] { } /** Contains Parser implementation helper methods not typically needed for using parsers. */ -object Parser extends ParserMain { +object Parser extends ParserMain: sealed abstract class Result[+T] { def isFailure: Boolean def isValid: Boolean @@ -332,7 +332,8 @@ object Parser extends ParserMain { } def and[T](a: Parser[T], b: Parser[_]): Parser[T] = a.ifValid(b.ifValid(new And(a, b))) -} + +end Parser trait ParserMain { diff --git a/internal/util-relation/src/test/scala/RelationTest.scala b/internal/util-relation/src/test/scala/RelationTest.scala index 912b63696..3cd71875f 100644 --- a/internal/util-relation/src/test/scala/RelationTest.scala +++ b/internal/util-relation/src/test/scala/RelationTest.scala @@ -23,9 +23,9 @@ object RelationTest extends Properties("Relation") { r._2s == _2s && r.reverseMap.keySet == _2s && pairs.forall { case (a, b) => (r.forward(a) contains b) && - (r.reverse(b) contains a) && - (r.forwardMap(a) contains b) && - (r.reverseMap(b) contains a) + (r.reverse(b) contains a) && + (r.forwardMap(a) contains b) && + (r.reverseMap(b) contains a) } } @@ -47,9 +47,9 @@ object RelationTest extends Properties("Relation") { } && all(removeFine) { case (a, b) => ("Forward does not contain removed" |: (!r.forward(a).contains(b))) && - ("Reverse does not contain removed" |: (!r.reverse(b).contains(a))) && - ("Forward map does not contain removed" |: (notIn(r.forwardMap, a, b))) && - ("Reverse map does not contain removed" |: (notIn(r.reverseMap, b, a))) + ("Reverse does not contain removed" |: (!r.reverse(b).contains(a))) && + ("Forward map does not contain removed" |: (notIn(r.forwardMap, a, b))) && + ("Reverse map does not contain removed" |: (notIn(r.reverseMap, b, a))) } } diff --git a/main-settings/src/main/scala/sbt/Append.scala b/main-settings/src/main/scala/sbt/Append.scala index 68aa27d9b..19db3bc17 100644 --- a/main-settings/src/main/scala/sbt/Append.scala +++ b/main-settings/src/main/scala/sbt/Append.scala @@ -16,18 +16,18 @@ import sbt.internal.io.Source import sbt.internal.util.Attributed import sbt.io.{ AllPassFilter, NothingFilter } -object Append { - @implicitNotFound("No Append.Value[${A}, ${B}] found, so ${B} cannot be appended to ${A}") - trait Value[A, B] { - def appendValue(a: A, b: B): A - } +object Append: + @implicitNotFound("No Append.Value[${A1}, ${A2}] found, so ${A2} cannot be appended to ${A1}") + trait Value[A1, A2]: + def appendValue(a1: A1, a2: A2): A1 + end Value - @implicitNotFound("No Append.Values[${A}, ${B}] found, so ${B} cannot be appended to ${A}") - trait Values[A, -B] { - def appendValues(a: A, b: B): A - } + @implicitNotFound("No Append.Values[${A1}, ${A2}] found, so ${A2} cannot be appended to ${A1}") + trait Values[A1, -A2]: + def appendValues(a1: A1, a2: A2): A1 + end Values - trait Sequence[A, -B, T] extends Value[A, T] with Values[A, B] + trait Sequence[A1, -A2, A3] extends Value[A1, A3] with Values[A1, A2] implicit def appendSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] = new Sequence[Seq[T], Seq[V], V] { @@ -35,11 +35,9 @@ object Append { def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T) } - implicit def appendSeqImplicit[T, V](implicit ev: V => T): Sequence[Seq[T], Seq[V], V] = - new Sequence[Seq[T], Seq[V], V] { - def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ b.map(x => (x: T)) - def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T) - } + given appendSeqImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[Seq[A1], Seq[V], V] with + override def appendValues(a: Seq[A1], b: Seq[V]): Seq[A1] = a ++ b.map(x => (x: A1)) + override def appendValue(a: Seq[A1], b: V): Seq[A1] = a :+ (b: A1) @compileTimeOnly("This can be used in += only.") implicit def appendTaskValueSeq[T, V <: T]: Value[Seq[Task[T]], Initialize[Task[V]]] = @@ -54,17 +52,14 @@ object Append { def appendValue(a: List[T], b: V): List[T] = a :+ (b: T) } - implicit def appendListImplicit[T, V](implicit ev: V => T): Sequence[List[T], List[V], V] = - new Sequence[List[T], List[V], V] { - def appendValues(a: List[T], b: List[V]): List[T] = a ::: b.map(x => (x: T)) - def appendValue(a: List[T], b: V): List[T] = a :+ (b: T) - } + given appendListImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[List[A1], List[V], V] with + override def appendValues(a: List[A1], b: List[V]): List[A1] = a ++ b.map(x => (x: A1)) + override def appendValue(a: List[A1], b: V): List[A1] = a :+ (b: A1) - implicit def appendVectorImplicit[T, V](implicit ev: V => T): Sequence[Vector[T], Seq[V], V] = - new Sequence[Vector[T], Seq[V], V] { - def appendValues(a: Vector[T], b: Seq[V]): Vector[T] = a ++ b.map(x => (x: T)) - def appendValue(a: Vector[T], b: V): Vector[T] = a :+ (b: T) - } + given appendVectorImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[Vector[A1], Vector[V], V] + with + override def appendValues(a: Vector[A1], b: Vector[V]): Vector[A1] = a ++ b.map(x => (x: A1)) + override def appendValue(a: Vector[A1], b: V): Vector[A1] = a :+ (b: A1) // psst... these are implemented with SAM conversions implicit def appendString: Value[String, String] = _ + _ @@ -122,4 +117,4 @@ object Append { b } } -} +end Append diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index 13ccec44e..095a5e112 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -15,13 +15,13 @@ import sbt.KeyRanks.{ DTask, Invisible } import sbt.Scope.{ GlobalScope, ThisScope } import sbt.internal.util.Types.const import sbt.internal.util.complete.Parser -import sbt.internal.util.{ Terminal => ITerminal, _ } +import sbt.internal.util.{ Terminal => ITerminal, * } import Util._ import sbt.util.Show import xsbti.VirtualFile /** A concrete settings system that uses `sbt.Scope` for the scope type. */ -object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { +object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits: type Classpath = Seq[Attributed[File]] type VirtualClasspath = Seq[Attributed[VirtualFile]] @@ -57,16 +57,14 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { current: ProjectRef, keyNameColor: Option[String] = None, ): Show[ScopedKey[_]] = - Show[ScopedKey[_]]( - key => { - val color: String => String = withColor(_, keyNameColor) - key.scope.extra.toOption - .flatMap(_.get(Scope.customShowString).map(color)) - .getOrElse { - Scope.display(key.scope, color(key.key.label), ref => displayRelative2(current, ref)) - } - } - ) + Show[ScopedKey[_]](key => { + val color: String => String = withColor(_, keyNameColor) + key.scope.extra.toOption + .flatMap(_.get(Scope.customShowString).map(color)) + .getOrElse { + Scope.display(key.scope, color(key.key.label), ref => displayRelative2(current, ref)) + } + }) private[sbt] def showShortKey( keyNameColor: Option[String], @@ -81,13 +79,12 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { case _ => Reference.display(project) + trailing } } - Show[ScopedKey[_]]( - key => - Scope.display( - key.scope, - withColor(key.key.label, keyNameColor), - ref => displayShort(ref) - ) + Show[ScopedKey[_]](key => + Scope.display( + key.scope, + withColor(key.key.label, keyNameColor), + ref => displayShort(ref) + ) ) } @@ -103,13 +100,12 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { currentBuild: URI, keyNameColor: Option[String] = None, ): Show[ScopedKey[_]] = - Show[ScopedKey[_]]( - key => - Scope.display( - key.scope, - withColor(key.key.label, keyNameColor), - ref => displayBuildRelative(currentBuild, ref) - ) + Show[ScopedKey[_]](key => + Scope.display( + key.scope, + withColor(key.key.label, keyNameColor), + ref => displayBuildRelative(currentBuild, ref) + ) ) /** @@ -181,18 +177,17 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { override def deriveAllowed[T](s: Setting[T], allowDynamic: Boolean): Option[String] = super.deriveAllowed(s, allowDynamic) orElse - (if (s.key.scope != ThisScope) - s"Scope cannot be defined for ${definedSettingString(s)}".some + (if s.key.scope != ThisScope then + Some(s"Scope cannot be defined for ${definedSettingString(s)}") else none) orElse s.dependencies .find(k => k.scope != ThisScope) - .map( - k => - s"Scope cannot be defined for dependency ${k.key.label} of ${definedSettingString(s)}" + .map(k => + s"Scope cannot be defined for dependency ${k.key.label} of ${definedSettingString(s)}" ) - override def intersect(s1: Scope, s2: Scope)( - implicit delegates: Scope => Seq[Scope] + override def intersect(s1: Scope, s2: Scope)(implicit + delegates: Scope => Seq[Scope] ): Option[Scope] = if (s2 == GlobalScope) Some(s1) // s1 is more specific else if (s1 == GlobalScope) Some(s2) // s2 is more specific @@ -211,69 +206,71 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { sbt.internal.util.complete.Parsers.spaceDelimited(argLabel) /** Lifts the result of a setting initialization into a Task. */ - def toITask[T](i: Initialize[T]): Initialize[Task[T]] = map(i)(std.TaskExtra.inlineTask) + def toITask[A1](i: Initialize[A1]): Initialize[Task[A1]] = map(i)(std.TaskExtra.inlineTask) def toSParser[T](p: Parser[T]): State => Parser[T] = const(p) def toISParser[T](p: Initialize[Parser[T]]): Initialize[State => Parser[T]] = p(toSParser) def toIParser[T](p: Initialize[InputTask[T]]): Initialize[State => Parser[Task[T]]] = p(_.parser) - import std.SettingMacro.{ settingDynMacroImpl, settingMacroImpl } + // import std.SettingMacro.{ settingDynMacroImpl, settingMacroImpl } import std.TaskMacro.{ - inputTaskDynMacroImpl, - inputTaskMacroImpl, - taskDynMacroImpl, - taskIfMacroImpl, - taskMacroImpl + // inputTaskDynMacroImpl, + // inputTaskMacroImpl, + // taskDynMacroImpl, + // taskIfMacroImpl, + taskMacroImpl, } import std._ import language.experimental.macros - def task[T](t: T): Def.Initialize[Task[T]] = macro taskMacroImpl[T] - def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T] - def setting[T](t: T): Def.Initialize[T] = macro settingMacroImpl[T] - def settingDyn[T](t: Def.Initialize[T]): Def.Initialize[T] = macro settingDynMacroImpl[T] - def inputTask[T](t: T): Def.Initialize[InputTask[T]] = macro inputTaskMacroImpl[T] - def inputTaskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[InputTask[T]] = - macro inputTaskDynMacroImpl[T] - def taskIf[T](a: T): Def.Initialize[Task[T]] = macro taskIfMacroImpl[T] + inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] = + ${ taskMacroImpl[A1]('a1) } - private[sbt] def selectITask[A, B]( - fab: Initialize[Task[Either[A, B]]], - fin: Initialize[Task[A => B]] - ): Initialize[Task[B]] = + // def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T] + // def setting[T](t: T): Def.Initialize[T] = macro settingMacroImpl[T] + // def settingDyn[T](t: Def.Initialize[T]): Def.Initialize[T] = macro settingDynMacroImpl[T] + // def inputTask[T](t: T): Def.Initialize[InputTask[T]] = macro inputTaskMacroImpl[T] + // def inputTaskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[InputTask[T]] = { + // macro inputTaskDynMacroImpl[T] + // } + // def taskIf[T](a: T): Def.Initialize[Task[T]] = macro taskIfMacroImpl[T] + + private[sbt] def selectITask[A1, A2]( + fab: Initialize[Task[Either[A1, A2]]], + fin: Initialize[Task[A1 => A2]] + ): Initialize[Task[A2]] = fab.zipWith(fin)((ab, in) => TaskExtra.select(ab, in)) - import Scoped.syntax._ + import Scoped.syntax.* // { Def => _, DTask => _, Invisible => _, * } // derived from select private[sbt] def branchS[A, B, C]( x: Def.Initialize[Task[Either[A, B]]] - )(l: Def.Initialize[Task[A => C]])(r: Def.Initialize[Task[B => C]]): Def.Initialize[Task[C]] = { - val lhs = { + )(l: Def.Initialize[Task[A => C]])(r: Def.Initialize[Task[B => C]]): Def.Initialize[Task[C]] = + val lhs: Initialize[Task[Either[B, C]]] = { val innerLhs: Def.Initialize[Task[Either[A, Either[B, C]]]] = x.map((fab: Either[A, B]) => fab.map(Left(_))) val innerRhs: Def.Initialize[Task[A => Either[B, C]]] = l.map((fn: A => C) => fn.andThen(Right(_))) - selectITask(innerLhs, innerRhs) + selectITask[A, Either[B, C]](innerLhs, innerRhs) } - selectITask(lhs, r) - } + selectITask[B, C](lhs, r) // derived from select def ifS[A]( x: Def.Initialize[Task[Boolean]] - )(t: Def.Initialize[Task[A]])(e: Def.Initialize[Task[A]]): Def.Initialize[Task[A]] = { + )(t: Def.Initialize[Task[A]])(e: Def.Initialize[Task[A]]): Def.Initialize[Task[A]] = val condition: Def.Initialize[Task[Either[Unit, Unit]]] = - x.map((p: Boolean) => if (p) Left(()) else Right(())) + x.map { (p: Boolean) => if p then Left(()) else Right(()) } val left: Def.Initialize[Task[Unit => A]] = - t.map((a: A) => { _ => a }) + t.map { (a: A) => { (_: Unit) => a } } val right: Def.Initialize[Task[Unit => A]] = - e.map((a: A) => { _ => a }) + e.map { (a: A) => { (_: Unit) => a } } branchS(condition)(left)(right) - } - /** Returns `PromiseWrap[A]`, which is a wrapper around `scala.concurrent.Promise`. + /** + * Returns `PromiseWrap[A]`, which is a wrapper around `scala.concurrent.Promise`. * When a task is typed promise (e.g. `Def.Initialize[Task[PromiseWrap[A]]]`),an implicit * method called `await` is injected which will run in a thread outside of concurrent restriction budget. */ @@ -282,35 +279,40 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { // The following conversions enable the types Initialize[T], Initialize[Task[T]], and Task[T] to // be used in task and setting macros as inputs with an ultimate result of type T - implicit def macroValueI[T](@deprecated("unused", "") in: Initialize[T]): MacroValue[T] = ??? + // implicit def macroValueI[T](@deprecated("unused", "") in: Initialize[T]): MacroValue[T] = ??? - implicit def macroValueIT[T](@deprecated("unused", "") in: Initialize[Task[T]]): MacroValue[T] = - ??? + // implicit def macroValueIT[T](@deprecated("unused", "") in: Initialize[Task[T]]): MacroValue[T] = + // ??? - implicit def macroValueIInT[T]( - @deprecated("unused", "") in: Initialize[InputTask[T]] - ): InputEvaluated[T] = ??? + // implicit def macroValueIInT[T]( + // @deprecated("unused", "") in: Initialize[InputTask[T]] + // ): InputEvaluated[T] = ??? - implicit def taskMacroValueIT[T]( - @deprecated("unused", "") in: Initialize[Task[T]] - ): MacroTaskValue[T] = ??? + // implicit def taskMacroValueIT[T]( + // @deprecated("unused", "") in: Initialize[Task[T]] + // ): MacroTaskValue[T] = ??? - implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ??? + // implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ??? // The following conversions enable the types Parser[T], Initialize[Parser[T]], and // Initialize[State => Parser[T]] to be used in the inputTask macro as an input with an ultimate // result of type T - implicit def parserInitToInput[T]( - @deprecated("unused", "") p: Initialize[Parser[T]] - ): ParserInput[T] = ??? + // implicit def parserInitToInput[T]( + // @deprecated("unused", "") p: Initialize[Parser[T]] + // ): ParserInput[T] = ??? - implicit def parserInitStateToInput[T]( - @deprecated("unused", "") p: Initialize[State => Parser[T]] - ): ParserInput[T] = ??? + // implicit def parserInitStateToInput[T]( + // @deprecated("unused", "") p: Initialize[State => Parser[T]] + // ): ParserInput[T] = ??? - def settingKey[T](description: String): SettingKey[T] = macro std.KeyMacro.settingKeyImpl[T] - def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T] - def inputKey[T](description: String): InputKey[T] = macro std.KeyMacro.inputKeyImpl[T] + inline def settingKey[A1](inline description: String): SettingKey[A1] = + ${ std.KeyMacro.settingKeyImpl[A1]('description) } + + inline def taskKey[A1](inline description: String): TaskKey[A1] = + ${ std.KeyMacro.taskKeyImpl[A1]('description) } + + inline def inputKey[A1](inline description: String): InputKey[A1] = + ${ std.KeyMacro.inputKeyImpl[A1]('description) } class InitOps[T](private val x: Initialize[T]) extends AnyVal { def toTaskable: Taskable[T] = x @@ -320,7 +322,8 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { def toTaskable: Taskable[T] = x } - /** This works around Scala 2.12.12's + /** + * This works around Scala 2.12.12's * "a pure expression does nothing in statement position" * * {{{ @@ -330,8 +333,8 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { */ def unit(a: Any): Unit = () - private[sbt] def dummy[T: Manifest](name: String, description: String): (TaskKey[T], Task[T]) = - (TaskKey[T](name, description, DTask), dummyTask(name)) + private[sbt] def dummy[A: Manifest](name: String, description: String): (TaskKey[A], Task[A]) = + (TaskKey[A](name, description, DTask), dummyTask(name)) private[sbt] def dummyTask[T](name: String): Task[T] = { import std.TaskExtra.{ task => newTask, _ } @@ -350,27 +353,32 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits { Invisible ) - private[sbt] val (stateKey, dummyState) = dummy[State]("state", "Current build state.") + private[sbt] val (stateKey: TaskKey[State], dummyState: Task[State]) = + dummy[State]("state", "Current build state.") - private[sbt] val (streamsManagerKey, dummyStreamsManager) = Def.dummy[std.Streams[ScopedKey[_]]]( - "streams-manager", - "Streams manager, which provides streams for different contexts." - ) -} + private[sbt] val ( + streamsManagerKey: TaskKey[std.Streams[ScopedKey[_]]], + dummyStreamsManager: Task[std.Streams[ScopedKey[_]]] + ) = + Def.dummy[std.Streams[ScopedKey[_]]]( + "streams-manager", + "Streams manager, which provides streams for different contexts." + ) +end Def // these need to be mixed into the sbt package object // because the target doesn't involve Initialize or anything in Def trait TaskMacroExtra { - implicit def macroValueT[T](@deprecated("unused", "") in: Task[T]): std.MacroValue[T] = ??? + // implicit def macroValueT[T](@deprecated("unused", "") in: Task[T]): std.MacroValue[T] = ??? - implicit def macroValueIn[T](@deprecated("unused", "") in: InputTask[T]): std.InputEvaluated[T] = - ??? + // implicit def macroValueIn[T](@deprecated("unused", "") in: InputTask[T]): std.InputEvaluated[T] = + // ??? - implicit def parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ??? + // implicit def parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ??? - implicit def stateParserToInput[T]( - @deprecated("unused", "") in: State => Parser[T] - ): std.ParserInput[T] = ??? + // implicit def stateParserToInput[T]( + // @deprecated("unused", "") in: State => Parser[T] + // ): std.ParserInput[T] = ??? } sealed trait InitializeImplicits0 { self: Def.type => diff --git a/main-settings/src/main/scala/sbt/DelegateIndex.scala b/main-settings/src/main/scala/sbt/DelegateIndex.scala index e187ce931..c6ac7d02c 100644 --- a/main-settings/src/main/scala/sbt/DelegateIndex.scala +++ b/main-settings/src/main/scala/sbt/DelegateIndex.scala @@ -22,7 +22,7 @@ private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) exte case Some(pd) => pd.confs.get(conf) match { case Some(cs) => cs - case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil + case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil } case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil } diff --git a/main-settings/src/main/scala/sbt/InputTask.scala b/main-settings/src/main/scala/sbt/InputTask.scala index faea5bd00..3f0ea338a 100644 --- a/main-settings/src/main/scala/sbt/InputTask.scala +++ b/main-settings/src/main/scala/sbt/InputTask.scala @@ -15,25 +15,25 @@ import sbt.internal.util.Types._ import sbt.internal.util.Util._ /** Parses input and produces a task to run. Constructed using the companion object. */ -final class InputTask[T] private (val parser: State => Parser[Task[T]]) { - def mapTask[S](f: Task[T] => Task[S]): InputTask[S] = - new InputTask[S](s => parser(s) map f) +final class InputTask[A1] private (val parser: State => Parser[Task[A1]]): + def mapTask[S](f: Task[A1] => Task[S]): InputTask[S] = + InputTask[S](s => parser(s) map f) - def partialInput(in: String): InputTask[T] = - new InputTask[T](s => Parser(parser(s))(in)) + def partialInput(in: String): InputTask[A1] = + InputTask[A1](s => Parser(parser(s))(in)) - def fullInput(in: String): InputTask[T] = - new InputTask[T]( - s => - Parser.parse(in, parser(s)) match { - case Right(v) => Parser.success(v) - case Left(msg) => - val indented = msg.linesIterator.map(" " + _).mkString("\n") - Parser.failure(s"Invalid programmatic input:\n$indented") - } + def fullInput(in: String): InputTask[A1] = + InputTask[A1](s => + Parser.parse(in, parser(s)) match { + case Right(v) => Parser.success(v) + case Left(msg) => + val indented = msg.linesIterator.map(" " + _).mkString("\n") + Parser.failure(s"Invalid programmatic input:\n$indented") + } ) -} +end InputTask +/* object InputTask { implicit class InitializeInput[T](i: Initialize[InputTask[T]]) { def partialInput(in: String): Initialize[InputTask[T]] = i(_ partialInput in) @@ -41,17 +41,15 @@ object InputTask { import std.FullInstance._ def toTask(in: String): Initialize[Task[T]] = flatten( - (Def.stateKey zipWith i)( - (sTask, it) => - sTask map ( - s => - Parser.parse(in, it.parser(s)) match { - case Right(t) => Def.value(t) - case Left(msg) => - val indented = msg.linesIterator.map(" " + _).mkString("\n") - sys.error(s"Invalid programmatic input:\n$indented") - } - ) + (Def.stateKey zipWith i)((sTask, it) => + sTask map (s => + Parser.parse(in, it.parser(s)) match { + case Right(t) => Def.value(t) + case Left(msg) => + val indented = msg.linesIterator.map(" " + _).mkString("\n") + sys.error(s"Invalid programmatic input:\n$indented") + } + ) ) ) } @@ -91,24 +89,24 @@ object InputTask { } /** - * Constructs an InputTask from: - * a) a Parser constructed using other Settings, but not Tasks - * b) a dynamically constructed Task that uses Settings, Tasks, and the result of parsing. - */ + * Constructs an InputTask from: + * a) a Parser constructed using other Settings, but not Tasks + * b) a dynamically constructed Task that uses Settings, Tasks, and the result of parsing. + */ def createDyn[I, T]( p: Initialize[State => Parser[I]] )(action: Initialize[Task[I => Initialize[Task[T]]]]): Initialize[InputTask[T]] = separate(p)(std.FullInstance.flattenFun[I, T](action)) - /** A dummy parser that consumes no input and produces nothing useful (unit).*/ + /** A dummy parser that consumes no input and produces nothing useful (unit). */ def emptyParser: State => Parser[Unit] = Types.const(sbt.internal.util.complete.DefaultParsers.success(())) - /** Implementation detail that is public because it is used by a macro.*/ + /** Implementation detail that is public because it is used by a macro. */ def parserAsInput[T](p: Parser[T]): Initialize[State => Parser[T]] = Def.valueStrict(Types.const(p)) - /** Implementation detail that is public because it is used by a macro.*/ + /** Implementation detail that is public because it is used by a macro. */ def initParserAsInput[T](i: Initialize[Parser[T]]): Initialize[State => Parser[T]] = i(Types.const[State, Parser[T]]) @@ -126,10 +124,10 @@ object InputTask { } /** - * The proper solution is to have a Manifest context bound and accept slight source incompatibility, - * The affected InputTask construction methods are all deprecated and so it is better to keep complete - * compatibility. Because the AttributeKey is local, it uses object equality and the manifest is not used. - */ + * The proper solution is to have a Manifest context bound and accept slight source incompatibility, + * The affected InputTask construction methods are all deprecated and so it is better to keep complete + * compatibility. Because the AttributeKey is local, it uses object equality and the manifest is not used. + */ private[this] def localKey[T]: AttributeKey[T] = AttributeKey.local[Unit].asInstanceOf[AttributeKey[T]] @@ -170,10 +168,10 @@ object InputTask { val newTask = Task(t.info, newAction) seen.put(t, newTask) newTask - } else - t0.asInstanceOf[Task[A]] + } else t0.asInstanceOf[Task[A]] } } f(task) } } + */ diff --git a/main-settings/src/main/scala/sbt/Previous.scala b/main-settings/src/main/scala/sbt/Previous.scala index acd6ba18f..7d1c29d4f 100644 --- a/main-settings/src/main/scala/sbt/Previous.scala +++ b/main-settings/src/main/scala/sbt/Previous.scala @@ -47,13 +47,15 @@ object Previous { private final val StreamName = "previous" private[sbt] final val DependencyDirectory = "previous-dependencies" - /** Represents a reference task.previous*/ + /** Represents a reference task.previous */ private[sbt] final class Referenced[T](val key: Key[T], val format: JsonFormat[T]) { def this(task: ScopedTaskKey[T], format: JsonFormat[T]) = this(Key(task, task), format) - @deprecated("unused", "1.3.0") - private[sbt] def task: ScopedKey[Task[T]] = key.task + + // @deprecated("unused", "1.3.0") + // private[sbt] def task: ScopedKey[Task[T]] = key.task + lazy val stamped: JsonFormat[T] = - StampedFormat.withStamp(key.task.key.manifest.toString)(format) + StampedFormat.withStamp(key.task.key.classTag.toString)(format) def setTask(newTask: ScopedKey[Task[T]]) = new Referenced(newTask, format) private[sbt] def read(streams: Streams): Option[T] = try Option(streams(key.cacheKey).cacheStoreFactory.make(StreamName).read[T]()(stamped)) @@ -82,7 +84,7 @@ object Previous { else { val am = enclosing.scope.extra match { case Select(a) => a.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey]) - case _ => AttributeMap.empty.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey]) + case _ => AttributeMap.empty.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey]) } Def.ScopedKey(enclosing.scope.copy(extra = Select(am)), enclosing.key) } @@ -120,7 +122,7 @@ object Previous { // We first collect all of the successful tasks and write their scoped key into a map // along with their values. val successfulTaskResults = (for { - results.TPair(task, Value(v)) <- results.toTypedSeq + results.TPair(task, Result.Value(v)) <- results.toTypedSeq key <- task.info.attributes.get(Def.taskDefinitionKey).asInstanceOf[Option[AnyTaskKey]] } yield key -> v).toMap // We then traverse the successful results and look up all of the referenced values for @@ -147,28 +149,27 @@ object Previous { /** Public as a macro implementation detail. Do not call directly. */ def runtime[T](skey: TaskKey[T])(implicit format: JsonFormat[T]): Initialize[Task[Option[T]]] = { - val inputs = (Global / cache) zip Def.validated(skey, selfRefOk = true) zip (Global / references) - inputs { - case ((prevTask, resolved), refs) => - val key = Key(resolved, resolved) - refs.recordReference(key, format) // always evaluated on project load - prevTask.map(_.get(key)) // evaluated if this task is evaluated + val inputs = + (Global / cache) zip Def.validated(skey, selfRefOk = true) zip (Global / references) + inputs { case ((prevTask, resolved), refs) => + val key = Key(resolved, resolved) + refs.recordReference(key, format) // always evaluated on project load + prevTask.map(_.get(key)) // evaluated if this task is evaluated } } /** Public as a macro implementation detail. Do not call directly. */ - def runtimeInEnclosingTask[T](skey: TaskKey[T])( - implicit format: JsonFormat[T] + def runtimeInEnclosingTask[T](skey: TaskKey[T])(implicit + format: JsonFormat[T] ): Initialize[Task[Option[T]]] = { val inputs = (Global / cache) .zip(Def.validated(skey, selfRefOk = true)) .zip(Global / references) .zip(Def.resolvedScoped) - inputs { - case (((prevTask, resolved), refs), inTask: ScopedKey[Task[_]] @unchecked) => - val key = Key(resolved, inTask) - refs.recordReference(key, format) // always evaluated on project load - prevTask.map(_.get(key)) // evaluated if this task is evaluated + inputs { case (((prevTask, resolved), refs), inTask: ScopedKey[Task[_]] @unchecked) => + val key = Key(resolved, inTask) + refs.recordReference(key, format) // always evaluated on project load + prevTask.map(_.get(key)) // evaluated if this task is evaluated } } } diff --git a/main-settings/src/main/scala/sbt/PromiseWrap.scala b/main-settings/src/main/scala/sbt/PromiseWrap.scala index ec9a50817..fbd083857 100644 --- a/main-settings/src/main/scala/sbt/PromiseWrap.scala +++ b/main-settings/src/main/scala/sbt/PromiseWrap.scala @@ -9,14 +9,14 @@ package sbt import scala.concurrent.{ Promise => XPromise } -final class PromiseWrap[A] { +final class PromiseWrap[A]: private[sbt] val underlying: XPromise[A] = XPromise() def complete(result: Result[A]): Unit = result match { - case Inc(cause) => underlying.failure(cause) - case Value(value) => underlying.success(value) + case Result.Inc(cause) => underlying.failure(cause) + case Result.Value(value) => underlying.success(value) } def success(value: A): Unit = underlying.success(value) def failure(cause: Throwable): Unit = underlying.failure(cause) def isCompleted: Boolean = underlying.isCompleted -} +end PromiseWrap diff --git a/main-settings/src/main/scala/sbt/Reference.scala b/main-settings/src/main/scala/sbt/Reference.scala index 74267ba89..7d24067cf 100644 --- a/main-settings/src/main/scala/sbt/Reference.scala +++ b/main-settings/src/main/scala/sbt/Reference.scala @@ -54,7 +54,7 @@ object ProjectRef { } object RootProject { - /** Reference to the root project at 'base'.*/ + /** Reference to the root project at 'base'. */ def apply(base: File): RootProject = RootProject(IO toURI base) } object Reference { @@ -96,7 +96,7 @@ object Reference { case ProjectRef(b, _) => b } - /** Extracts the build URI from a Reference if one has been explicitly defined.*/ + /** Extracts the build URI from a Reference if one has been explicitly defined. */ def uri(ref: Reference): Option[URI] = ref match { case RootProject(b) => Some(b) case ProjectRef(b, _) => Some(b) diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 4fa31f51c..99fcbb2c4 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -408,9 +408,8 @@ object Scope { projectInherit: ProjectRef => Seq[ProjectRef], configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey] ): DelegateIndex = { - val pDelegates = refs map { - case (ref, project) => - (ref, delegateIndex(ref, configurations(project))(projectInherit, configInherit)) + val pDelegates = refs map { case (ref, project) => + (ref, delegateIndex(ref, configurations(project))(projectInherit, configInherit)) } toMap; new DelegateIndex0(pDelegates) } diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index ae774b30a..e4721ad70 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -34,9 +34,13 @@ trait SlashSyntax { implicit def sbtSlashSyntaxRichReferenceAxis(a: ScopeAxis[Reference]): RichReference = new RichReference(Scope(a, This, This, This)) - implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r) - implicit def sbtSlashSyntaxRichProject[A](p: A)(implicit x: A => Reference): RichReference = - (p: Reference) + // implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r) + + given sbtSlashSyntaxRichReference: Conversion[Reference, RichReference] = + (r: Reference) => Select(r) + + given sbtSlashSyntaxRichProject[A](using Conversion[A, Reference]): Conversion[A, RichReference] = + (a: A) => Select(a: Reference) implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration = new RichConfiguration(Scope(This, Select(c), This, This)) @@ -62,7 +66,7 @@ object SlashSyntax { sealed trait HasSlashKey { protected def scope: Scope @nowarn - final def /[K](key: Scoped.ScopingSetting[K]): K = key in scope + final def /[K](key: Scoped.ScopingSetting[K]): K = key.in(scope) } sealed trait HasSlashKeyOrAttrKey extends HasSlashKey { diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 6ac79293a..367619423 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -13,40 +13,40 @@ import sbt.internal.util.Types._ import sbt.internal.util.{ ~>, AList, AttributeKey, Settings, SourcePosition } import sbt.util.OptJsonWriter import sbt.ConcurrentRestrictions.Tag -import sbt.Def.{ Initialize, KeyedInitialize, ScopedKey, Setting, setting } +import sbt.Def.{ Initialize, ScopedKey, Setting, setting } import std.TaskExtra.{ task => mktask, _ } /** An abstraction on top of Settings for build configuration and task definition. */ -sealed trait Scoped extends Equals { +sealed trait Scoped extends Equals: def scope: Scope val key: AttributeKey[_] - override def equals(that: Any) = + override def equals(that: Any): Boolean = (this eq that.asInstanceOf[AnyRef]) || (that match { case that: Scoped => scope == that.scope && key == that.key && canEqual(that) case _ => false }) - override def hashCode() = (scope, key).## -} + override def hashCode(): Int = (scope, key).## +end Scoped /** A SettingKey, TaskKey or `Initialize[Task]` that can be converted into an `Initialize[Task]`. */ -sealed trait Taskable[T] { - def toTask: Initialize[Task[T]] -} +sealed trait Taskable[A]: + def toTask: Initialize[Task[A]] +end Taskable sealed trait TaskableImplicits { self: Taskable.type => - implicit def fromInit[T](x: Initialize[T]): Taskable[T] = - new Taskable[T] { def toTask = Def.toITask(x) } + implicit def fromInit[A](x: Initialize[A]): Taskable[A] = + new Taskable[A] { def toTask = Def.toITask(x) } } object Taskable extends TaskableImplicits { - implicit def fromITask[T](x: Initialize[Task[T]]): Taskable[T] = - new Taskable[T] { def toTask = x } + implicit def fromITask[A](x: Initialize[Task[A]]): Taskable[A] = + new Taskable[A] { def toTask = x } } -/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/ -sealed trait ScopedTaskable[T] extends Scoped with Taskable[T] +/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks. */ +sealed trait ScopedTaskable[A] extends Scoped with Taskable[A] /** * Identifies a setting. It consists of three parts: the scope, the name, and the type of a value associated with this key. @@ -54,72 +54,72 @@ sealed trait ScopedTaskable[T] extends Scoped with Taskable[T] * The name and the type are represented by a value of type `AttributeKey[T]`. * Instances are constructed using the companion object. */ -sealed abstract class SettingKey[T] - extends ScopedTaskable[T] - with KeyedInitialize[T] - with Scoped.ScopingSetting[SettingKey[T]] - with Scoped.DefinableSetting[T] { +sealed abstract class SettingKey[A1] + extends ScopedTaskable[A1] + with Def.KeyedInitialize[A1] + with Scoped.ScopingSetting[SettingKey[A1]] + with Scoped.DefinableSetting[A1]: - val key: AttributeKey[T] + val key: AttributeKey[A1] override def toString: String = s"SettingKey($scope / $key)" - final def toTask: Initialize[Task[T]] = this apply inlineTask + final def toTask: Initialize[Task[A1]] = this apply inlineTask - final def scopedKey: ScopedKey[T] = ScopedKey(scope, key) + final def scopedKey: ScopedKey[A1] = ScopedKey(scope, key) // @deprecated(Scope.inIsDeprecated, "1.5.0") - final def in(scope: Scope): SettingKey[T] = + final def in(scope: Scope): SettingKey[A1] = Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key) - final def :=(v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T] + // 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](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 ++=[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.fakeSettingAppend1Position[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 <++=[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](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 --=[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] + // final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T] - final def append1[V](v: Initialize[V], source: SourcePosition)( - implicit a: Append.Value[T, V] - ): Setting[T] = make(v, source)(a.appendValue) + final def append1[V](v: Initialize[V], source: SourcePosition)(implicit + a: Append.Value[A1, V] + ): Setting[A1] = make(v, source)(a.appendValue) - final def appendN[V](vs: Initialize[V], source: SourcePosition)( - implicit a: Append.Values[T, V] - ): Setting[T] = make(vs, source)(a.appendValues) + final def appendN[V](vs: Initialize[V], source: SourcePosition)(implicit + a: Append.Values[A1, V] + ): Setting[A1] = make(vs, source)(a.appendValues) - final def remove1[V](v: Initialize[V], source: SourcePosition)( - implicit r: Remove.Value[T, V] - ): Setting[T] = make(v, source)(r.removeValue) - final def removeN[V](vs: Initialize[V], source: SourcePosition)( - implicit r: Remove.Values[T, V] - ): Setting[T] = make(vs, source)(r.removeValues) + final def remove1[V](v: Initialize[V], source: SourcePosition)(implicit + r: Remove.Value[A1, V] + ): Setting[A1] = make(v, source)(r.removeValue) + final def removeN[V](vs: Initialize[V], source: SourcePosition)(implicit + r: Remove.Values[A1, V] + ): Setting[A1] = make(vs, source)(r.removeValues) - final def transform(f: T => T, source: SourcePosition): Setting[T] = set(scopedKey(f), source) + final def transform(f: A1 => A1, source: SourcePosition): Setting[A1] = set(scopedKey(f), source) protected[this] def make[S](other: Initialize[S], source: SourcePosition)( - f: (T, S) => T - ): Setting[T] = set(this.zipWith(other)(f), source) + f: (A1, S) => A1 + ): Setting[A1] = set(this.zipWith(other)(f), source) - final def withRank(rank: Int): SettingKey[T] = + final def withRank(rank: Int): SettingKey[A1] = SettingKey(AttributeKey.copyWithRank(key, rank)) def canEqual(that: Any): Boolean = that.isInstanceOf[SettingKey[_]] -} +end SettingKey /** * Identifies a task. It consists of three parts: the scope, the name, and the type of the value computed by a task associated with this key. @@ -127,67 +127,67 @@ sealed abstract class SettingKey[T] * The name and the type are represented by a value of type `AttributeKey[Task[T]]`. * Instances are constructed using the companion object. */ -sealed abstract class TaskKey[T] - extends ScopedTaskable[T] - with KeyedInitialize[Task[T]] - with Scoped.ScopingSetting[TaskKey[T]] - with Scoped.DefinableTask[T] { +sealed abstract class TaskKey[A1] + extends ScopedTaskable[A1] + with Def.KeyedInitialize[Task[A1]] + with Scoped.ScopingSetting[TaskKey[A1]] + with Scoped.DefinableTask[A1]: - val key: AttributeKey[Task[T]] + val key: AttributeKey[Task[A1]] override def toString: String = s"TaskKey($scope / $key)" - def toTask: Initialize[Task[T]] = this + def toTask: Initialize[Task[A1]] = this - def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key) + def scopedKey: ScopedKey[Task[A1]] = ScopedKey(scope, key) // @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(scope: Scope): TaskKey[T] = + def in(scope: Scope): TaskKey[A1] = Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key) - def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[Task[T]] = - macro std.TaskMacro.taskAppend1Impl[T, U] + // 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 ++=[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.fakeTaskAppend1Position[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] + // 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](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] + // final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[Task[T]] = + // macro std.TaskMacro.taskRemoveNImpl[T, U] - def append1[V](v: Initialize[Task[V]], source: SourcePosition)( - implicit a: Append.Value[T, V] - ): Setting[Task[T]] = make(v, source)(a.appendValue) + def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit + a: Append.Value[A1, V] + ): Setting[Task[A1]] = make(v, source)(a.appendValue) - def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)( - implicit a: Append.Values[T, V] - ): Setting[Task[T]] = make(vs, source)(a.appendValues) + def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit + a: Append.Values[A1, V] + ): Setting[Task[A1]] = make(vs, source)(a.appendValues) - final def remove1[V](v: Initialize[Task[V]], source: SourcePosition)( - implicit r: Remove.Value[T, V] - ): Setting[Task[T]] = make(v, source)(r.removeValue) + final def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit + r: Remove.Value[A1, V] + ): Setting[Task[A1]] = make(v, source)(r.removeValue) - final def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)( - implicit r: Remove.Values[T, V] - ): Setting[Task[T]] = make(vs, source)(r.removeValues) + final def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit + r: Remove.Values[A1, V] + ): Setting[Task[A1]] = make(vs, source)(r.removeValues) private[this] def make[S](other: Initialize[Task[S]], source: SourcePosition)( - f: (T, S) => T - ): Setting[Task[T]] = set(this.zipWith(other)((a, b) => (a, b) map f.tupled), source) + f: (A1, S) => A1 + ): Setting[Task[A1]] = set(this.zipWith(other)((a, b) => (a, b) map f.tupled), source) - final def withRank(rank: Int): TaskKey[T] = + final def withRank(rank: Int): TaskKey[A1] = TaskKey(AttributeKey.copyWithRank(key, rank)) def canEqual(that: Any): Boolean = that.isInstanceOf[TaskKey[_]] -} +end TaskKey /** * Identifies an input task. An input task parses input and produces a task to run. @@ -196,36 +196,36 @@ sealed abstract class TaskKey[T] * The name and the type are represented by a value of type `AttributeKey[InputTask[T]]`. * Instances are constructed using the companion object. */ -sealed trait InputKey[T] +sealed trait InputKey[A1] extends Scoped - with KeyedInitialize[InputTask[T]] - with Scoped.ScopingSetting[InputKey[T]] - with Scoped.DefinableSetting[InputTask[T]] { + with Def.KeyedInitialize[InputTask[A1]] + with Scoped.ScopingSetting[InputKey[A1]] + with Scoped.DefinableSetting[InputTask[A1]]: - val key: AttributeKey[InputTask[T]] + val key: AttributeKey[InputTask[A1]] override def toString: String = s"InputKey($scope / $key)" - def scopedKey: ScopedKey[InputTask[T]] = ScopedKey(scope, key) + def scopedKey: ScopedKey[InputTask[A1]] = ScopedKey(scope, key) // @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(scope: Scope): InputKey[T] = + def in(scope: Scope): InputKey[A1] = Scoped.scopedInput(Scope.replaceThis(this.scope)(scope), this.key) - final def :=(v: T): Setting[InputTask[T]] = macro std.TaskMacro.inputTaskAssignMacroImpl[T] - final def ~=(f: T => T): Setting[InputTask[T]] = macro std.TaskMacro.itaskTransformPosition[T] + // final def :=(v: A1): Setting[InputTask[A1]] = macro std.TaskMacro.inputTaskAssignMacroImpl[A1] + // final def ~=(f: A1 => A1): Setting[InputTask[A1]] = macro std.TaskMacro.itaskTransformPosition[A1] - final def transform(f: T => T, source: SourcePosition): Setting[InputTask[T]] = + final def transform(f: A1 => A1, source: SourcePosition): Setting[InputTask[A1]] = set(scopedKey(_ mapTask { _ map f }), source) - final def withRank(rank: Int): InputKey[T] = + final def withRank(rank: Int): InputKey[A1] = InputKey(AttributeKey.copyWithRank(key, rank)) def canEqual(that: Any): Boolean = that.isInstanceOf[InputKey[_]] -} +end InputKey /** Methods and types related to constructing settings, including keys, scopes, and initializations. */ -object Scoped { +object Scoped: implicit def taskScopedToKey[T](s: TaskKey[T]): ScopedKey[Task[T]] = ScopedKey(s.scope, s.key) implicit def inputScopedToKey[T](s: InputKey[T]): ScopedKey[InputTask[T]] = @@ -244,41 +244,41 @@ object Scoped { * * name.in(Compile).:=("hello ugly syntax") * }}} - * */ - sealed trait ScopingSetting[ResultType] { - // @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(s: Scope): ResultType + sealed trait ScopingSetting[ResultType]: + private[sbt] def in(s: Scope): ResultType + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(s: Scope): ResultType - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(p: Reference): ResultType = in(Select(p), This, This) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(p: Reference): ResultType = in(Select(p), This, This) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(t: Scoped): ResultType = in(This, This, Select(t.key)) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(t: Scoped): ResultType = in(This, This, Select(t.key)) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(c: ConfigKey): ResultType = in(This, Select(c), This) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(c: ConfigKey): ResultType = in(This, Select(c), This) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(c: ConfigKey, t: Scoped): ResultType = in(This, Select(c), Select(t.key)) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(c: ConfigKey, t: Scoped): ResultType = in(This, Select(c), Select(t.key)) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(p: Reference, c: ConfigKey): ResultType = in(Select(p), Select(c), This) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(p: Reference, c: ConfigKey): ResultType = in(Select(p), Select(c), This) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(p: Reference, t: Scoped): ResultType = in(Select(p), This, Select(t.key)) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(p: Reference, t: Scoped): ResultType = in(Select(p), This, Select(t.key)) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in(p: Reference, c: ConfigKey, t: Scoped): ResultType = - in(Select(p), Select(c), Select(t.key)) + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in(p: Reference, c: ConfigKey, t: Scoped): ResultType = + // in(Select(p), Select(c), Select(t.key)) - @deprecated(Scope.inIsDeprecated, "1.5.0") - def in( - p: ScopeAxis[Reference], - c: ScopeAxis[ConfigKey], - t: ScopeAxis[AttributeKey[_]] - ): ResultType = in(Scope(p, c, t, This)) - } + // @deprecated(Scope.inIsDeprecated, "1.5.0") + // def in( + // p: ScopeAxis[Reference], + // c: ScopeAxis[ConfigKey], + // t: ScopeAxis[AttributeKey[_]] + // ): ResultType = in(Scope(p, c, t, This)) + end ScopingSetting def scopedSetting[T](s: Scope, k: AttributeKey[T]): SettingKey[T] = new SettingKey[T] { val scope = s; val key = k } @@ -295,10 +295,10 @@ object Scoped { sealed trait DefinableSetting[S] { def scopedKey: ScopedKey[S] - private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S] + // private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S] - final def <<=(app: Initialize[S]): Setting[S] = - macro std.TaskMacro.fakeSettingAssignPosition[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] = @@ -353,46 +353,51 @@ object Scoped { def map[T](f: S => T): Initialize[Task[T]] = init(s => mktask(f(s))) def flatMap[T](f: S => Task[T]): Initialize[Task[T]] = init(f) } - sealed trait DefinableTask[S] { self: TaskKey[S] => - private[sbt] def :==(app: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionPure[S] + sealed trait DefinableTask[A1] { self: TaskKey[A1] => - private[sbt] def ::=(app: Task[S]): Setting[Task[S]] = - macro std.TaskMacro.taskAssignPositionT[S] + // private[sbt] def :==(app: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionPure[S] - def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S] - def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S] + // private[sbt] def ::=(app: Task[S]): Setting[Task[S]] = + // macro std.TaskMacro.taskAssignPositionT[S] - def <<=(app: Initialize[Task[S]]): Setting[Task[S]] = - macro std.TaskMacro.fakeItaskAssignPosition[S] + // def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S] + // def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S] - def set(app: Initialize[Task[S]], source: SourcePosition): Setting[Task[S]] = + // def <<=(app: Initialize[Task[S]]): Setting[Task[S]] = + // macro std.TaskMacro.fakeItaskAssignPosition[S] + + def set(app: Initialize[Task[A1]], source: SourcePosition): Setting[Task[A1]] = Def.setting(scopedKey, app, source) - def transform(f: S => S, source: SourcePosition): Setting[Task[S]] = + def transform(f: A1 => A1, source: SourcePosition): Setting[Task[A1]] = set(scopedKey(_ map f), source) - @deprecated( - "No longer needed with new task syntax and SettingKey inheriting from Initialize.", - "0.13.2" - ) - def task: SettingKey[Task[S]] = scopedSetting(scope, key) + // @deprecated( + // "No longer needed with new task syntax and SettingKey inheriting from Initialize.", + // "0.13.2" + // ) + // def task: SettingKey[Task[A1]] = scopedSetting(scope, key) - def toSettingKey: SettingKey[Task[S]] = scopedSetting(scope, key) + def toSettingKey: SettingKey[Task[A1]] = scopedSetting(scope, key) - def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key) + def get(settings: Settings[Scope]): Option[Task[A1]] = settings.get(scope, key) - def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) { - case None => mktask { None }; case Some(t) => t map some.fn + def ? : Initialize[Task[Option[A1]]] = Def.optional(scopedKey) { + case None => mktask { None } + case Some(t) => t map some[A1] } - def ??[T >: S](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)(_ getOrElse mktask(or)) + def ??[T >: A1](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)(_ getOrElse mktask(or)) - def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = - (this.? zipWith i)((x, y) => (x, y) map { case (a, b) => a getOrElse b }) + // def or[A2 >: A1](i: Initialize[Task[A2]]): Initialize[Task[A2]] = + // this.?.zipWith(i) { (toa1: Task[Option[A1]], ta2: Task[A2]) => + // (toa1, ta2).map { case (oa1: Option[A1], a2: A2) => oa1 getOrElse b2 } + // } } - /** Enriches `Initialize[Task[S]]` types. + /** + * Enriches `Initialize[Task[S]]` types. * * @param i the original `Initialize[Task[S]]` value to enrich * @tparam S the type of the underlying value @@ -407,14 +412,14 @@ object Scoped { def failure: Initialize[Task[Incomplete]] = i(_.failure) def result: Initialize[Task[Result[S]]] = i(_.result) - def xtriggeredBy[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] = - nonLocal(tasks, Def.triggeredBy) + def xtriggeredBy[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] = + nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.triggeredBy) - def triggeredBy[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] = - nonLocal(tasks, Def.triggeredBy) + def triggeredBy[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] = + nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.triggeredBy) - def runBefore[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] = - nonLocal(tasks, Def.runBefore) + def runBefore[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] = + nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.runBefore) private[this] def nonLocal( tasks: Seq[AnyInitTask], @@ -423,7 +428,8 @@ object Scoped { Initialize.joinAny[Task](tasks).zipWith(i)((ts, i) => i.copy(info = i.info.set(key, ts))) } - /** Enriches `Initialize[InputTask[S]]` types. + /** + * Enriches `Initialize[InputTask[S]]` types. * * @param i the original `Initialize[InputTask[S]]` value to enrich * @tparam S the type of the underlying value @@ -434,13 +440,14 @@ object Scoped { protected def onTask[T](f: Task[S] => Task[T]): Initialize[InputTask[T]] = i(_ mapTask f) def dependsOn(tasks: AnyInitTask*): Initialize[InputTask[S]] = { - i.zipWith(Initialize.joinAny[Task](tasks))( - (thisTask, deps) => thisTask.mapTask(_.dependsOn(deps: _*)) + i.zipWith(Initialize.joinAny[Task](tasks))((thisTask, deps) => + thisTask.mapTask(_.dependsOn(deps: _*)) ) } } - /** Enriches `Initialize[R[S]]` types. Abstracts over the specific task-like type constructor. + /** + * Enriches `Initialize[R[S]]` types. Abstracts over the specific task-like type constructor. * * @tparam S the type of the underlying vault * @tparam R the task-like type constructor (either Task or InputTask) @@ -487,7 +494,7 @@ object Scoped { def mapFailure[T](f: Incomplete => T): Initialize[R[T]] = onTask(_.result map (f compose failM)) } - type AnyInitTask = Initialize[Task[T]] forSome { type T } + type AnyInitTask = Initialize[Task[Any]] implicit def richTaskSeq[T](in: Seq[Initialize[Task[T]]]): RichTaskSeq[T] = new RichTaskSeq(in) final class RichTaskSeq[T](keys: Seq[Initialize[Task[T]]]) { @@ -501,8 +508,8 @@ object Scoped { Initialize.joinAny[Task](keys).apply(deps => nop.dependsOn(deps: _*)) } - sealed abstract class RichTaskables[K[L[x]]](final val keys: K[Taskable])( - implicit a: AList[K] + sealed abstract class RichTaskables[K[L[x]]](final val keys: K[Taskable])(implicit + a: AList[K] ) { type App[T] = Initialize[Task[T]] @@ -513,10 +520,12 @@ object Scoped { /** Convert the higher-kinded function to a Function1. For tuples that means call `.tupled`. */ protected def convert[M[_], Ret](f: Fun[M, Ret]): K[M] => Ret - private[this] val inputs: K[App] = a.transform(keys, λ[Taskable ~> App](_.toTask)) + private[this] val inputs: K[App] = a.transform(keys) { + [A] => (fa: Taskable[A]) => fa.toTask + } - private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] = - Def.app[AList.SplitK[K, Task]#l, Task[T]](inputs)(f)(AList.asplit[K, Task](a)) + private[this] def onTasks[A1](f: K[Task] => Task[A1]): App[A1] = + Def.app[SplitK[K, Task], Task[A1]](inputs)(f)(AList.asplit[K, Task](a)) def flatMap[T](f: Fun[Id, Task[T]]): App[T] = onTasks(_.flatMap(convert(f))) def flatMapR[T](f: Fun[Result, Task[T]]): App[T] = onTasks(_.flatMapR(convert(f))) @@ -529,52 +538,52 @@ object Scoped { // format: off type ST[X] = Taskable[X] - final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.T2K[A, B]#l](t2)(AList.tuple2[A, B]) { + final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.Tuple2K[A, B]](t2)(AList.tuple2[A, B]) { type Fun[M[_], Ret] = (M[A], M[B]) => Ret def identityMap = map(mkTuple2) protected def convert[M[_], R](f: (M[A], M[B]) => R) = f.tupled } - final class RichTaskable3[A, B, C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[AList.T3K[A, B, C]#l](t3)(AList.tuple3[A, B, C]) { + final class RichTaskable3[A, B, C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[AList.Tuple3K[A, B, C]](t3)(AList.tuple3[A, B, C]) { type Fun[M[_], Ret] = (M[A], M[B], M[C]) => Ret def identityMap = map(mkTuple3) protected def convert[M[_], R](f: Fun[M, R]) = f.tupled } - final class RichTaskable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[AList.T4K[A, B, C, D]#l](t4)(AList.tuple4[A, B, C, D]) { + final class RichTaskable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[AList.Tuple4K[A, B, C, D]](t4)(AList.tuple4[A, B, C, D]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D]) => Ret def identityMap = map(mkTuple4) protected def convert[M[_], R](f: Fun[M, R]) = f.tupled } - final class RichTaskable5[A, B, C, D, E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[AList.T5K[A, B, C, D, E]#l](t5)(AList.tuple5[A, B, C, D, E]) { + final class RichTaskable5[A, B, C, D, E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[AList.Tuple5K[A, B, C, D, E]](t5)(AList.tuple5[A, B, C, D, E]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E]) => Ret def identityMap = map(mkTuple5) protected def convert[M[_], R](f: Fun[M, R]) = f.tupled } - final class RichTaskable6[A, B, C, D, E, F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])) extends RichTaskables[AList.T6K[A, B, C, D, E, F]#l](t6)(AList.tuple6[A, B, C, D, E, F]) { + final class RichTaskable6[A, B, C, D, E, F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])) extends RichTaskables[AList.Tuple6K[A, B, C, D, E, F]](t6)(AList.tuple6[A, B, C, D, E, F]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F]) => Ret def identityMap = map(mkTuple6) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled } - final class RichTaskable7[A, B, C, D, E, F, G](t7: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G])) extends RichTaskables[AList.T7K[A, B, C, D, E, F, G]#l](t7)(AList.tuple7[A, B, C, D, E, F, G]) { + final class RichTaskable7[A, B, C, D, E, F, G](t7: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G])) extends RichTaskables[AList.Tuple7K[A, B, C, D, E, F, G]](t7)(AList.tuple7[A, B, C, D, E, F, G]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G]) => Ret def identityMap = map(mkTuple7) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled } - final class RichTaskable8[A, B, C, D, E, F, G, H](t8: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H])) extends RichTaskables[AList.T8K[A, B, C, D, E, F, G, H]#l](t8)(AList.tuple8[A, B, C, D, E, F, G, H]) { + final class RichTaskable8[A, B, C, D, E, F, G, H](t8: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H])) extends RichTaskables[AList.Tuple8K[A, B, C, D, E, F, G, H]](t8)(AList.tuple8[A, B, C, D, E, F, G, H]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H]) => Ret def identityMap = map(mkTuple8) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled } - final class RichTaskable9[A, B, C, D, E, F, G, H, I](t9: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I])) extends RichTaskables[AList.T9K[A, B, C, D, E, F, G, H, I]#l](t9)(AList.tuple9[A, B, C, D, E, F, G, H, I]) { + final class RichTaskable9[A, B, C, D, E, F, G, H, I](t9: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I])) extends RichTaskables[AList.Tuple9K[A, B, C, D, E, F, G, H, I]](t9)(AList.tuple9[A, B, C, D, E, F, G, H, I]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I]) => Ret def identityMap = map(mkTuple9) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled } - final class RichTaskable10[A, B, C, D, E, F, G, H, I, J](t10: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J]))) extends RichTaskables[AList.T10K[A, B, C, D, E, F, G, H, I, J]#l](t10)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) { + final class RichTaskable10[A, B, C, D, E, F, G, H, I, J](t10: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J]))) extends RichTaskables[AList.Tuple10K[A, B, C, D, E, F, G, H, I, J]](t10)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J]) => Ret def identityMap = map(mkTuple10) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled } - final class RichTaskable11[A, B, C, D, E, F, G, H, I, J, K](t11: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K]))) extends RichTaskables[AList.T11K[A, B, C, D, E, F, G, H, I, J, K]#l](t11)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) { + final class RichTaskable11[A, B, C, D, E, F, G, H, I, J, K](t11: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K]))) extends RichTaskables[AList.Tuple11K[A, B, C, D, E, F, G, H, I, J, K]](t11)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K]) => Ret def identityMap = map(mkTuple11) protected def convert[M[_], R](z: Fun[M, R]) = z.tupled @@ -595,54 +604,64 @@ object Scoped { def mkTuple14[A, B, C, D, E, F, G, H, I, J, K, L, N, O] = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L, n: N, o: O) => (a, b, c, d, e, f, g, h, i, j, k, l, n, o) def mkTuple15[A, B, C, D, E, F, G, H, I, J, K, L, N, O, P] = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L, n: N, o: O, p: P) => (a, b, c, d, e, f, g, h, i, j, k, l, n, o, p) - final class Apply2[A, B](t2: (Initialize[A], Initialize[B])) { - def apply[T](z: (A, B) => T) = Def.app[AList.T2K[A, B]#l, T](t2)(z.tupled)(AList.tuple2[A, B]) + final class Apply2[A, B](t2: (Initialize[A], Initialize[B])): + def apply[R](z: (A, B) => R) = Def.app[AList.Tuple2K[A, B], R](t2)(z.tupled)(AList.tuple2[A, B]) def identity = apply(mkTuple2) - } - final class Apply3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])) { - def apply[T](z: (A, B, C) => T) = Def.app[AList.T3K[A, B, C]#l, T](t3)(z.tupled)(AList.tuple3[A, B, C]) + end Apply2 + + final class Apply3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])): + def apply[T](z: (A, B, C) => T) = Def.app[AList.Tuple3K[A, B, C], T](t3)(z.tupled)(AList.tuple3[A, B, C]) def identity = apply(mkTuple3) - } - final class Apply4[A, B, C, D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) { - def apply[T](z: (A, B, C, D) => T) = Def.app[AList.T4K[A, B, C, D]#l, T](t4)(z.tupled)(AList.tuple4[A, B, C, D]) + end Apply3 + + final class Apply4[A, B, C, D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])): + def apply[T](z: (A, B, C, D) => T) = Def.app[AList.Tuple4K[A, B, C, D], T](t4)(z.tupled)(AList.tuple4[A, B, C, D]) def identity = apply(mkTuple4) - } - final class Apply5[A, B, C, D, E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) { - def apply[T](z: (A, B, C, D, E) => T) = Def.app[AList.T5K[A, B, C, D, E]#l, T](t5)(z.tupled)(AList.tuple5[A, B, C, D, E]) + end Apply4 + + final class Apply5[A, B, C, D, E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])): + def apply[T](z: (A, B, C, D, E) => T) = Def.app[AList.Tuple5K[A, B, C, D, E], T](t5)(z.tupled)(AList.tuple5[A, B, C, D, E]) def identity = apply(mkTuple5) - } - final class Apply6[A, B, C, D, E, F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) { - def apply[T](z: (A, B, C, D, E, F) => T) = Def.app[AList.T6K[A, B, C, D, E, F]#l, T](t6)(z.tupled)(AList.tuple6[A, B, C, D, E, F]) + end Apply5 + + final class Apply6[A, B, C, D, E, F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])): + def apply[T](z: (A, B, C, D, E, F) => T) = Def.app[AList.Tuple6K[A, B, C, D, E, F], T](t6)(z.tupled)(AList.tuple6[A, B, C, D, E, F]) def identity = apply(mkTuple6) - } - final class Apply7[A, B, C, D, E, F, G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) { - def apply[T](z: (A, B, C, D, E, F, G) => T) = Def.app[AList.T7K[A, B, C, D, E, F, G]#l, T](t7)(z.tupled)(AList.tuple7[A, B, C, D, E, F, G]) + end Apply6 + + final class Apply7[A, B, C, D, E, F, G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])): + def apply[T](z: (A, B, C, D, E, F, G) => T) = Def.app[AList.Tuple7K[A, B, C, D, E, F, G], T](t7)(z.tupled)(AList.tuple7[A, B, C, D, E, F, G]) def identity = apply(mkTuple7) - } - final class Apply8[A, B, C, D, E, F, G, H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) { - def apply[T](z: (A, B, C, D, E, F, G, H) => T) = Def.app[AList.T8K[A, B, C, D, E, F, G, H]#l, T](t8)(z.tupled)(AList.tuple8[A, B, C, D, E, F, G, H]) + end Apply7 + + final class Apply8[A, B, C, D, E, F, G, H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])): + def apply[T](z: (A, B, C, D, E, F, G, H) => T) = Def.app[AList.Tuple8K[A, B, C, D, E, F, G, H], T](t8)(z.tupled)(AList.tuple8[A, B, C, D, E, F, G, H]) def identity = apply(mkTuple8) - } - final class Apply9[A, B, C, D, E, F, G, H, I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) { - def apply[T](z: (A, B, C, D, E, F, G, H, I) => T) = Def.app[AList.T9K[A, B, C, D, E, F, G, H, I]#l, T](t9)(z.tupled)(AList.tuple9[A, B, C, D, E, F, G, H, I]) + end Apply8 + + final class Apply9[A, B, C, D, E, F, G, H, I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])): + def apply[T](z: (A, B, C, D, E, F, G, H, I) => T) = Def.app[AList.Tuple9K[A, B, C, D, E, F, G, H, I], T](t9)(z.tupled)(AList.tuple9[A, B, C, D, E, F, G, H, I]) def identity = apply(mkTuple9) - } - final class Apply10[A, B, C, D, E, F, G, H, I, J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) { - def apply[T](z: (A, B, C, D, E, F, G, H, I, J) => T) = Def.app[AList.T10K[A, B, C, D, E, F, G, H, I, J]#l, T](t10)(z.tupled)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) + end Apply9 + + final class Apply10[A, B, C, D, E, F, G, H, I, J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])): + def apply[T](z: (A, B, C, D, E, F, G, H, I, J) => T) = Def.app[AList.Tuple10K[A, B, C, D, E, F, G, H, I, J], T](t10)(z.tupled)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) def identity = apply(mkTuple10) - } - final class Apply11[A, B, C, D, E, F, G, H, I, J, K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) { - def apply[T](z: (A, B, C, D, E, F, G, H, I, J, K) => T) = Def.app[AList.T11K[A, B, C, D, E, F, G, H, I, J, K]#l, T](t11)(z.tupled)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) + end Apply10 + + final class Apply11[A, B, C, D, E, F, G, H, I, J, K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])): + def apply[T](z: (A, B, C, D, E, F, G, H, I, J, K) => T) = Def.app[AList.Tuple11K[A, B, C, D, E, F, G, H, I, J, K], T](t11)(z.tupled)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) def identity = apply(mkTuple11) - } + end Apply11 // format: on private[sbt] def extendScoped(s1: Scoped, ss: Seq[Scoped]): Seq[AttributeKey[_]] = s1.key +: ss.map(_.key) -} +end Scoped -/** The sbt 0.10 style DSL was deprecated in 0.13.13, favouring the use of the '.value' macro. +/** + * The sbt 0.10 style DSL was deprecated in 0.13.13, favouring the use of the '.value' macro. * * See https://www.scala-sbt.org/1.x/docs/Migrating-from-sbt-013x.html#Migrating+from+sbt+0.12+style for how to migrate. */ @@ -682,93 +701,98 @@ object TupleSyntax extends TupleSyntax import Scoped.extendScoped -/** Constructs InputKeys, which are associated with input tasks to define a setting.*/ -object InputKey { - def apply[T: Manifest]( +/** Constructs InputKeys, which are associated with input tasks to define a setting. */ +object InputKey: + def apply[A1: Manifest]( label: String, description: String = "", rank: Int = KeyRanks.DefaultInputRank - ): InputKey[T] = - apply(AttributeKey[InputTask[T]](label, description, rank)) + ): InputKey[A1] = + apply(AttributeKey[InputTask[A1]](label, description, rank)) - def apply[T: Manifest]( + def apply[A1: Manifest]( label: String, description: String, extend1: Scoped, extendN: Scoped* - ): InputKey[T] = apply(label, description, KeyRanks.DefaultInputRank, extend1, extendN: _*) + ): InputKey[A1] = apply(label, description, KeyRanks.DefaultInputRank, extend1, extendN: _*) - def apply[T: Manifest]( + def apply[A1: Manifest]( label: String, description: String, rank: Int, extend1: Scoped, extendN: Scoped* - ): InputKey[T] = - apply(AttributeKey[InputTask[T]](label, description, extendScoped(extend1, extendN), rank)) + ): InputKey[A1] = + apply(AttributeKey[InputTask[A1]](label, description, extendScoped(extend1, extendN), rank)) - def apply[T](akey: AttributeKey[InputTask[T]]): InputKey[T] = + def apply[A1](akey: AttributeKey[InputTask[A1]]): InputKey[A1] = Scoped.scopedInput(Scope.ThisScope, akey) -} -/** Constructs TaskKeys, which are associated with tasks to define a setting.*/ -object TaskKey { - def apply[T: Manifest]( +end InputKey + +/** Constructs TaskKeys, which are associated with tasks to define a setting. */ +object TaskKey: + def apply[A1: Manifest]( label: String, description: String = "", rank: Int = KeyRanks.DefaultTaskRank - ): TaskKey[T] = - apply(AttributeKey[Task[T]](label, description, rank)) + ): TaskKey[A1] = + apply(AttributeKey[Task[A1]](label, description, rank)) - def apply[T: Manifest]( + def apply[A1: Manifest]( label: String, description: String, extend1: Scoped, extendN: Scoped* - ): TaskKey[T] = - apply(AttributeKey[Task[T]](label, description, extendScoped(extend1, extendN))) + ): TaskKey[A1] = + apply(AttributeKey[Task[A1]](label, description, extendScoped(extend1, extendN))) - def apply[T: Manifest]( + def apply[A1: Manifest]( label: String, description: String, rank: Int, extend1: Scoped, extendN: Scoped* - ): TaskKey[T] = - apply(AttributeKey[Task[T]](label, description, extendScoped(extend1, extendN), rank)) + ): TaskKey[A1] = + apply(AttributeKey[Task[A1]](label, description, extendScoped(extend1, extendN), rank)) - def apply[T](akey: AttributeKey[Task[T]]): TaskKey[T] = Scoped.scopedTask(Scope.ThisScope, akey) + def apply[A1](akey: AttributeKey[Task[A1]]): TaskKey[A1] = + Scoped.scopedTask(Scope.ThisScope, akey) - def local[T: Manifest]: TaskKey[T] = apply[T](AttributeKey.local[Task[T]]) -} + def local[A1: Manifest]: TaskKey[A1] = apply[A1](AttributeKey.local[Task[A1]]) -/** Constructs SettingKeys, which are associated with a value to define a basic setting.*/ -object SettingKey { - def apply[T: Manifest: OptJsonWriter]( +end TaskKey + +/** Constructs SettingKeys, which are associated with a value to define a basic setting. */ +object SettingKey: + def apply[A1: Manifest: OptJsonWriter]( label: String, description: String = "", rank: Int = KeyRanks.DefaultSettingRank - ): SettingKey[T] = - apply(AttributeKey[T](label, description, rank)) + ): SettingKey[A1] = + apply(AttributeKey[A1](label, description, rank)) - def apply[T: Manifest: OptJsonWriter]( + def apply[A1: Manifest: OptJsonWriter]( label: String, description: String, extend1: Scoped, extendN: Scoped* - ): SettingKey[T] = - apply(AttributeKey[T](label, description, extendScoped(extend1, extendN))) + ): SettingKey[A1] = + apply(AttributeKey[A1](label, description, extendScoped(extend1, extendN))) - def apply[T: Manifest: OptJsonWriter]( + def apply[A1: Manifest: OptJsonWriter]( label: String, description: String, rank: Int, extend1: Scoped, extendN: Scoped* - ): SettingKey[T] = - apply(AttributeKey[T](label, description, extendScoped(extend1, extendN), rank)) + ): SettingKey[A1] = + apply(AttributeKey[A1](label, description, extendScoped(extend1, extendN), rank)) - def apply[T](akey: AttributeKey[T]): SettingKey[T] = Scoped.scopedSetting(Scope.ThisScope, akey) + def apply[A1](akey: AttributeKey[A1]): SettingKey[A1] = + Scoped.scopedSetting(Scope.ThisScope, akey) - def local[T: Manifest: OptJsonWriter]: SettingKey[T] = apply[T](AttributeKey.local[T]) -} + def local[A1: Manifest: OptJsonWriter]: SettingKey[A1] = apply[A1](AttributeKey.local[A1]) + +end SettingKey diff --git a/main-settings/src/main/scala/sbt/std/InputConvert.scala b/main-settings/src/main/scala/sbt/std/InputConvert.scala index c133a2eaa..1a4720efa 100644 --- a/main-settings/src/main/scala/sbt/std/InputConvert.scala +++ b/main-settings/src/main/scala/sbt/std/InputConvert.scala @@ -8,81 +8,103 @@ package sbt package std -import scala.reflect.macros._ - +import sbt.internal.util.appmacro.{ Convert, ContextUtil } import sbt.internal.util.complete.Parser -import sbt.internal.util.appmacro.{ Convert, Converted } import Def.Initialize +import scala.quoted.* -object InputInitConvert extends Convert { - def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] = - nme match { - case InputWrapper.WrapInitName => Converted.Success[c.type](in) - case InputWrapper.WrapInitTaskName => Converted.Failure[c.type](in.pos, initTaskErrorMessage) - case _ => Converted.NotApplicable[c.type] - } +class InputInitConvert[C <: Quotes & scala.Singleton](override val qctx: C) + extends Convert[C](qctx) + with ContextUtil[C](qctx): + import qctx.reflect.* + + override def convert[A: Type](nme: String, in: Term): Converted = + nme match + case InputWrapper.WrapInitName => Converted.success(in) + case InputWrapper.WrapInitTaskName => Converted.Failure(in.pos, initTaskErrorMessage) + case _ => Converted.NotApplicable() private def initTaskErrorMessage = "Internal sbt error: initialize+task wrapper not split" -} +end InputInitConvert -/** Converts an input `Tree` of type `Parser[T]` or `State => Parser[T]` into a `Tree` of type `State => Parser[T]`.*/ -object ParserConvert extends Convert { - def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] = - nme match { - case ParserInput.WrapName => Converted.Success[c.type](in) - case ParserInput.WrapInitName => Converted.Failure[c.type](in.pos, initParserErrorMessage) - case _ => Converted.NotApplicable[c.type] - } +/** Converts an input `Term` of type `Parser[A]` or `State => Parser[A]` into a `Term` of type `State => Parser[A]`. */ +class ParserConvert[C <: Quotes & scala.Singleton](override val qctx: C) + extends Convert[C](qctx) + with ContextUtil[C](qctx): + import qctx.reflect.* + + override def convert[A: Type](nme: String, in: Term): Converted = + nme match + case ParserInput.WrapName => Converted.success(in) + case ParserInput.WrapInitName => Converted.Failure(in.pos, initParserErrorMessage) + case _ => Converted.NotApplicable() private def initParserErrorMessage = "Internal sbt error: initialize+parser wrapper not split" -} +end ParserConvert /** Convert instance for plain `Task`s not within the settings system. */ -object TaskConvert extends Convert { - def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == InputWrapper.WrapTaskName) Converted.Success[c.type](in) - else Converted.NotApplicable[c.type] -} - -/** Converts an input `Tree` of type `Initialize[T]`, `Initialize[Task[T]]`, or `Task[T]` into a `Tree` of type `Initialize[Task[T]]`.*/ -object FullConvert extends Convert { - def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] = - nme match { - case InputWrapper.WrapInitTaskName => Converted.Success[c.type](in) - case InputWrapper.WrapPreviousName => Converted.Success[c.type](in) - case InputWrapper.WrapInitName => wrapInit[T](c)(in) - case InputWrapper.WrapTaskName => wrapTask[T](c)(in) - case _ => Converted.NotApplicable[c.type] - } - - private def wrapInit[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = { - val i = c.Expr[Initialize[T]](tree) - val t = c.universe.reify(Def.toITask(i.splice)).tree - Converted.Success[c.type](t) - } - - private def wrapTask[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = { - val i = c.Expr[Task[T]](tree) - val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree - Converted.Success[c.type](t) - } -} +class TaskConvert[C <: Quotes & scala.Singleton](override val qctx: C) + extends Convert[C](qctx) + with ContextUtil[C](qctx): + import qctx.reflect.* + override def convert[A: Type](nme: String, in: Term): Converted = + if nme == InputWrapper.WrapTaskName then Converted.success(in) + else Converted.NotApplicable() +end TaskConvert /** - * Converts an input `Tree` of type `State => Parser[T]` or `Initialize[State => Parser[T]]` - * into a `Tree` of type `Initialize[State => Parser[T]]`. + * Converts an input `Term` of type `Initialize[A]`, `Initialize[Task[A]]`, or `Task[A]` into + * a `Term` of type `Initialize[Task[A]]`. */ -object InitParserConvert extends Convert { - def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] = - nme match { - case ParserInput.WrapName => wrap[T](c)(in) - case ParserInput.WrapInitName => Converted.Success[c.type](in) - case _ => Converted.NotApplicable[c.type] - } +class FullConvert[C <: Quotes & scala.Singleton](override val qctx: C) + extends Convert[C](qctx) + with ContextUtil[C](qctx): + import qctx.reflect.* - private def wrap[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = { - val e = c.Expr[State => Parser[T]](tree) - val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) } - Converted.Success[c.type](t.tree) - } -} + override def convert[A: Type](nme: String, in: Term): Converted = + nme match + case InputWrapper.WrapInitTaskName => Converted.success(in) + case InputWrapper.WrapPreviousName => Converted.success(in) + case InputWrapper.WrapInitName => wrapInit[A](in) + case InputWrapper.WrapTaskName => wrapTask[A](in) + case _ => Converted.NotApplicable() + + private def wrapInit[A: Type](tree: Term): Converted = + val i = tree.asExprOf[Initialize[A]] + val t = '{ + Def.toITask($i) + } + Converted.success(t.asTerm) + + private def wrapTask[A: Type](tree: Term): Converted = + val i = tree.asExprOf[Task[A]] + val t = '{ + Def.valueStrict[Task[A]]($i) + } + Converted.success(t.asTerm) + +end FullConvert + +/** + * Converts an input `Term` of type `State => Parser[A]` or `Initialize[State => Parser[A]]` + * into a `Term` of type `Initialize[State => Parser[A]]`. + */ +class InitParserConvert[C <: Quotes & scala.Singleton](override val qctx: C) + extends Convert[C](qctx) + with ContextUtil[C](qctx): + import qctx.reflect.* + + override def convert[A: Type](nme: String, in: Term): Converted = + nme match + case ParserInput.WrapName => wrap[A](in) + case ParserInput.WrapInitName => Converted.success(in) + case _ => Converted.NotApplicable() + + private def wrap[A: Type](tree: Term): Converted = + val e = tree.asExprOf[State => Parser[A]] + val t = '{ + Def.valueStrict[State => Parser[A]]($e) + } + Converted.success(t.asTerm) + +end InitParserConvert diff --git a/main-settings/src/main/scala/sbt/std/InputWrapper.scala b/main-settings/src/main/scala/sbt/std/InputWrapper.scala index f0fc8fb62..2684e5848 100644 --- a/main-settings/src/main/scala/sbt/std/InputWrapper.scala +++ b/main-settings/src/main/scala/sbt/std/InputWrapper.scala @@ -18,10 +18,10 @@ import sbt.internal.util.appmacro.ContextUtil import sbt.internal.util.complete.Parser /** Implementation detail. The wrap methods temporarily hold inputs (as a Tree, at compile time) until a task or setting macro processes it. */ -object InputWrapper { +object InputWrapper: /* The names of the wrapper methods should be obscure. - * Wrapper checking is based solely on this name, so it must not conflict with a user method name. - * The user should never see this method because it is compile-time only and only used internally by the task macro system.*/ + * Wrapper checking is based solely on this name, so it must not conflict with a user method name. + * The user should never see this method because it is compile-time only and only used internally by the task macro system.*/ private[std] final val WrapTaskName = "wrapTask_\u2603\u2603" private[std] final val WrapInitName = "wrapInit_\u2603\u2603" @@ -62,7 +62,7 @@ object InputWrapper { private[this] def implDetailError = sys.error("This method is an implementation detail and should not be referenced.") - +/* private[std] def wrapTask[T: c.WeakTypeTag](c: blackbox.Context)( ts: c.Expr[Any], pos: c.Position @@ -100,11 +100,11 @@ object InputWrapper { wrapImpl[Option[T], InputWrapper.type](c, InputWrapper, WrapPreviousName)(ts, pos) /** - * Wraps an arbitrary Tree in a call to the `.` method of this module for later processing by an enclosing macro. - * The resulting Tree is the manually constructed version of: - * - * `c.universe.reify { .[T](ts.splice) }` - */ + * Wraps an arbitrary Tree in a call to the `.` method of this module for later processing by an enclosing macro. + * The resulting Tree is the manually constructed version of: + * + * `c.universe.reify { .[T](ts.splice) }` + */ def wrapImpl[T: c.WeakTypeTag, S <: AnyRef with Singleton]( c: blackbox.Context, s: S, @@ -117,7 +117,9 @@ object InputWrapper { val tpe = c.weakTypeOf[T] val nme = TermName(wrapName).encodedName val sel = Select(Ident(iw), nme) - sel.setPos(pos) // need to set the position on Select, because that is where the compileTimeOnly check looks + sel.setPos( + pos + ) // need to set the position on Select, because that is where the compileTimeOnly check looks val tree = ApplyTree(TypeApply(sel, TypeTree(tpe) :: Nil), ts.tree :: Nil) tree.setPos(ts.tree.pos) // JZ: I'm not sure why we need to do this. Presumably a caller is wrapping this tree in a @@ -166,7 +168,7 @@ object InputWrapper { unexpectedType(c)(pos, tpe) } - /** Translates .previous(format) to Previous.runtime()(format).value*/ + /** Translates .previous(format) to Previous.runtime()(format).value */ def previousMacroImpl[T: c.WeakTypeTag]( c: blackbox.Context )(format: c.Expr[sjsonnew.JsonFormat[T]]): c.Expr[Option[T]] = { @@ -177,16 +179,17 @@ object InputWrapper { val tsTyped = c.Expr[TaskKey[T]](t) val newTree = c.universe.reify { Previous.runtime[T](tsTyped.splice)(format.splice) } wrapPrevious[T](c)(newTree, a.pos) - } else - unexpectedType(c)(a.pos, t.tpe) + } else unexpectedType(c)(a.pos, t.tpe) case x => ContextUtil.unexpectedTree(x) } } private def unexpectedType(c: blackbox.Context)(pos: c.Position, tpe: c.Type) = c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}") -} + */ +end InputWrapper +/* sealed abstract class MacroTaskValue[T] { @compileTimeOnly( "`taskValue` can only be used within a setting macro, such as :=, +=, ++=, or Def.setting." @@ -222,18 +225,19 @@ sealed abstract class ParserInputTask[T] { def parsed: Task[T] = macro ParserInput.parsedInputMacroImpl[T] } sealed abstract class MacroPrevious[T] { - @compileTimeOnly( - "`previous` can only be used within a task macro, such as :=, +=, ++=, or Def.task." - ) - def previous(implicit format: sjsonnew.JsonFormat[T]): Option[T] = - macro InputWrapper.previousMacroImpl[T] + // @compileTimeOnly( + // "`previous` can only be used within a task macro, such as :=, +=, ++=, or Def.task." + // ) + // def previous(implicit format: sjsonnew.JsonFormat[T]): Option[T] = + // macro InputWrapper.previousMacroImpl[T] } + */ /** Implementation detail. The wrap method temporarily holds the input parser (as a Tree, at compile time) until the input task macro processes it. */ -object ParserInput { +object ParserInput: /* The name of the wrapper method should be obscure. - * Wrapper checking is based solely on this name, so it must not conflict with a user method name. - * The user should never see this method because it is compile-time only and only used internally by the task macros.*/ + * Wrapper checking is based solely on this name, so it must not conflict with a user method name. + * The user should never see this method because it is compile-time only and only used internally by the task macros.*/ private[std] val WrapName = "parser_\u2603\u2603" private[std] val WrapInitName = "initParser_\u2603\u2603" @@ -248,7 +252,7 @@ object ParserInput { ) def `initParser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T = sys.error("This method is an implementation detail and should not be referenced.") - +/* private[std] def wrap[T: c.WeakTypeTag]( c: blackbox.Context )(ts: c.Expr[Any], pos: c.Position): c.Expr[T] = @@ -287,7 +291,7 @@ object ParserInput { wrapInit[Task[T]](c)(c.universe.reify { Def.toIParser(e.splice) }, pos) } - /** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/ + /** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper. */ def parsedMacroImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[T] = ContextUtil.selectMacroImpl[T](c) { (p, pos) => p.tree.tpe match { @@ -296,7 +300,7 @@ object ParserInput { case tpe if tpe <:< c.weakTypeOf[Initialize[Parser[T]]] => wrapInitParser[T](c)(p.tree, pos) case tpe if tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]] => wrapInit[T](c)(p, pos) - case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl") + case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl") } } @@ -315,4 +319,6 @@ object ParserInput { private def unexpectedType(c: blackbox.Context)(pos: c.Position, tpe: c.Type, label: String) = c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in $label.") -} + */ + +end ParserInput diff --git a/main-settings/src/main/scala/sbt/std/Instances.scala b/main-settings/src/main/scala/sbt/std/Instances.scala new file mode 100644 index 000000000..f97dc70c0 --- /dev/null +++ b/main-settings/src/main/scala/sbt/std/Instances.scala @@ -0,0 +1,102 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package std + +import Def.Initialize +import sbt.util.{ Applicative, Monad } +import sbt.internal.util.AList +import sbt.internal.util.Types.{ const, Id, Compose, idFun } +import sbt.internal.util.complete.{ DefaultParsers, Parser } + +object InitializeInstance: + given initializeMonad: Monad[Initialize] with + type F[x] = Initialize[x] + + override def pure[A1](a: () => A1): Initialize[A1] = Def.pure(a) + override def map[A1, A2](in: Initialize[A1])(f: A1 => A2): Initialize[A2] = Def.map(in)(f) + override def ap[A1, A2](ff: Initialize[A1 => A2])(fa: Initialize[A1]): Initialize[A2] = + Def.ap[A1, A2](ff)(fa) + override def flatMap[A1, A2](fa: Initialize[A1])(f: A1 => Initialize[A2]) = + Def.flatMap[A1, A2](fa)(f) +end InitializeInstance + +private[std] object ComposeInstance: + import InitializeInstance.initializeMonad + val InitInstance = summon[Applicative[Initialize]] + val F1F2: Applicative[Compose[Initialize, Task]] = summon[Applicative[Compose[Initialize, Task]]] +end ComposeInstance + +object ParserInstance: + // import sbt.internal.util.Classes.Applicative + // private[this] implicit val parserApplicative: Applicative[M] = new Applicative[M] { + // def apply[S, T](f: M[S => T], v: M[S]): M[A1] = s => (f(s) ~ v(s)) map { case (a, b) => a(b) } + // def pure[S](s: => S) = const(Parser.success(s)) + // def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f) + // } + + given Applicative[[a] =>> State => Parser[a]] with + type F[x] = State => Parser[x] + override def pure[A1](a: () => A1): State => Parser[A1] = const(DefaultParsers.success(a())) + override def ap[A1, A2](ff: F[A1 => A2])(fa: F[A1]): F[A2] = + (s: State) => (ff(s) ~ fa(s)).map { case (f, a) => f(a) } + override def map[A1, A2](fa: F[A1])(f: A1 => A2) = + (s: State) => fa(s).map(f) +end ParserInstance + +/** Composes the Task and Initialize Instances to provide an Instance for [A1] Initialize[Task[A1]]. */ +object FullInstance: + type SS = sbt.internal.util.Settings[Scope] + val settingsData = TaskKey[SS]( + "settings-data", + "Provides access to the project data for the build.", + KeyRanks.DTask + ) + + given Monad[Initialize] = InitializeInstance.initializeMonad + val F1F2: Applicative[Compose[Initialize, Task]] = ComposeInstance.F1F2 + given Monad[Compose[Initialize, Task]] with + type F[x] = Initialize[Task[x]] + override def pure[A1](x: () => A1): Initialize[Task[A1]] = F1F2.pure(x) + override def ap[A1, A2](ff: Initialize[Task[A1 => A2]])( + fa: Initialize[Task[A1]] + ): Initialize[Task[A2]] = + F1F2.ap(ff)(fa) + + override def flatMap[A1, A2](fa: Initialize[Task[A1]])( + f: A1 => Initialize[Task[A2]] + ): Initialize[Task[A2]] = + val nested: Initialize[Task[Initialize[Task[A2]]]] = F1F2.map(fa)(f) + flatten(nested) + + override def flatten[A1](in: Initialize[Task[Initialize[Task[A1]]]]): Initialize[Task[A1]] = + type K[L[x]] = + AList.Tuple3K[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]][ + L + ] + Def.app[K, Task[A1]]((in, settingsData, Def.capturedTransformations)) { + case (a: Task[Initialize[Task[A1]]], data: Task[SS], f) => + import TaskExtra.multT2Task + (a, data).flatMap { case (a, d) => f(a) evaluate d } + }(AList.tuple3[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]]) + +/* + def flattenFun[S, T]( + in: Initialize[Task[S => Initialize[Task[A1]]]] + ): Initialize[S => Task[A1]] = { + type K[L[x]] = + AList.T3K[Task[S => Initialize[Task[A1]]], Task[SS], Initialize ~> Initialize]#l[L] + Def.app[K, S => Task[A1]]((in, settingsData, Def.capturedTransformations)) { + case (a: Task[S => Initialize[Task[A1]]], data: Task[SS], f) => { (s: S) => + import TaskExtra.multT2Task + (a, data) flatMap { case (af, d) => f(af(s)) evaluate d } + } + }(AList.tuple3) + } + */ +end FullInstance diff --git a/main-settings/src/main/scala/sbt/std/KeyMacro.scala b/main-settings/src/main/scala/sbt/std/KeyMacro.scala index f7eaaf033..28aa41bf2 100644 --- a/main-settings/src/main/scala/sbt/std/KeyMacro.scala +++ b/main-settings/src/main/scala/sbt/std/KeyMacro.scala @@ -9,79 +9,71 @@ package sbt package std import scala.annotation.tailrec -import scala.reflect.macros._ +import scala.quoted.* import sbt.util.OptJsonWriter -private[sbt] object KeyMacro { - def settingKeyImpl[T: c.WeakTypeTag]( - c: blackbox.Context - )(description: c.Expr[String]): c.Expr[SettingKey[T]] = - keyImpl2[T, SettingKey[T]](c) { (name, mf, ojw) => - c.universe.reify { SettingKey[T](name.splice, description.splice)(mf.splice, ojw.splice) } - } - def taskKeyImpl[T: c.WeakTypeTag]( - c: blackbox.Context - )(description: c.Expr[String]): c.Expr[TaskKey[T]] = - keyImpl[T, TaskKey[T]](c) { (name, mf) => - c.universe.reify { TaskKey[T](name.splice, description.splice)(mf.splice) } - } - def inputKeyImpl[T: c.WeakTypeTag]( - c: blackbox.Context - )(description: c.Expr[String]): c.Expr[InputKey[T]] = - keyImpl[T, InputKey[T]](c) { (name, mf) => - c.universe.reify { InputKey[T](name.splice, description.splice)(mf.splice) } - } - - def keyImpl[T: c.WeakTypeTag, S: c.WeakTypeTag](c: blackbox.Context)( - f: (c.Expr[String], c.Expr[Manifest[T]]) => c.Expr[S] - ): c.Expr[S] = - f(getName(c), getImplicit[Manifest[T]](c)) - - private def keyImpl2[T: c.WeakTypeTag, S: c.WeakTypeTag](c: blackbox.Context)( - f: (c.Expr[String], c.Expr[Manifest[T]], c.Expr[OptJsonWriter[T]]) => c.Expr[S] - ): c.Expr[S] = - f(getName(c), getImplicit[Manifest[T]](c), getImplicit[OptJsonWriter[T]](c)) - - private def getName[S: c.WeakTypeTag, T: c.WeakTypeTag](c: blackbox.Context): c.Expr[String] = { - import c.universe._ - val enclosingValName = definingValName( - c, - methodName => - s"""$methodName must be directly assigned to a val, such as `val x = $methodName[Int]("description")`.""" - ) - c.Expr[String](Literal(Constant(enclosingValName))) - } - - private def getImplicit[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[T] = { - import c.universe._ - c.Expr[T](c.inferImplicitValue(weakTypeOf[T])) - } - - def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = { - import c.universe.{ Apply => ApplyTree, _ } - val methodName = c.macroApplication.symbol.name - def processName(n: Name): String = - n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary - @tailrec def enclosingVal(trees: List[c.Tree]): String = { - trees match { - case ValDef(_, name, _, _) :: _ => processName(name) - case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) - // lazy val x: X = has this form for some reason (only when the explicit type is present, though) - case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: _ if mods.hasFlag(Flag.LAZY) => - processName(name) - case _ => - c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString)) - "" +private[sbt] object KeyMacro: + def settingKeyImpl[A1: Type]( + description: Expr[String] + )(using qctx: Quotes): Expr[SettingKey[A1]] = + keyImpl2[A1, SettingKey[A1]]("settingKey") { (name, mf, ojw) => + val n = Expr(name) + '{ + SettingKey[A1]($n, $description)($mf, $ojw) } } - enclosingVal(enclosingTrees(c).toList) - } - def enclosingTrees(c: blackbox.Context): Seq[c.Tree] = - c.asInstanceOf[reflect.macros.runtime.Context] - .callsiteTyper - .context - .enclosingContextChain - .map(_.tree.asInstanceOf[c.Tree]) -} + def taskKeyImpl[A1: Type](description: Expr[String])(using qctx: Quotes): Expr[TaskKey[A1]] = + keyImpl[A1, TaskKey[A1]]("taskKey") { (name, mf) => + val n = Expr(name) + '{ + TaskKey[A1]($n, $description)($mf) + } + } + + def inputKeyImpl[A1: Type](description: Expr[String])(using qctx: Quotes): Expr[InputKey[A1]] = + keyImpl[A1, InputKey[A1]]("inputKey") { (name, mf) => + val n = Expr(name) + '{ + InputKey[A1]($n, $description)($mf) + } + } + + private def keyImpl[A1: Type, A2: Type](methodName: String)( + f: (String, Expr[Manifest[A1]]) => Expr[A2] + )(using qctx: Quotes): Expr[A2] = + val tpe = summon[Type[A1]] + f( + definingValName(errorMsg(methodName)), + Expr.summon[Manifest[A1]].getOrElse(sys.error("Manifest[A] not found for $tpe")) + ) + + private def keyImpl2[A1: Type, A2: Type](methodName: String)( + f: (String, Expr[Manifest[A1]], Expr[OptJsonWriter[A1]]) => Expr[A2] + )(using qctx: Quotes): Expr[A2] = + val tpe = summon[Type[A1]] + f( + definingValName(errorMsg(methodName)), + Expr.summon[Manifest[A1]].getOrElse(sys.error("Manifest[A] not found for $tpe")), + Expr.summon[OptJsonWriter[A1]].getOrElse(sys.error("OptJsonWriter[A] not found for $tpe")), + ) + + private def errorMsg(methodName: String): String = + s"""$methodName must be directly assigned to a val, such as `val x = $methodName[Int]("description")`.""" + + private def definingValName(errorMsg: String)(using qctx: Quotes): String = + val term = enclosingTerm + if term.isValDef then term.name + else sys.error(errorMsg) + + def enclosingTerm(using qctx: Quotes) = + import qctx.reflect._ + def enclosingTerm0(sym: Symbol): Symbol = + sym match + case sym if sym.flags is Flags.Macro => enclosingTerm0(sym.owner) + case sym if !sym.isTerm => enclosingTerm0(sym.owner) + case _ => sym + enclosingTerm0(Symbol.spliceOwner) + +end KeyMacro diff --git a/main-settings/src/main/scala/sbt/std/SettingMacro.scala b/main-settings/src/main/scala/sbt/std/SettingMacro.scala index 43128193b..b46018f78 100644 --- a/main-settings/src/main/scala/sbt/std/SettingMacro.scala +++ b/main-settings/src/main/scala/sbt/std/SettingMacro.scala @@ -9,26 +9,18 @@ package sbt package std import Def.Initialize -import sbt.internal.util.Types.{ Id, idFun } -import sbt.internal.util.AList -import sbt.internal.util.appmacro.{ - Convert, - Converted, - Instance, - LinterDSL, - MixedBuilder, - MonadInstance -} - -object InitializeInstance extends MonadInstance { - type M[x] = Initialize[x] - def app[K[L[x]], Z](in: K[Initialize], f: K[Id] => Z)(implicit a: AList[K]): Initialize[Z] = - Def.app[K, Z](in)(f)(a) - def map[S, T](in: Initialize[S], f: S => T): Initialize[T] = Def.map(in)(f) - def flatten[T](in: Initialize[Initialize[T]]): Initialize[T] = Def.bind(in)(idFun[Initialize[T]]) - def pure[T](t: () => T): Initialize[T] = Def.pure(t) -} +// import sbt.internal.util.Types.{ Id, idFun } +// import sbt.internal.util.AList +// import sbt.internal.util.appmacro.{ +// Convert, +// Converted, +// Instance, +// LinterDSL, +// MixedBuilder, +// MonadInstance +// } +/* import reflect.macros._ object InitializeConvert extends Convert { @@ -36,8 +28,8 @@ object InitializeConvert extends Convert { nme match { case InputWrapper.WrapInitName => convert[T](c)(in) case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName => failTask[c.type](c)(in.pos) - case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos) - case _ => Converted.NotApplicable + case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos) + case _ => Converted.NotApplicable } private def convert[T: c.WeakTypeTag](c: blackbox.Context)(in: c.Tree): Converted[c.type] = { @@ -72,3 +64,4 @@ object SettingMacro { Instance.idTransform[c.type] ) } + */ diff --git a/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala b/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala index 6a9b78aa7..533db20bc 100644 --- a/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala +++ b/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala @@ -11,11 +11,12 @@ import sbt.SettingKey import sbt.dsl.LinterLevel import sbt.dsl.LinterLevel.{ Abort, Warn } import sbt.internal.util.Terminal -import sbt.internal.util.appmacro.{ Convert, LinterDSL } +// import sbt.internal.util.appmacro.{ Convert, LinterDSL } import scala.io.AnsiColor import scala.reflect.macros.blackbox +/* abstract class BaseTaskLinterDSL extends LinterDSL { def isDynamicTask: Boolean def convert: Convert @@ -29,19 +30,19 @@ abstract class BaseTaskLinterDSL extends LinterDSL { val initializeType = typeOf[sbt.Def.Initialize[_]] /* - * Lints a task tree. - * - * @param insideIf indicates whether or not the current tree is enclosed in an if statement. - * It is generally illegal to call `.value` on a task within such a tree unless - * the tree has been annotated with `@sbtUnchecked`. - * @param insideAnon indicates whether or not the current tree is enclosed in an anonymous - * function. It is generally illegal to call `.value` on a task within such - * a tree unless the tree has been annotated with `@sbtUnchecked`. - * @param uncheckedWrapper an optional tree that is provided to lint a tree in the form: - * `tree.value: @sbtUnchecked` for some tree. This can be used to - * prevent the linter from rejecting task evaluation within a - * conditional or an anonymous function. - */ + * Lints a task tree. + * + * @param insideIf indicates whether or not the current tree is enclosed in an if statement. + * It is generally illegal to call `.value` on a task within such a tree unless + * the tree has been annotated with `@sbtUnchecked`. + * @param insideAnon indicates whether or not the current tree is enclosed in an anonymous + * function. It is generally illegal to call `.value` on a task within such + * a tree unless the tree has been annotated with `@sbtUnchecked`. + * @param uncheckedWrapper an optional tree that is provided to lint a tree in the form: + * `tree.value: @sbtUnchecked` for some tree. This can be used to + * prevent the linter from rejecting task evaluation within a + * conditional or an anonymous function. + */ class traverser(insideIf: Boolean, insideAnon: Boolean, uncheckedWrapper: Option[Tree]) extends Traverser { @@ -128,12 +129,12 @@ abstract class BaseTaskLinterDSL extends LinterDSL { case Block(stmts, expr) => if (!isDynamicTask) { /* The missing .value analysis is dumb on purpose because it's expensive. - * Detecting valid use cases of idents whose type is an sbt key is difficult - * and dangerous because we may miss some corner cases. Instead, we report - * on the easiest cases in which we are certain that the user does not want - * to have a stale key reference. Those are idents in the rhs of a val definition - * whose name is `_` and those idents that are in statement position inside blocks. - */ + * Detecting valid use cases of idents whose type is an sbt key is difficult + * and dangerous because we may miss some corner cases. Instead, we report + * on the easiest cases in which we are certain that the user does not want + * to have a stale key reference. Those are idents in the rhs of a val definition + * whose name is `_` and those idents that are in statement position inside blocks. + */ stmts.foreach { // TODO: Consider using unused names analysis to be able to report on more cases case ValDef(_, valName, _, rhs) if valName == termNames.WILDCARD => @@ -217,7 +218,7 @@ object TaskLinterDSLFeedback { | Regular tasks always evaluate task dependencies (`.value`) regardless of `if` expressions. |$SolutionHeader: | 1. Use a conditional task `Def.taskIf(...)` to evaluate it when the `if` predicate is true or false. - | 2. Or turn the task body into a single `if` expression; the task is then auto-converted to a conditional task. + | 2. Or turn the task body into a single `if` expression; the task is then auto-converted to a conditional task. | 3. Or make the static evaluation explicit by declaring `$task.value` outside the `if` expression. | 4. If you still want to force the static lookup, you may annotate the task lookup with `@sbtUnchecked`, e.g. `($task.value: @sbtUnchecked)`. | 5. Add `import sbt.dsl.LinterLevel.Ignore` to your build file to disable all task linting. @@ -241,3 +242,4 @@ object TaskLinterDSLFeedback { | 2. Add `import sbt.dsl.LinterLevel.Ignore` to your build file to disable all task linting. """.stripMargin } + */ diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index 9d0dd530d..75131ddc1 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -9,81 +9,46 @@ package sbt package std import Def.{ Initialize, Setting } -import sbt.internal.util.Types.{ Id, const, idFun } +import sbt.util.{ Applicative, Monad } +import sbt.internal.util.Types.{ Id, Compose, const, idFun } import sbt.internal.util.appmacro.{ + Cont, ContextUtil, - Converted, - Instance, - LinterDSL, - MixedBuilder, - MonadInstance + Convert, + // Instance, + // LinterDSL, + // MixedBuilder, + // MonadInstance } -import Instance.Transform -import sbt.internal.util.complete.{ DefaultParsers, Parser } +// import Instance.Transform import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition, ~> } import language.experimental.macros import scala.annotation.tailrec -import reflect.macros._ import scala.reflect.internal.util.UndefinedPosition +import scala.quoted.* /** Instance for the monad/applicative functor for plain Tasks. */ -object TaskInstance extends MonadInstance { +/* +object TaskInstance: import TaskExtra._ - final type M[x] = Task[x] - def app[K[L[x]], Z](in: K[Task], f: K[Id] => Z)(implicit a: AList[K]): Task[Z] = in map f - def map[S, T](in: Task[S], f: S => T): Task[T] = in map f - def flatten[T](in: Task[Task[T]]): Task[T] = in flatMap idFun[Task[T]] - def pure[T](t: () => T): Task[T] = toTask(t) -} -object ParserInstance extends Instance { - import sbt.internal.util.Classes.Applicative - private[this] implicit val parserApplicative: Applicative[M] = new Applicative[M] { - def apply[S, T](f: M[S => T], v: M[S]): M[T] = s => (f(s) ~ v(s)) map { case (a, b) => a(b) } - def pure[S](s: => S) = const(Parser.success(s)) - def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f) - } + given taskMonad: Monad[Task] with + type F[a] = Task[a] + override def pure[A1](a: () => A1): Task[A1] = toTask(a) - final type M[x] = State => Parser[x] - def app[K[L[x]], Z](in: K[M], f: K[Id] => Z)(implicit a: AList[K]): M[Z] = a.apply(in, f) - def map[S, T](in: M[S], f: S => T): M[T] = s => in(s) map f - def pure[T](t: () => T): State => Parser[T] = const(DefaultParsers.success(t())) -} - -/** Composes the Task and Initialize Instances to provide an Instance for [T] Initialize[Task[T]].*/ -object FullInstance - extends Instance.Composed[Initialize, Task](InitializeInstance, TaskInstance) - with MonadInstance { - type SS = sbt.internal.util.Settings[Scope] - val settingsData = TaskKey[SS]( - "settings-data", - "Provides access to the project data for the build.", - KeyRanks.DTask - ) - - def flatten[T](in: Initialize[Task[Initialize[Task[T]]]]): Initialize[Task[T]] = { - type K[L[x]] = AList.T3K[Task[Initialize[Task[T]]], Task[SS], Initialize ~> Initialize]#l[L] - Def.app[K, Task[T]]((in, settingsData, Def.capturedTransformations)) { - case (a: Task[Initialize[Task[T]]], data: Task[SS], f) => - import TaskExtra.multT2Task - (a, data) flatMap { case (a, d) => f(a) evaluate d } - }(AList.tuple3) - } - - def flattenFun[S, T](in: Initialize[Task[S => Initialize[Task[T]]]]): Initialize[S => Task[T]] = { - type K[L[x]] = - AList.T3K[Task[S => Initialize[Task[T]]], Task[SS], Initialize ~> Initialize]#l[L] - Def.app[K, S => Task[T]]((in, settingsData, Def.capturedTransformations)) { - case (a: Task[S => Initialize[Task[T]]], data: Task[SS], f) => { (s: S) => - import TaskExtra.multT2Task - (a, data) flatMap { case (af, d) => f(af(s)) evaluate d } + override def ap[A1, A2](ff: Task[A1 => A2])(in: Task[A1]): Task[A2] = + multT2Task((in, ff)).map { case (x, f) => + f(x) } - }(AList.tuple3) - } -} -object TaskMacro { + override def map[A1, A2](in: Task[A1])(f: A1 => A2): Task[A2] = in.map(f) + override def flatMap[A1, A2](in: F[A1])(f: A1 => F[A2]): F[A2] = in.flatMap(f) + override def flatten[A1](in: Task[Task[A1]]): Task[A1] = in.flatMap(idFun[Task[A1]]) +end TaskInstance + */ + +object TaskMacro: final val AssignInitName = "set" final val Append1InitName = "append1" final val AppendNInitName = "appendN" @@ -100,41 +65,44 @@ object TaskMacro { """`<<=` operator is removed. Use `key := { x.value }` or `key ~= (old => { newValue })`. |See https://www.scala-sbt.org/1.x/docs/Migrating-from-sbt-013x.html""".stripMargin - import LinterDSL.{ Empty => EmptyLinter } + type F[x] = Initialize[Task[x]] - def taskMacroImpl[T: c.WeakTypeTag]( - c: blackbox.Context - )(t: c.Expr[T]): c.Expr[Initialize[Task[T]]] = { - import c.universe._ - t.tree match { - // the tree matches `if` and only `if` - case If(cond, thenp, elsep) => - c.Expr[Initialize[Task[T]]](mkIfS[T](c)(cond, thenp, elsep)) + object ContSyntax extends Cont + import ContSyntax.* + + // import LinterDSL.{ Empty => EmptyLinter } + + def taskMacroImpl[A1: Type](t: Expr[A1])(using qctx: Quotes): Expr[Initialize[Task[A1]]] = + // import qctx.reflect.* + t match + case '{ if ($cond) then $thenp else $elsep } => mkIfS[A1](t) case _ => - Instance.contImpl[T, Id](c, FullInstance, FullConvert, MixedBuilder, TaskLinterDSL)( - Left(t), - Instance.idTransform[c.type] - ) - } - } + val convert1: Convert[qctx.type] = new FullConvert(qctx) + convert1.contMapN[A1, F, Id](t, convert1.idTransform) + // Instance.contImpl[A1, Id](c, FullInstance, FullConvert, MixedBuilder, TaskLinterDSL)( + // Left(t), + // Instance.idTransform[c.type] + // ) - def mkIfS[A: c.WeakTypeTag]( - c: blackbox.Context - )(cond: c.Tree, thenp: c.Tree, elsep: c.Tree): c.Tree = { - import c.universe._ - val AA = implicitly[c.WeakTypeTag[A]].tpe - q"""_root_.sbt.Def.ifS[$AA](_root_.sbt.Def.task($cond))(_root_.sbt.Def.task[$AA]($thenp: $AA))(_root_.sbt.Def.task[$AA]($elsep: $AA))""" - } + def mkIfS[A1: Type](using + qctx: Quotes + )(t: Expr[A1]): Expr[Initialize[Task[A1]]] = + t match + case '{ if ($cond) then $thenp else $elsep } => + '{ + Def.ifS[A1](Def.task($cond))(Def.task[A1]($thenp))(Def.task[A1]($elsep)) + } - def taskDynMacroImpl[T: c.WeakTypeTag]( +/* + def taskDynMacroImpl[A1: Type]( c: blackbox.Context - )(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[Task[T]]] = - Instance.contImpl[T, Id](c, FullInstance, FullConvert, MixedBuilder, TaskDynLinterDSL)( + )(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[Task[A1]]] = + Instance.contImpl[A1, Id](c, FullInstance, FullConvert, MixedBuilder, TaskDynLinterDSL)( Right(t), Instance.idTransform[c.type] ) - def taskIfMacroImpl[A: c.WeakTypeTag]( + def taskIfMacroImpl[A: Type]( c: blackbox.Context )(a: c.Expr[A]): c.Expr[Initialize[Task[A]]] = { import c.universe._ @@ -148,58 +116,58 @@ object TaskMacro { } /** Implementation of := macro for settings. */ - def settingAssignMacroImpl[T: c.WeakTypeTag]( + def settingAssignMacroImpl[A1: Type]( c: blackbox.Context - )(v: c.Expr[T]): c.Expr[Setting[T]] = { - val init = SettingMacro.settingMacroImpl[T](c)(v) + )(v: c.Expr[A1]): c.Expr[Setting[A1]] = { + val init = SettingMacro.settingMacroImpl[A1](c)(v) val assign = transformMacroImpl(c)(init.tree)(AssignInitName) - c.Expr[Setting[T]](assign) + c.Expr[Setting[A1]](assign) } /** Implementation of := macro for tasks. */ - def taskAssignMacroImpl[T: c.WeakTypeTag]( + def taskAssignMacroImpl[A1: Type]( c: blackbox.Context - )(v: c.Expr[T]): c.Expr[Setting[Task[T]]] = { - val init = taskMacroImpl[T](c)(v) + )(v: c.Expr[A1]): c.Expr[Setting[Task[A1]]] = { + val init = taskMacroImpl[A1](c)(v) val assign = transformMacroImpl(c)(init.tree)(AssignInitName) - c.Expr[Setting[Task[T]]](assign) + c.Expr[Setting[Task[A1]]](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: blackbox.Context)( - @deprecated("unused", "") app: c.Expr[Initialize[T]] - ): c.Expr[Setting[T]] = - ContextUtil.selectMacroImpl[Setting[T]](c)((_, pos) => c.abort(pos, assignMigration)) + def fakeSettingAssignPosition[A1: Type](c: blackbox.Context)( + @deprecated("unused", "") app: c.Expr[Initialize[A1]] + ): c.Expr[Setting[A1]] = + ContextUtil.selectMacroImpl[Setting[A1]](c)((_, pos) => c.abort(pos, assignMigration)) - def fakeSettingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag]( + def fakeSettingAppend1Position[S: Type, V: Type]( c: blackbox.Context )(@deprecated("unused", "") v: c.Expr[Initialize[V]])( @deprecated("unused", "") a: c.Expr[Append.Value[S, V]] ): c.Expr[Setting[S]] = ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, append1Migration)) - def fakeSettingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag]( + def fakeSettingAppendNPosition[S: Type, V: Type]( c: blackbox.Context )(@deprecated("unused", "") vs: c.Expr[Initialize[V]])( @deprecated("unused", "") a: c.Expr[Append.Values[S, V]] ): c.Expr[Setting[S]] = ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, appendNMigration)) - def fakeItaskAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)( - @deprecated("unused", "") app: c.Expr[Initialize[Task[T]]] - ): c.Expr[Setting[Task[T]]] = - ContextUtil.selectMacroImpl[Setting[Task[T]]](c)((_, pos) => c.abort(pos, assignMigration)) + def fakeItaskAssignPosition[A1: Type](c: blackbox.Context)( + @deprecated("unused", "") app: c.Expr[Initialize[Task[A1]]] + ): c.Expr[Setting[Task[A1]]] = + ContextUtil.selectMacroImpl[Setting[Task[A1]]](c)((_, pos) => c.abort(pos, assignMigration)) - def fakeTaskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag]( + def fakeTaskAppend1Position[S: Type, V: Type]( c: blackbox.Context )(@deprecated("unused", "") v: c.Expr[Initialize[Task[V]]])( @deprecated("unused", "") a: c.Expr[Append.Value[S, V]] ): c.Expr[Setting[Task[S]]] = ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, append1Migration)) - def fakeTaskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag]( + def fakeTaskAppendNPosition[S: Type, V: Type]( c: blackbox.Context )(@deprecated("unused", "") vs: c.Expr[Initialize[Task[V]]])( @deprecated("unused", "") a: c.Expr[Append.Values[S, V]] @@ -209,68 +177,68 @@ object TaskMacro { // Implementations of <<= macro variations for tasks and settings. // These just get the source position of the call site. - def itaskAssignPosition[T: c.WeakTypeTag]( + def itaskAssignPosition[A1: Type]( c: blackbox.Context - )(app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] = + )(app: c.Expr[Initialize[Task[A1]]]): c.Expr[Setting[Task[A1]]] = settingAssignPosition(c)(app) - def taskAssignPositionT[T: c.WeakTypeTag]( + def taskAssignPositionT[A1: Type]( c: blackbox.Context - )(app: c.Expr[Task[T]]): c.Expr[Setting[Task[T]]] = + )(app: c.Expr[Task[A1]]): c.Expr[Setting[Task[A1]]] = itaskAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) }) - def taskAssignPositionPure[T: c.WeakTypeTag]( + def taskAssignPositionPure[A1: Type]( c: blackbox.Context - )(app: c.Expr[T]): c.Expr[Setting[Task[T]]] = + )(app: c.Expr[A1]): c.Expr[Setting[Task[A1]]] = taskAssignPositionT(c)(c.universe.reify { TaskExtra.constant(app.splice) }) - def taskTransformPosition[S: c.WeakTypeTag]( + def taskTransformPosition[S: Type]( c: blackbox.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]( + def settingTransformPosition[S: Type]( c: blackbox.Context )(f: c.Expr[S => S]): c.Expr[Setting[S]] = c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName)) - def itaskTransformPosition[S: c.WeakTypeTag]( + def itaskTransformPosition[S: Type]( c: blackbox.Context )(f: c.Expr[S => S]): c.Expr[Setting[S]] = c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName)) - def settingAssignPure[T: c.WeakTypeTag](c: blackbox.Context)(app: c.Expr[T]): c.Expr[Setting[T]] = + def settingAssignPure[A1: Type](c: blackbox.Context)(app: c.Expr[A1]): c.Expr[Setting[A1]] = settingAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) }) - def settingAssignPosition[T: c.WeakTypeTag]( + def settingAssignPosition[A1: Type]( c: blackbox.Context - )(app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] = - c.Expr[Setting[T]](transformMacroImpl(c)(app.tree)(AssignInitName)) + )(app: c.Expr[Initialize[A1]]): c.Expr[Setting[A1]] = + c.Expr[Setting[A1]](transformMacroImpl(c)(app.tree)(AssignInitName)) /** Implementation of := macro for tasks. */ - def inputTaskAssignMacroImpl[T: c.WeakTypeTag]( + def inputTaskAssignMacroImpl[A1: Type]( c: blackbox.Context - )(v: c.Expr[T]): c.Expr[Setting[InputTask[T]]] = { - val init = inputTaskMacroImpl[T](c)(v) + )(v: c.Expr[A1]): c.Expr[Setting[InputTask[A1]]] = { + val init = inputTaskMacroImpl[A1](c)(v) val assign = transformMacroImpl(c)(init.tree)(AssignInitName) - c.Expr[Setting[InputTask[T]]](assign) + c.Expr[Setting[InputTask[A1]]](assign) } /** Implementation of += macro for tasks. */ - def taskAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def taskAppend1Impl[A1: Type, U: Type]( c: blackbox.Context - )(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[Task[T]]] = { + )(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = { val init = taskMacroImpl[U](c)(v) val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) - c.Expr[Setting[Task[T]]](append) + c.Expr[Setting[Task[A1]]](append) } /** Implementation of += macro for settings. */ - def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def settingAppend1Impl[A1: Type, U: Type]( c: blackbox.Context - )(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] = { + )(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[A1]] = { import c.universe._ - val ttpe = c.weakTypeOf[T] + val ttpe = c.weakTypeOf[A1] val typeArgs = ttpe.typeArgs v.tree.tpe match { // To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically. @@ -283,71 +251,71 @@ object TaskMacro { TypeApply(Select(preT, TermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil), Select(v.tree, TermName("taskValue").encodedName) :: Nil ) - c.Expr[Setting[T]](tree) + c.Expr[Setting[A1]](tree) case x => ContextUtil.unexpectedTree(x) } case _ => val init = SettingMacro.settingMacroImpl[U](c)(v) val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName) - c.Expr[Setting[T]](append) + c.Expr[Setting[A1]](append) } } /** Implementation of ++= macro for tasks. */ - def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def taskAppendNImpl[A1: Type, U: Type]( c: blackbox.Context - )(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] = { + )(vs: c.Expr[U])(a: c.Expr[Append.Values[A1, U]]): c.Expr[Setting[Task[A1]]] = { val init = taskMacroImpl[U](c)(vs) val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) - c.Expr[Setting[Task[T]]](append) + c.Expr[Setting[Task[A1]]](append) } /** Implementation of ++= macro for settings. */ - def settingAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def settingAppendNImpl[A1: Type, U: Type]( c: blackbox.Context - )(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[T]] = { + )(vs: c.Expr[U])(a: c.Expr[Append.Values[A1, U]]): c.Expr[Setting[A1]] = { val init = SettingMacro.settingMacroImpl[U](c)(vs) val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName) - c.Expr[Setting[T]](append) + c.Expr[Setting[A1]](append) } /** Implementation of -= macro for tasks. */ - def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def taskRemove1Impl[A1: Type, U: Type]( c: blackbox.Context - )(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] = { + )(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = { val init = taskMacroImpl[U](c)(v) val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName) - c.Expr[Setting[Task[T]]](remove) + c.Expr[Setting[Task[A1]]](remove) } /** Implementation of -= macro for settings. */ - def settingRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def settingRemove1Impl[A1: Type, U: Type]( c: blackbox.Context - )(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[T]] = { + )(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[A1]] = { val init = SettingMacro.settingMacroImpl[U](c)(v) val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName) - c.Expr[Setting[T]](remove) + c.Expr[Setting[A1]](remove) } /** Implementation of --= macro for tasks. */ - def taskRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def taskRemoveNImpl[A1: Type, U: Type]( c: blackbox.Context - )(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[Task[T]]] = { + )(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[Task[A1]]] = { val init = taskMacroImpl[U](c)(vs) val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName) - c.Expr[Setting[Task[T]]](remove) + c.Expr[Setting[Task[A1]]](remove) } /** Implementation of --= macro for settings. */ - def settingRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag]( + def settingRemoveNImpl[A1: Type, U: Type]( c: blackbox.Context - )(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[T]] = { + )(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[A1]] = { val init = SettingMacro.settingMacroImpl[U](c)(vs) val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName) - c.Expr[Setting[T]](remove) + c.Expr[Setting[A1]](remove) } - private[this] def appendMacroImpl( + private[A1his] def appendMacroImpl( c: blackbox.Context )(init: c.Tree, append: c.Tree)(newName: String): c.Tree = { import c.universe._ @@ -364,7 +332,7 @@ object TaskMacro { } } - private[this] def removeMacroImpl( + private[A1his] def removeMacroImpl( c: blackbox.Context )(init: c.Tree, remove: c.Tree)(newName: String): c.Tree = { import c.universe._ @@ -381,7 +349,7 @@ object TaskMacro { } } - private[this] def transformMacroImpl(c: blackbox.Context)(init: c.Tree)( + private[A1his] def transformMacroImpl(c: blackbox.Context)(init: c.Tree)( newName: String ): c.Tree = { import c.universe._ @@ -396,7 +364,7 @@ object TaskMacro { ) } - private[this] def sourcePosition(c: blackbox.Context): c.Expr[SourcePosition] = { + private[A1his] def sourcePosition(c: blackbox.Context): c.Expr[SourcePosition] = { import c.universe.reify val pos = c.enclosingPosition if (!pos.isInstanceOf[UndefinedPosition] && pos.line >= 0 && pos.source != null) { @@ -404,11 +372,10 @@ object TaskMacro { val name = constant[String](c, settingSource(c, f.path, f.name)) val line = constant[Int](c, pos.line) reify { LinePosition(name.splice, line.splice) } - } else - reify { NoPosition } + } else reify { NoPosition } } - private[this] def settingSource(c: blackbox.Context, path: String, name: String): String = { + private[A1his] def settingSource(c: blackbox.Context, path: String, name: String): String = { @tailrec def inEmptyPackage(s: c.Symbol): Boolean = s != c.universe.NoSymbol && ( s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage( s.owner @@ -421,24 +388,24 @@ object TaskMacro { } } - private[this] def constant[T: c.TypeTag](c: blackbox.Context, t: T): c.Expr[T] = { + private[A1his] def constant[A1: c.TypeTag](c: blackbox.Context, t: T): c.Expr[A1] = { import c.universe._ - c.Expr[T](Literal(Constant(t))) + c.Expr[A1](Literal(Constant(t))) } - def inputTaskMacroImpl[T: c.WeakTypeTag]( + def inputTaskMacroImpl[A1: Type]( c: blackbox.Context - )(t: c.Expr[T]): c.Expr[Initialize[InputTask[T]]] = - inputTaskMacro0[T](c)(t) + )(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] = + inputTaskMacro0[A1](c)(t) - def inputTaskDynMacroImpl[T: c.WeakTypeTag]( + def inputTaskDynMacroImpl[A1: Type]( c: blackbox.Context - )(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[InputTask[T]]] = - inputTaskDynMacro0[T](c)(t) + )(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] = + inputTaskDynMacro0[A1](c)(t) - private[this] def inputTaskMacro0[T: c.WeakTypeTag]( + private[A1his] def inputTaskMacro0[A1: Type]( c: blackbox.Context - )(t: c.Expr[T]): c.Expr[Initialize[InputTask[T]]] = + )(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] = iInitializeMacro(c)(t) { et => val pt = iParserMacro(c)(et) { pt => iTaskMacro(c)(pt) @@ -446,77 +413,77 @@ object TaskMacro { c.universe.reify { InputTask.make(pt.splice) } } - private[this] def iInitializeMacro[M[_], T](c: blackbox.Context)(t: c.Expr[T])( - f: c.Expr[T] => c.Expr[M[T]] - )(implicit tt: c.WeakTypeTag[T], mt: c.WeakTypeTag[M[T]]): c.Expr[Initialize[M[T]]] = { - val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[T](in)).tree - val cond = c.Expr[T](conditionInputTaskTree(c)(t.tree)) + private[A1his] def iInitializeMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])( + f: c.Expr[A1] => c.Expr[M[A1]] + )(implicit tt: Type[A1], mt: Type[M[A1]]): c.Expr[Initialize[M[A1]]] = { + val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[A1](in)).tree + val cond = c.Expr[A1](conditionInputTaskTree(c)(t.tree)) Instance - .contImpl[T, M](c, InitializeInstance, InputInitConvert, MixedBuilder, EmptyLinter)( + .contImpl[A1, M](c, InitializeInstance, InputInitConvert, MixedBuilder, EmptyLinter)( Left(cond), inner ) } - private[this] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = { + private[A1his] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = { import c.universe._ import InputWrapper._ - def wrapInitTask[T: c.WeakTypeTag](tree: Tree) = { - val e = c.Expr[Initialize[Task[T]]](tree) - wrapTask[T](c)(wrapInit[Task[T]](c)(e, tree.pos), tree.pos).tree + def wrapInitTask[A1: Type](tree: Tree) = { + val e = c.Expr[Initialize[Task[A1]]](tree) + wrapTask[A1](c)(wrapInit[Task[A1]](c)(e, tree.pos), tree.pos).tree } - def wrapInitParser[T: c.WeakTypeTag](tree: Tree) = { - val e = c.Expr[Initialize[State => Parser[T]]](tree) - ParserInput.wrap[T](c)(wrapInit[State => Parser[T]](c)(e, tree.pos), tree.pos).tree + def wrapInitParser[A1: Type](tree: Tree) = { + val e = c.Expr[Initialize[State => Parser[A1]]](tree) + ParserInput.wrap[A1](c)(wrapInit[State => Parser[A1]](c)(e, tree.pos), tree.pos).tree } - def wrapInitInput[T: c.WeakTypeTag](tree: Tree) = { - val e = c.Expr[Initialize[InputTask[T]]](tree) - wrapInput[T](wrapInit[InputTask[T]](c)(e, tree.pos).tree) + def wrapInitInput[A1: Type](tree: Tree) = { + val e = c.Expr[Initialize[InputTask[A1]]](tree) + wrapInput[A1](wrapInit[InputTask[A1]](c)(e, tree.pos).tree) } - def wrapInput[T: c.WeakTypeTag](tree: Tree) = { - val e = c.Expr[InputTask[T]](tree) - val p = ParserInput.wrap[Task[T]](c)(ParserInput.inputParser(c)(e), tree.pos) - wrapTask[T](c)(p, tree.pos).tree + def wrapInput[A1: Type](tree: Tree) = { + val e = c.Expr[InputTask[A1]](tree) + val p = ParserInput.wrap[Task[A1]](c)(ParserInput.inputParser(c)(e), tree.pos) + wrapTask[A1](c)(p, tree.pos).tree } def expand(nme: String, tpe: Type, tree: Tree): Converted[c.type] = nme match { - case WrapInitTaskName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe))) - case WrapPreviousName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe))) - case ParserInput.WrapInitName => Converted.Success(wrapInitParser(tree)(c.WeakTypeTag(tpe))) - case WrapInitInputName => Converted.Success(wrapInitInput(tree)(c.WeakTypeTag(tpe))) - case WrapInputName => Converted.Success(wrapInput(tree)(c.WeakTypeTag(tpe))) + case WrapInitTaskName => Converted.Success(wrapInitTask(tree)(Type(tpe))) + case WrapPreviousName => Converted.Success(wrapInitTask(tree)(Type(tpe))) + case ParserInput.WrapInitName => Converted.Success(wrapInitParser(tree)(Type(tpe))) + case WrapInitInputName => Converted.Success(wrapInitInput(tree)(Type(tpe))) + case WrapInputName => Converted.Success(wrapInput(tree)(Type(tpe))) case _ => Converted.NotApplicable } val util = ContextUtil[c.type](c) util.transformWrappers(t, (nme, tpe, tree, original) => expand(nme, tpe, tree)) } - private[this] def iParserMacro[M[_], T](c: blackbox.Context)(t: c.Expr[T])( - f: c.Expr[T] => c.Expr[M[T]] - )(implicit tt: c.WeakTypeTag[T], mt: c.WeakTypeTag[M[T]]): c.Expr[State => Parser[M[T]]] = { - val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[T](in)).tree - Instance.contImpl[T, M](c, ParserInstance, ParserConvert, MixedBuilder, LinterDSL.Empty)( + private[A1his] def iParserMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])( + f: c.Expr[A1] => c.Expr[M[A1]] + )(implicit tt: Type[A1], mt: Type[M[A1]]): c.Expr[State => Parser[M[A1]]] = { + val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[A1](in)).tree + Instance.contImpl[A1, M](c, ParserInstance, ParserConvert, MixedBuilder, LinterDSL.Empty)( Left(t), inner ) } - private[this] def iTaskMacro[T: c.WeakTypeTag]( + private[A1his] def iTaskMacro[A1: Type]( c: blackbox.Context - )(t: c.Expr[T]): c.Expr[Task[T]] = + )(t: c.Expr[A1]): c.Expr[Task[A1]] = Instance - .contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, EmptyLinter)( + .contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, EmptyLinter)( Left(t), Instance.idTransform ) - private[this] def inputTaskDynMacro0[T: c.WeakTypeTag]( + private[A1his] def inputTaskDynMacro0[A1: Type]( c: blackbox.Context - )(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[InputTask[T]]] = { + )(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] = { import c.universe.{ Apply => ApplyTree, _ } import internal.decorators._ - val tag = implicitly[c.WeakTypeTag[T]] + val tag = implicitly[Type[A1]] val util = ContextUtil[c.type](c) val it = Ident(util.singleton(InputTask)) val isParserWrapper = InitParserConvert.asPredicate(c) @@ -545,7 +512,9 @@ object TaskMacro { val vd = util.freshValDef(tpe, qual.symbol.pos, functionSym) // val $x: result = Some((qual, tpe, vd)) val tree = util.refVal(original, vd) // $x - tree.setPos(qual.pos) // position needs to be set so that wrapKey passes the position onto the wrapper + tree.setPos( + qual.pos + ) // position needs to be set so that wrapKey passes the position onto the wrapper assert(tree.tpe != null, "Null type: " + tree) tree.setType(tpe) tree @@ -554,13 +523,13 @@ object TaskMacro { def inputTaskCreate(name: String, tpeA: Type, tpeB: Type, arg1: Tree, arg2: Tree) = { val typedApp = TypeApply(util.select(it, name), TypeTree(tpeA) :: TypeTree(tpeB) :: Nil) val app = ApplyTree(ApplyTree(typedApp, arg1 :: Nil), arg2 :: Nil) - c.Expr[Initialize[InputTask[T]]](app) + c.Expr[Initialize[InputTask[A1]]](app) } // Tree for InputTask.createFree[](arg1) def inputTaskCreateFree(tpe: Type, arg: Tree) = { val typedApp = TypeApply(util.select(it, InputTaskCreateFreeName), TypeTree(tpe) :: Nil) val app = ApplyTree(typedApp, arg :: Nil) - c.Expr[Initialize[InputTask[T]]](app) + c.Expr[Initialize[InputTask[A1]]](app) } def expandTask[I: WeakTypeTag](dyn: Boolean, tx: Tree): c.Expr[Initialize[Task[I]]] = if (dyn) @@ -570,7 +539,7 @@ object TaskMacro { def wrapTag[I: WeakTypeTag]: WeakTypeTag[Initialize[Task[I]]] = weakTypeTag def sub(name: String, tpe: Type, qual: Tree, selection: Tree): Converted[c.type] = { - val tag = c.WeakTypeTag[T](tpe) + val tag = Type[A1](tpe) InitParserConvert(c)(name, qual)(tag) transform { tree => subWrapper(tpe, tree, selection) } @@ -582,28 +551,33 @@ object TaskMacro { val fCore = util.createFunction(param :: Nil, tx, functionSym) val bodyTpe = wrapTag(tag).tpe val fTpe = util.functionType(tpe :: Nil, bodyTpe) - val fTag = c.WeakTypeTag[Any](fTpe) // don't know the actual type yet, so use Any + val fTag = Type[Any](fTpe) // don't know the actual type yet, so use Any val fInit = expandTask(false, fCore)(fTag).tree inputTaskCreate(InputTaskCreateDynName, tpe, tag.tpe, p, fInit) case None => - val init = expandTask[T](true, tx).tree + val init = expandTask[A1](true, tx).tree inputTaskCreateFree(tag.tpe, init) } } -} + */ -object PlainTaskMacro { - def task[T](t: T): Task[T] = macro taskImpl[T] - def taskImpl[T: c.WeakTypeTag](c: blackbox.Context)(t: c.Expr[T]): c.Expr[Task[T]] = - Instance.contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskLinterDSL)( +end TaskMacro + +/* +object PlainTaskMacro: + def task[A1](t: T): Task[A1] = macro taskImpl[A1] + def taskImpl[A1: Type](c: blackbox.Context)(t: c.Expr[A1]): c.Expr[Task[A1]] = + Instance.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskLinterDSL)( Left(t), Instance.idTransform[c.type] ) - def taskDyn[T](t: Task[T]): Task[T] = macro taskDynImpl[T] - def taskDynImpl[T: c.WeakTypeTag](c: blackbox.Context)(t: c.Expr[Task[T]]): c.Expr[Task[T]] = - Instance.contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskDynLinterDSL)( + def taskDyn[A1](t: Task[A1]): Task[A1] = macro taskDynImpl[A1] + def taskDynImpl[A1: Type](c: blackbox.Context)(t: c.Expr[Task[A1]]): c.Expr[Task[A1]] = + Instance.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskDynLinterDSL)( Right(t), Instance.idTransform[c.type] ) -} + +end PlainTaskMacro + */ diff --git a/main-settings/src/main/scala/sbt/unchecked.scala b/main-settings/src/main/scala/sbt/unchecked.scala index 55261fa97..012d15a20 100644 --- a/main-settings/src/main/scala/sbt/unchecked.scala +++ b/main-settings/src/main/scala/sbt/unchecked.scala @@ -9,7 +9,8 @@ package sbt import scala.annotation.Annotation -/** An annotation to designate that the annotated entity +/** + * An annotation to designate that the annotated entity * should not be considered for additional sbt compiler checks. * These checks ensure that the DSL is predictable and prevents * users from doing dangerous things at the cost of a stricter diff --git a/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala b/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala index 313459dbb..c5b751211 100644 --- a/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala +++ b/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala @@ -112,8 +112,7 @@ object BuildSettingsInstances { implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = withScope(genSettingKey[A]) implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = withScope(genTaskKey[A]) - implicit def arbKey[A: Manifest]( - implicit + implicit def arbKey[A: Manifest](implicit arbInputKey: Arbitrary[InputKey[A]], arbSettingKey: Arbitrary[SettingKey[A]], arbTaskKey: Arbitrary[TaskKey[A]], diff --git a/main-settings/src/test/scala/sbt/ScopedSpec.scala b/main-settings/src/test/scala/sbt/ScopedSpec.scala index 8e5702188..ed30b7322 100644 --- a/main-settings/src/test/scala/sbt/ScopedSpec.scala +++ b/main-settings/src/test/scala/sbt/ScopedSpec.scala @@ -83,7 +83,7 @@ object ScopedSpec extends Properties("Scoped") { } } - /// + // / def settingKey[A](label: Label, manifest: Manifest[A], scope: Scope): SettingKey[A] = { val noJsonWriter = NoJsonWriter[A]() @@ -101,7 +101,7 @@ object ScopedSpec extends Properties("Scoped") { AttributeKey[A](label.value)(manifest, jsonWriter) } - /// + // / def expectEq(k1: Scoped, k2: Scoped): Prop = ?=(k1, k2) && ?=(k2, k1) map eqLabels(k1, k2) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 159276235..a8897032a 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -87,9 +87,8 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { - forAll( - (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: Key) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) + forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: Key) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) ) } diff --git a/main-settings/src/test/scala/sbt/std/UsageTest.scala b/main-settings/src/test/scala/sbt/std/UsageTest.scala index ec1f2149e..f7e022d32 100644 --- a/main-settings/src/test/scala/sbt/std/UsageTest.scala +++ b/main-settings/src/test/scala/sbt/std/UsageTest.scala @@ -75,7 +75,7 @@ object Assign { ) val it1 = Def.inputTask { - tsk.parsed //"as" //dummy.value.parsed + tsk.parsed // "as" //dummy.value.parsed } val it2 = Def.inputTask { "lit" diff --git a/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala b/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala index e2d214657..03dfcd17c 100644 --- a/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala +++ b/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala @@ -380,5 +380,5 @@ class TaskNegSpec extends funsuite.FixtureAnyFunSuite with fixture.TestDataFixtu """.stripMargin } } - */ + */ } diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index d1c5010d0..0807bd3c3 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -384,7 +384,7 @@ object EvaluateTask { } def logIncResult(result: Result[_], state: State, streams: Streams) = result match { - case Inc(i) => logIncomplete(i, state, streams); case _ => () + case Result.Inc(i) => logIncomplete(i, state, streams); case _ => () } def logIncomplete(result: Incomplete, state: State, streams: Streams): Unit = { @@ -623,8 +623,8 @@ object EvaluateTask { def onResult[T, S](result: Result[T])(f: T => S): S = result match { - case Value(v) => f(v) - case Inc(inc) => throw inc + case Result.Value(v) => f(v) + case Result.Inc(inc) => throw inc } // if the return type Seq[Setting[_]] is not explicitly given, scalac hangs diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index a6f607bce..3c181def5 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -742,8 +742,8 @@ object BuildServerProtocol { private def bspCompileTask: Def.Initialize[Task[Int]] = Def.task { Keys.compile.result.value match { - case Value(_) => StatusCode.Success - case Inc(cause) => + case Result.Value(_) => StatusCode.Success + case Result.Inc(cause) => cause.getCause match { case _: CompileFailed => StatusCode.Error case _: InterruptedException => StatusCode.Cancelled diff --git a/tasks-standard/src/main/scala/sbt/Task.scala b/tasks-standard/src/main/scala/sbt/Task.scala index c89893f4a..606537956 100644 --- a/tasks-standard/src/main/scala/sbt/Task.scala +++ b/tasks-standard/src/main/scala/sbt/Task.scala @@ -7,13 +7,16 @@ package sbt +import sbt.internal.Action import sbt.internal.util.Types._ import sbt.internal.util.{ ~>, AList, AttributeKey, AttributeMap } import ConcurrentRestrictions.{ Tag, TagMap, tagsKey } -import sbt.internal.Action +import sbt.util.Monad -/** Combines metadata `info` and a computation `work` to define a task. */ -final case class Task[A](info: Info[A], work: Action[A]) { +/** + * Combines metadata `info` and a computation `work` to define a task. + */ +final case class Task[A](info: Info[A], work: Action[A]): override def toString = info.name getOrElse ("Task(" + info + ")") override def hashCode = info.hashCode @@ -22,11 +25,31 @@ final case class Task[A](info: Info[A], work: Action[A]) { val tgs: TagMap = info.get(tagsKey).getOrElse(TagMap.empty) val value = tags.foldLeft(tgs)((acc, tag) => acc + tag) val nextInfo = info.set(tagsKey, value) - copy(info = nextInfo) + withInfo(info = nextInfo) } def tags: TagMap = info get tagsKey getOrElse TagMap.empty -} + + private[sbt] def withInfo(info: Info[A]): Task[A] = + Task(info = info, work = this.work) +end Task + +object Task: + import sbt.std.TaskExtra.* + + given taskMonad: Monad[Task] with + type F[a] = Task[a] + override def pure[A1](a: () => A1): Task[A1] = toTask(a) + + override def ap[A1, A2](ff: Task[A1 => A2])(in: Task[A1]): Task[A2] = + multT2Task((in, ff)).map { case (x, f) => + f(x) + } + + override def map[A1, A2](in: Task[A1])(f: A1 => A2): Task[A2] = in.map(f) + override def flatMap[A1, A2](in: F[A1])(f: A1 => F[A2]): F[A2] = in.flatMap(f) + override def flatten[A1](in: Task[Task[A1]]): Task[A1] = in.flatMap(idFun[Task[A1]]) +end Task /** * Used to provide information about a task, such as the name, description, and tags for controlling @@ -52,8 +75,9 @@ final case class Info[T]( override def toString = if (attributes.isEmpty) "_" else attributes.toString } -object Info { + +object Info: val Name = AttributeKey[String]("name") val Description = AttributeKey[String]("description") val defaultAttributeMap = const(AttributeMap.empty) -} +end Info diff --git a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala index f6b2809e5..ab51afa6d 100644 --- a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala +++ b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala @@ -117,6 +117,7 @@ trait TaskExtra extends TaskExtra0 { final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x: A } + final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask) final implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] { def fork[T](f: S => T): Seq[Task[T]] = in.map(x => task(f(x))) @@ -271,6 +272,7 @@ trait TaskExtra extends TaskExtra0 { (p run pio).exitValue() } } + object TaskExtra extends TaskExtra { def processIO(s: TaskStreams[_]): ProcessIO = { def transfer(id: String) = (in: InputStream) => BasicIO.transferFully(in, s.binary(id)) diff --git a/tasks/src/main/scala/sbt/Execute.scala b/tasks/src/main/scala/sbt/Execute.scala index 24f6b9f3f..56c7acb20 100644 --- a/tasks/src/main/scala/sbt/Execute.scala +++ b/tasks/src/main/scala/sbt/Execute.scala @@ -64,7 +64,7 @@ private[sbt] final class Execute[F[_] <: AnyRef]( private[this] val forward = idMap[F[Any], IDSet[F[Any]]] private[this] val reverse = idMap[F[Any], Iterable[F[Any]]] - private[this] val callers = pMap[F, Compose[IDSet, F]#Apply] + private[this] val callers = pMap[F, Compose[IDSet, F]] private[this] val state = idMap[F[Any], State] private[this] val viewCache = pMap[F, Node[F, *]] private[this] val results = pMap[F, Result] diff --git a/util-cache/src/main/scala/sbt/util/StampedFormat.scala b/util-cache/src/main/scala/sbt/util/StampedFormat.scala index 5b2177a8e..cdb9ed805 100644 --- a/util-cache/src/main/scala/sbt/util/StampedFormat.scala +++ b/util-cache/src/main/scala/sbt/util/StampedFormat.scala @@ -7,13 +7,13 @@ package sbt.util -import scala.reflect.Manifest +import scala.reflect.ClassTag import sjsonnew.{ BasicJsonProtocol, Builder, deserializationError, JsonFormat, Unbuilder } object StampedFormat extends BasicJsonProtocol { - def apply[T](format: JsonFormat[T])(implicit mf: Manifest[JsonFormat[T]]): JsonFormat[T] = { + def apply[T](format: JsonFormat[T])(implicit mf: ClassTag[JsonFormat[T]]): JsonFormat[T] = { withStamp(stamp(format))(format) } @@ -46,9 +46,9 @@ object StampedFormat extends BasicJsonProtocol { } } - private def stamp[T](format: JsonFormat[T])(implicit mf: Manifest[JsonFormat[T]]): Int = + private def stamp[T](format: JsonFormat[T])(implicit mf: ClassTag[JsonFormat[T]]): Int = typeHash(mf) - private def typeHash[T](implicit mf: Manifest[T]) = mf.toString.hashCode + private def typeHash[T](implicit mf: ClassTag[T]) = mf.toString.hashCode } diff --git a/util-collection/src/main/scala/sbt/internal/util/AList.scala b/util-collection/src/main/scala/sbt/internal/util/AList.scala index 6a79bdfe1..28f3ff330 100644 --- a/util-collection/src/main/scala/sbt/internal/util/AList.scala +++ b/util-collection/src/main/scala/sbt/internal/util/AList.scala @@ -64,29 +64,87 @@ object AList: override def transform[F1[_], F2[_]](value: Unit)(f: [x] => F1[x] => F2[x]): Unit = () override def traverse[F1[_], F2[_]: Applicative](value: Unit)( f: [a] => F1[a] => F2[a] - ): F2[Unit] = summon[Applicative[F2]].pure(()) + ): F2[Unit] = summon[Applicative[F2]].pure(() => ()) override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: Unit)( f: [a] => F1[a] => F2[P[a]] - ): F2[Unit] = summon[Applicative[F2]].pure(()) + ): F2[Unit] = summon[Applicative[F2]].pure(() => ()) override def foldr[F1[_], A2](value: Unit, init: A2)( f: [a] => (F1[a], A2) => A2 ): A2 = init - def single[A1]: AList[[F[_]] =>> F[A1]] = - new AList[[F[_]] =>> F[A1]]: - override def transform[F1[_], F2[_]](value: F1[A1])(f: [x] => F1[x] => F2[x]): F2[A1] = - f(value) - override def traverse[F1[_], F2[_]: Applicative](value: F1[A1])( - f: [a] => F1[a] => F2[a] - ): F2[A1] = f(value) - override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: F1[A1])( - f: [a] => F1[a] => F2[P[a]] - ): F2[P[A1]] = f(value) - override def foldr[F1[_], A2](value: F1[A1], init: A2)( - f: [a] => (F1[a], A2) => A2 - ): A2 = f(value, init) + type Single[A1] = AList[[F[_]] =>> F[A1]] - def tuple2[A1, A2]: AList[[F[_]] =>> Tuple.Map[(A1, A2), F]] = tuple[(A1, A2)] + def single[A1]: Single[A1] = new Single[A1]: + override def transform[F1[_], F2[_]](value: F1[A1])(f: [x] => F1[x] => F2[x]): F2[A1] = + f(value) + override def traverse[F1[_], F2[_]: Applicative](value: F1[A1])( + f: [a] => F1[a] => F2[a] + ): F2[A1] = f(value) + override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: F1[A1])( + f: [a] => F1[a] => F2[P[a]] + ): F2[P[A1]] = f(value) + override def foldr[F1[_], A2](value: F1[A1], init: A2)( + f: [a] => (F1[a], A2) => A2 + ): A2 = f(value, init) + + type ASplit[K1[F1[_]], F2[_]] = AList[SplitK[K1, F2]] + def asplit[K1[g[_]], G2[_]](base: AList[K1]): ASplit[K1, G2] = new ASplit[K1, G2]: + def transform[F1[_], F2[_]](value: SplitK[K1, G2][F1])( + f: [a] => F1[a] => F2[a] + ): SplitK[K1, G2][F2] = + base.transform[Compose[F1, G2], Compose[F2, G2]](value) { + nestCon[F1, F2, G2](f) + } + def traverse[F1[_], F2[_]: Applicative](value: SplitK[K1, G2][F1])( + f: [a] => F1[a] => F2[a] + ): F2[SplitK[K1, G2][Id]] = traverseX[F1, F2, Id](value)(f) + + def traverseX[F1[_], F2[_]: Applicative, P[_]](value: SplitK[K1, G2][F1])( + f: [a] => F1[a] => F2[P[a]] + ): F2[SplitK[K1, G2][P]] = + base.traverseX[Compose[F1, G2], F2, Compose[P, G2]](value) { + nestCon[F1, Compose[F2, P], G2](f) + } + def foldr[F1[_], A1](value: SplitK[K1, G2][F1], init: A1)( + f: [a] => (F1[a], A1) => A1 + ): A1 = base.foldr[Compose[F1, G2], A1](value, init) { + // This is safe because F1[G2[a]] is F1[a] + f.asInstanceOf[[a] => (F1[G2[a]], A1) => A1] + } + + type Tuple2K[A1, A2] = [F[_]] =>> Tuple.Map[(A1, A2), F] + def tuple2[A1, A2]: AList[Tuple2K[A1, A2]] = tuple[(A1, A2)] + type Tuple3K[A1, A2, A3] = [F[_]] =>> Tuple.Map[(A1, A2, A3), F] + def tuple3[A1, A2, A3]: AList[Tuple3K[A1, A2, A3]] = tuple[(A1, A2, A3)] + type Tuple4K[A1, A2, A3, A4] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4), F] + def tuple4[A1, A2, A3, A4]: AList[Tuple4K[A1, A2, A3, A4]] = tuple[(A1, A2, A3, A4)] + type Tuple5K[A1, A2, A3, A4, A5] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5), F] + def tuple5[A1, A2, A3, A4, A5]: AList[Tuple5K[A1, A2, A3, A4, A5]] = tuple[(A1, A2, A3, A4, A5)] + type Tuple6K[A1, A2, A3, A4, A5, A6] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6), F] + def tuple6[A1, A2, A3, A4, A5, A6]: AList[Tuple6K[A1, A2, A3, A4, A5, A6]] = + tuple[(A1, A2, A3, A4, A5, A6)] + type Tuple7K[A1, A2, A3, A4, A5, A6, A7] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7), F] + def tuple7[A1, A2, A3, A4, A5, A6, A7]: AList[Tuple7K[A1, A2, A3, A4, A5, A6, A7]] = + tuple[(A1, A2, A3, A4, A5, A6, A7)] + type Tuple8K[A1, A2, A3, A4, A5, A6, A7, A8] = + [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8), F] + def tuple8[A1, A2, A3, A4, A5, A6, A7, A8]: AList[Tuple8K[A1, A2, A3, A4, A5, A6, A7, A8]] = + tuple[(A1, A2, A3, A4, A5, A6, A7, A8)] + type Tuple9K[A1, A2, A3, A4, A5, A6, A7, A8, A9] = + [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9), F] + def tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9] + : AList[Tuple9K[A1, A2, A3, A4, A5, A6, A7, A8, A9]] = + tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9)] + type Tuple10K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] = + [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), F] + def tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] + : AList[Tuple10K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] = + tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)] + type Tuple11K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] = + [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), F] + def tuple11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] + : AList[Tuple11K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]] = + tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)] def tuple[Tup <: Tuple]: AList[[F[_]] =>> Tuple.Map[Tup, F]] = new AList[[F[_]] =>> Tuple.Map[Tup, F]]: @@ -104,7 +162,8 @@ object AList: ): F2[Tuple.Map[Tup, Id]] = val F2 = summon[Applicative[F2]] value match - case _: Tuple.Map[EmptyTuple, F1] => F2.pure(nil[Tup].asInstanceOf[Tuple.Map[Tup, Id]]) + case _: Tuple.Map[EmptyTuple, F1] => + F2.pure(() => nil[Tup].asInstanceOf[Tuple.Map[Tup, Id]]) case (head: F1[x] @unchecked) *: (tail: Tuple.Map[Tail[Tup], F1] @unchecked) => val tt = tuple[Tail[Tup]].traverse[F1, F2](tail)(f) val g = (t: Tail[Tup]) => (h: x) => (h *: t) @@ -117,7 +176,7 @@ object AList: ): F2[Tuple.Map[Tup, P]] = val F2 = summon[Applicative[F2]] value match - case _: Tuple.Map[EmptyTuple, F1] => F2.pure(nil[Tuple.Map[Tup, P]]) + case _: Tuple.Map[EmptyTuple, F1] => F2.pure(() => nil[Tuple.Map[Tup, P]]) case (head: F1[x] @unchecked) *: (tail: Tuple.Map[Tail[Tup], F1] @unchecked) => val tt = traverseX[F1, F2, P](tail.asInstanceOf)(f) val g = (t: Tuple.Map[Tail[Tup], P]) => @@ -142,7 +201,7 @@ object AList: val ap = summon[Applicative[F1]] def loop[V](in: List[F1[A]], g: List[A] => V): F1[V] = in match - case Nil => ap.pure(g(Nil)) + case Nil => ap.pure(() => g(Nil)) case x :: xs => val h = (ts: List[A]) => (t: A) => g(t :: ts) ap.ap(loop(xs, h))(x) diff --git a/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index bbe44e300..876fd2ef4 100644 --- a/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -8,7 +8,7 @@ package sbt.internal.util import Types._ -import scala.reflect.Manifest +import scala.reflect.ClassTag import sbt.util.OptJsonWriter // T must be invariant to work properly. @@ -19,10 +19,11 @@ import sbt.util.OptJsonWriter * A key in an [[AttributeMap]] that constrains its associated value to be of type `T`. The key is * uniquely defined by its `label` and type `T`, represented at runtime by `manifest`. */ -sealed trait AttributeKey[T] { +sealed trait AttributeKey[A]: /** The runtime evidence for `T`. */ - def manifest: Manifest[T] + // def manifest: Manifest[A] + def classTag: ClassTag[A] /** The label is the identifier for the key and is camelCase by convention. */ def label: String @@ -47,46 +48,46 @@ sealed trait AttributeKey[T] { /** Identifies the relative importance of a key among other keys. */ def rank: Int - def optJsonWriter: OptJsonWriter[T] + def optJsonWriter: OptJsonWriter[A] -} +end AttributeKey private[sbt] abstract class SharedAttributeKey[T] extends AttributeKey[T] { override final def toString = label override final def hashCode = label.hashCode override final def equals(o: Any) = (this eq o.asInstanceOf[AnyRef]) || (o match { - case a: SharedAttributeKey[t] => a.label == this.label && a.manifest == this.manifest + case a: SharedAttributeKey[t] => a.label == this.label && a.classTag == this.classTag case _ => false }) final def isLocal: Boolean = false } object AttributeKey { - def apply[T: Manifest: OptJsonWriter](name: String): AttributeKey[T] = + def apply[T: ClassTag: OptJsonWriter](name: String): AttributeKey[T] = make(name, None, Nil, Int.MaxValue) - def apply[T: Manifest: OptJsonWriter](name: String, rank: Int): AttributeKey[T] = + def apply[T: ClassTag: OptJsonWriter](name: String, rank: Int): AttributeKey[T] = make(name, None, Nil, rank) - def apply[T: Manifest: OptJsonWriter](name: String, description: String): AttributeKey[T] = + def apply[T: ClassTag: OptJsonWriter](name: String, description: String): AttributeKey[T] = apply(name, description, Nil) - def apply[T: Manifest: OptJsonWriter]( + def apply[T: ClassTag: OptJsonWriter]( name: String, description: String, rank: Int ): AttributeKey[T] = apply(name, description, Nil, rank) - def apply[T: Manifest: OptJsonWriter]( + def apply[T: ClassTag: OptJsonWriter]( name: String, description: String, extend: Seq[AttributeKey[_]] ): AttributeKey[T] = apply(name, description, extend, Int.MaxValue) - def apply[T: Manifest: OptJsonWriter]( + def apply[T: ClassTag: OptJsonWriter]( name: String, description: String, extend: Seq[AttributeKey[_]], @@ -95,21 +96,21 @@ object AttributeKey { make(name, Some(description), extend, rank) private[sbt] def copyWithRank[T](a: AttributeKey[T], rank: Int): AttributeKey[T] = - make(a.label, a.description, a.extend, rank)(a.manifest, a.optJsonWriter) + make(a.label, a.description, a.extend, rank)(a.classTag, a.optJsonWriter) private[this] def make[T]( name: String, description0: Option[String], extend0: Seq[AttributeKey[_]], rank0: Int - )(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = + )(implicit mf: ClassTag[T], ojw: OptJsonWriter[T]): AttributeKey[T] = new SharedAttributeKey[T] { require( name.headOption.exists(_.isLower), s"A named attribute key must start with a lowercase letter: $name" ) - def manifest = mf + def classTag = mf val label = Util.hyphenToCamel(name) def description = description0 def extend = extend0 @@ -117,9 +118,9 @@ object AttributeKey { def optJsonWriter = ojw } - private[sbt] def local[T](implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = + private[sbt] def local[T](implicit mf: ClassTag[T], ojw: OptJsonWriter[T]): AttributeKey[T] = new AttributeKey[T] { - def manifest = mf + def classTag = mf def label = LocalLabel def description = None def extend = Nil diff --git a/util-collection/src/main/scala/sbt/internal/util/Settings.scala b/util-collection/src/main/scala/sbt/internal/util/Settings.scala index 22e3291f0..9d6e7b0d7 100644 --- a/util-collection/src/main/scala/sbt/internal/util/Settings.scala +++ b/util-collection/src/main/scala/sbt/internal/util/Settings.scala @@ -105,14 +105,19 @@ trait Init[ScopeType]: def update[A1](key: ScopedKey[A1])(f: A1 => A1): Setting[A1] = setting[A1](key, map(key)(f), NoPosition) - def bind[A1, A2](in: Initialize[A1])(f: A1 => Initialize[A2]): Initialize[A2] = Bind(f, in) + def flatMap[A1, A2](in: Initialize[A1])(f: A1 => Initialize[A2]): Initialize[A2] = Bind(f, in) def map[A1, A2](in: Initialize[A1])(f: A1 => A2): Initialize[A2] = Apply[[F[_]] =>> F[A1], A2](f, in, AList.single[A1]) - def app[K[L[x]], T](inputs: K[Initialize])(f: K[Id] => T)(implicit + def app[K[L[x]], A2](inputs: K[Initialize])(f: K[Id] => A2)(implicit alist: AList[K] - ): Initialize[T] = Apply[K, T](f, inputs, alist) + ): Initialize[A2] = Apply[K, A2](f, inputs, alist) + + def ap[A1, A2](ff: Initialize[A1 => A2])(in: Initialize[A1]): Initialize[A2] = + app[[F[_]] =>> (F[A1 => A2], F[A1]), A2]((ff, in)) { (f, a1) => + f(a1) + }(AList.tuple2[A1 => A2, A1]) def uniform[A1, A2](inputs: Seq[Initialize[A1]])(f: Seq[A1] => A2): Initialize[A2] = Apply[[F[_]] =>> List[F[A1]], A2](f, inputs.toList, AList.list[A1]) @@ -657,8 +662,10 @@ trait Init[ScopeType]: def evaluate(map: Settings[ScopeType]): A1 def zip[A2](o: Initialize[A2]): Initialize[(A1, A2)] = zipTupled(o)(idFun) + def zipWith[A2, U](o: Initialize[A2])(f: (A1, A2) => U): Initialize[U] = zipTupled(o)(f.tupled) + private[this] def zipTupled[A2, U](o: Initialize[A2])(f: ((A1, A2)) => U): Initialize[U] = Apply[[F[_]] =>> Tuple.Map[(A1, A2), F], U](f, (this, o), AList.tuple2[A1, A2]) diff --git a/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala b/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala index 1470f37e5..89f3807f1 100644 --- a/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala +++ b/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala @@ -18,7 +18,12 @@ trait TypeFunctions: type ConstK[A] = [F[_]] =>> A */ - sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] } + type Compose[F1[_], F2[_]] = [a] =>> F1[F2[a]] + + /** + * Example: calling `SplitK[K1, Task]` returns the type lambda `F[a] => K1[F[Task[a]]`. + */ + type SplitK[K1[F1[_]], F2[_]] = [f[_]] =>> K1[Compose[f, F2]] sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] } private type AnyLeft[A] = Left[A, Nothing] @@ -39,12 +44,13 @@ trait TypeFunctions: final def idK[F[_]]: [a] => F[a] => F[a] = [a] => (fa: F[a]) => fa // .setToString("TypeFunctions.idK") - /* - def nestCon[M[_], N[_], G[_]](f: M ~> N): (M ∙ G)#l ~> (N ∙ G)#l = - f.asInstanceOf[(M ∙ G)#l ~> (N ∙ G)#l] // implemented with a cast to avoid extra object+method call. - // castless version: - // λ[(M ∙ G)#l ~> (N ∙ G)#l](f(_)) + inline def nestCon[F1[_], F2[_], F3[_]]( + f: [a] => F1[a] => F2[a] + ): [a] => Compose[F1, F3][a] => Compose[F2, F3][a] = + f.asInstanceOf[[a] => Compose[F1, F3][a] => Compose[F2, F3][a]] + + /* type Endo[T] = T => T type ~>|[A[_], B[_]] = A ~> Compose[Option, B]#Apply */ diff --git a/util-collection/src/main/scala/sbt/util/Applicative.scala b/util-collection/src/main/scala/sbt/util/Applicative.scala index 340e43b72..8d5c00a20 100644 --- a/util-collection/src/main/scala/sbt/util/Applicative.scala +++ b/util-collection/src/main/scala/sbt/util/Applicative.scala @@ -7,14 +7,27 @@ package sbt.util -trait Applicative[F[_]] extends Apply[F]: - def pure[A](x: A): F[A] +import sbt.internal.util.Types.Compose - override def map[A, B](fa: F[A])(f: A => B): F[B] = - ap(pure(f))(fa) +trait Applicative[F[_]] extends Apply[F]: + def pure[A1](x: () => A1): F[A1] + + override def map[A1, A2](fa: F[A1])(f: A1 => A2): F[A2] = + ap(pure(() => f))(fa) end Applicative object Applicative: given Applicative[Option] = OptionInstances.optionMonad given Applicative[List] = ListInstances.listMonad + + given [F1[_], F2[_]](using Applicative[F1], Applicative[F2]): Applicative[Compose[F1, F2]] with + type F[x] = F1[F2[x]] + val F1 = summon[Applicative[F1]] + val F2 = summon[Applicative[F2]] + override def pure[A1](x: () => A1): F1[F2[A1]] = F1.pure(() => F2.pure(x)) + override def ap[A1, A2](f1f2f: Compose[F1, F2][A1 => A2])( + f1f2a: Compose[F1, F2][A1] + ): F1[F2[A2]] = + F1.ap(F1.map(f1f2f) { (f2f: F2[A1 => A2]) => (f2a: F2[A1]) => F2.ap(f2f)(f2a) })(f1f2a) + end Applicative diff --git a/util-collection/src/main/scala/sbt/util/Apply.scala b/util-collection/src/main/scala/sbt/util/Apply.scala index 0bcd35e25..8d20bdd0b 100644 --- a/util-collection/src/main/scala/sbt/util/Apply.scala +++ b/util-collection/src/main/scala/sbt/util/Apply.scala @@ -8,10 +8,10 @@ package sbt.util trait Apply[F[_]] extends Functor[F]: - def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] + def ap[A1, A2](ff: F[A1 => A2])(fa: F[A1]): F[A2] - def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] = - ap(map(fa)(a => (b: B) => (a, b)))(fb) + def product[A1, A2](fa: F[A1], fb: F[A2]): F[(A1, A2)] = + ap(map(fa)(a => (b: A2) => (a, b)))(fb) end Apply object Apply: diff --git a/util-collection/src/main/scala/sbt/util/FlatMap.scala b/util-collection/src/main/scala/sbt/util/FlatMap.scala index 310c9492b..b22638e99 100644 --- a/util-collection/src/main/scala/sbt/util/FlatMap.scala +++ b/util-collection/src/main/scala/sbt/util/FlatMap.scala @@ -11,9 +11,9 @@ import scala.annotation.implicitNotFound @implicitNotFound("Could not find an instance of FlatMap for ${F}") trait FlatMap[F[_]] extends Apply[F]: - def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] + def flatMap[A1, A2](fa: F[A1])(f: A1 => F[A2]): F[A2] - def flatten[A](ffa: F[F[A]]): F[A] = + def flatten[A1](ffa: F[F[A1]]): F[A1] = flatMap(ffa)(fa => fa) end FlatMap diff --git a/util-collection/src/main/scala/sbt/util/Functor.scala b/util-collection/src/main/scala/sbt/util/Functor.scala index ffbc175c6..5a96b21aa 100644 --- a/util-collection/src/main/scala/sbt/util/Functor.scala +++ b/util-collection/src/main/scala/sbt/util/Functor.scala @@ -8,7 +8,7 @@ package sbt.util trait Functor[F[_]]: - def map[A, B](fa: F[A])(f: A => B): F[B] + def map[A1, A2](fa: F[A1])(f: A1 => A2): F[A2] end Functor object Functor: diff --git a/util-collection/src/main/scala/sbt/util/ListInstances.scala b/util-collection/src/main/scala/sbt/util/ListInstances.scala index d88b85c6b..c5917628a 100644 --- a/util-collection/src/main/scala/sbt/util/ListInstances.scala +++ b/util-collection/src/main/scala/sbt/util/ListInstances.scala @@ -11,7 +11,7 @@ private[sbt] object ListInstances: lazy val listMonad: Monad[List] = new Monad[List]: type F[a] = List[a] - def pure[A](x: A): List[A] = List(x) + def pure[A1](x: () => A1): List[A1] = List(x()) def ap[A, B](ff: List[A => B])(fa: List[A]): List[B] = for f <- ff diff --git a/util-collection/src/main/scala/sbt/util/OptionInstances.scala b/util-collection/src/main/scala/sbt/util/OptionInstances.scala index 774cebeee..289aaed31 100644 --- a/util-collection/src/main/scala/sbt/util/OptionInstances.scala +++ b/util-collection/src/main/scala/sbt/util/OptionInstances.scala @@ -12,7 +12,7 @@ private[sbt] object OptionInstances: new Monad[Option]: type F[a] = Option[a] - def pure[A](x: A): Option[A] = Some(x) + def pure[A](x: () => A): Option[A] = Some(x()) def ap[A, B](ff: Option[A => B])(fa: Option[A]): Option[B] = if ff.isDefined && fa.isDefined then Some(ff.get(fa.get)) else None