Skip to content

Commit

Permalink
Update presentation compiler to a829a6a (#18347)
Browse files Browse the repository at this point in the history
[Cherry-picked 70be2df]
  • Loading branch information
rochala authored and Kordyjan committed Dec 7, 2023
1 parent f55b40e commit d307420
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 12 deletions.
27 changes: 19 additions & 8 deletions presentation-compiler/src/main/dotty/tools/pc/HoverProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,34 @@ object HoverProvider:
printer: ShortenedTypePrinter
)(using Context): ju.Optional[HoverSignature] = path match
case SelectDynamicExtractor(sel, n, name) =>
def findRefinement(tp: Type): ju.Optional[HoverSignature] =
def findRefinement(tp: Type): Option[HoverSignature] =
tp match
case RefinedType(info, refName, tpe) if name == refName.toString() =>
case RefinedType(_, refName, tpe) if name == refName.toString() =>
val tpeString =
if n == nme.selectDynamic then s": ${printer.tpe(tpe.resultType)}"
else printer.tpe(tpe)
ju.Optional.of(

val valOrDef =
if n == nme.selectDynamic && !tpe.isInstanceOf[ExprType]
then "val"
else "def"

Some(
new ScalaHover(
expressionType = Some(tpeString),
symbolSignature = Some(s"def $name$tpeString")
symbolSignature = Some(s"$valOrDef $name$tpeString"),
)
)
case RefinedType(info, _, _) =>
findRefinement(info)
case _ => ju.Optional.empty()
case RefinedType(parent, _, _) =>
findRefinement(parent)
case _ => None

val refTpe = sel.tpe.metalsDealias match
case r: RefinedType => Some(r)
case t: (TermRef | TypeProxy) => Some(t.termSymbol.info.metalsDealias)
case _ => None

findRefinement(sel.tpe.termSymbol.info.dealias)
refTpe.flatMap(findRefinement).asJava
case _ =>
ju.Optional.empty()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,18 @@ class Completions(
case Import

def include(sym: Symbol)(using Context): Boolean =
def hasSyntheticCursorSuffix: Boolean =
if !sym.name.endsWith(Cursor.value) then false
else
val realNameLength = sym.decodedName.length - Cursor.value.length
sym.source == pos.source &&
sym.span.start + realNameLength == pos.span.end

val generalExclude =
isUninterestingSymbol(sym) ||
!isNotLocalForwardReference(sym) ||
sym.isPackageObject
sym.isPackageObject ||
hasSyntheticCursorSuffix

def isWildcardParam(sym: Symbol) =
if sym.isTerm && sym.owner.isAnonymousFunction then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,16 @@ object MtagsEnrichments extends CommonMtagsEnrichments:
else symbol
)
val sym = toSemanticdbSymbol(symbol)
def parentSymbols =
if symbol.name == nme.apply && symbol.maybeOwner.is(ModuleClass) then
List(
symbol.maybeOwner,
symbol.maybeOwner.companion,
).filter(_ != NoSymbol) ++ symbol.allOverriddenSymbols
else symbol.allOverriddenSymbols
val documentation = search.documentation(
sym,
() => symbol.allOverriddenSymbols.map(toSemanticdbSymbol).toList.asJava
() => parentSymbols.iterator.map(toSemanticdbSymbol).toList.asJava,
)
if documentation.isPresent then Some(documentation.get())
else None
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
package dotty.tools.pc.tests.hover

import dotty.tools.pc.base.BaseHoverSuite

import org.junit.Test
import dotty.tools.pc.utils.MockEntries
import scala.meta.pc.SymbolDocumentation

class HoverDocSuite extends BaseHoverSuite:

override protected def mockEntries: MockEntries = new MockEntries:
override def documentations: Set[SymbolDocumentation] = Set(
ScalaMockDocumentation("java/lang/String#substring().", "substring", List(MockParam("beginIndex"))),
ScalaMockDocumentation("java/util/Collections#emptyList().", "emptyList"),
ScalaMockDocumentation("_empty_/Alpha.apply().", "apply", List(MockParam("x"))),
ScalaMockDocumentation("_empty_/Alpha#", "init", List(MockParam("x"))),
ScalaMockDocumentation("scala/collection/LinearSeqOps#headOption().", "headOption"),
)

@Test def `doc` =
check(
"""object a {
| <<java.util.Collections.empty@@List[Int]>>
|}
|""".stripMargin,
"""|**Expression type**:
|```scala
|java.util.List[Int]
|```
|**Symbol signature**:
|```scala
|final def emptyList[T](): java.util.List[T]
|```
|Found documentation for java/util/Collections#emptyList().
|""".stripMargin,
)

@Test def `doc-parent` =
check(
"""|object a {
| <<List(12).hea@@dOption>>
|}
|""".stripMargin,
// Assert that the docstring is extracted.
"""|```scala
|override def headOption: Option[Int]
|```
|Found documentation for scala/collection/LinearSeqOps#headOption().
|""".stripMargin,

)

@Test def `java-method` =
check(
"""|object a {
| <<"".substri@@ng(1)>>
|}
""".stripMargin,
"""|```scala
|def substring(beginIndex: Int): String
|```
|Found documentation for java/lang/String#substring().
|""".stripMargin
)

@Test def `object` =
check(
"""|
|/**
| * Doc about object
| */
|object Alpha {
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `object1` =
check(
"""|
|/**
| * Doc about object
| */
|object Alpha {
| /**
| * Doc about method
| */
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `case-class` =
check(
"""|
|/**
| * Doc about case class
| *
| */
|case class Alpha(x: Int)
|
|/**
| * Doc about object
| */
|object Alpha {
| /**
| * Doc about method
| */
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `case-class1` =
check(
"""|
|/**
| * Doc about case class
| *
| */
|case class Alpha(x: Int)
|
|/**
| * Doc about object
| */
|object Alpha {
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|
|""".stripMargin,
)

@Test def `case-class2` =
check(
"""|
|/**
| * Doc about case class
| *
| */
|case class Alpha(x: Int)
|
|object Alpha {
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `case-class3` =
check(
"""|
|/**
| * Doc about case class
| *
| */
|case class Alpha(x: Int)
|
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Alpha
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `class` =
check(
"""|
|/**
| * Doc about class
| *
| */
|class Alpha(x: Int)
|
|object Alpha {
| def apply(x: Int) = x + 1
|}
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def apply(x: Int): Int
|```
|Found documentation for _empty_/Alpha.apply().
|""".stripMargin,
)

@Test def `universal-apply` =
check(
"""|
|/**
| * Doc about class
| *
| */
|class Alpha(x: Int)
|
|object Main {
| val x = <<Alp@@ha(2)>>
|}
|""".stripMargin,
"""|```scala
|def this(x: Int): Alpha
|```
|Found documentation for _empty_/Alpha#
|""".stripMargin,
)
Loading

0 comments on commit d307420

Please sign in to comment.