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
Image Alt
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@JsonRequest("textDocument/documentHighlight")
2def documentHighlights(params: TextDocumentPositionParams) :
3 CompletableFuture[util.List[DocumentHighlight]] = {
4 val source: Path = params.getTextDocument.getUri.toAbsolutePath
5 val fileName: String = source.getFileName.toString
6 val relativePath: Path = sourceRoot.relativize(source)
7 val semanticDBPath: Path = targetDir
8 .resolve("target/classes/META-INF/semanticdb")
9 .resolve(relativePath)
10 .resolveSibling(fileName + ".semanticdb")
11 val in: InputStream = Files.newInputStream(semanticDBPath)
12 val doc: TextDocument = TextDocuments.parseFrom(in).documents.head
13 val position: Position = params.position
14 val symbolOccurrence: Option[SymbolOccurrence] =
15 doc.occurrences.find{ occurence =>
16 val range: Range = occurence.range.get
17 range.startLine <= position.getLine &&
18 range.endLine >= position.getLine &&
19 range.startCharacter <= position.getCharacter &&
20 range.endCharacter >= position.getCharacter
21 }
22 val occurencesList = for{
23 occurence <- symbolOccurrence
24 otherOccurence <- doc.occurrences
25 if occurence.symbol == otherOccurence.symbol
26 range <- otherOccurence.range
27 } yield new DocumentHighlight(range)
28 val completableFuture = new CompletableFuture[util.List[DocumentHighlight]]()
29 completableFuture.complete(occurencesList)
30}

Subscribe to our newsletter and never miss an article