@@ -985,6 +985,9 @@ trait Types
985
985
else (baseClasses.head.newOverloaded(this , alts))
986
986
}
987
987
988
+ // !!!
989
+ // !!! DUPLICATED LOGIC ALERT, edits in `findMembers` here must be replicated in `findMember`.
990
+ // !!!
988
991
def findMembers (excludedFlags : Long , requiredFlags : Long ): Scope = {
989
992
def findMembersInternal : Scope = {
990
993
var members : Scope = null
@@ -996,6 +999,8 @@ trait Types
996
999
var excluded = excludedFlags | DEFERRED
997
1000
var continue = true
998
1001
var self : Type = null
1002
+ var seenFirstNonRefinementClass : Boolean = false
1003
+ var refinementParents : List [Symbol ] = Nil
999
1004
while (continue) {
1000
1005
continue = false
1001
1006
val bcs0 = baseClasses
@@ -1008,34 +1013,53 @@ trait Types
1008
1013
val flags = sym.flags
1009
1014
if ((flags & required) == required) {
1010
1015
val excl = flags & excluded
1011
- if (excl == 0L &&
1012
- (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
1013
- (bcs eq bcs0) ||
1014
- (flags & PrivateLocal ) != PrivateLocal ||
1015
- (bcs0.head.hasTransOwner(bcs.head)))) {
1016
+ val isMember = (
1017
+ excl == 0L
1018
+ && (
1019
+ (flags & PRIVATE ) != PRIVATE // non-privates are always members
1020
+ || (
1021
+ ! seenFirstNonRefinementClass // classes don't inherit privates
1022
+ || refinementParents.contains(bcs.head) // refinements inherit privates of direct parents
1023
+ )
1024
+ )
1025
+ )
1026
+
1027
+ // !!!
1028
+ // !!! DUPLICATED LOGIC ALERT, edits in `findMembers` here must be replicated in `findMember`.
1029
+ // !!!
1030
+ if (isMember) {
1016
1031
if (members eq null ) members = newFindMemberScope
1017
1032
var others : ScopeEntry = members.lookupEntry(sym.name)
1018
1033
var symtpe : Type = null
1019
- while ((others ne null ) && {
1020
- val other = others.sym
1021
- (other ne sym) &&
1022
- ((other.owner eq sym.owner) ||
1023
- (flags & PRIVATE ) != 0 || {
1024
- if (self eq null ) self = narrowForFindMember(this )
1025
- if (symtpe eq null ) symtpe = self.memberType(sym)
1026
- ! (self.memberType(other) matches symtpe)
1027
- })}) {
1028
- others = members lookupNextEntry others
1034
+ @ inline def computeSelfAndSymtpe () = {
1035
+ if (self eq null ) self = narrowForFindMember(this )
1036
+ if (symtpe eq null ) symtpe = self.memberType(sym)
1029
1037
}
1038
+ while ( (others ne null )
1039
+ && {
1040
+ val other = others.sym
1041
+ ( (other ne sym)
1042
+ && ( (other.owner eq sym.owner)
1043
+ || (flags & PRIVATE ) != 0
1044
+ || { computeSelfAndSymtpe(); ! (self.memberType(other) matches symtpe)}
1045
+ )
1046
+ )
1047
+ }
1048
+ ) others = members lookupNextEntry others
1030
1049
if (others eq null ) members enter sym
1031
1050
} else if (excl == DEFERRED ) {
1032
1051
continue = true
1033
1052
}
1034
1053
}
1035
1054
entry = entry.next
1036
1055
} // while (entry ne null)
1037
- // excluded = excluded | LOCAL
1038
- bcs = bcs.tail
1056
+ val sym = bcs.head
1057
+ if (sym.isRefinementClass)
1058
+ refinementParents :::= bcs.head.parentSymbols // keep track of direct parents of refinements
1059
+ else if (sym.isClass)
1060
+ seenFirstNonRefinementClass = true
1061
+
1062
+ bcs = bcs.tail // Unlike `findMember`, we can't when constructor here.
1039
1063
} // while (!bcs.isEmpty)
1040
1064
required |= DEFERRED
1041
1065
excluded &= ~ (DEFERRED .toLong)
@@ -1052,12 +1076,15 @@ trait Types
1052
1076
* Find member(s) in this type. If several members matching criteria are found, they are
1053
1077
* returned in an OverloadedSymbol
1054
1078
*
1055
- * @param name The member's name, where nme.ANYNAME means `unspecified`
1079
+ * @param name The member's name
1056
1080
* @param excludedFlags Returned members do not have these flags
1057
1081
* @param requiredFlags Returned members do have these flags
1058
1082
* @param stableOnly If set, return only members that are types or stable values
1059
1083
*/
1060
1084
// TODO: use narrow only for modules? (correct? efficiency gain?)
1085
+ // !!!
1086
+ // !!! DUPLICATED LOGIC ALERT, edits in `findMember` must be replicated in `findMembers`.
1087
+ // !!!
1061
1088
def findMember (name : Name , excludedFlags : Long , requiredFlags : Long , stableOnly : Boolean ): Symbol = {
1062
1089
def findMemberInternal : Symbol = {
1063
1090
var member : Symbol = NoSymbol
@@ -1070,9 +1097,9 @@ trait Types
1070
1097
var membertpe : Type = null
1071
1098
var required = requiredFlags
1072
1099
var excluded : Long = excludedFlags | DEFERRED
1073
- var seenFirstNonRefinementClass : Boolean = false
1074
1100
var continue = true
1075
1101
var self : Type = null
1102
+ var seenFirstNonRefinementClass : Boolean = false
1076
1103
var refinementParents : List [Symbol ] = Nil
1077
1104
1078
1105
while (continue) {
@@ -1097,6 +1124,10 @@ trait Types
1097
1124
)
1098
1125
)
1099
1126
)
1127
+
1128
+ // !!!
1129
+ // !!! DUPLICATED LOGIC ALERT, edits in `findMember` must be replicated in `findMembers`.
1130
+ // !!!
1100
1131
if (isMember) {
1101
1132
if (name.isTypeName || (stableOnly && sym.isStable && ! sym.hasVolatileType)) {
1102
1133
if (Statistics .canEnable) Statistics .popTimer(typeOpsStack, start)
@@ -1122,12 +1153,20 @@ trait Types
1122
1153
} else { // Already found 2 or more members
1123
1154
var others : List [Symbol ] = members
1124
1155
var symtpe : Type = null
1125
- @ inline def computeSelfAndSymtpe () = {
1126
- if (self eq null ) self = narrowForFindMember(this )
1127
- if (symtpe eq null ) symtpe = self.memberType(sym)
1156
+ @ inline
1157
+ def isNewMember (other : Symbol ): Boolean = {
1158
+ ( (other ne sym)
1159
+ && ( (other.owner eq sym.owner)
1160
+ || (flags & PRIVATE ) != 0
1161
+ || {
1162
+ if (self eq null ) { self = narrowForFindMember(this ); symtpe = self.memberType(sym) }
1163
+ ! (self.memberType(other) matches symtpe)
1164
+ }
1165
+ )
1166
+ )
1128
1167
}
1129
1168
while ( (others ne null )
1130
- && {
1169
+ && isNewMember(others.head)
1131
1170
val other = others.head
1132
1171
( (other ne sym)
1133
1172
&& ( (other.owner eq sym.owner)
@@ -1150,6 +1189,9 @@ trait Types
1150
1189
entry = decls lookupNextEntry entry
1151
1190
} // while (entry ne null)
1152
1191
1192
+ // !!!
1193
+ // !!! DUPLICATED LOGIC ALERT, edits in `findMember` must be replicated in `findMembers`.
1194
+ // !!!
1153
1195
val sym = bcs.head
1154
1196
if (sym.isRefinementClass)
1155
1197
refinementParents :::= bcs.head.parentSymbols // keep track of direct parents of refinements
0 commit comments