Skip to content

Commit 6dcfeab

Browse files
Backport "Improve signature help by more stable position calculation + better named arg support" to LTS (#20845)
Backports #19214 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 244ecdf + 1168afb commit 6dcfeab

21 files changed

+1935
-461
lines changed

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
277277
if (t.symbol.exists && t.hasType) {
278278
if (!t.symbol.isCompleted) t.symbol.info = UnspecifiedErrorType
279279
t.symbol.annotations.foreach { annot =>
280-
/* In some cases annotations are are used on themself (possibly larger cycles).
280+
/* In some cases annotations are used on themself (possibly larger cycles).
281281
* This is the case with the java.lang.annotation.Target annotation, would end
282282
* in an infinite loop while cleaning. The `seen` is added to ensure that those
283283
* trees are not cleand twice.

compiler/src/dotty/tools/dotc/util/Signatures.scala

Lines changed: 255 additions & 155 deletions
Large diffs are not rendered by default.

language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,18 @@ class DottyLanguageServer extends LanguageServer
551551
override def signatureHelp(params: TextDocumentPositionParams) = computeAsync { canceltoken =>
552552
val uri = new URI(params.getTextDocument.getUri)
553553
val driver = driverFor(uri)
554-
implicit def ctx: Context = driver.currentCtx
555554

556-
val pos = sourcePosition(driver, uri, params.getPosition)
557-
val trees = driver.openedTrees(uri)
558-
val path = Interactive.pathTo(trees, pos)
559-
val (paramN, callableN, signatures) = Signatures.signatureHelp(path, pos.span)
560-
new SignatureHelp(signatures.map(signatureToSignatureInformation).asJava, callableN, paramN)
555+
driver.compilationUnits.get(uri) match
556+
case Some(unit) =>
557+
given newCtx: Context = driver.currentCtx.fresh.setCompilationUnit(unit)
558+
val pos = sourcePosition(driver, uri, params.getPosition)
559+
val adjustedSpan = pos.span.withEnd(pos.span.end + 1)
560+
val path = Interactive.pathTo(ctx.compilationUnit.tpdTree, adjustedSpan)
561+
val (paramN, callableN, signatures) = Signatures.signatureHelp(path, adjustedSpan)
562+
563+
new SignatureHelp(signatures.map(signatureToSignatureInformation).asJava, callableN, paramN)
564+
565+
case _ => new SignatureHelp()
561566

562567
}
563568

@@ -929,23 +934,25 @@ object DottyLanguageServer {
929934

930935
/** Convert `signature` to a `SignatureInformation` */
931936
def signatureToSignatureInformation(signature: Signatures.Signature): lsp4j.SignatureInformation = {
932-
val tparams = signature.tparams.map(Signatures.Param("", _))
933937
val paramInfoss =
934-
(tparams ::: signature.paramss.flatten).map(paramToParameterInformation)
938+
(signature.paramss.flatten).map(paramToParameterInformation)
935939
val paramLists =
936-
if signature.paramss.forall(_.isEmpty) && tparams.nonEmpty then
937-
""
938-
else
939-
signature.paramss
940-
.map { paramList =>
941-
val labels = paramList.map(_.show)
942-
val prefix = if paramList.exists(_.isImplicit) then "using " else ""
943-
labels.mkString(prefix, ", ", "")
944-
}
945-
.mkString("(", ")(", ")")
946-
val tparamsLabel = if (signature.tparams.isEmpty) "" else signature.tparams.mkString("[", ", ", "]")
940+
signature.paramss
941+
.map { paramList =>
942+
val labels = paramList.map(_.show)
943+
val isImplicit = paramList.exists:
944+
case p: Signatures.MethodParam => p.isImplicit
945+
case _ => false
946+
val prefix = if isImplicit then "using " else ""
947+
val isTypeParams = paramList.forall(_.isInstanceOf[Signatures.TypeParam]) && paramList.nonEmpty
948+
val wrap: String => String = label => if isTypeParams then
949+
s"[$label]"
950+
else
951+
s"($label)"
952+
wrap(labels.mkString(prefix, ", ", ""))
953+
}.mkString
947954
val returnTypeLabel = signature.returnType.map(t => s": $t").getOrElse("")
948-
val label = s"${signature.name}$tparamsLabel$paramLists$returnTypeLabel"
955+
val label = s"${signature.name}$paramLists$returnTypeLabel"
949956
val documentation = signature.doc.map(DottyLanguageServer.markupContent)
950957
val sig = new lsp4j.SignatureInformation(label)
951958
sig.setParameters(paramInfoss.asJava)

0 commit comments

Comments
 (0)