Skip to content

IDE: Fix crash on malformed input #5151

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

Merged
merged 1 commit into from
Sep 24, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ class DottyLanguageServer extends LanguageServer
(Nil, Include.overriding)
}
val defs = Interactive.namedTrees(trees, include, sym)
defs.map(d => location(d.namePos)).asJava
defs.flatMap(d => location(d.namePos)).asJava
}
}

Expand All @@ -311,7 +311,7 @@ class DottyLanguageServer extends LanguageServer
Include.references | Include.overriding | (if (includeDeclaration) Include.definitions else 0)
val refs = Interactive.findTreesMatching(trees, includes, sym)

refs.map(ref => location(ref.namePos)).asJava
refs.flatMap(ref => location(ref.namePos)).asJava
}
}

Expand All @@ -331,7 +331,10 @@ class DottyLanguageServer extends LanguageServer
Include.references | Include.definitions | Include.linkedClass | Include.overriding
val refs = Interactive.findTreesMatching(trees, includes, sym)

val changes = refs.groupBy(ref => toUri(ref.source).toString).mapValues(_.map(ref => new TextEdit(range(ref.namePos), newName)).asJava)
val changes = refs.groupBy(ref => toUri(ref.source).toString)
.mapValues(refs =>
refs.flatMap(ref =>
range(ref.namePos).map(nameRange => new TextEdit(nameRange, newName))).asJava)

new WorkspaceEdit(changes.asJava)
}
Expand All @@ -349,9 +352,10 @@ class DottyLanguageServer extends LanguageServer
if (sym == NoSymbol) Nil.asJava
else {
val refs = Interactive.namedTrees(uriTrees, Include.references | Include.overriding, sym)
( for (ref <- refs if ref.namePos.exists)
yield new DocumentHighlight(range(ref.namePos), DocumentHighlightKind.Read)
).asJava
(for {
ref <- refs
nameRange <- range(ref.namePos)
} yield new DocumentHighlight(nameRange, DocumentHighlightKind.Read)).asJava
}
}

Expand Down Expand Up @@ -382,7 +386,10 @@ class DottyLanguageServer extends LanguageServer
val uriTrees = driver.openedTrees(uri)

val defs = Interactive.namedTrees(uriTrees, includeReferences = false, _ => true)
defs.map(d => JEither.forLeft(symbolInfo(d.tree.symbol, d.namePos))).asJava
(for {
d <- defs
info <- symbolInfo(d.tree.symbol, d.namePos)
} yield JEither.forLeft(info)).asJava
}

override def symbol(params: WorkspaceSymbolParams) = computeAsync { cancelToken =>
Expand All @@ -393,7 +400,7 @@ class DottyLanguageServer extends LanguageServer

val trees = driver.allTrees
val defs = Interactive.namedTrees(trees, includeReferences = false, nameSubstring = query)
defs.map(d => symbolInfo(d.tree.symbol, d.namePos))
defs.flatMap(d => symbolInfo(d.tree.symbol, d.namePos))
}.asJava
}

Expand Down Expand Up @@ -427,15 +434,18 @@ object DottyLanguageServer {
}

/** Convert a SourcePosition to an lsp4j.Range */
def range(p: SourcePosition): lsp4j.Range =
new lsp4j.Range(
new lsp4j.Position(p.startLine, p.startColumn),
new lsp4j.Position(p.endLine, p.endColumn)
)
def range(p: SourcePosition): Option[lsp4j.Range] =
if (p.exists)
Some(new lsp4j.Range(
new lsp4j.Position(p.startLine, p.startColumn),
new lsp4j.Position(p.endLine, p.endColumn)
))
else
None

/** Convert a SourcePosition to an lsp4.Location */
def location(p: SourcePosition): lsp4j.Location =
new lsp4j.Location(toUri(p.source).toString, range(p))
def location(p: SourcePosition): Option[lsp4j.Location] =
range(p).map(r => new lsp4j.Location(toUri(p.source).toString, r))

/** Convert a MessageContainer to an lsp4j.Diagnostic */
def diagnostic(mc: MessageContainer): Option[lsp4j.Diagnostic] =
Expand All @@ -457,8 +467,9 @@ object DottyLanguageServer {
}

val code = mc.contained().errorId.errorNumber.toString
Some(new lsp4j.Diagnostic(
range(mc.pos), mc.message, severity(mc.level), /*source =*/ "", code))
range(mc.pos).map(r =>
new lsp4j.Diagnostic(
r, mc.message, severity(mc.level), /*source =*/ "", code))
}

/** Create an lsp4j.CompletionItem from a Symbol */
Expand Down Expand Up @@ -506,7 +517,7 @@ object DottyLanguageServer {
}

/** Create an lsp4j.SymbolInfo from a Symbol and a SourcePosition */
def symbolInfo(sym: Symbol, pos: SourcePosition)(implicit ctx: Context): lsp4j.SymbolInformation = {
def symbolInfo(sym: Symbol, pos: SourcePosition)(implicit ctx: Context): Option[lsp4j.SymbolInformation] = {
def symbolKind(sym: Symbol)(implicit ctx: Context): lsp4j.SymbolKind = {
import lsp4j.{SymbolKind => SK}

Expand All @@ -531,6 +542,6 @@ object DottyLanguageServer {
else
null

new lsp4j.SymbolInformation(name, symbolKind(sym), location(pos), containerName)
location(pos).map(l => new lsp4j.SymbolInformation(name, symbolKind(sym), l, containerName))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import dotty.tools.languageserver.util.Code._

class DocumentSymbolTest {

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

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

Expand Down