Skip to content

Commit

Permalink
Expand Selection in comments for Scala 2 (#6109)
Browse files Browse the repository at this point in the history
* wip

* ok

* test

* wip

* test

* address reviews

* use common SelectionRangeUtils

* test

* Update mtags/src/main/scala-2/scala/meta/internal/pc/SelectionRangeProvider.scala

Co-authored-by: Katarzyna Marek <[email protected]>

---------

Co-authored-by: Katarzyna Marek <[email protected]>
  • Loading branch information
doofin and kasiaMarek authored Apr 11, 2024
1 parent 0887abd commit 08bcf0d
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package scala.meta.internal.pc

import java.{util => ju}

import scala.meta._
import scala.meta.internal.jdk.CollectionConverters._
import scala.meta.pc.OffsetParams

Expand Down Expand Up @@ -39,17 +40,22 @@ class SelectionRangeProvider(
// lastVisitedParentTrees that will contain the exact tree structure we
// need to create the selection range, starting from the position
val _ = locateUntyped(pos)

val bareRanges = lastVisitedParentTrees
.map { tree: Tree =>
val selectionRange = new SelectionRange()
selectionRange.setRange(tree.pos.toLsp)
selectionRange
}

bareRanges.reduceRight(setParent)
}
val commentRanges =
getCommentRanges(pos, lastVisitedParentTrees, param.text()).map { x =>
new SelectionRange() { setRange(x.toLsp) }
}.toList

(commentRanges ++ bareRanges)
.reduceRightOption(setParent)
.getOrElse(new SelectionRange())
}
selectionRanges
}

Expand Down Expand Up @@ -84,4 +90,35 @@ class SelectionRangeProvider(
}
}

import compiler._
def getCommentRanges(
cursorPos: Position,
path: List[Tree],
srcText: String
): List[Position] = {

val (treeStart, treeEnd) = path.headOption
.map(t => (t.pos.start, t.pos.end))
.getOrElse((0, srcText.size))

// only tokenize comments from first range to reduce computation
val srcSliced = srcText.slice(treeStart, treeEnd)

val tokens = srcSliced.tokenize.toOption

if (tokens.isEmpty) Nil
else
SelectionRangeUtils
.commentRangesFromTokens(
tokens.toList.flatten,
cursorPos.start,
treeStart
) map { case (s, e) =>
cursorPos
.withStart(s)
.withEnd(e)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import java.util as ju

import scala.jdk.CollectionConverters.*

import scala.meta.inputs.Position
import scala.meta.internal.mtags.MtagsEnrichments.*
import scala.meta.internal.pc.SelectionRangeProvider.*
import scala.meta.pc.OffsetParams
import scala.meta.tokens.Token

import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.interactive.Interactive
Expand Down Expand Up @@ -103,30 +101,8 @@ object SelectionRangeProvider:

import scala.meta.dialects.Scala3
import scala.meta.*
import scala.meta.Token.Comment
import dotty.tools.dotc.ast.tpd

def commentRangesFromTokens(
tokenList: List[Token],
cursorStart: SourcePosition,
offsetStart: Int,
) =
val cursorStartShifted = cursorStart.start - offsetStart

tokenList
.collect { case x: Comment =>
(x.start, x.end, x.pos)
}
.collect {
case (commentStart, commentEnd, _)
if commentStart <= cursorStartShifted && cursorStartShifted <= commentEnd =>
cursorStart
.withStart(commentStart + offsetStart)
.withEnd(commentEnd + offsetStart)
.toLsp

}
end commentRangesFromTokens

/** get comments under cursor */
def getCommentRanges(
Expand All @@ -144,10 +120,15 @@ object SelectionRangeProvider:
val tokens = srcSliced.tokenize.toOption
if tokens.isEmpty then Nil
else
commentRangesFromTokens(
tokens.toList.flatten,
cursor,
treeStart,
)
SelectionRangeUtils
.commentRangesFromTokens(
tokens.toList.flatten,
cursor.start,
treeStart
) map { case (s, e) =>
cursor
.withStart(s)
.withEnd(e).toLsp
}
end getCommentRanges
end SelectionRangeProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package scala.meta.internal.pc

import scala.meta.tokens.Token
import scala.meta.tokens.Token.Comment

object SelectionRangeUtils {

/**
* common part for scala 2/3 for selection expansion in comment
*
* @param tokenList
* @param cursorStart
* @param offsetStart
* @return
*/
def commentRangesFromTokens(
tokenList: List[Token],
cursorStart: Int,
offsetStart: Int
): List[(Int, Int)] = {
val cursorStartShifted = cursorStart - offsetStart

tokenList
.collect { case x: Comment =>
(x.start, x.end, x.pos)
}
.collect {
case (commentStart, commentEnd, _)
if commentStart <= cursorStartShifted && cursorStartShifted <= commentEnd =>
(commentStart + offsetStart, commentEnd + offsetStart)

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ package tests.pc

class SelectionRangeCommentSuite extends BaseSelectionRangeSuite {

override def ignoreScalaVersion: Option[IgnoreScalaVersion] = Some(
IgnoreScala2
)

check(
"match",
"""|object Main extends App {
Expand All @@ -22,15 +18,7 @@ class SelectionRangeCommentSuite extends BaseSelectionRangeSuite {
| a <- Some(1)
| b <- Some(2)
| } yield a + b
|}""".stripMargin,
"""|object Main extends >>region>>App {
| /*comment*/
| val total = for {
| a <- Some(1)
| b <- Some(2)
| } yield a + b<<region<<
|}
|""".stripMargin
|}""".stripMargin
)
)

Expand Down

0 comments on commit 08bcf0d

Please sign in to comment.