@@ -56,7 +56,7 @@ trait MemberLookup {
5656
5757 query match {
5858 case Query .StrictMemberId (id) =>
59- localLookup(id , nearest).nextOption .map(_ -> id)
59+ downwardLookup( List (id) , nearest).map(_ -> id)
6060 case Query .QualifiedId (Query .Qual .This , _, rest) =>
6161 downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
6262 case Query .QualifiedId (Query .Qual .Package , _, rest) =>
@@ -101,43 +101,37 @@ trait MemberLookup {
101101 sym.isCompleted && sym.info.exists
102102 }
103103
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 ] = {
105108 import quotes .reflect ._
106109
107110 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-
118111 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+ }
124117
125118 def hackResolveModule (s : Symbol ): Symbol =
126119 if s.flags.is(Flags .Module ) then s.moduleClass else s
127120
128121 // val syms0 = syms.toList
129122 // val matched0 = syms0.filter(matches)
130123 // 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: {{{")
132125 // syms0.foreach { s => println(s"\t$s") }
133126 // println("}}}")
134127 // val matched = matched0.iterator
135128
136129 // def showMatched() = matched0.foreach { s =>
137130 // println(s"\t $s")
138131 // }
139- // println(s"localLookup in class ${owner} for `$q`{forceTerm=$forceTerm}: ")
132+ // println(s"localLookup in class ${owner} for `${sel.ident}`{kind=${sel.kind}}:{{{ ")
140133 // showMatched()
134+ // println("}}}")
141135
142136 val matched = syms.filter(matches)
143137 matched.map(hackResolveModule)
@@ -172,10 +166,22 @@ trait MemberLookup {
172166 import quotes .reflect ._
173167 query match {
174168 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+ }
176182 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
179185
180186 if lookedUp.isEmpty then None else {
181187 // tm/tp - term/type symbols which we looked up and which allow further lookup
@@ -198,4 +204,25 @@ trait MemberLookup {
198204 }
199205}
200206
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