Xtext自定义验证器警告 - 如何标记关键字?

时间:2015-07-27 21:35:32

标签: validation warnings xtext xtend

我在xtext中有一个简单的Greeting示例。所以DSL定义如下:

grammar org.xtext.example.mydsl.Tests with org.eclipse.xtext.common.Terminals

generate tests "http://www.xtext.org/example/mydsl/Tests"

Model:
    greetings+= Greeting*;

Greeting:
    'Hello' name=ID '!';

此外,我有以下验证器:

@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
    if (!Character.isUpperCase(greeting.name.charAt(0))) {
        warning('Name should start with a capital', 
                TestsPackage.Literals.GREETING__NAME,
                -1,
                INVALID_NAME)
    }
}

如果我像这样编写验证器并且有一个类似的表达式         “你好,世界!” 在我的模型中,“世界”被标记,即在它下面有这条黄线。如果我只想标记关键字,那么在这种情况下只需要“Hello”,我该怎么办? 我尝试了很多东西,我只能设法标记整行“Hello world!”或者只是“世界”。

谢谢!

2 个答案:

答案 0 :(得分:3)

查看报告警告/错误的其他方法。有一个需要偏移量和长度。您可以使用节点模型来获取关键字

class MyDslValidator extends AbstractMyDslValidator {

    public static val INVALID_NAME = 'invalidName'
    @Inject extension MyDslGrammarAccess

    @Check
    def checkGreetingStartsWithCapital(Greeting greeting) {
        if (!Character.isUpperCase(greeting.name.charAt(0))) {
            val node = NodeModelUtils.findActualNodeFor(greeting)

            for (n : node.asTreeIterable) {
                val ge = n.grammarElement
                if (ge instanceof Keyword && ge == greetingAccess.helloKeyword_0) {
                    messageAcceptor.acceptWarning(
                        'Name should start with a capital',
                        greeting,
                        n.offset,
                        n.length,
                        INVALID_NAME
                    )
                }
            }

        }
    }
}

答案 1 :(得分:1)

我找到了另一个非常简单的解决方案,我没有想到包括更改DSL,即将关键字添加为属性。

Greeting:
    keyword='Hello' name=ID '!';

然后验证器的工作方式如下:

@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
    if (!Character.isUpperCase(greeting.name.charAt(0))) {
        warning('Name should start with a capital', 
                TestsPackage.Literals.GREETING__KEYWORD,
                -1,
                INVALID_NAME)
    }
}