Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1315eda

Browse files
zielinskyhenryxparker
andauthored
Porting XRayModeHints (#23891)
Porting scalameta/metals#7639 Co-authored-by: Henry Parker <henryxparker@gmail.com>
1 parent e227128 commit 1315eda

File tree

4 files changed

+410
-11
lines changed

4 files changed

+410
-11
lines changed

‎presentation-compiler/src/main/dotty/tools/pc/PcInlayHintsProvider.scala‎

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class PcInlayHintsProvider(
5454
val pos = driver.sourcePosition(params)
5555

5656
def provide(): List[InlayHint] =
57-
val deepFolder = DeepFolder[InlayHints](collectDecorations)
57+
val deepFolder = PcCollector.DeepFolderWithParent[InlayHints](collectDecorations)
5858
Interactive
5959
.pathTo(driver.openedTrees(uri), pos)(using driver.currentCtx)
6060
.headOption
@@ -68,11 +68,23 @@ class PcInlayHintsProvider(
6868
def collectDecorations(
6969
inlayHints: InlayHints,
7070
tree: Tree,
71+
parent: Option[Tree]
7172
): InlayHints =
73+
// XRay hints are not mutually exclusive with other hints, so they must be matched separately
74+
val firstPassHints = (tree, parent) match {
75+
case XRayModeHint(tpe, pos) =>
76+
inlayHints.addToBlock(
77+
adjustPos(pos).toLsp,
78+
LabelPart(": ") :: toLabelParts(tpe, pos),
79+
InlayHintKind.Type
80+
)
81+
case _ => inlayHints
82+
}
83+
7284
tree match
7385
case ImplicitConversion(symbol, range) =>
7486
val adjusted = adjustPos(range)
75-
inlayHints
87+
firstPassHints
7688
.add(
7789
adjusted.startPos.toLsp,
7890
labelPart(symbol, symbol.decodedName) :: LabelPart("(") :: Nil,
@@ -84,35 +96,35 @@ class PcInlayHintsProvider(
8496
InlayHintKind.Parameter,
8597
)
8698
case ImplicitParameters(trees, pos) =>
87-
inlayHints.add(
99+
firstPassHints.add(
88100
adjustPos(pos).toLsp,
89101
ImplicitParameters.partsFromImplicitArgs(trees).map((label, maybeSymbol) =>
90102
maybeSymbol match
91103
case Some(symbol) => labelPart(symbol, label)
92104
case None => LabelPart(label)
93105
),
94-
InlayHintKind.Parameter
106+
InlayHintKind.Parameter,
95107
)
96108
case ValueOf(label, pos) =>
97-
inlayHints.add(
109+
firstPassHints.add(
98110
adjustPos(pos).toLsp,
99111
LabelPart("(") :: LabelPart(label) :: List(LabelPart(")")),
100112
InlayHintKind.Parameter,
101113
)
102114
case TypeParameters(tpes, pos, sel)
103115
if !syntheticTupleApply(sel) =>
104116
val label = tpes.map(toLabelParts(_, pos)).separated("[", ", ", "]")
105-
inlayHints.add(
117+
firstPassHints.add(
106118
adjustPos(pos).endPos.toLsp,
107119
label,
108120
InlayHintKind.Type,
109121
)
110122
case InferredType(tpe, pos, defTree)
111123
if !isErrorTpe(tpe) =>
112124
val adjustedPos = adjustPos(pos).endPos
113-
if inlayHints.containsDef(adjustedPos.start) then inlayHints
125+
if firstPassHints.containsDef(adjustedPos.start) then firstPassHints
114126
else
115-
inlayHints
127+
firstPassHints
116128
.add(
117129
adjustedPos.toLsp,
118130
LabelPart(": ") :: toLabelParts(tpe, pos),
@@ -138,7 +150,7 @@ class PcInlayHintsProvider(
138150
pos.withStart(pos.start + 1)
139151

140152

141-
args.foldLeft(inlayHints) {
153+
args.foldLeft(firstPassHints) {
142154
case (ih, (name, pos0, isByName)) =>
143155
val pos = adjustPos(pos0)
144156
val isBlock = isBlockParam(pos)
@@ -158,7 +170,7 @@ class PcInlayHintsProvider(
158170
)
159171
else ih
160172
}
161-
case _ => inlayHints
173+
case _ => firstPassHints
162174

163175
private def toLabelParts(
164176
tpe: Type,
@@ -491,3 +503,55 @@ object Parameters:
491503
case _ => None
492504
else None
493505
end Parameters
506+
507+
object XRayModeHint:
508+
def unapply(trees: (Tree, Option[Tree]))(using params: InlayHintsParams, ctx: Context): Option[(Type, SourcePosition)] =
509+
if params.hintsXRayMode() then
510+
val (tree, parent) = trees
511+
val isParentApply = parent match
512+
case Some(_: Apply) => true
513+
case _ => false
514+
val isParentOnSameLine = parent match
515+
case Some(sel: Select) if sel.isForComprehensionMethod => false
516+
case Some(par) if par.sourcePos.exists && par.sourcePos.line == tree.sourcePos.line => true
517+
case _ => false
518+
519+
tree match
520+
/*
521+
anotherTree
522+
.innerSelect()
523+
*/
524+
case a @ Apply(inner, _)
525+
if inner.sourcePos.exists && !isParentOnSameLine && !isParentApply &&
526+
endsInSimpleSelect(a) && isEndOfLine(tree.sourcePos) =>
527+
Some((a.tpe.widen.deepDealiasAndSimplify, tree.sourcePos))
528+
/*
529+
innerTree
530+
.select
531+
*/
532+
case select @ Select(innerTree, _)
533+
if innerTree.sourcePos.exists && !isParentOnSameLine && !isParentApply &&
534+
isEndOfLine(tree.sourcePos) =>
535+
Some((select.tpe.widen.deepDealiasAndSimplify, tree.sourcePos))
536+
case _ => None
537+
else None
538+
539+
@tailrec
540+
private def endsInSimpleSelect(ap: Tree)(using ctx: Context): Boolean =
541+
ap match
542+
case Apply(sel: Select, _) =>
543+
sel.name != nme.apply && !isInfix(sel)
544+
case Apply(TypeApply(sel: Select, _), _) =>
545+
sel.name != nme.apply && !isInfix(sel)
546+
case Apply(innerTree @ Apply(_, _), _) =>
547+
endsInSimpleSelect(innerTree)
548+
case _ => false
549+
550+
private def isEndOfLine(pos: SourcePosition): Boolean =
551+
if pos.exists then
552+
val source = pos.source
553+
val end = pos.end
554+
end >= source.length || source(end) == '\n' || source(end) == '\r'
555+
else false
556+
557+
end XRayModeHint

‎presentation-compiler/test/dotty/tools/pc/base/BaseInlayHintsSuite.scala‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class BaseInlayHintsSuite extends BasePCSuite {
3434
inferredTypes = true,
3535
typeParameters = true,
3636
implicitParameters = true,
37+
hintsXRayMode = true,
3738
byNameParameters = true,
3839
implicitConversions = true,
3940
namedParameters = true,

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /