Skip to content

Commit d981e08

Browse files
Florian3ktgodzik
authored andcommitted
Compare span points in pathTo to determine best span (scala#23581)
Closes scala#22207 [Cherry-picked 98c594f]
1 parent 5c077f0 commit d981e08

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

compiler/src/dotty/tools/dotc/ast/NavigateAST.scala

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,29 @@ object NavigateAST {
9494
* When choosing better fit we compare spans. If candidate span has starting or ending point inside (exclusive)
9595
* current best fit it is selected as new best fit. This means that same spans are failing the first predicate.
9696
*
97-
* In case when spans start and end at same offsets we prefer non synthethic one.
97+
* In case when spans start and end at same offsets we prefer non synthethic one,
98+
* and then one with better point (see isBetterPoint below).
9899
*/
99100
def isBetterFit(currentBest: List[Positioned], candidate: List[Positioned]): Boolean =
100101
if currentBest.isEmpty && candidate.nonEmpty then true
101102
else if currentBest.nonEmpty && candidate.nonEmpty then
102103
val bestSpan = currentBest.head.span
103104
val candidateSpan = candidate.head.span
104105

105-
bestSpan != candidateSpan &&
106-
envelops(bestSpan, candidateSpan) ||
107-
bestSpan.contains(candidateSpan) && bestSpan.isSynthetic && !candidateSpan.isSynthetic
106+
def isBetterPoint =
107+
// Given two spans with same end points,
108+
// we compare their points in relation to the point we are looking for (span.point)
109+
// The candidate (candidateSpan.point) is better than what we have so far (bestSpan.point), when:
110+
// 1) candidate is closer to target from the right
111+
span.point <= candidateSpan.point && candidateSpan.point < bestSpan.point
112+
// 2) candidate is closer to target from the left
113+
|| bestSpan.point < candidateSpan.point && candidateSpan.point <= span.point
114+
// 3) candidate is to on the left side of target, and best so far is on the right
115+
|| candidateSpan.point <= span.point && span.point < bestSpan.point
116+
117+
bestSpan != candidateSpan && envelops(bestSpan, candidateSpan)
118+
|| bestSpan.contains(candidateSpan) && bestSpan.isSynthetic && !candidateSpan.isSynthetic
119+
|| candidateSpan.start == bestSpan.start && candidateSpan.end == bestSpan.end && isBetterPoint
108120
else false
109121

110122
def isRecoveryTree(sel: untpd.Select): Boolean =

presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTermSuite.scala

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,3 +747,39 @@ class HoverTermSuite extends BaseHoverSuite:
747747
|""".stripMargin,
748748
"def substring(x$0: Int, x$1: Int): String".hover
749749
)
750+
751+
@Test def `multiple-valdefs-1` =
752+
check(
753+
"""|object O {
754+
| val x@@x, yy, zz = 1
755+
|}
756+
|""".stripMargin,
757+
"val xx: Int".hover
758+
)
759+
760+
@Test def `multiple-valdefs-2` =
761+
check(
762+
"""|object O {
763+
| val xx, y@@y, zz = 1
764+
|}
765+
|""".stripMargin,
766+
"val yy: Int".hover
767+
)
768+
769+
@Test def `multiple-valdefs-3` =
770+
check(
771+
"""|object O {
772+
| val xx, yy, z@@z = 1
773+
|}
774+
|""".stripMargin,
775+
"val zz: Int".hover
776+
)
777+
778+
@Test def `multiple-valdefs-4` =
779+
check(
780+
"""|object O {
781+
| val xx, thisIsAVeryLongNa@@me, zz = 1
782+
|}
783+
|""".stripMargin,
784+
"val thisIsAVeryLongName: Int".hover
785+
)

0 commit comments

Comments
 (0)