我的Xtext语法如下:
Model:
MsgDef
;
MsgDef:
(definitions+=definition)+
;
definition:
type=fieldType ' '+ name=ValidID (' '* '=' ' '* const=Value)?
;
我正在尝试为definition元素创建一个工具提示,该提示仅包含该元素所跨越的文本。
(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实现,而且我不知道如何处理它们。
如何获得定义?