Get Xtext element for hover

263 views Asked by At

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?

0

There are 0 answers