diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index c0e2049f8..510b9cc00 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -701,7 +701,9 @@ object Keys { @deprecated("No longer used", "1.3.0") private[sbt] val executeProgress = settingKey[State => TaskProgress]("Experimental task execution listener.").withRank(DTask) val commandProgress = settingKey[Seq[ExecuteProgress2]]("Command progress listeners receive events when commands start and end, in addition to task progress events.") - val lintUnused = inputKey[Unit]("Check for keys unused by other settings and tasks.") + val lintUnused = inputKey[Unit]( + "Check for keys unused by other settings and tasks. Keys that are only used via key.all(ScopeFilter).value may still be reported as unused." + ) val lintIncludeFilter = settingKey[String => Boolean]("Filters key names that should be included in the lint check.") val lintExcludeFilter = settingKey[String => Boolean]("Filters key names that should be excluded in the lint check.") val excludeLintKeys = settingKey[Set[Def.KeyedInitialize[?]]]("Keys excluded from lintUnused task") diff --git a/main/src/main/scala/sbt/ScopeFilter.scala b/main/src/main/scala/sbt/ScopeFilter.scala index d50e9e40b..142c278a3 100644 --- a/main/src/main/scala/sbt/ScopeFilter.scala +++ b/main/src/main/scala/sbt/ScopeFilter.scala @@ -97,12 +97,8 @@ object ScopeFilter { * static inspections will not show them. */ def all(sfilter: => ScopeFilter): Initialize[Seq[A]] = - val inner = Def.flatMap(getData): data => + Def.flatMap(getData): data => sfilter(data).toSeq.map(s => Project.inScope(s, i)).join - val dynamicDeps = i match - case k: Def.KeyedInitialize[?] => Seq((k.scopedKey.key, sfilter)) - case _ => Nil - Def.withDynamicDependencies(inner, dynamicDeps) final class TaskKeyAll[A] private[sbt] (i: Initialize[Task[A]]): /** @@ -110,13 +106,9 @@ object ScopeFilter { * static inspections will not show them. */ def all(sfilter: => ScopeFilter): Initialize[Task[Seq[A]]] = - val inner = Def.flatMap(getData): data => + Def.flatMap(getData): data => import std.TaskExtra.* sfilter(data).toSeq.map(s => Project.inScope(s, i)).join(_.join) - val dynamicDeps = i match - case k: Def.KeyedInitialize[?] => Seq((k.scopedKey.key, sfilter)) - case _ => Nil - Def.withDynamicDependencies(inner, dynamicDeps) private[sbt] val Make = new Make {} trait Make { @@ -245,21 +237,6 @@ object ScopeFilter { .toMap new Data(units, resolve, new AllScopes(scopes, grouped)) - def expandDynamicDeps(deps: Seq[Any], structure: BuildStructure): Set[ - Def.ScopedKey[?] - ] = - if deps.isEmpty then Set.empty - else - val data = dataFromStructure(structure) - val result = scala.collection.mutable.Set.empty[Def.ScopedKey[?]] - for dep <- deps do - dep match - case (key: AttributeKey[?], filter: ScopeFilter) => - try filter(data).foreach(scope => result += Def.ScopedKey(scope, key)) - catch case _: Exception => () - case _ => - result.toSet - private[sbt] val allScopes: Initialize[AllScopes] = Def.setting { val scopes = Def.StaticScopes.value val grouped: ScopeMap = diff --git a/main/src/main/scala/sbt/internal/LintUnused.scala b/main/src/main/scala/sbt/internal/LintUnused.scala index 767477f14..c349d82d7 100644 --- a/main/src/main/scala/sbt/internal/LintUnused.scala +++ b/main/src/main/scala/sbt/internal/LintUnused.scala @@ -135,11 +135,7 @@ object LintUnused { val display = Def.showShortKey(None) // extracted.showKey val comp = structure.compiledMap val cMap = Def.flattenLocals(comp) - val staticUsed: Set[ScopedKey[?]] = cMap.values.flatMap(_.dependencies).toSet - val dynamicDeps = - comp.values.flatMap(_.settings).flatMap(s => s.init.dynamicDependencies).toSeq - val dynamicUsed = ScopeFilter.expandDynamicDeps(dynamicDeps, structure) - val used: Set[ScopedKey[?]] = staticUsed ++ dynamicUsed + val used: Set[ScopedKey[?]] = cMap.values.flatMap(_.dependencies).toSet val unused: Seq[ScopedKey[?]] = cMap.keys.filter(!used.contains(_)).toSeq val withDefinedAts: Seq[UnusedKey] = unused.map: u => val data = Project.scopedKeyData(structure, u) diff --git a/util-collection/src/main/scala/sbt/internal/util/INode.scala b/util-collection/src/main/scala/sbt/internal/util/INode.scala index d3a26024c..0f9579009 100644 --- a/util-collection/src/main/scala/sbt/internal/util/INode.scala +++ b/util-collection/src/main/scala/sbt/internal/util/INode.scala @@ -54,8 +54,7 @@ class EvaluateSettings[I <: Init]( o.a match case None => constant(() => o.f(None)) case Some(i) => single[s, A](transform(i), x => o.f(Some(x))) - case d: DynamicDepsInitialize[A] => transform(d.inner) - case StaticScopes => strictConstant(allScopes) + case StaticScopes => strictConstant(allScopes) private lazy val roots: Seq[INode[?]] = compiledSettings.flatMap { cs => (cs.settings map { s => 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 a596de6c1..cf05f2fa5 100644 --- a/util-collection/src/main/scala/sbt/internal/util/Settings.scala +++ b/util-collection/src/main/scala/sbt/internal/util/Settings.scala @@ -631,9 +631,6 @@ trait Init: sealed trait Initialize[A1]: def dependencies: Seq[ScopedKey[?]] - /** Dynamic dependencies (e.g. from .all(ScopeFilter)) not visible in the static graph. */ - private[sbt] def dynamicDependencies: Seq[Any] = Nil - def apply[A2](g: A1 => A2): Initialize[A2] private[sbt] def mapReferenced(g: MapScoped): Initialize[A1] @@ -890,7 +887,6 @@ trait Init: private[sbt] final class Bind[S, A1](val f: S => Initialize[A1], val in: Initialize[S]) extends Initialize[A1]: override def dependencies: Seq[ScopedKey[?]] = in.dependencies - override def dynamicDependencies: Seq[Any] = in.dynamicDependencies override def apply[A2](g: A1 => A2): Initialize[A2] = Bind[S, A2](s => f(s)(g), in) override def evaluate(ss: Settings): A1 = f(in.evaluate(ss)).evaluate(ss) override def mapReferenced(g: MapScoped) = @@ -911,7 +907,6 @@ trait Init: private[sbt] final class Optional[S, A1](val a: Option[Initialize[S]], val f: Option[S] => A1) extends Initialize[A1]: override def dependencies: Seq[ScopedKey[?]] = deps(a.toList) - override def dynamicDependencies: Seq[Any] = a.toList.flatMap(_.dynamicDependencies) override def apply[A2](g: A1 => A2): Initialize[A2] = new Optional[S, A2](a, g compose f) override def mapReferenced(g: MapScoped): Initialize[A1] = @@ -961,7 +956,6 @@ trait Init: private[sbt] final class Uniform[A1, A2](val f: Seq[A1] => A2, val inputs: List[Initialize[A1]]) extends Initialize[A2]: override def dependencies: Seq[ScopedKey[?]] = deps(inputs) - override def dynamicDependencies: Seq[Any] = inputs.flatMap(_.dynamicDependencies) override def mapReferenced(g: MapScoped): Initialize[A2] = Uniform(f, inputs.map(_.mapReferenced(g))) override def mapConstant(g: MapConstant): Initialize[A2] = @@ -986,7 +980,6 @@ trait Init: import sbt.internal.util.TupleMapExtension.* override def dependencies: Seq[ScopedKey[?]] = deps(inputs.toList0) - override def dynamicDependencies: Seq[Any] = inputs.toList0.flatMap(_.dynamicDependencies) override def mapReferenced(g: MapScoped): Initialize[A1] = Apply(f, inputs.transform(mapReferencedK(g))) override def mapConstant(g: MapConstant): Initialize[A1] = @@ -1007,32 +1000,6 @@ trait Init: inputs.toList0.foldLeft(init) { (v, i) => i.processAttributes(v)(f) } end Apply - private[sbt] final class DynamicDepsInitialize[A1]( - val inner: Initialize[A1], - val dynamicDeps: Seq[Any] - ) extends Initialize[A1]: - override def dependencies: Seq[ScopedKey[?]] = inner.dependencies - override def dynamicDependencies: Seq[Any] = dynamicDeps - override def apply[A2](g: A1 => A2): Initialize[A2] = - DynamicDepsInitialize(inner.apply(g), dynamicDeps) - override def mapReferenced(g: MapScoped): Initialize[A1] = - DynamicDepsInitialize(inner.mapReferenced(g), dynamicDeps) - override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] = - inner.validateKeyReferenced(g).map(DynamicDepsInitialize(_, dynamicDeps)) - override def mapConstant(g: MapConstant): Initialize[A1] = - DynamicDepsInitialize(inner.mapConstant(g), dynamicDeps) - override def evaluate(ss: Settings): A1 = inner.evaluate(ss) - private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 = - inner.processAttributes(init)(f) - end DynamicDepsInitialize - - private[sbt] object DynamicDepsInitialize: - def apply[A1](inner: Initialize[A1], deps: Seq[Any]): Initialize[A1] = - if deps.isEmpty then inner else new DynamicDepsInitialize(inner, deps) - - def withDynamicDependencies[A1](init: Initialize[A1], deps: Seq[Any]): Initialize[A1] = - DynamicDepsInitialize(init, deps) - private def remove[A](s: Seq[A], v: A) = s.filterNot(_ == v) final class Undefined private[sbt] (val defining: Setting[?], val referencedKey: ScopedKey[?])