Skip to content

Commit 441ba4e

Browse files
committed
Replace Set with UniqList in memberNames
1 parent b311b4e commit 441ba4e

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -615,14 +615,11 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
615615
* The members are sorted by name and signature to guarantee a stable ordering.
616616
*/
617617
private def sortedMembersBasedOnFlags(tp: Type, required: Flag, excluded: FlagSet): List[Symbol] = {
618-
// The output of `memberNames` is a Set, sort it to guarantee a stable ordering.
619-
val names = tp.memberNames(takeAllFilter).toSeq.sorted
620-
val buffer = mutable.ListBuffer[Symbol]()
621-
names.foreach { name =>
622-
buffer ++= tp.memberBasedOnFlags(name, required, excluded)
618+
val names = tp.memberNames(takeAllFilter).toList
619+
names.flatMap { name =>
620+
tp.memberBasedOnFlags(name, required, excluded)
623621
.alternatives.sortBy(_.signature)(Signature.lexicographicOrdering).map(_.symbol)
624622
}
625-
buffer.toList
626623
}
627624

628625
/*

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Variances.Variance
1818
import annotation.tailrec
1919
import util.SimpleIdentityMap
2020
import util.Stats
21+
import util.UniqList
2122
import java.util.WeakHashMap
2223
import scala.util.control.NonFatal
2324
import config.Config
@@ -2231,16 +2232,16 @@ object SymDenotations {
22312232
}
22322233
}
22332234

2234-
def memberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): Set[Name] =
2235+
def memberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): UniqList[Name] =
22352236
if (this.is(PackageClass) || !Config.cacheMemberNames)
22362237
computeMemberNames(keepOnly) // don't cache package member names; they might change
22372238
else {
22382239
if (!memberNamesCache.isValid) memberNamesCache = MemberNames.newCache()
22392240
memberNamesCache(keepOnly, this)
22402241
}
22412242

2242-
def computeMemberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): Set[Name] = {
2243-
var names = Set[Name]()
2243+
def computeMemberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): UniqList[Name] = {
2244+
val names = new UniqList.Builder[Name]
22442245
def maybeAdd(name: Name) = if (keepOnly(thisType, name)) names += name
22452246
try {
22462247
for (p <- parentSyms if p.isClass)
@@ -2253,7 +2254,7 @@ object SymDenotations {
22532254
else info.decls.iterator.filter(_.isOneOf(GivenOrImplicitVal))
22542255
else info.decls.iterator
22552256
for (sym <- ownSyms) maybeAdd(sym.name)
2256-
names
2257+
names.result
22572258
}
22582259
catch {
22592260
case ex: Throwable =>
@@ -2466,10 +2467,10 @@ object SymDenotations {
24662467
end computeMembersNamed
24672468

24682469
/** The union of the member names of the package and the package object */
2469-
override def memberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): Set[Name] = {
2470-
def recur(pobjs: List[ClassDenotation], acc: Set[Name]): Set[Name] = pobjs match {
2470+
override def memberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): UniqList[Name] = {
2471+
def recur(pobjs: List[ClassDenotation], acc: UniqList[Name]): UniqList[Name] = pobjs match {
24712472
case pcls :: pobjs1 =>
2472-
recur(pobjs1, acc.union(pcls.memberNames(keepOnly)))
2473+
recur(pobjs1, acc | pcls.memberNames(keepOnly))
24732474
case nil =>
24742475
acc
24752476
}
@@ -2752,7 +2753,7 @@ object SymDenotations {
27522753
/** A cache for sets of member names, indexed by a NameFilter */
27532754
trait MemberNames extends InheritedCache {
27542755
def apply(keepOnly: NameFilter, clsd: ClassDenotation)
2755-
(implicit onBehalf: MemberNames, ctx: Context): Set[Name]
2756+
(implicit onBehalf: MemberNames, ctx: Context): UniqList[Name]
27562757
}
27572758

27582759
object MemberNames {
@@ -2813,7 +2814,7 @@ object SymDenotations {
28132814
}
28142815

28152816
private class MemberNamesImpl(createdAt: Period) extends InheritedCacheImpl(createdAt) with MemberNames {
2816-
private var cache: SimpleIdentityMap[NameFilter, Set[Name]] = SimpleIdentityMap.empty
2817+
private var cache: SimpleIdentityMap[NameFilter, UniqList[Name]] = SimpleIdentityMap.empty
28172818

28182819
final def isValid(using Context): Boolean =
28192820
cache != null && isValidAt(ctx.phase)

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Variances.{Variance, varianceFromInt, varianceToInt, setStructuralVarianc
2323
import typer.Nullables
2424
import util.Stats._
2525
import util.SimpleIdentitySet
26+
import util.UniqList
2627
import ast.tpd._
2728
import ast.TreeTypeMap
2829
import printing.Texts._
@@ -902,7 +903,7 @@ object Types {
902903
* @note: OK to use a Set[Name] here because Name hashcodes are replayable,
903904
* hence the Set will always give the same names in the same order.
904905
*/
905-
final def memberNames(keepOnly: NameFilter, pre: Type = this)(using Context): Set[Name] = this match {
906+
final def memberNames(keepOnly: NameFilter, pre: Type = this)(using Context): UniqList[Name] = this match {
906907
case tp: ClassInfo =>
907908
val names = tp.cls.classDenot.memberNames(keepOnly)
908909
if keepOnly.isStable then names else names.filter(keepOnly(pre, _))
@@ -916,7 +917,7 @@ object Types {
916917
case tp: OrType =>
917918
tp.tp1.memberNames(keepOnly, pre) & tp.tp2.memberNames(keepOnly, pre)
918919
case _ =>
919-
Set()
920+
UniqList.empty
920921
}
921922

922923
def memberDenots(keepOnly: NameFilter, f: (Name, mutable.Buffer[SingleDenotation]) => Unit)(using Context): Seq[SingleDenotation] = {

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ object RefChecks {
5151
}
5252
{
5353
val defaultGetterNames = defaultGetterClass.asClass.memberNames(defaultMethodFilter)
54-
val defaultMethodNames = defaultGetterNames map { _ replace {
54+
val defaultMethodNames = defaultGetterNames.toList.map { _ replace {
5555
case DefaultGetterName(methName, _) => methName
56-
}}
56+
}}.distinct
5757

5858
for (name <- defaultMethodNames) {
5959
val methods = clazz.info.member(name).alternatives.map(_.symbol)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dotty.tools.dotc.util
2+
3+
opaque type UniqList[+A] >: Null <: AnyRef = List[A]
4+
5+
object UniqList:
6+
def empty: UniqList[Nothing] = Nil
7+
extension [A](xs: UniqList[A])
8+
def foreach(f: A => Unit): Unit = xs.foreach(f)
9+
def filter(p: A => Boolean): UniqList[A] = xs.filter(p)
10+
def + (x: A): UniqList[A] = if xs.contains(x) then xs else xs :+ x
11+
def & (ys: UniqList[A]): UniqList[A] = xs.filter(ys.contains)
12+
def | (ys: UniqList[A]): UniqList[A] = (xs ::: ys).distinct
13+
def toList: List[A] = xs
14+
15+
class Builder[A] extends scala.collection.mutable.Builder[A, UniqList[A]]:
16+
private val xs = new scala.collection.mutable.ListBuffer[A]
17+
override def addOne(x: A): this.type = { xs += x; this }
18+
override def addAll(ys: IterableOnce[A]): this.type = { xs ++= ys; this }
19+
override def clear(): Unit = xs.clear()
20+
override def result(): UniqList[A] = xs.distinct.toList
21+
override def sizeHint(size: Int) = xs.sizeHint(size)

0 commit comments

Comments
 (0)