mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 00:38:56 +00:00
[lsi] Added hover support
Change-Id: I68d5203a992f4e4ea2a0d84f625e9c814e6c1d40 Signed-off-by: akosyakov <anton.kosyakov@typefox.io>
This commit is contained in:
parent
62f0535ee2
commit
900e930fb3
5 changed files with 200 additions and 8 deletions
|
@ -51,6 +51,7 @@ class DocumentExtensions {
|
|||
}
|
||||
|
||||
def RangeImpl newRange(Resource resource, ITextRegion region) {
|
||||
if (region === null) return null
|
||||
return resource.newRange(region.offset, region.offset + region.length)
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import io.typefox.lsapi.FileEvent
|
|||
import io.typefox.lsapi.InitializeParams
|
||||
import io.typefox.lsapi.InitializeResult
|
||||
import io.typefox.lsapi.InitializeResultImpl
|
||||
import io.typefox.lsapi.LanguageDescriptionImpl
|
||||
import io.typefox.lsapi.Location
|
||||
import io.typefox.lsapi.MessageParams
|
||||
import io.typefox.lsapi.PublishDiagnosticsParams
|
||||
|
@ -55,21 +56,21 @@ import java.util.concurrent.CompletableFuture
|
|||
import java.util.function.Consumer
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.LanguageInfo
|
||||
import org.eclipse.xtext.ide.editor.contentassist.ContentAssistEntry
|
||||
import org.eclipse.xtext.ide.editor.syntaxcoloring.IEditorHighlightingConfigurationProvider
|
||||
import org.eclipse.xtext.ide.server.concurrent.CancellableIndicator
|
||||
import org.eclipse.xtext.ide.server.concurrent.RequestManager
|
||||
import org.eclipse.xtext.ide.server.contentassist.ContentAssistService
|
||||
import org.eclipse.xtext.ide.server.findReferences.WorkspaceResourceAccess
|
||||
import org.eclipse.xtext.ide.server.hover.HoverService
|
||||
import org.eclipse.xtext.ide.server.symbol.DocumentSymbolService
|
||||
import org.eclipse.xtext.ide.server.symbol.WorkspaceSymbolService
|
||||
import org.eclipse.xtext.resource.FileExtensionProvider
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider
|
||||
import org.eclipse.xtext.validation.Issue
|
||||
|
||||
import static io.typefox.lsapi.util.LsapiFactories.*
|
||||
import io.typefox.lsapi.LanguageDescriptionImpl
|
||||
import org.eclipse.xtext.resource.FileExtensionProvider
|
||||
import org.eclipse.xtext.LanguageInfo
|
||||
import org.eclipse.xtext.ide.editor.syntaxcoloring.IEditorHighlightingConfigurationProvider
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -99,6 +100,7 @@ import org.eclipse.xtext.ide.editor.syntaxcoloring.IEditorHighlightingConfigurat
|
|||
|
||||
val result = new InitializeResultImpl
|
||||
result.capabilities = new ServerCapabilitiesImpl => [
|
||||
hoverProvider = true
|
||||
definitionProvider = true
|
||||
referencesProvider = true
|
||||
documentSymbolProvider = true
|
||||
|
@ -335,6 +337,25 @@ import org.eclipse.xtext.ide.editor.syntaxcoloring.IEditorHighlightingConfigurat
|
|||
|
||||
// end symbols
|
||||
|
||||
// hover
|
||||
|
||||
override hover(TextDocumentPositionParams params) {
|
||||
return requestManager.runRead[ cancelIndicator |
|
||||
val uri = params.textDocument.uri.toUri
|
||||
val resourceServiceProvider = uri.resourceServiceProvider
|
||||
val hoverService = resourceServiceProvider?.get(HoverService)
|
||||
if (hoverService === null)
|
||||
return emptyHover
|
||||
|
||||
return workspaceManager.doRead(uri) [ document, resource |
|
||||
val offset = document.getOffSet(params.position)
|
||||
return hoverService.hover(resource, offset)
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
// end hover
|
||||
|
||||
override didChangeConfiguraton(DidChangeConfigurationParams params) {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
@ -343,10 +364,6 @@ import org.eclipse.xtext.ide.editor.syntaxcoloring.IEditorHighlightingConfigurat
|
|||
return CompletableFuture.completedFuture(unresolved)
|
||||
}
|
||||
|
||||
override hover(TextDocumentPositionParams position) {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
||||
override signatureHelp(TextDocumentPositionParams position) {
|
||||
throw new UnsupportedOperationException("TODO: auto-generated method stub")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.server.hover
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Singleton
|
||||
import io.typefox.lsapi.Hover
|
||||
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider
|
||||
import org.eclipse.xtext.ide.server.DocumentExtensions
|
||||
import org.eclipse.xtext.resource.EObjectAtOffsetHelper
|
||||
import org.eclipse.xtext.resource.ILocationInFileProvider
|
||||
import org.eclipse.xtext.resource.XtextResource
|
||||
|
||||
import static io.typefox.lsapi.util.LsapiFactories.*
|
||||
|
||||
/**
|
||||
* @author kosyakov - Initial contribution and API
|
||||
*/
|
||||
@Singleton
|
||||
class HoverService {
|
||||
|
||||
@Inject
|
||||
extension DocumentExtensions
|
||||
|
||||
@Inject
|
||||
extension EObjectAtOffsetHelper
|
||||
|
||||
@Inject
|
||||
extension ILocationInFileProvider
|
||||
|
||||
@Inject
|
||||
extension IEObjectDocumentationProvider
|
||||
|
||||
def Hover hover(XtextResource resource, int offset) {
|
||||
val element = resource.resolveElementAt(offset)
|
||||
if (element === null)
|
||||
return emptyHover
|
||||
|
||||
val documentation = element.documentation
|
||||
if (documentation === null)
|
||||
return emptyHover
|
||||
|
||||
val contents = #[newMarkedString(documentation, null)]
|
||||
|
||||
val containedElement = resource.resolveContainedElementAt(offset)
|
||||
val textRegion = containedElement.significantTextRegion
|
||||
if (textRegion === null)
|
||||
return newHover(contents, null)
|
||||
|
||||
if (!textRegion.contains(offset))
|
||||
return emptyHover
|
||||
|
||||
val range = resource.newRange(textRegion)
|
||||
return newHover(contents, range)
|
||||
}
|
||||
|
||||
}
|
|
@ -131,6 +131,8 @@ class AbstractLanguageServerTest implements Consumer<PublishDiagnosticsParams> {
|
|||
«element.toExpectation»
|
||||
«ENDFOR»
|
||||
'''
|
||||
|
||||
protected def dispatch String toExpectation(Void it) { '' }
|
||||
|
||||
protected def dispatch String toExpectation(Location it) '''«uri.relativize» «range.toExpectation»'''
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.tests.server
|
||||
|
||||
import io.typefox.lsapi.Hover
|
||||
import io.typefox.lsapi.MarkedString
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.junit.Test
|
||||
|
||||
import static io.typefox.lsapi.util.LsapiFactories.*
|
||||
import static org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* @author kosyakov - Initial contribution and API
|
||||
*/
|
||||
class HoverTest extends AbstractLanguageServerTest {
|
||||
|
||||
@Test
|
||||
def void testHover_01() {
|
||||
testHover[
|
||||
model = '''
|
||||
/**
|
||||
* Some documentation.
|
||||
*/
|
||||
type Foo {
|
||||
}
|
||||
'''
|
||||
line = 3
|
||||
column = 'type F'.length
|
||||
expectedHover = '''
|
||||
[[3, 5] .. [3, 8]]
|
||||
Some documentation.
|
||||
'''
|
||||
]
|
||||
}
|
||||
|
||||
@Test
|
||||
def void testHover_02() {
|
||||
testHover[
|
||||
model = '''
|
||||
/**
|
||||
* Some documentation.
|
||||
*/
|
||||
type Foo {}
|
||||
'''
|
||||
line = 3
|
||||
column = '{'.length
|
||||
]
|
||||
}
|
||||
|
||||
@Test
|
||||
def void testHover_03() {
|
||||
testHover[
|
||||
model = '''
|
||||
/**
|
||||
* Some documentation.
|
||||
*/
|
||||
type Foo {
|
||||
Foo foo
|
||||
}
|
||||
'''
|
||||
line = 4
|
||||
column = ' F'.length
|
||||
expectedHover = '''
|
||||
[[4, 1] .. [4, 4]]
|
||||
Some documentation.
|
||||
'''
|
||||
]
|
||||
}
|
||||
|
||||
protected def void testHover((HoverTestConfiguration)=>void configurator) {
|
||||
val extension configuration = new HoverTestConfiguration
|
||||
configurator.apply(configuration)
|
||||
|
||||
val fileUri = filePath -> model
|
||||
|
||||
initialize
|
||||
open(fileUri, model)
|
||||
|
||||
val hover = languageServer.hover(newTextDocumentPositionParams(fileUri, line, column))
|
||||
val actualHover = hover.get.toExpectation
|
||||
assertEquals(expectedHover, actualHover)
|
||||
}
|
||||
|
||||
@Accessors
|
||||
static class HoverTestConfiguration {
|
||||
String model = ''
|
||||
String filePath = 'MyModel.testlang'
|
||||
int line = 0
|
||||
int column = 0
|
||||
String expectedHover = ''
|
||||
}
|
||||
|
||||
protected dispatch def String toExpectation(Hover it) '''
|
||||
«range.toExpectation»
|
||||
«FOR content : contents»
|
||||
«content.toExpectation»
|
||||
«ENDFOR»
|
||||
'''
|
||||
|
||||
protected dispatch def String toExpectation(
|
||||
MarkedString it
|
||||
) '''«IF !language.nullOrEmpty»«language» -> «ENDIF»«value»'''
|
||||
|
||||
}
|
Loading…
Reference in a new issue