@@ -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 )
@@ -1016,6 +1017,71 @@ trait Types extends api.Types { self: SymbolTable =>
1016
1017
if (alts.isEmpty) sym
1017
1018
else (baseClasses.head.newOverloaded(this , alts))
1018
1019
}
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
+ }
1019
1085
1020
1086
/**
1021
1087
* 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 =>
1122
1188
baseClasses.head.newOverloaded(this , members.toList)
1123
1189
}
1124
1190
}
1191
+
1125
1192
/** The (existential or otherwise) skolems and existentially quantified variables which are free in this type */
1126
1193
def skolemsExceptMethodTypeParams : List [Symbol ] = {
1127
1194
var boundSyms : List [Symbol ] = List ()
@@ -6906,12 +6973,14 @@ object TypesStats {
6906
6973
val lubCount = Statistics .newCounter (" #toplevel lubs/glbs" )
6907
6974
val nestedLubCount = Statistics .newCounter (" #all lubs/glbs" )
6908
6975
val findMemberCount = Statistics .newCounter (" #findMember ops" )
6976
+ val findMembersCount = Statistics .newCounter (" #findMembers ops" )
6909
6977
val noMemberCount = Statistics .newSubCounter(" of which not found" , findMemberCount)
6910
6978
val multMemberCount = Statistics .newSubCounter(" of which multiple overloaded" , findMemberCount)
6911
6979
val typerNanos = Statistics .newTimer (" time spent typechecking" , " typer" )
6912
6980
val lubNanos = Statistics .newStackableTimer(" time spent in lubs" , typerNanos)
6913
6981
val subtypeNanos = Statistics .newStackableTimer(" time spent in <:<" , typerNanos)
6914
6982
val findMemberNanos = Statistics .newStackableTimer(" time spent in findmember" , typerNanos)
6983
+ val findMembersNanos = Statistics .newStackableTimer(" time spent in findmembers" , typerNanos)
6915
6984
val asSeenFromNanos = Statistics .newStackableTimer(" time spent in asSeenFrom" , typerNanos)
6916
6985
val baseTypeSeqNanos = Statistics .newStackableTimer(" time spent in baseTypeSeq" , typerNanos)
6917
6986
val baseClassesNanos = Statistics .newStackableTimer(" time spent in baseClasses" , typerNanos)
0 commit comments