@@ -668,7 +668,8 @@ trait Types extends api.Types { self: SymbolTable =>
668
668
* Note: unfortunately it doesn't work to exclude DEFERRED this way.
669
669
*/
670
670
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
672
673
673
674
def memberBasedOnName (name : Name , excludedFlags : Long ): Symbol =
674
675
findMember(name, excludedFlags, 0 , false )
@@ -1017,6 +1018,71 @@ trait Types extends api.Types { self: SymbolTable =>
1017
1018
if (alts.isEmpty) sym
1018
1019
else (baseClasses.head.newOverloaded(this , alts))
1019
1020
}
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
+ }
1020
1086
1021
1087
/**
1022
1088
* 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 =>
1123
1189
baseClasses.head.newOverloaded(this , members.toList)
1124
1190
}
1125
1191
}
1192
+
1126
1193
/** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */
1127
1194
def skolemsExceptMethodTypeParams : List [Symbol ] = {
1128
1195
var boundSyms : List [Symbol ] = List ()
@@ -6917,12 +6984,14 @@ object TypesStats {
6917
6984
val lubCount = Statistics .newCounter (" #toplevel lubs/glbs" )
6918
6985
val nestedLubCount = Statistics .newCounter (" #all lubs/glbs" )
6919
6986
val findMemberCount = Statistics .newCounter (" #findMember ops" )
6987
+ val findMembersCount = Statistics .newCounter (" #findMembers ops" )
6920
6988
val noMemberCount = Statistics .newSubCounter(" of which not found" , findMemberCount)
6921
6989
val multMemberCount = Statistics .newSubCounter(" of which multiple overloaded" , findMemberCount)
6922
6990
val typerNanos = Statistics .newTimer (" time spent typechecking" , " typer" )
6923
6991
val lubNanos = Statistics .newStackableTimer(" time spent in lubs" , typerNanos)
6924
6992
val subtypeNanos = Statistics .newStackableTimer(" time spent in <:<" , typerNanos)
6925
6993
val findMemberNanos = Statistics .newStackableTimer(" time spent in findmember" , typerNanos)
6994
+ val findMembersNanos = Statistics .newStackableTimer(" time spent in findmembers" , typerNanos)
6926
6995
val asSeenFromNanos = Statistics .newStackableTimer(" time spent in asSeenFrom" , typerNanos)
6927
6996
val baseTypeSeqNanos = Statistics .newStackableTimer(" time spent in baseTypeSeq" , typerNanos)
6928
6997
val baseClassesNanos = Statistics .newStackableTimer(" time spent in baseClasses" , typerNanos)
0 commit comments