Refactor document symbols

This commit is contained in:
Patrick Förster 2018-12-24 20:27:32 +01:00
parent fe8bbc9068
commit 6e8cd43a0b
10 changed files with 79 additions and 97 deletions

View file

@ -1,16 +0,0 @@
package texlab
import org.eclipse.lsp4j.DocumentSymbol
import java.net.URI
class BibtexDocument(uri: URI) : Document(uri) {
override fun analyze() {
// TODO
}
override fun documentSymbol(workspace: Workspace): List<DocumentSymbol> {
// TODO
return emptyList()
}
}

View file

@ -1,11 +1,11 @@
package texlab
import org.eclipse.lsp4j.DocumentSymbol
import org.eclipse.lsp4j.TextDocumentContentChangeEvent
import texlab.syntax.CharStream
import texlab.syntax.latex.LatexSyntaxTree
import java.net.URI
abstract class Document(val uri: URI) {
sealed class Document(val uri: URI) {
private var version: Int = -1
@ -36,6 +36,20 @@ abstract class Document(val uri: URI) {
}
protected abstract fun analyze()
abstract fun documentSymbol(workspace: Workspace): List<DocumentSymbol>
}
class LatexDocument(uri: URI) : Document(uri) {
var tree: LatexSyntaxTree = LatexSyntaxTree(text)
override fun analyze() {
tree = LatexSyntaxTree(text)
}
}
class BibtexDocument(uri: URI) : Document(uri) {
override fun analyze() {
// TODO
}
}

View file

@ -1,19 +0,0 @@
package texlab
import org.eclipse.lsp4j.DocumentSymbol
import texlab.syntax.latex.LatexEnvironmentSymbolFinder
import texlab.syntax.latex.LatexSyntaxTree
import java.net.URI
class LatexDocument(uri: URI) : Document(uri) {
var tree: LatexSyntaxTree = LatexSyntaxTree(text)
override fun analyze() {
tree = LatexSyntaxTree(text)
}
override fun documentSymbol(workspace: Workspace): List<DocumentSymbol> {
return LatexEnvironmentSymbolFinder.find(tree)
}
}

View file

@ -17,6 +17,10 @@ import texlab.rename.AggregateRenamer
import texlab.rename.LatexEnvironmentRenamer
import texlab.rename.RenameRequest
import texlab.rename.Renamer
import texlab.symbol.AggregateSymbolProvider
import texlab.symbol.LatexEnvironmentSymbolProvider
import texlab.symbol.SymbolProvider
import texlab.symbol.SymbolRequest
import java.net.URI
import java.util.concurrent.CompletableFuture
@ -39,6 +43,8 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : TextDocumentSe
LatexKernelCommandProvider(),
LatexUserCommandProvider()))
private val symbolProvider: SymbolProvider = AggregateSymbolProvider(LatexEnvironmentSymbolProvider)
private val renamer: Renamer = AggregateRenamer(LatexEnvironmentRenamer)
private val foldingProvider: FoldingProvider =
@ -78,12 +84,15 @@ class TextDocumentServiceImpl(private val workspace: Workspace) : TextDocumentSe
CompletableFuture<MutableList<Either<SymbolInformation, DocumentSymbol>>> {
synchronized(workspace) {
val uri = URI.create(params.textDocument.uri)
val symbols = workspace.documents
val document = workspace.documents
.firstOrNull { it.uri == uri }
?.documentSymbol(workspace)
?.map { Either.forRight<SymbolInformation, DocumentSymbol>(it) }
?.toMutableList()
?: mutableListOf()
?: return CompletableFuture.completedFuture(null)
val request = SymbolRequest(document)
val symbols = symbolProvider
.getSymbols(request)
.map { Either.forRight<SymbolInformation, DocumentSymbol>(it) }
.toMutableList()
return CompletableFuture.completedFuture(symbols)
}
}

View file

@ -0,0 +1,9 @@
package texlab.symbol
import org.eclipse.lsp4j.DocumentSymbol
class AggregateSymbolProvider(private vararg val providers: SymbolProvider) : SymbolProvider {
override fun getSymbols(request: SymbolRequest): List<DocumentSymbol> {
return providers.flatMap { it.getSymbols(request) }
}
}

View file

@ -0,0 +1,25 @@
package texlab.symbol
import org.eclipse.lsp4j.DocumentSymbol
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.SymbolKind
import texlab.LatexDocument
object LatexEnvironmentSymbolProvider : SymbolProvider {
override fun getSymbols(request: SymbolRequest): List<DocumentSymbol> {
if (request.document !is LatexDocument) {
return emptyList()
}
val symbols = mutableListOf<DocumentSymbol>()
for (environment in request.document.tree.environments) {
symbols.add(createSymbol(environment.beginName, environment.beginNameRange))
symbols.add(createSymbol(environment.endName, environment.endNameRange))
}
return symbols
}
private fun createSymbol(name: String, range: Range): DocumentSymbol {
return DocumentSymbol(name, SymbolKind.EnumMember, range, range)
}
}

View file

@ -0,0 +1,8 @@
package texlab.symbol
import org.eclipse.lsp4j.DocumentSymbol
interface SymbolProvider {
fun getSymbols(request: SymbolRequest): List<DocumentSymbol>
}

View file

@ -0,0 +1,5 @@
package texlab.symbol
import texlab.Document
data class SymbolRequest(val document: Document)

View file

@ -1,29 +0,0 @@
package texlab.syntax.latex
import org.eclipse.lsp4j.DocumentSymbol
import org.eclipse.lsp4j.SymbolKind
abstract class LatexEnvironmentSymbolFinder {
companion object {
val kind: SymbolKind = SymbolKind.EnumMember
fun find(tree: LatexSyntaxTree): List<DocumentSymbol> {
val symbols = mutableListOf<DocumentSymbol>()
for (environment in tree.environments) {
symbols.add(
DocumentSymbol(
environment.beginName,
kind,
environment.beginNameRange,
environment.beginNameRange))
symbols.add(
DocumentSymbol(
environment.endName,
kind,
environment.endNameRange,
environment.endNameRange))
}
return symbols
}
}
}

View file

@ -1,24 +0,0 @@
package texlab.syntax.latex
import org.eclipse.lsp4j.DocumentSymbol
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class LatexEnvironmentSymbolFinderTests {
@Test
fun `it should find empty and nonempty environments`() {
val text = "\\begin{foo}\n\\end{}"
val tree = LatexSyntaxTree(text)
val range1 = Range(Position(0, 7), Position(0, 10))
val range2 = Range(Position(1, 5), Position(1, 5))
val symbol1 = DocumentSymbol("foo", LatexEnvironmentSymbolFinder.kind, range1, range1)
val symbol2 = DocumentSymbol("", LatexEnvironmentSymbolFinder.kind, range2, range2)
val symbols = LatexEnvironmentSymbolFinder.find(tree)
assertEquals(2, symbols.size)
assertEquals(symbol1, symbols[0])
assertEquals(symbol2, symbols[1])
}
}