Skip to content

Commit fa907b9

Browse files
Backport "Allow range selection on function parameter to select a parameter list" to LTS (#20937)
Backports #19777 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents f0d74b7 + 649ed7f commit fa907b9

File tree

2 files changed

+76
-5
lines changed

2 files changed

+76
-5
lines changed

presentation-compiler/src/main/dotty/tools/pc/SelectionRangeProvider.scala

+30-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import java.util as ju
66
import scala.jdk.CollectionConverters._
77
import scala.meta.pc.OffsetParams
88

9+
import dotty.tools.dotc.ast.tpd
910
import dotty.tools.dotc.core.Contexts.Context
1011
import dotty.tools.dotc.interactive.Interactive
1112
import dotty.tools.dotc.interactive.InteractiveDriver
1213
import dotty.tools.dotc.util.SourceFile
14+
import dotty.tools.dotc.util.SourcePosition
1315
import dotty.tools.pc.utils.MtagsEnrichments.*
1416

1517
import org.eclipse.lsp4j
@@ -46,11 +48,7 @@ class SelectionRangeProvider(
4648
Interactive.pathTo(driver.openedTrees(uri), pos)(using ctx)
4749

4850
val bareRanges = path
49-
.map { tree =>
50-
val selectionRange = new SelectionRange()
51-
selectionRange.setRange(tree.sourcePos.toLsp)
52-
selectionRange
53-
}
51+
.flatMap(selectionRangesFromTree(pos))
5452

5553
val comments =
5654
driver.compilationUnits.get(uri).map(_.comments).toList.flatten
@@ -79,6 +77,33 @@ class SelectionRangeProvider(
7977
}
8078
end selectionRange
8179

80+
/** Given a tree, create a seq of [[SelectionRange]]s corresponding to that tree. */
81+
private def selectionRangesFromTree(pos: SourcePosition)(tree: tpd.Tree)(using Context) =
82+
def toSelectionRange(srcPos: SourcePosition) =
83+
val selectionRange = new SelectionRange()
84+
selectionRange.setRange(srcPos.toLsp)
85+
selectionRange
86+
87+
val treeSelectionRange = toSelectionRange(tree.sourcePos)
88+
89+
tree match
90+
case tpd.DefDef(name, paramss, tpt, rhs) =>
91+
// If source position is within a parameter list, add a selection range covering that whole list.
92+
val selectedParams =
93+
paramss
94+
.iterator
95+
.flatMap: // parameter list to a sourcePosition covering the whole list
96+
case Seq(param) => Some(param.sourcePos)
97+
case params @ Seq(head, tail*) =>
98+
val srcPos = head.sourcePos
99+
val lastSpan = tail.last.span
100+
Some(SourcePosition(srcPos.source, srcPos.span union lastSpan, srcPos.outer))
101+
case Seq() => None
102+
.find(_.contains(pos))
103+
.map(toSelectionRange)
104+
selectedParams ++ Seq(treeSelectionRange)
105+
case _ => Seq(treeSelectionRange)
106+
82107
private def setParent(
83108
child: SelectionRange,
84109
parent: SelectionRange

presentation-compiler/test/dotty/tools/pc/tests/SelectionRangeSuite.scala

+46
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,49 @@ class SelectionRangeSuite extends BaseSelectionRangeSuite:
101101
|}<<region<<""".stripMargin
102102
)
103103
)
104+
105+
@Test def `function params` =
106+
check(
107+
"""|object Main extends App {
108+
| def func(a@@: Int, b: Int) =
109+
| a + b
110+
|}""".stripMargin,
111+
List[String](
112+
"""|object Main extends App {
113+
| def func(>>region>>a: Int<<region<<, b: Int) =
114+
| a + b
115+
|}""".stripMargin,
116+
"""|object Main extends App {
117+
| def func(>>region>>a: Int, b: Int<<region<<) =
118+
| a + b
119+
|}""".stripMargin,
120+
"""|object Main extends App {
121+
| >>region>>def func(a: Int, b: Int) =
122+
| a + b<<region<<
123+
|}""".stripMargin
124+
)
125+
)
126+
check(
127+
"""|object Main extends App {
128+
| val func = (a@@: Int, b: Int) =>
129+
| a + b
130+
|}""".stripMargin,
131+
List[String](
132+
"""|object Main extends App {
133+
| val func = (>>region>>a: Int<<region<<, b: Int) =>
134+
| a + b
135+
|}""".stripMargin,
136+
"""|object Main extends App {
137+
| val func = (>>region>>a: Int, b: Int<<region<<) =>
138+
| a + b
139+
|}""".stripMargin,
140+
"""|object Main extends App {
141+
| val func = >>region>>(a: Int, b: Int) =>
142+
| a + b<<region<<
143+
|}""".stripMargin,
144+
"""|object Main extends App {
145+
| >>region>>val func = (a: Int, b: Int) =>
146+
| a + b<<region<<
147+
|}""".stripMargin
148+
)
149+
)

0 commit comments

Comments
 (0)