@@ -668,7 +668,8 @@ trait Types extends api.Types { self: SymbolTable =>
668668 * Note: unfortunately it doesn't work to exclude DEFERRED this way.
669669 */
670670 def membersBasedOnFlags (excludedFlags : Long , requiredFlags : Long ): List [Symbol ] =
671- findMember(nme.ANYNAME , excludedFlags, requiredFlags, false ).alternatives
671+ findMembers(excludedFlags, requiredFlags)
672+ // findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives
672673
673674 def memberBasedOnName (name : Name , excludedFlags : Long ): Symbol =
674675 findMember(name, excludedFlags, 0 , false )
@@ -1016,6 +1017,71 @@ trait Types extends api.Types { self: SymbolTable =>
10161017 if (alts.isEmpty) sym
10171018 else (baseClasses.head.newOverloaded(this , alts))
10181019 }
1020+
1021+ def findMembers (excludedFlags : Long , requiredFlags : Long ): List [Symbol ] = {
1022+ // if this type contains type variables, put them to sleep for a while -- don't just wipe them out by
1023+ // replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements
1024+ // without this, the matchesType call would lead to type variables on both sides
1025+ // of a subtyping/equality judgement, which can lead to recursive types being constructed.
1026+ // See (t0851) for a situation where this happens.
1027+ val suspension : List [TypeVar ] = if (this .isGround) null else suspendTypeVarsInType(this )
1028+
1029+ Statistics .incCounter(findMembersCount)
1030+ val start = Statistics .pushTimer(typeOpsStack, findMembersNanos)
1031+
1032+ // Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
1033+ var members : Scope = null
1034+ var excluded = excludedFlags | DEFERRED
1035+ var continue = true
1036+ var self : Type = null
1037+ var membertpe : Type = null
1038+ while (continue) {
1039+ continue = false
1040+ val bcs0 = baseClasses
1041+ var bcs = bcs0
1042+ while (! bcs.isEmpty) {
1043+ val decls = bcs.head.info.decls
1044+ var entry = decls.elems
1045+ while (entry ne null ) {
1046+ val sym = entry.sym
1047+ if (sym hasAllFlags requiredFlags) {
1048+ val excl = sym.getFlag(excluded)
1049+ if (excl == 0L &&
1050+ (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
1051+ (bcs eq bcs0) ||
1052+ ! sym.isPrivateLocal ||
1053+ (bcs0.head.hasTransOwner(bcs.head)))) {
1054+ if (members eq null ) members = newScope
1055+ var prevEntry = members.lookupEntry(sym.name)
1056+ var symtpe : Type = null
1057+ while ((prevEntry ne null ) &&
1058+ ! ((prevEntry.sym eq sym) ||
1059+ (prevEntry.sym.owner ne sym.owner) &&
1060+ ! sym.hasFlag(PRIVATE ) && {
1061+ if (self eq null ) self = this .narrow
1062+ if (symtpe eq null ) symtpe = self.memberType(sym)
1063+ self.memberType(prevEntry.sym) matches symtpe
1064+ })) {
1065+ prevEntry = members lookupNextEntry prevEntry
1066+ }
1067+ if (prevEntry eq null ) {
1068+ members enter sym
1069+ }
1070+ } else if (excl == DEFERRED ) {
1071+ continue = true
1072+ }
1073+ }
1074+ entry = entry.next
1075+ } // while (entry ne null)
1076+ // excluded = excluded | LOCAL
1077+ bcs = bcs.tail
1078+ } // while (!bcs.isEmpty)
1079+ excluded = excludedFlags
1080+ } // while (continue)
1081+ Statistics .popTimer(typeOpsStack, start)
1082+ if (suspension ne null ) suspension foreach (_.suspended = false )
1083+ if (members eq null ) Nil else members.toList
1084+ }
10191085
10201086 /**
10211087 * Find member(s) in this type. If several members matching criteria are found, they are
@@ -1122,6 +1188,7 @@ trait Types extends api.Types { self: SymbolTable =>
11221188 baseClasses.head.newOverloaded(this , members.toList)
11231189 }
11241190 }
1191+
11251192 /** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */
11261193 def skolemsExceptMethodTypeParams : List [Symbol ] = {
11271194 var boundSyms : List [Symbol ] = List ()
@@ -6906,12 +6973,14 @@ object TypesStats {
69066973 val lubCount = Statistics .newCounter (" #toplevel lubs/glbs" )
69076974 val nestedLubCount = Statistics .newCounter (" #all lubs/glbs" )
69086975 val findMemberCount = Statistics .newCounter (" #findMember ops" )
6976+ val findMembersCount = Statistics .newCounter (" #findMembers ops" )
69096977 val noMemberCount = Statistics .newSubCounter(" of which not found" , findMemberCount)
69106978 val multMemberCount = Statistics .newSubCounter(" of which multiple overloaded" , findMemberCount)
69116979 val typerNanos = Statistics .newTimer (" time spent typechecking" , " typer" )
69126980 val lubNanos = Statistics .newStackableTimer(" time spent in lubs" , typerNanos)
69136981 val subtypeNanos = Statistics .newStackableTimer(" time spent in <:<" , typerNanos)
69146982 val findMemberNanos = Statistics .newStackableTimer(" time spent in findmember" , typerNanos)
6983+ val findMembersNanos = Statistics .newStackableTimer(" time spent in findmembers" , typerNanos)
69156984 val asSeenFromNanos = Statistics .newStackableTimer(" time spent in asSeenFrom" , typerNanos)
69166985 val baseTypeSeqNanos = Statistics .newStackableTimer(" time spent in baseTypeSeq" , typerNanos)
69176986 val baseClassesNanos = Statistics .newStackableTimer(" time spent in baseClasses" , typerNanos)
0 commit comments