Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update presentation compiler to a829a6a #18347

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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