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