@@ -12,7 +12,8 @@ import Contexts.*
1212import Symbols .*
1313import Flags .*
1414import Names .Name
15- import StdNames .nme
15+ import Types ._
16+ import StdNames .{nme , tpnme }
1617import NameOps .*
1718import Denotations .StaleSymbol
1819import util .Spans .Span
@@ -379,6 +380,11 @@ object ExtractSemanticDB:
379380 traverseAnnotsOfDefinition(ctorSym)
380381 ctorParams(tree.constr.termParamss, tree.constr.leadingTypeParams, tree.body)
381382 registerDefinition(ctorSym, tree.constr.nameSpan.startPos, Set .empty, tree.source)
383+ case ReflectiveSelectableApply (qual, memberName, sel) =>
384+ traverse(sel.qualifier)
385+ val qualTpe = qual.symbol.info
386+ val member = extractRefinement(qualTpe, memberName)
387+ member.foreach(sym => registerUse(sym.symbolName, sel.nameSpan, tree.source))
382388 case tree : Apply if tree.fun.symbol.exists =>
383389 @ tu lazy val genParamSymbol : Name => String = tree.fun.symbol.funParamSymbol
384390 traverse(tree.fun)
@@ -467,6 +473,35 @@ object ExtractSemanticDB:
467473
468474 end traverse
469475
476+ private def extractRefinement (site : Type , memberName : String )(using Context ): Option [Symbol ] =
477+ def loop (site : Type , owner : Symbol ): Option [Symbol ] =
478+ site match
479+ case RefinedType (_, name, info) if name.toString() == memberName =>
480+ val flags = info match
481+ case _ : (ExprType | MethodOrPoly ) => Method
482+ case _ => EmptyFlags
483+ val symbolOwner = newSymbol(owner, tpnme.REFINE_CLASS , Trait , NoType )
484+ val symbol = newSymbol(symbolOwner, name, flags, info)
485+ Some (symbol)
486+ case RefinedType (parent, _, _) => loop(parent, owner)
487+ case tp : ExprType => loop(tp.superType, owner)
488+ case tp : TypeProxy =>
489+ loop(tp.superType, tp.typeSymbol)
490+ case _ =>
491+ None
492+ loop(site, NoSymbol )
493+
494+ private object ReflectiveSelectableApply :
495+ def unapply (tree : Tree )(using Context ): Option [(Tree , String , Select )] = tree match
496+ case Apply (
497+ sel @ Select (Apply (Ident (reflSelectable), List (qual)), fun),
498+ Literal (Constants .Constant (memberName : String )) :: args
499+ ) if reflSelectable == nme.reflectiveSelectable &&
500+ (fun == nme.selectDynamic || fun == nme.applyDynamic) =>
501+ Some (qual, memberName, sel)
502+ case _ => None
503+ end ReflectiveSelectableApply
504+
470505 private object PatternValDef :
471506
472507 def unapply (tree : ValDef )(using Context ): Option [(Tree , Tree )] = tree.rhs match
0 commit comments