Skip to content

Commit

Permalink
chore: backport changes from metals (#19452)
Browse files Browse the repository at this point in the history
Backports changes from 
- scalameta/metals#5891
- scalameta/metals#5982
  • Loading branch information
tgodzik authored Jan 17, 2024
2 parents 78c4da2 + 882f2c7 commit 57321f2
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 23 deletions.
29 changes: 16 additions & 13 deletions presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,20 @@ object HoverProvider:
val text = params.text().nn
val sourceFile = SourceFile.virtual(uri, text)
driver.run(uri, sourceFile)
val unit = driver.compilationUnits.get(uri)

given ctx: Context = driver.currentCtx
given ctx: Context =
val ctx = driver.currentCtx
unit.map(ctx.fresh.setCompilationUnit).getOrElse(ctx)
val pos = driver.sourcePosition(params)
val trees = driver.openedTrees(uri)
val path = unit
.map(unit => Interactive.pathTo(unit.tpdTree, pos.span))
.getOrElse(Interactive.pathTo(driver.openedTrees(uri), pos))
val indexedContext = IndexedContext(ctx)

def typeFromPath(path: List[Tree]) =
if path.isEmpty then NoType else path.head.tpe

val path = Interactive.pathTo(trees, pos)
val tp = typeFromPath(path)
val tpw = tp.widenTermRefExpr
// For expression we need to find all enclosing applies to get the exact generic type
Expand All @@ -72,7 +76,10 @@ object HoverProvider:
|path:
|- ${path.map(_.toString()).mkString("\n- ")}
|trees:
|- ${trees.map(_.toString()).mkString("\n- ")}
|- ${unit
.map(u => List(u.tpdTree))
.getOrElse(driver.openedTrees(uri).map(_.tree))
.map(_.toString()).mkString("\n- ")}
|""".stripMargin,
s"$uri::$posId"
)
Expand All @@ -83,15 +90,9 @@ object HoverProvider:
val skipCheckOnName =
!pos.isPoint // don't check isHoveringOnName for RangeHover

val printerContext =
driver.compilationUnits.get(uri) match
case Some(unit) =>
val newctx =
ctx.fresh.setCompilationUnit(unit)
Interactive.contextOfPath(enclosing)(using newctx)
case None => ctx
val printerCtx = Interactive.contextOfPath(path)
val printer = ShortenedTypePrinter(search, IncludeDefaultParam.Include)(
using IndexedContext(printerContext)
using IndexedContext(printerCtx)
)
MetalsInteractive.enclosingSymbolsWithExpressionType(
enclosing,
Expand Down Expand Up @@ -142,7 +143,8 @@ object HoverProvider:
expressionType = Some(expressionType),
symbolSignature = Some(hoverString),
docstring = Some(docString),
forceExpressionType = forceExpressionType
forceExpressionType = forceExpressionType,
contextInfo = printer.getUsedRenamesInfo
)
).nn
case _ =>
Expand Down Expand Up @@ -176,6 +178,7 @@ object HoverProvider:
new ScalaHover(
expressionType = Some(tpeString),
symbolSignature = Some(s"$valOrDef $name$tpeString"),
contextInfo = printer.getUsedRenamesInfo
)
)
case RefinedType(parent, _, _) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ final class PcSyntheticDecorationsProvider(
val source =
SourceFile.virtual(filePath.toString, sourceText)
driver.run(uri, source)

given InferredType.Text = InferredType.Text(text)
given ctx: Context = driver.currentCtx
val unit = driver.currentCtx.run.nn.units.head

Expand Down Expand Up @@ -219,11 +221,16 @@ object TypeParameters:
end TypeParameters

object InferredType:
def unapply(tree: Tree)(using Context) =
opaque type Text = Array[Char]
object Text:
def apply(text: Array[Char]): Text = text

def unapply(tree: Tree)(using text: Text, cxt: Context) =
tree match
case vd @ ValDef(_, tpe, _)
if isValidSpan(tpe.span, vd.nameSpan) &&
!vd.symbol.is(Flags.Enum) =>
!vd.symbol.is(Flags.Enum) &&
!isValDefBind(text, vd) =>
if vd.symbol == vd.symbol.sourceSymbol then
Some(tpe.tpe, tpe.sourcePos.withSpan(vd.nameSpan), vd)
else None
Expand All @@ -247,6 +254,14 @@ object InferredType:
nameSpan.exists &&
!nameSpan.isZeroExtent

/* If is left part of val definition bind:
* val <<t>> @ ... =
*/
def isValDefBind(text: Text, vd: ValDef)(using Context) =
val afterDef = text.drop(vd.nameSpan.end)
val index = afterDef.indexAfterSpacesAndComments
index >= 0 && index < afterDef.size && afterDef(index) == '@'

end InferredType

case class Synthetics(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class ShortenedTypePrinter(
AbsOverride,
Lazy
)

private val foundRenames = collection.mutable.Map.empty[Symbol, String]

def getUsedRenamesInfo(using Context): List[String] =
foundRenames.map { (from, to) =>
s"type $to = ${from.showName}"
}.toList

def expressionType(tpw: Type)(using Context): Option[String] =
tpw match
Expand Down Expand Up @@ -117,8 +124,10 @@ class ShortenedTypePrinter(

prefixIterator.flatMap { owner =>
val prefixAfterRename = ownersAfterRename(owner)
val ownerRename = indexedCtx.rename(owner)
ownerRename.foreach(rename => foundRenames += owner -> rename)
val currentRenamesSearchResult =
indexedCtx.rename(owner).map(Found(owner, _, prefixAfterRename))
ownerRename.map(Found(owner, _, prefixAfterRename))
lazy val configRenamesSearchResult =
renameConfigMap.get(owner).map(Missing(owner, _, prefixAfterRename))
currentRenamesSearchResult orElse configRenamesSearchResult
Expand Down Expand Up @@ -181,7 +190,9 @@ class ShortenedTypePrinter(

override protected def selectionString(tp: NamedType): String =
indexedCtx.rename(tp.symbol) match
case Some(value) => value
case Some(value) =>
foundRenames += tp.symbol -> value
value
case None => super.selectionString(tp)

override def toText(tp: Type): Text =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,34 @@ object MtagsEnrichments extends CommonMtagsEnrichments:

def stripBackticks: String = s.stripPrefix("`").stripSuffix("`")

extension (text: Array[Char])
def indexAfterSpacesAndComments: Int = {
var isInComment = false
var startedStateChange = false
val index = text.indexWhere {
case '/' if !isInComment && !startedStateChange =>
startedStateChange = true
false
case '*' if !isInComment && startedStateChange =>
startedStateChange = false
isInComment = true
false
case '/' if isInComment && startedStateChange =>
startedStateChange = false
isInComment = false
false
case '*' if isInComment && !startedStateChange =>
startedStateChange = true
false
case c if isInComment || c.isSpaceChar || c == '\t' =>
startedStateChange = false
false
case _ => true
}
if (startedStateChange) index - 1
else index
}

extension (search: SymbolSearch)
def symbolDocumentation(symbol: Symbol)(using
Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,3 +498,31 @@ class SyntheticDecorationsSuite extends BaseSyntheticDecorationsSuite:
|""".stripMargin
)

@Test def `val-def-with-bind` =
check(
"""
|object O {
| val tupleBound @ (one, two) = ("1", "2")
|}
|""".stripMargin,
"""
|object O {
| val tupleBound @ (one: String, two: String) = ("1", "2")
|}
|""".stripMargin
)

@Test def `val-def-with-bind-and-comment` =
check(
"""
|object O {
| val tupleBound /* comment */ @ (one, two) = ("1", "2")
|}
|""".stripMargin,
"""
|object O {
| val tupleBound /* comment */ @ (one: String, two: String) = ("1", "2")
|}
|""".stripMargin
)

Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,28 @@ class InsertInferredTypeSuite extends BaseCodeActionSuite:
|""".stripMargin
)

@Test def `import-rename` =
checkEdit(
"""
|package a
|import scala.collection.{AbstractMap => AB}
|
|object Main {
| def test(): AB[Int, String] = ???
| val <<x>> = test()
|}
|""".stripMargin,
"""
|package a
|import scala.collection.{AbstractMap => AB}
|
|object Main {
| def test(): AB[Int, String] = ???
| val x: AB[Int, String] = test()
|}
|""".stripMargin
)

def checkEdit(
original: String,
expected: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ class HoverDefnSuite extends BaseHoverSuite:
"""package b.p@@kg
|object Main
|""".stripMargin,
// TODO, doesn's show information on packages
""
"package b.pkg".hover,
)

@Test def `pat-bind` =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ class HoverTermSuite extends BaseHoverSuite:
|object MyIntOut:
| extension (i: MyIntOut) def uneven = i.value % 2 == 1
|
|val a = MyIntOut(1).un@@even
|object Test:
| val a = MyIntOut(1).un@@even
|""".stripMargin,
"""extension (i: MyIntOut) def uneven: Boolean
|""".stripMargin.hover
Expand Down Expand Up @@ -593,4 +594,46 @@ class HoverTermSuite extends BaseHoverSuite:
|extension [A](self: A) def inferredTypeArg[C](value: C): C
|```
|""".stripMargin
)
)

@Test def `import-rename` =
check(
"""
|import scala.collection.{AbstractMap => AB}
|import scala.collection.{Set => S}
|
|object Main {
| def test(): AB[Int, String] = ???
| <<val t@@t = test()>>
|}
|""".stripMargin,
"""
|```scala
|type AB = AbstractMap
|```
|
|```scala
|val tt: AB[Int, String]
|```""".stripMargin,
)

@Test def `import-rename2` =
check(
"""
|import scala.collection.{AbstractMap => AB}
|import scala.collection.{Set => S}
|
|object Main {
| <<def te@@st(d: S[Int], f: S[Char]): AB[Int, String] = ???>>
|}
|""".stripMargin,
"""
|```scala
|type S = Set
|type AB = AbstractMap
|```
|
|```scala
|def test(d: S[Int], f: S[Char]): AB[Int, String]
|```""".stripMargin,
)
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ class HoverTypeSuite extends BaseHoverSuite:
|object MyIntOut:
| extension (i: MyIntOut) def uneven = i.value % 2 == 1
|
|val a = MyIntOut(1).un@@even
|object Test:
| val a = MyIntOut(1).un@@even
|""".stripMargin,
"""|extension (i: MyIntOut) def uneven: Boolean
|""".stripMargin.hover,
Expand Down
2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1341,7 +1341,7 @@ object Build {
BuildInfoPlugin.buildInfoDefaultSettings

lazy val presentationCompilerSettings = {
val mtagsVersion = "1.2.0+54-1a664e80-SNAPSHOT"
val mtagsVersion = "1.2.0+67-30f8ab53-SNAPSHOT"

Seq(
resolvers ++= Resolver.sonatypeOssRepos("snapshots"),
Expand Down

0 comments on commit 57321f2

Please sign in to comment.