Skip to content

Commit

Permalink
bugfix: completions for type companion object
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Jun 30, 2023
1 parent fc87ff0 commit bd6f879
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package scala.meta.internal.pc

import scala.util.control.NonFatal

import scala.meta.internal.mtags.MtagsEnrichments.decoded
import scala.meta.internal.mtags.MtagsEnrichments.stripBackticks

import dotty.tools.dotc.core.Contexts.*
Expand Down Expand Up @@ -49,7 +50,29 @@ object SemanticdbSymbols:
typeSym :: owner.info.decl(termName(value)).symbol :: Nil
else typeSym :: Nil
case Descriptor.Term(value) =>
owner.info.decl(termName(value)).symbol :: Nil
val outSymbol = owner.info.decl(termName(value)).symbol
if outSymbol.exists
then outSymbol :: Nil
else if owner.is(Package)
then
// Fallback for type companion objects,
// e.g.
// ```File.scala
// package a
// type Cow = Int
// object Cow
// ```
// `ScalaTopLevelMtags` emits `a/Cow.`
// but the symbol we look for is `a/File$package/Cow.`
// (look: tests.pc.CompletionWorkspaceSuite.type-apply)
owner.info.decls
.filter { s =>
s.isPackageObject && s.name.decoded.endsWith("$package")
}
.flatMap(tryMember)
.toList
else Nil
end if
case Descriptor.Package(value) =>
owner.info.decl(termName(value)).symbol :: Nil
case Descriptor.Parameter(value) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ class MetalsPrinter(
val typeSymbol = info.typeSymbol

if sym.is(Flags.Package) || sym.isClass then
" " + dotcPrinter.fullName(sym.owner)
" " + dotcPrinter.fullName(sym.effectiveOwner)
else if sym.is(Flags.Module) || typeSymbol.is(Flags.Module) then
if typeSymbol != NoSymbol then
" " + dotcPrinter.fullName(typeSymbol.owner)
else " " + dotcPrinter.fullName(sym.owner)
" " + dotcPrinter.fullName(typeSymbol.effectiveOwner)
else " " + dotcPrinter.fullName(sym.effectiveOwner)
else if sym.is(Flags.Method) then
defaultMethodSignature(sym, info, onlyMethodParams = true)
else tpe(info)
Expand Down
32 changes: 32 additions & 0 deletions tests/cross/src/test/scala/tests/pc/CompletionWorkspaceSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -944,4 +944,36 @@ class CompletionWorkspaceSuite extends BaseCompletionSuite {
),
)

check(
"type-apply".tag(IgnoreScala2),
"""|package demo
|
|package other:
| type MyType = Long
|
| object MyType:
| def apply(m: Long): MyType = m
|
|val j = MyTy@@
|""".stripMargin,
"""|MyType(m: Long): MyType
|MyType - demo.other""".stripMargin,
)

check(
"type-apply2".tag(IgnoreScala2),
"""|package demo
|
|package other:
| object MyType:
| def apply(m: Long): MyType = m
|
| type MyType = Long
|
|val j = MyTy@@
|""".stripMargin,
"""|MyType(m: Long): MyType
|MyType - demo.other""".stripMargin,
)

}
21 changes: 21 additions & 0 deletions tests/unit/src/test/scala/tests/ScalaToplevelSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,27 @@ class ScalaToplevelSuite extends BaseSuite {
all = true,
)

check(
"companion-to-type",
"""|package s
|type Cow = Long
|
|object Cow:
| def apply(m: Long): Cow = m
|
|""".stripMargin,
// For `s/Cow.` and `s/Cow.apply().` the corresponding symbols created by the compiler
// will be respectively `s/Test$package/Cow.` and `s/Test$package/Cow.apply().`.
//
// It is easier to work around this inconstancy in `SemanticdbSymbols.inverseSemanticdbSymbol`
// than to change symbols emitted by `ScalaTopLevelMtags`,
// since the object could be placed before type definition.
List("s/", "s/Test$package.", "s/Test$package.Cow#", "s/Cow.",
"s/Cow.apply()."),
dialect = dialects.Scala3,
all = true,
)

def check(
options: TestOptions,
code: String,
Expand Down

0 comments on commit bd6f879

Please sign in to comment.