My Xtext grammar looks like this:
Model:
MsgDef
;
MsgDef:
(definitions+=definition)+
;
definition:
type=fieldType ' '+ name=ValidID (' '* '=' ' '* const=Value)?
;
I am trying to create a tooltip for the definition element that just contains the text that is spanned by the element.
(Xtend syntax) Documentation provider:
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
}
}
My EOBjectHover implementation:
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 for completeness sake:
class MsgHoverProvider extends DefaultEObjectHoverProvider {
override protected boolean hasHover(EObject o){
return true;
}
}
I don't get the marked code to create regions for the definition grammar element. I have also tried getting the parent nodes until I encounter the definition node, but that didn't work because the parents were actually just RuleCall implementations, and I didn't know what to do with them.
How do I get the definition?