Skip to content

Commit d0a0b83

Browse files
authored
Merge pull request #7674 from si-codelounge/fix-document-symbol-responses-from-dotty-language-server
Fixes #7673: document symbol responses by language server
2 parents 2b059e6 + e6a10bf commit d0a0b83

File tree

5 files changed

+100
-24
lines changed

5 files changed

+100
-24
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ object Interactive {
185185
private def handle(utree: untpd.NameTree): Unit = {
186186
val tree = utree.asInstanceOf[tpd.NameTree]
187187
if (tree.symbol.exists
188+
&& tree.name != StdNames.nme.ERROR
188189
&& !tree.symbol.is(Synthetic)
189190
&& !tree.symbol.isPrimaryConstructor
190191
&& tree.span.exists

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ class Typer extends Namer
587587
case _ =>
588588
}
589589
val x = tpnme.ANON_CLASS
590-
val clsDef = TypeDef(x, templ1).withFlags(Final)
590+
val clsDef = TypeDef(x, templ1).withFlags(Final | Synthetic)
591591
typed(cpy.Block(tree)(clsDef :: Nil, New(Ident(x), Nil)), pt)
592592
case _ =>
593593
var tpt1 = typedType(tree.tpt)

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

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,20 @@ class DottyLanguageServer extends LanguageServer
488488

489489
val uriTrees = driver.openedTrees(uri)
490490

491-
val defs = Interactive.namedTrees(uriTrees, Include.empty)
491+
// Excludes type and term params from synthetic symbols
492+
val excludeParamsFromSyntheticSymbols = (n: NameTree) => {
493+
val owner = n.symbol.owner
494+
!n.symbol.is(Param) || {
495+
!owner.is(Synthetic) &&
496+
!owner.isPrimaryConstructor
497+
}
498+
}
499+
500+
val defs = Interactive.namedTrees(uriTrees, Include.local, excludeParamsFromSyntheticSymbols)
501+
492502
(for {
493-
d <- defs if !isWorksheetWrapper(d)
494-
info <- symbolInfo(d.tree.symbol, d.namePos)
503+
d <- defs if (!isWorksheetWrapper(d) && !isTopLevelWrapper(d))
504+
info <- symbolInfo(d.tree.symbol, d.pos)
495505
} yield JEither.forLeft(info)).asJava
496506
}
497507

@@ -807,6 +817,14 @@ object DottyLanguageServer {
807817
symbol.owner == ctx.definitions.EmptyPackageClass
808818
}
809819

820+
/**
821+
* Is this symbol the wrapper object for top level definitions?
822+
*/
823+
def isTopLevelWrapper(sourceTree: SourceTree)(implicit ctx: Context): Boolean = {
824+
val symbol = sourceTree.tree.symbol
825+
symbol.isPackageObject
826+
}
827+
810828
/** Create an lsp4j.CompletionItem from a completion result */
811829
def completionItem(completion: Completion)(implicit ctx: Context): lsp4j.CompletionItem = {
812830
def completionItemKind(sym: Symbol)(implicit ctx: Context): lsp4j.CompletionItemKind = {
@@ -882,24 +900,34 @@ object DottyLanguageServer {
882900
SK.Constructor
883901
else if (sym.is(Module))
884902
SK.Module
903+
else if (sym.isAllOf(EnumCase) || sym.isAllOf(EnumValue))
904+
SK.EnumMember
905+
else if (sym.is(Enum))
906+
SK.Enum
907+
else if (sym.is(Trait))
908+
SK.Interface
885909
else if (sym.isClass)
886910
SK.Class
887911
else if (sym.is(Mutable))
888912
SK.Variable
889913
else if (sym.is(Method))
890914
SK.Method
915+
else if (sym.is(TypeParam) || sym.isAbstractOrAliasType)
916+
SK.TypeParameter
891917
else
892918
SK.Field
893919
}
920+
def containerName(sym: Symbol): String = {
921+
val owner = if (sym.owner.exists && sym.owner.isPackageObject) sym.owner.owner else sym.owner
922+
if (owner.exists && !owner.isEmptyPackage) {
923+
owner.name.stripModuleClassSuffix.show
924+
} else
925+
null
926+
}
894927

895928
val name = sym.name.stripModuleClassSuffix.show
896-
val containerName =
897-
if (sym.owner.exists && !sym.owner.isEmptyPackage)
898-
sym.owner.name.show
899-
else
900-
null
901929

902-
location(pos).map(l => new lsp4j.SymbolInformation(name, symbolKind(sym), l, containerName))
930+
location(pos).map(l => new lsp4j.SymbolInformation(name, symbolKind(sym), l, containerName(sym)))
903931
}
904932

905933
/** Convert `signature` to a `SignatureInformation` */

language-server/test/dotty/tools/languageserver/DocumentSymbolTest.scala

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,86 @@ import dotty.tools.languageserver.util.Code._
99
class DocumentSymbolTest {
1010

1111
@Test def withErroneousTree: Unit =
12-
code"class ${m1}Foo$m2 { def }"
12+
code"${m1}class Foo { def }$m2"
1313
.withSource.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class))
1414

1515
@Test def documentSymbol0: Unit =
16-
code"class ${m1}Foo$m2".withSource.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class))
16+
code"${m1}class Foo$m2".withSource.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class))
1717

1818
@Test def documentSymbol1: Unit =
19-
code"class ${m1}Foo$m2; class ${m3}Bar$m4".withSource
19+
code"${m1}class Foo$m2; ${m3}class Bar$m4".withSource
2020
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class), (m3 to m4).symInfo("Bar", SymbolKind.Class))
2121

2222
@Test def documentSymbol3: Unit = {
2323
withSources(
24-
code"class ${m1}Foo$m2",
25-
code"class ${m3}Bar$m4"
24+
code"${m1}class Foo$m2",
25+
code"${m3}class Bar$m4"
2626
) .documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class))
2727
.documentSymbol(m3, (m3 to m4).symInfo("Bar", SymbolKind.Class))
2828
}
2929

3030
@Test def documentSymbolShowModule: Unit = {
31-
code"""object ${m1}Foo${m2}""".withSource
31+
code"""${m1}object Foo${m2}""".withSource
3232
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Module))
3333
}
3434

3535
@Test def documentSymbolShowClassAndCompanion: Unit = {
36-
code"""object ${m1}Foo${m2}
37-
|class ${m3}Foo${m4}""".withSource
36+
code"""${m1}object Foo${m2}
37+
|${m3}class Foo${m4}""".withSource
3838
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Module),
3939
(m3 to m4).symInfo("Foo", SymbolKind.Class))
4040
}
4141

4242
@Test def documentSymbolSynthetic: Unit = {
43-
code"""case class ${m1}Foo${m2}(${m3}x${m4}: Int)""".withSource
43+
code"""${m1}case class Foo(${m3}x: Int${m4})${m2}""".withSource
4444
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class),
4545
(m3 to m4).symInfo("x", SymbolKind.Field, "Foo"))
4646
}
47+
48+
@Test def documentSymbolEnumADT: Unit = {
49+
code"""${m1}enum Option[${m3}+T${m4}] {
50+
${m5}case Some(${m7}x: T${m8})${m6}
51+
${m9}case None${m10}
52+
}${m2}""".withSource
53+
.documentSymbol(m1, (m1 to m2).symInfo("Option", SymbolKind.Enum),
54+
(m3 to m4).symInfo("T", SymbolKind.TypeParameter, "Option"),
55+
(m5 to m6).symInfo("Some", SymbolKind.EnumMember, "Option"),
56+
(m7 to m8).symInfo("x", SymbolKind.Field, "Some"),
57+
(m9 to m10).symInfo("None", SymbolKind.EnumMember, "Option"))
58+
}
59+
60+
@Test def documentSymbolEnum: Unit = {
61+
code"""${m1}enum Color(${m3}val rgb: Int${m4}) {
62+
${m5}case Red extends Color(0xFF0000)${m6}
63+
${m7}case Green extends Color(0x00FF00)${m8}
64+
${m9}case Blue extends Color(0x0000FF)${m10}
65+
}${m2}""".withSource
66+
.documentSymbol(m1, (m1 to m2).symInfo("Color", SymbolKind.Enum),
67+
(m3 to m4).symInfo("rgb", SymbolKind.Field, "Color"),
68+
(m5 to m6).symInfo("Red", SymbolKind.EnumMember, "Color"),
69+
(m7 to m8).symInfo("Green", SymbolKind.EnumMember, "Color"),
70+
(m9 to m10).symInfo("Blue", SymbolKind.EnumMember, "Color"))
71+
}
72+
73+
@Test def documentSymbolTopLevelDef: Unit =
74+
code"${m1}def foo(): Unit = { }${m2}".withSource.documentSymbol(m1, (m1 to m2).symInfo("foo", SymbolKind.Method))
75+
76+
@Test def documentSymbolTrait: Unit =
77+
code"${m1}trait Foo(${m3}val x: Int${m4})${m2}".withSource.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Interface),
78+
(m3 to m4).symInfo("x", SymbolKind.Field, "Foo"))
79+
80+
@Test def documentSymbolLocalDef: Unit =
81+
code"""${m1}def foo(): Unit = {
82+
${m3}def bar(): Unit = { }${m4}
83+
${m5}val x: Int = 0${m6}
84+
}${m2}""".withSource.documentSymbol(m1, (m1 to m2).symInfo("foo", SymbolKind.Method),
85+
(m3 to m4).symInfo("bar", SymbolKind.Method, "foo"),
86+
(m5 to m6).symInfo("x", SymbolKind.Field, "foo") )
87+
88+
@Test def documentSymbolTypeFields: Unit =
89+
code"""${m1}class Foo {
90+
${m3}type T${m4}
91+
}${m2}""".withSource.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class),
92+
(m3 to m4).symInfo("T", SymbolKind.TypeParameter, "Foo"))
93+
4794
}

language-server/test/dotty/tools/languageserver/WorksheetTest.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,10 @@ class WorksheetTest {
189189
}
190190

191191
@Test def worksheetDocumentSymbol(): Unit = {
192-
ws"""class ${m1}Foo${m2} {
193-
def ${m3}bar${m4} = 123
194-
}""".withSource
195-
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class, WorksheetWrapper.moduleClassName.toString),
192+
ws"""${m1}class Foo {
193+
${m3}def bar = 123${m4}
194+
}${m2}""".withSource
195+
.documentSymbol(m1, (m1 to m2).symInfo("Foo", SymbolKind.Class, WorksheetWrapper.moduleClassName.stripModuleClassSuffix.toString),
196196
(m3 to m4).symInfo("bar", SymbolKind.Method, "Foo"))
197197
}
198198

@@ -202,7 +202,7 @@ class WorksheetTest {
202202
def ${m3}bar${m4} = 123
203203
}""",
204204
code"""class ${m5}Baz${m6}"""
205-
).symbol("Foo", (m1 to m2).symInfo("Foo", SymbolKind.Class, WorksheetWrapper.moduleClassName.toString))
205+
).symbol("Foo", (m1 to m2).symInfo("Foo", SymbolKind.Class, WorksheetWrapper.moduleClassName.stripModuleClassSuffix.toString))
206206
.symbol("bar", (m3 to m4).symInfo("bar", SymbolKind.Method, "Foo"))
207207
.symbol("Baz", (m5 to m6).symInfo("Baz", SymbolKind.Class))
208208
}

0 commit comments

Comments
 (0)