Моя грамматика Xtext выглядит следующим образом:
Model:
MsgDef
;
MsgDef:
(definitions+=definition)+
;
definition:
type=fieldType ' '+ name=ValidID (' '* '=' ' '* const=Value)?
;
Я пытаюсь создать всплывающую подсказку для элемента определения, который просто содержит текст, охватываемый элементом.
(синтаксис Xtend) Поставщик документации:
import dsl.dsl_msg.definition
import static extension org.eclipse.xtext.nodemodel.util.NodeModelUtils.*
class MsgDocumentationProvider implements IEObjectDocumentationProvider {
override getDocumentation(EObject o) {
val result = switch(o) {
definition : o.node?.tokenText
}
return result
}
}
Моя реализация EOBjectHover:
package dsl.ui.hover
import dsl.dsl_msg.definition
import com.google.inject.Inject
import org.eclipse.emf.ecore.EObject
import org.eclipse.jface.text.IRegion
import org.eclipse.jface.text.ITextViewer
import org.eclipse.jface.text.Region
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import org.eclipse.xtext.resource.EObjectAtOffsetHelper
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.ui.editor.hover.DispatchingEObjectTextHover
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider
import org.eclipse.xtext.util.Pair
import org.eclipse.xtext.util.Tuples
class MsgHover extends DispatchingEObjectTextHover {
@Inject
private EObjectAtOffsetHelper eObjectAtOffsetHelper;
@Inject private IEObjectHoverProvider msgHoverProvider;
override protected Pair<EObject, IRegion> getXtextElementAt(XtextResource resource, int offset) {
// check for cross reference
val crossLinkedEObject = eObjectAtOffsetHelper.resolveCrossReferencedElementAt(resource, offset);
if(crossLinkedEObject != null) {
[...]
} else {
val parseResult = resource.getParseResult();
if(parseResult != null) {
var leaf = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), offset);
if(leaf != null && leaf.isHidden() && leaf.getOffset() == offset) {
leaf = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), offset - 1);
}
// this is the part I am having trouble with
if(leaf != null && leaf.getGrammarElement() instanceof definition) {
val keyword = leaf.getGrammarElement() as definition;
return Tuples.create(keyword, new Region(leaf.getOffset(), leaf.getLength()));
}
//-----------------
}
}
return null;
}
override public Object getHoverInfo(EObject first, ITextViewer textViewer, IRegion hoverRegion) {
this.lastCreatorProvider = msgHoverProvider.getHoverInfo(first, textViewer, hoverRegion);
return this.lastCreatorProvider?.getInfo();
}
}
Hoverprovider для полноты ради:
class MsgHoverProvider extends DefaultEObjectHoverProvider {
override protected boolean hasHover(EObject o){
return true;
}
}
Я не получил отмеченный код для создания областей для элемента грамматики определения. Я также пытался получить родительские узлы, пока не столкнулся с узлом определения, но это не сработало, потому что родители на самом деле были просто реализациями RuleCall, и я не знал, что с ними делать.
Как мне получить определение?