Получить элемент Xtext для наведения - PullRequest
0 голосов
/ 26 июня 2018

Моя грамматика 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, и я не знал, что с ними делать.

Как мне получить определение?

...