@@ -56,7 +56,7 @@ trait MemberLookup {
56
56
57
57
query match {
58
58
case Query .StrictMemberId (id) =>
59
- localLookup(id , nearest).nextOption .map(_ -> id)
59
+ downwardLookup( List (id) , nearest).map(_ -> id)
60
60
case Query .QualifiedId (Query .Qual .This , _, rest) =>
61
61
downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
62
62
case Query .QualifiedId (Query .Qual .Package , _, rest) =>
@@ -101,43 +101,37 @@ trait MemberLookup {
101
101
sym.isCompleted && sym.info.exists
102
102
}
103
103
104
- private def localLookup (using Quotes )(query : String , owner : quotes.reflect.Symbol ): Iterator [quotes.reflect.Symbol ] = {
104
+ private def localLookup (using Quotes )(
105
+ sel : MemberLookup .Selector ,
106
+ owner : quotes.reflect.Symbol
107
+ ): Iterator [quotes.reflect.Symbol ] = {
105
108
import quotes .reflect ._
106
109
107
110
def findMatch (syms : Iterator [Symbol ]): Iterator [Symbol ] = {
108
- // Scaladoc overloading support allows terminal * (and they're meaningless)
109
- val cleanQuery = query.stripSuffix(" *" )
110
- val (q, forceTerm, forceType) =
111
- if cleanQuery endsWith " $" then
112
- (cleanQuery.init, true , false )
113
- else if cleanQuery endsWith " !" then
114
- (cleanQuery.init, false , true )
115
- else
116
- (cleanQuery, false , false )
117
-
118
111
def matches (s : Symbol ): Boolean =
119
- s.name == q && (
120
- if forceTerm then s.isTerm
121
- else if forceType then s.isType
122
- else true
123
- )
112
+ s.name == sel.ident && sel.kind. match {
113
+ case MemberLookup . SelectorKind . ForceTerm => s.isTerm
114
+ case MemberLookup . SelectorKind . ForceType => s.isType
115
+ case MemberLookup . SelectorKind . NoForce => true
116
+ }
124
117
125
118
def hackResolveModule (s : Symbol ): Symbol =
126
119
if s.flags.is(Flags .Module ) then s.moduleClass else s
127
120
128
121
// val syms0 = syms.toList
129
122
// val matched0 = syms0.filter(matches)
130
123
// if matched0.isEmpty then
131
- // println(s"Failed to look up $q in $owner; all members: {{{")
124
+ // println(s"Failed to look up ${sel.ident} in $owner; all members: {{{")
132
125
// syms0.foreach { s => println(s"\t$s") }
133
126
// println("}}}")
134
127
// val matched = matched0.iterator
135
128
136
129
// def showMatched() = matched0.foreach { s =>
137
130
// println(s"\t $s")
138
131
// }
139
- // println(s"localLookup in class ${owner} for `$q`{forceTerm=$forceTerm}: ")
132
+ // println(s"localLookup in class ${owner} for `${sel.ident}`{kind=${sel.kind}}:{{{ ")
140
133
// showMatched()
134
+ // println("}}}")
141
135
142
136
val matched = syms.filter(matches)
143
137
matched.map(hackResolveModule)
@@ -172,10 +166,22 @@ trait MemberLookup {
172
166
import quotes .reflect ._
173
167
query match {
174
168
case Nil => None
175
- case q :: Nil => localLookup(q, owner).nextOption
169
+ case q :: Nil =>
170
+ val sel = MemberLookup .Selector .fromString(q)
171
+ sel.kind match {
172
+ case MemberLookup .SelectorKind .NoForce =>
173
+ val lookedUp = localLookup(sel, owner).toSeq
174
+ // note: those flag lookups are necessary b/c for objects we return their classes
175
+ lookedUp.find(s => s.isType && ! s.flags.is(Flags .Module )).orElse(
176
+ lookedUp.find(s => s.isTerm || s.flags.is(Flags .Module ))
177
+ )
178
+ case _ =>
179
+ localLookup(sel, owner).nextOption
180
+
181
+ }
176
182
case q :: qs =>
177
- val lookedUp =
178
- localLookup(q , owner).toSeq
183
+ val sel = MemberLookup . Selector .fromString(q)
184
+ val lookedUp = localLookup(sel , owner).toSeq
179
185
180
186
if lookedUp.isEmpty then None else {
181
187
// tm/tp - term/type symbols which we looked up and which allow further lookup
@@ -198,4 +204,25 @@ trait MemberLookup {
198
204
}
199
205
}
200
206
201
- object MemberLookup extends MemberLookup
207
+ object MemberLookup extends MemberLookup {
208
+ enum SelectorKind {
209
+ case ForceTerm
210
+ case ForceType
211
+ case NoForce
212
+ }
213
+
214
+ case class Selector (ident : String , kind : SelectorKind )
215
+ object Selector {
216
+ def fromString (str : String ) = {
217
+ // Scaladoc overloading support allows terminal * (and they're meaningless)
218
+ val cleanStr = str.stripSuffix(" *" )
219
+
220
+ if cleanStr endsWith " $" then
221
+ Selector (cleanStr.init, SelectorKind .ForceTerm )
222
+ else if cleanStr endsWith " !" then
223
+ Selector (cleanStr.init, SelectorKind .ForceType )
224
+ else
225
+ Selector (cleanStr, SelectorKind .NoForce )
226
+ }
227
+ }
228
+ }
0 commit comments