Skip to main content

Implementing a server for the Language Server Protocol

Picture of Tomasz Godzik, null

Tomasz Godzik

Jul 17, 2019|5 min read
Implementing a server for the Language Server Protocol cover
1@JsonRequest("textDocument/documentHighlight")
2def documentHighlights(params: TextDocumentPositionParams)
3 : CompletableFuture[util.List[DocumentHighlight]] = ???
1// Let's get the path to the file we are working on
2val source: Path = params.getTextDocument.getUri.toAbsolutePath
3// SemanticDB is located in META-INF with the same prefix as the source
4// this should work assuming sourceRoot and targetDir are specified before
5val fileName: String = source.getFileName.toString
6val relativePath: Path = sourceRoot.relativize(source)
7val semanticDBPath: Path = targetDir
8 .resolve("target/classes/META-INF/semanticdb")
9 .resolve(relativePath)
10 .resolveSibling(fileName + ".semanticdb")
11// and then get the semanticDB information
12val in: InputStream = Files.newInputStream(semanticDBPath)
13val doc: TextDocument = TextDocuments.parseFrom(in).documents.head
1// Find matching symbol occurrence in SemanticDB
2val position: Position = params.position
3val symbolOccurrence: Option[SymbolOccurrence] =
4 doc.occurrences.find{ occurence =>
5 val range: Range = occurence.range.get
6 range.startLine <= position.getLine &&
7 range.endLine >= position.getLine &&
8 range.startCharacter <= position.getCharacter &&
9 range.endCharacter >= position.getCharacter
1val occurencesList = for{
2 occurence <- symbolOccurrence
3 otherOccurence <- doc.occurrences
4 if occurence.symbol == otherOccurence.symbol
5 range <- otherOccurence.range
6} yield new DocumentHighlight(range)
1val completableFuture = new CompletableFuture[util.List[DocumentHighlight]]()
2completableFuture.complete(occurencesList)
1
2@JsonRequest("textDocument/documentHighlight")
3def documentHighlights(params: TextDocumentPositionParams) :
4 CompletableFuture[util.List[DocumentHighlight]] = {
5 val source: Path = params.getTextDocument.getUri.toAbsolutePath
6 val fileName: String = source.getFileName.toString
7 val relativePath: Path = sourceRoot.relativize(source)
8 val semanticDBPath: Path = targetDir
9 .resolve("target/classes/META-INF/semanticdb")
10 .resolve(relativePath)
11 .resolveSibling(fileName + ".semanticdb")
12 val in: InputStream = Files.newInputStream(semanticDBPath)
13 val doc: TextDocument = TextDocuments.parseFrom(in).documents.head
14 val position: Position = params.position
15 val symbolOccurrence: Option[SymbolOccurrence] =
16 doc.occurrences.find{ occurence =>
17 val range: Range = occurence.range.get
18 range.startLine <= position.getLine &&
19 range.endLine >= position.getLine &&
20 range.startCharacter <= position.getCharacter &&
21 range.endCharacter >= position.getCharacter
22 }
23 val occurencesList = for{
24 occurence <- symbolOccurrence
25 otherOccurence <- doc.occurrences
26 if occurence.symbol == otherOccurence.symbol
27 range <- otherOccurence.range
28 } yield new DocumentHighlight(range)
29 val completableFuture = new CompletableFuture[util.List[DocumentHighlight]]()
30 completableFuture.complete(occurencesList)
31}

Subscribe to our newsletter and never miss an article