首页 > 解决方案 > 获取悬停的 Xtext 元素

问题描述

我的 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 实现,我不知道如何处理它们。

我如何获得定义?

标签: eclipse-plugindslxtext

解决方案


推荐阅读