Skip to content

Commit 985f955

Browse files
committed
Fixes scala#7673: document symbol responses by language server
- Fixed range of symbols (using symbol position and not symbol name position) - Removed top level container object - Improved symbol kinds (added enums, enum value/cases, traits as interfaces, and type params/fields) - Added local members - Fixed container names (stripping the module class suffix)
1 parent 4ba3710 commit 985f955

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

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: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,19 @@ class DottyLanguageServer extends LanguageServer
489489

490490
val uriTrees = driver.openedTrees(uri)
491491

492-
val defs = Interactive.namedTrees(uriTrees, Include.empty)
492+
val excludeLocalsFromSyntheticSymbols = (n: NameTree) => {
493+
val owner = n.symbol.owner
494+
n.symbol.is(Case) || {
495+
!owner.is(Synthetic) &&
496+
!owner.isPrimaryConstructor
497+
}
498+
}
499+
500+
val defs = Interactive.namedTrees(uriTrees, Include.local, excludeLocalsFromSyntheticSymbols)
501+
493502
(for {
494-
d <- defs if !isWorksheetWrapper(d)
495-
info <- symbolInfo(d.tree.symbol, d.namePos)
503+
d <- defs if (!isWorksheetWrapper(d) && !isTopLevelWrapper(d))
504+
info <- symbolInfo(d.tree.symbol, d.pos)
496505
} yield JEither.forLeft(info)).asJava
497506
}
498507

@@ -808,6 +817,14 @@ object DottyLanguageServer {
808817
symbol.owner == ctx.definitions.EmptyPackageClass
809818
}
810819

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+
811828
/** Create an lsp4j.CompletionItem from a completion result */
812829
def completionItem(completion: Completion)(implicit ctx: Context): lsp4j.CompletionItem = {
813830
def completionItemKind(sym: Symbol)(implicit ctx: Context): lsp4j.CompletionItemKind = {
@@ -883,24 +900,36 @@ object DottyLanguageServer {
883900
SK.Constructor
884901
else if (sym.is(Module))
885902
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
886909
else if (sym.isClass)
887910
SK.Class
888911
else if (sym.is(Mutable))
889912
SK.Variable
890913
else if (sym.is(Method))
891914
SK.Method
915+
else if (sym.is(TypeParam) || sym.isAbstractOrAliasType)
916+
SK.TypeParameter
892917
else
893918
SK.Field
894919
}
920+
def containerName(sym: Symbol): String = {
921+
if (sym.owner.exists && !sym.owner.isEmptyPackage) {
922+
if (sym.owner.isPackageObject && sym.owner.owner.exists) {
923+
sym.owner.owner.name.stripModuleClassSuffix.show
924+
} else
925+
sym.owner.name.stripModuleClassSuffix.show
926+
} else
927+
null
928+
}
895929

896930
val name = sym.name.stripModuleClassSuffix.show
897-
val containerName =
898-
if (sym.owner.exists && !sym.owner.isEmptyPackage)
899-
sym.owner.name.show
900-
else
901-
null
902931

903-
location(pos).map(l => new lsp4j.SymbolInformation(name, symbolKind(sym), l, containerName))
932+
location(pos).map(l => new lsp4j.SymbolInformation(name, symbolKind(sym), l, containerName(sym)))
904933
}
905934

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

0 commit comments

Comments
 (0)