@@ -42,6 +42,7 @@ class PcInlayHintsProvider(
4242 val source =
4343 SourceFile .virtual(filePath.toString, sourceText)
4444 driver.run(uri, source)
45+ given InlayHintsParams = params
4546
4647 given InferredType .Text = InferredType .Text (text)
4748 given ctx : Context = driver.currentCtx
@@ -65,7 +66,7 @@ class PcInlayHintsProvider(
6566 tree : Tree ,
6667 ): InlayHints =
6768 tree match
68- case ImplicitConversion (symbol, range) if params.implicitConversions() =>
69+ case ImplicitConversion (symbol, range) =>
6970 val adjusted = adjustPos(range)
7071 inlayHints
7172 .add(
@@ -78,8 +79,7 @@ class PcInlayHintsProvider(
7879 LabelPart (" )" ) :: Nil ,
7980 InlayHintKind .Parameter ,
8081 )
81- case ImplicitParameters (symbols, pos, allImplicit)
82- if params.implicitParameters() =>
82+ case ImplicitParameters (symbols, pos, allImplicit) =>
8383 val labelParts = symbols.map(s => List (labelPart(s, s.decodedName)))
8484 val label =
8585 if allImplicit then labelParts.separated(" (using " , " , " , " )" )
@@ -89,22 +89,22 @@ class PcInlayHintsProvider(
8989 label,
9090 InlayHintKind .Parameter ,
9191 )
92- case ValueOf (label, pos) if params.implicitParameters() =>
92+ case ValueOf (label, pos) =>
9393 inlayHints.add(
9494 adjustPos(pos).toLsp,
9595 LabelPart (" (" ) :: LabelPart (label) :: List (LabelPart (" )" )),
9696 InlayHintKind .Parameter ,
9797 )
9898 case TypeParameters (tpes, pos, sel)
99- if params.typeParameters() && ! syntheticTupleApply(sel) =>
99+ if ! syntheticTupleApply(sel) =>
100100 val label = tpes.map(toLabelParts(_, pos)).separated(" [" , " , " , " ]" )
101101 inlayHints.add(
102102 adjustPos(pos).endPos.toLsp,
103103 label,
104104 InlayHintKind .Type ,
105105 )
106106 case InferredType (tpe, pos, defTree)
107- if params.inferredTypes() && ! isErrorTpe(tpe) =>
107+ if ! isErrorTpe(tpe) =>
108108 val adjustedPos = adjustPos(pos).endPos
109109 if inlayHints.containsDef(adjustedPos.start) then inlayHints
110110 else
@@ -191,14 +191,16 @@ class PcInlayHintsProvider(
191191end PcInlayHintsProvider
192192
193193object ImplicitConversion :
194- def unapply (tree : Tree )(using Context ) =
195- tree match
196- case Apply (fun : Ident , args) if isSynthetic(fun) =>
197- implicitConversion(fun, args)
198- case Apply (Select (fun, name), args)
199- if name == nme.apply && isSynthetic(fun) =>
200- implicitConversion(fun, args)
201- case _ => None
194+ def unapply (tree : Tree )(using params : InlayHintsParams , ctx : Context ) =
195+ if (params.implicitConversions()) {
196+ tree match
197+ case Apply (fun : Ident , args) if isSynthetic(fun) =>
198+ implicitConversion(fun, args)
199+ case Apply (Select (fun, name), args)
200+ if name == nme.apply && isSynthetic(fun) =>
201+ implicitConversion(fun, args)
202+ case _ => None
203+ } else None
202204 private def isSynthetic (tree : Tree )(using Context ) =
203205 tree.span.isSynthetic && tree.symbol.isOneOf(Flags .GivenOrImplicit )
204206
@@ -212,52 +214,64 @@ object ImplicitConversion:
212214end ImplicitConversion
213215
214216object ImplicitParameters :
215- def unapply (tree : Tree )(using Context ) =
216- tree match
217- case Apply (fun, args)
218- if args.exists(isSyntheticArg) && ! tree.sourcePos.span.isZeroExtent =>
219- val (implicitArgs, providedArgs) = args.partition(isSyntheticArg)
220- val allImplicit = providedArgs.isEmpty || providedArgs.forall {
221- case Ident (name) => name == nme.MISSING
222- case _ => false
223- }
224- val pos = implicitArgs.head.sourcePos
225- Some (implicitArgs.map(_.symbol), pos, allImplicit)
226- case _ => None
217+ def unapply (tree : Tree )(using params : InlayHintsParams , ctx : Context ) =
218+ if (params.implicitParameters()) {
219+ tree match
220+ case Apply (fun, args)
221+ if args.exists(isSyntheticArg) && ! tree.sourcePos.span.isZeroExtent =>
222+ val (implicitArgs, providedArgs) = args.partition(isSyntheticArg)
223+ val allImplicit = providedArgs.isEmpty || providedArgs.forall {
224+ case Ident (name) => name == nme.MISSING
225+ case _ => false
226+ }
227+ val pos = implicitArgs.head.sourcePos
228+ Some (implicitArgs.map(_.symbol), pos, allImplicit)
229+ case _ => None
230+ } else None
227231
228232 private def isSyntheticArg (tree : Tree )(using Context ) = tree match
229233 case tree : Ident =>
230- tree.span.isSynthetic && tree.symbol.isOneOf(Flags .GivenOrImplicit )
234+ tree.span.isSynthetic && tree.symbol.isOneOf(Flags .GivenOrImplicit ) &&
235+ ! isQuotes(tree)
231236 case _ => false
237+
238+ // Decorations for Quotes are rarely useful
239+ private def isQuotes (tree : Tree )(using Context ) =
240+ tree.tpe.typeSymbol == defn.QuotesClass
241+
232242end ImplicitParameters
233243
234244object ValueOf :
235- def unapply (tree : Tree )(using Context ) =
236- tree match
237- case Apply (ta @ TypeApply (fun, _), _)
238- if fun.span.isSynthetic && isValueOf(fun) =>
239- Some (
240- " new " + tpnme.valueOf.decoded.capitalize + " (...)" ,
241- fun.sourcePos,
242- )
243- case _ => None
245+ def unapply (tree : Tree )(using params : InlayHintsParams , ctx : Context ) =
246+ if (params.implicitParameters()) {
247+ tree match
248+ case Apply (ta @ TypeApply (fun, _), _)
249+ if fun.span.isSynthetic && isValueOf(fun) =>
250+ Some (
251+ " new " + tpnme.valueOf.decoded.capitalize + " (...)" ,
252+ fun.sourcePos,
253+ )
254+ case _ => None
255+ } else None
244256 private def isValueOf (tree : Tree )(using Context ) =
245257 val symbol = tree.symbol.maybeOwner
246258 symbol.name.decoded == tpnme.valueOf.decoded.capitalize
247259end ValueOf
248260
249261object TypeParameters :
250- def unapply (tree : Tree )(using Context ) =
251- tree match
252- case TypeApply (sel : Select , _) if sel.isForComprehensionMethod => None
253- case TypeApply (fun, args) if inferredTypeArgs(args) =>
254- val pos = fun match
255- case sel : Select if sel.isInfix =>
256- sel.sourcePos.withEnd(sel.nameSpan.end)
257- case _ => fun.sourcePos
258- val tpes = args.map(_.typeOpt.stripTypeVar.widen.finalResultType)
259- Some ((tpes, pos.endPos, fun))
260- case _ => None
262+ def unapply (tree : Tree )(using params : InlayHintsParams , ctx : Context ) =
263+ if (params.typeParameters()) {
264+ tree match
265+ case TypeApply (sel : Select , _)
266+ if sel.isForComprehensionMethod || sel.isInfix ||
267+ sel.symbol.name == nme.unapply =>
268+ None
269+ case TypeApply (fun, args) if inferredTypeArgs(args) =>
270+ val tpes = args.map(_.tpe.stripTypeVar.widen.finalResultType)
271+ Some ((tpes, fun.sourcePos.endPos, fun))
272+ case _ => None
273+ } else None
274+
261275 private def inferredTypeArgs (args : List [Tree ]): Boolean =
262276 args.forall {
263277 case tt : TypeTree if tt.span.exists && ! tt.span.isZeroExtent => true
@@ -270,29 +284,35 @@ object InferredType:
270284 object Text :
271285 def apply (text : Array [Char ]): Text = text
272286
273- def unapply (tree : Tree )(using text : Text , cxt : Context ) =
274- tree match
275- case vd @ ValDef (_, tpe, _)
276- if isValidSpan(tpe.span, vd.nameSpan) &&
277- ! vd.symbol.is(Flags .Enum ) &&
278- ! isValDefBind(text, vd) =>
279- if vd.symbol == vd.symbol.sourceSymbol then
280- Some (tpe.typeOpt, tpe.sourcePos.withSpan(vd.nameSpan), vd)
281- else None
282- case vd @ DefDef (_, _, tpe, _)
283- if isValidSpan(tpe.span, vd.nameSpan) &&
284- tpe.span.start >= vd.nameSpan.end &&
285- ! vd.symbol.isConstructor &&
286- ! vd.symbol.is(Flags .Mutable ) =>
287- if vd.symbol == vd.symbol.sourceSymbol then
288- Some (tpe.typeOpt, tpe.sourcePos, vd)
289- else None
290- case bd @ Bind (
291- name,
292- Ident (nme.WILDCARD ),
293- ) =>
294- Some (bd.symbol.info, bd.namePos, bd)
295- case _ => None
287+ def unapply (tree : Tree )(using params : InlayHintsParams , text : Text , ctx : Context ) =
288+ if (params.inferredTypes()) {
289+ tree match
290+ case vd @ ValDef (_, tpe, _)
291+ if isValidSpan(tpe.span, vd.nameSpan) &&
292+ ! vd.symbol.is(Flags .Enum ) &&
293+ (isNotInUnapply(vd) || params.hintsInPatternMatch()) &&
294+ ! isValDefBind(text, vd) =>
295+ if vd.symbol == vd.symbol.sourceSymbol then
296+ Some (tpe.tpe, tpe.sourcePos.withSpan(vd.nameSpan), vd)
297+ else None
298+ case vd @ DefDef (_, _, tpe, _)
299+ if isValidSpan(tpe.span, vd.nameSpan) &&
300+ tpe.span.start >= vd.nameSpan.end &&
301+ ! vd.symbol.isConstructor &&
302+ ! vd.symbol.is(Flags .Mutable ) =>
303+ if vd.symbol == vd.symbol.sourceSymbol then
304+ Some (tpe.tpe, tpe.sourcePos, vd)
305+ else None
306+ case bd @ Bind (
307+ name,
308+ Ident (nme.WILDCARD ),
309+ ) if ! bd.span.isZeroExtent && bd.symbol.isTerm && params.hintsInPatternMatch() =>
310+ Some (bd.symbol.info, bd.namePos, bd)
311+ case _ => None
312+ } else None
313+
314+ private def isNotInUnapply (vd : ValDef )(using Context ) =
315+ vd.rhs.span.exists && vd.rhs.span.start > vd.nameSpan.end
296316
297317 private def isValidSpan (tpeSpan : Span , nameSpan : Span ): Boolean =
298318 tpeSpan.isZeroExtent &&
0 commit comments