Skip to content

Commit

Permalink
bugfix: rename end marker for lolac definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Nov 8, 2023
1 parent 213e575 commit f46ca8c
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 15 deletions.
43 changes: 40 additions & 3 deletions mtags/src/main/scala-3/scala/meta/internal/pc/PcCollector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ abstract class PcCollector[T](
case _ => rawPath
def collect(
parent: Option[Tree]
)(tree: Tree, pos: SourcePosition, symbol: Option[Symbol]): T
)(tree: Tree | EndMarker, pos: SourcePosition, symbol: Option[Symbol]): T

/**
* @return (adjusted position, should strip backticks)
Expand Down Expand Up @@ -435,7 +435,7 @@ abstract class PcCollector[T](
parent: Option[Tree],
): Set[T] =
def collect(
tree: Tree,
tree: Tree | EndMarker,
pos: SourcePosition,
symbol: Option[Symbol] = None,
) =
Expand Down Expand Up @@ -493,6 +493,12 @@ abstract class PcCollector[T](
case df: NamedDefTree
if df.span.isCorrect && df.nameSpan.isCorrect &&
filter(df) && !isGeneratedGiven(df) =>
def collectEndMarker =
EndMarker.getPosition(df, pos, sourceText).map {
collect(EndMarker(df.symbol), _)
}
end collectEndMarker

val annots = collectTrees(df.mods.annotations)
val traverser =
new PcCollector.DeepFolderWithParent[Set[T]](
Expand All @@ -502,7 +508,7 @@ abstract class PcCollector[T](
occurences + collect(
df,
pos.withSpan(df.nameSpan),
)
) ++ collectEndMarker
) { case (set, tree) =>
traverser(set, tree)
}
Expand Down Expand Up @@ -667,3 +673,34 @@ case class ExtensionParamOccurence(
sym: Symbol,
methods: List[untpd.Tree],
)

case class EndMarker(symbol: Symbol)

object EndMarker:
/**
* Matches end marker line from start to the name's beginning.
* E.g.
* end /* some comment */
*/
private val endMarkerRegex = """.*end(/\*.*\*/|\s)+""".r
def getPosition(df: NamedDefTree, pos: SourcePosition, sourceText: String)(
implicit ct: Context
): Option[SourcePosition] =
val name = df.name.toString()
val endMarkerLine =
sourceText.slice(df.span.start, df.span.end).split('\n').last
val index = endMarkerLine.length() - name.length()
if index < 0 then None
else
val (possiblyEndMarker, possiblyEndMarkerName) =
endMarkerLine.splitAt(index)
Option.when(
possiblyEndMarkerName == name &&
endMarkerRegex.matches(possiblyEndMarker)
)(
pos
.withStart(df.span.end - name.length())
.withEnd(df.span.end)
)
end getPosition
end EndMarker
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class PcDocumentHighlightProvider(
def collect(
parent: Option[Tree]
)(
tree: Tree,
tree: Tree | EndMarker,
toAdjust: SourcePosition,
sym: Option[Symbol],
): DocumentHighlight =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,26 @@ import org.eclipse.{lsp4j as l}
final class PcInlineValueProviderImpl(
val driver: InteractiveDriver,
val params: OffsetParams,
) extends PcCollector[Occurence](driver, params)
) extends PcCollector[Option[Occurence]](driver, params)
with InlineValueProvider:

val text = params.text.toCharArray()

val position: l.Position = pos.toLsp.getStart()

override def collect(parent: Option[Tree])(
tree: Tree,
tree: Tree | EndMarker,
pos: SourcePosition,
sym: Option[Symbol],
): Occurence =
): Option[Occurence] =
val (adjustedPos, _) = adjust(pos)
Occurence(tree, parent, adjustedPos)
tree match
case tree: Tree => Some(Occurence(tree, parent, adjustedPos))
case _ => None

override def defAndRefs(): Either[String, (Definition, List[Reference])] =
val newctx = driver.currentCtx.fresh.setCompilationUnit(unit)
val allOccurences = result()
val allOccurences = result().flatten
for
definition <- allOccurences
.collectFirst { case Occurence(defn: ValDef, _, pos) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ final class PcRenameProvider(

def collect(
parent: Option[Tree]
)(tree: Tree, toAdjust: SourcePosition, sym: Option[Symbol]): l.TextEdit =
)(
tree: Tree | EndMarker,
toAdjust: SourcePosition,
sym: Option[Symbol],
): l.TextEdit =
val (pos, stripBackticks) = adjust(toAdjust, forRename = true)
l.TextEdit(
pos.toLsp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class PcSemanticTokensProvider(
* 3. type parameters,
* In all those cases we don't have a specific value for sure.
*/
private def isDeclaration(tree: Tree) = tree match
private def isDeclaration(tree: Tree | EndMarker) = tree match
case df: ValOrDefDef => df.rhs.isEmpty
case df: TypeDef =>
df.rhs match
Expand All @@ -47,7 +47,8 @@ final class PcSemanticTokensProvider(
* that the compiler sees them as vals, as it's not clear
* if they should be declaration/definition at all.
*/
private def isDefinition(tree: Tree) = tree match
private def isDefinition(tree: Tree | EndMarker) = tree match
case _: EndMarker => true
case df: Bind => true
case df: ValOrDefDef =>
!df.rhs.isEmpty && !df.symbol.isAllOf(Flags.EnumCase)
Expand All @@ -60,8 +61,16 @@ final class PcSemanticTokensProvider(
object Collector extends PcCollector[Option[Node]](driver, params):
override def collect(
parent: Option[Tree]
)(tree: Tree, pos: SourcePosition, symbol: Option[Symbol]): Option[Node] =
val sym = symbol.fold(tree.symbol)(identity)
)(
tree: Tree | EndMarker,
pos: SourcePosition,
symbol: Option[Symbol],
): Option[Node] =
val sym =
tree match
case tree: Tree =>
symbol.fold(tree.symbol)(identity)
case EndMarker(sym) => sym
if !pos.exists || sym == null || sym == NoSymbol then None
else
Some(
Expand Down
24 changes: 24 additions & 0 deletions tests/cross/src/test/scala/tests/pc/PcRenameSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,28 @@ class PcRenameSuite extends BasePcRenameSuite {
| } yield b
|""".stripMargin,
)

check(
"end-marker".tag(IgnoreScala2),
"""|def <<he@@llo>>(a: Int) =
| ???
|end <<hello>>
|""".stripMargin,
)

check(
"end-marker-with-comment".tag(IgnoreScala2),
"""|def <<he@@llo>>(a: Int) =
| ???
|end /* a comment */ <<hello>> /* a comment */
|""".stripMargin,
)

check(
"end-marker-wrong".tag(IgnoreScala2),
"""|def <<f@@oo>> =
| def bar =
| ???
| end bar""".stripMargin,
)
}
6 changes: 6 additions & 0 deletions tests/input/src/main/scala-3/example/EndMarker.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

object EndMarker:
def foo =
1
end foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

object EndMarker/*EndMarker.scala*/:
def foo/*EndMarker.scala*/ =
1
end/*<no symbol>*/ foo/*EndMarker.scala*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*example(Package):6*/package example

/*example.EndMarker(Module):6*/object EndMarker:
/*example.EndMarker.foo(Method):5*/def foo =
1
end foo
3 changes: 2 additions & 1 deletion tests/unit/src/test/resources/expect/toplevels-scala3.expect
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ example/ColorEnum.scala -> example/Color#
example/Comments.scala -> example/Comments#
example/Companion.scala -> example/Companion#
example/Companion.scala -> example/Companion.
example/EndMarker.scala -> example/EndMarker.
example/EtaExpansion.scala -> example/EtaExpansion#
example/Extension.scala -> example/AbstractExtension#
example/Extension.scala -> example/Extension$package.
Expand Down Expand Up @@ -52,4 +53,4 @@ example/nested/LocalClass.scala -> example/nested/LocalClass#
example/nested/package.scala -> example/PackageObjectSibling#
example/nested/package.scala -> example/nested/package.
example/package.scala -> example/package.
example/type/Backtick.scala -> example/type/Backtick#
example/type/Backtick.scala -> example/type/Backtick#
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

object EndMarker/*example.EndMarker.*/:
def foo/*example.EndMarker.foo().*/ =
1
end foo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<<package>>/*keyword*/ <<example>>/*namespace*/

<<object>>/*keyword*/ <<EndMarker>>/*class*/:
<<def>>/*keyword*/ <<foo>>/*method,definition*/ =
<<1>>/*number*/
<<end>>/*keyword*/ <<foo>>/*method,definition*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

object EndMarker/*example.EndMarker.*/:
def foo/*example.EndMarker.foo().*/ =
1
end foo/*example.EndMarker.foo().*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package example

object EndMarker/*example.EndMarker.*/:
def foo =
1
end foo

0 comments on commit f46ca8c

Please sign in to comment.