Skip to content

Commit

Permalink
Add selection range for a parameter list in a function/method
Browse files Browse the repository at this point in the history
Given a query as
```scala
def func(a@@: Int, b: Int)(c: Int) =
    a + b + c
```
range selection will now let you choose `a: Int, b: Int`.
The previous options are `a: Int` and the whole definition of `func`.
  • Loading branch information
natsukagami committed Feb 26, 2024
1 parent 2e684d8 commit 9f61ed5
Showing 1 changed file with 30 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import java.util as ju
import scala.jdk.CollectionConverters._
import scala.meta.pc.OffsetParams

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.interactive.Interactive
import dotty.tools.dotc.interactive.InteractiveDriver
import dotty.tools.dotc.util.SourceFile
import dotty.tools.dotc.util.SourcePosition
import dotty.tools.pc.utils.MtagsEnrichments.*

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

val bareRanges = path
.map { tree =>
val selectionRange = new SelectionRange()
selectionRange.setRange(tree.sourcePos.toLsp)
selectionRange
}
.flatMap(selectionRangesFromTree(pos))

val comments =
driver.compilationUnits.get(uri).map(_.comments).toList.flatten
Expand Down Expand Up @@ -79,6 +77,33 @@ class SelectionRangeProvider(
}
end selectionRange

/** Given a tree, create a seq of [[SelectionRange]]s corresponding to that tree. */
private def selectionRangesFromTree(pos: SourcePosition)(tree: tpd.Tree)(using Context) =
def toSelectionRange(srcPos: SourcePosition) =
val selectionRange = new SelectionRange()
selectionRange.setRange(srcPos.toLsp)
selectionRange

val treeSelectionRange = toSelectionRange(tree.sourcePos)

tree match
case tpd.DefDef(name, paramss, tpt, rhs) =>
// If source position is within a parameter list, add a selection range covering that whole list.
val selectedParams =
paramss
.iterator
.flatMap: // parameter list to a sourcePosition covering the whole list
case Seq(param) => Some(param.sourcePos)
case params @ Seq(head, tail*) =>
val srcPos = head.sourcePos
val lastSpan = tail.last.span
Some(SourcePosition(srcPos.source, srcPos.span union lastSpan, srcPos.outer))
case Seq() => None
.find(_.contains(pos))
.map(toSelectionRange)
selectedParams ++ Seq(treeSelectionRange)
case _ => Seq(treeSelectionRange)

private def setParent(
child: SelectionRange,
parent: SelectionRange
Expand Down

0 comments on commit 9f61ed5

Please sign in to comment.