Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable warnings in build.sc, overhaul Agg to avoid triggering spurious deprecation warnings #2519

Merged
merged 4 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 75 additions & 37 deletions main/api/src/mill/api/AggWrapper.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package mill.api

import scala.annotation.nowarn
import scala.collection.mutable
import scala.collection.{IterableFactory, IterableOps, mutable}
import scala.language.implicitConversions

object Strict extends AggWrapper(true)
Expand All @@ -14,26 +13,37 @@ private[mill] sealed class AggWrapper(strictUniqueness: Boolean) {
* ordering. Raises an exception if a duplicate is found; call
* `toSeq.distinct` if you explicitly want to make it swallow duplicates
*/
trait Agg[V] extends IterableOnce[V] {
trait Agg[V]
extends IterableOnce[V]
with IterableOps[V, Agg, Agg[V]] {

override def iterableFactory: IterableFactory[Agg]

override def fromSpecific(coll: IterableOnce[V]): Agg[V] = fromSpecific0(coll)
protected def fromSpecific0(coll: IterableOnce[V]): Agg[V]

override def newSpecificBuilder: scala.collection.mutable.Builder[V, Agg[V]] =
newSpecificBuilder0
protected def newSpecificBuilder0: scala.collection.mutable.Builder[V, Agg[V]]

def contains(v: V): Boolean
def items: Iterator[V]
def indexed: IndexedSeq[V]
def flatMap[T](f: V => IterableOnce[T]): Agg[T]
def map[T](f: V => T): Agg[T]
def filter(f: V => Boolean): Agg[V]
def withFilter(f: V => Boolean): Agg[V]

def collect[T](f: PartialFunction[V, T]): Agg[T]
def zipWithIndex: Agg[(V, Int)]
def reverse: Agg[V]
def zip[T](other: Agg[T]): Agg[(V, T)]
def ++[T >: V](other: IterableOnce[T]): Agg[T]
def length: Int
def isEmpty: Boolean
def nonEmpty: Boolean = !isEmpty
def foreach[U](f: V => U): Unit
}

object Agg {
object Agg extends IterableFactory[Agg] {
def empty[V]: Agg[V] = new Agg.Mutable[V]
implicit def jsonFormat[T: upickle.default.ReadWriter]: upickle.default.ReadWriter[Agg[T]] =
upickle.default
Expand All @@ -43,79 +53,107 @@ private[mill] sealed class AggWrapper(strictUniqueness: Boolean) {
Agg.from(_)
)

def apply[V](items: V*): Agg[V] = from(items)
implicit def from[V](items: IterableOnce[V]): Agg[V] = Mutable.from(items)
object Mutable {
implicit def from[V](items: IterableOnce[V]): Mutable[V] = {
val set = new Agg.Mutable[V]()
items.iterator.foreach(set.append)
set
}

def newBuilder[V] = new mutable.Builder[V, Mutable[V]] {
var mutable = new Agg.Mutable[V]()
def clear(): Unit = { mutable = new Agg.Mutable[V]() }
def result(): Mutable[V] = mutable

implicit def from[V](items: IterableOnce[V]): Agg[V] = {
val set = new Agg.Mutable[V]()
items.iterator.foreach(set.append)
set
def addOne(elem: V): this.type = {
mutable.append(elem)
this
}
}
}

class Mutable[V]() extends Agg[V] {
def iterableFactory: IterableFactory[Mutable] = new IterableFactory[Mutable] {
def from[A](source: IterableOnce[A]): Mutable[A] = Mutable.from(source)
def empty[A]: Mutable[A] = new Mutable[A]()
def newBuilder[A]: mutable.Builder[A, Mutable[A]] = Mutable.newBuilder[A]
}

protected def fromSpecific0(coll: IterableOnce[V]): Mutable[V] = from(coll)
protected def newSpecificBuilder0: mutable.Builder[V, Agg[V]] = {
Mutable.newBuilder[V]
}

private[this] val set0 = mutable.LinkedHashSet.empty[V]
def contains(v: V): Boolean = set0.contains(v)
def append(v: V): AnyVal =

def contains(v: V) = set0.contains(v)
def coll = this

override def toIterable: Iterable[V] = set0.toIterable
def append(v: V): AnyVal = {
if (!contains(v)) {
set0.add(v)

} else if (strictUniqueness) {
throw new Exception("Duplicated item inserted into OrderedSet: " + v)
}
}

def appendAll(vs: Seq[V]): Unit = vs.foreach(append)
def items: Iterator[V] = set0.iterator
def indexed: IndexedSeq[V] = items.toIndexedSeq
def set: collection.Set[V] = set0

def map[T](f: V => T): Agg[T] = {
override def map[T](f: V => T): Mutable[T] = {
val output = new Agg.Mutable[T]
for (i <- items) output.append(f(i))
output
}
def flatMap[T](f: V => IterableOnce[T]): Agg[T] = {

override def flatMap[T](f: V => IterableOnce[T]): Mutable[T] = {
val output = new Agg.Mutable[T]
for (i <- items) for (i0 <- f(i).iterator) output.append(i0)
output
}
def filter(f: V => Boolean): Agg[V] = {

override def filter(f: V => Boolean): Mutable[V] = {
val output = new Agg.Mutable[V]
for (i <- items) if (f(i)) output.append(i)
output
}
def withFilter(f: V => Boolean): Agg[V] = filter(f)

def collect[T](f: PartialFunction[V, T]): Agg[T] =
this.filter(f.isDefinedAt).map(x => f(x))
protected def withFilter0(f: V => Boolean): collection.WithFilter[V, Mutable] =
new collection.WithFilter[V, Mutable] {
lazy val filtered = filter(f)
override def map[B](f: V => B): Mutable[B] = filtered.map(f)

def zipWithIndex: Agg[(V, Int)] = {
var i = 0
this.map { x =>
i += 1
(x, i - 1)
override def flatMap[B](f: V => IterableOnce[B]): Mutable[B] = filtered.flatMap(f)

override def foreach[U](f: V => U): Unit = filtered.foreach(f)

override def withFilter(q: V => Boolean): collection.WithFilter[V, Mutable] =
filtered.withFilter0(f)
}
}

def reverse: Agg[V] = Agg.from(indexed.reverseIterator)
override def reverse: Mutable[V] = Mutable.from(indexed.reverseIterator)

def zip[T](other: Agg[T]): Agg[(V, T)] = Agg.from(items.zip(other.items))
def ++[T >: V](other: IterableOnce[T]): Agg[T] = Agg.from(items ++ other)
def zip[T](other: Agg[T]): Mutable[(V, T)] = Mutable.from(items.zip(other.items))
def length: Int = set0.size

def exists(p: V => Boolean): Boolean = items.exists(p)
def find(p: V => Boolean): Option[V] = items.find(p)
def forall(p: V => Boolean): Boolean = items.forall(p)
def foreach[U](f: V => U): Unit = items.foreach(f)
def isEmpty: Boolean = items.isEmpty
def seq: scala.collection.IterableOnce[V] = items
override def exists(p: V => Boolean): Boolean = items.exists(p)
override def find(p: V => Boolean): Option[V] = items.find(p)
override def forall(p: V => Boolean): Boolean = items.forall(p)
override def foreach[U](f: V => U): Unit = items.foreach(f)
override def isEmpty: Boolean = items.isEmpty
def iterator: Iterator[V] = items

override def hashCode(): Int = items.map(_.hashCode()).sum
override def equals(other: Any): Boolean = other match {
case s: Agg[_] => items.sameElements(s.items)
case _ => super.equals(other)
}
override def toString: String = items.mkString("Agg(", ", ", ")")

}

override def newBuilder[A]: mutable.Builder[A, Agg[A]] = Mutable.newBuilder[A]
}
}
2 changes: 1 addition & 1 deletion runner/src/mill/runner/MillBuildRootModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class MillBuildRootModule()(implicit
super.scalacOptions() ++
Seq(
"-Xplugin:" + lineNumberPluginClasspath().map(_.path).mkString(","),
"-nowarn",
"-deprecation",
// Make sure we abort of the plugin is not found, to ensure any
// classpath/plugin-discovery issues are surfaced early rather than
// after hours of debugging
Expand Down