Xtext standard warning - how to tag a keyword?

I have a simple example of a greeting in xtext. Thus, DSL is defined as follows:

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 '!';

      

Also, I have the following validator:

@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)
    }
}

      

If I write a validator like this and get an expression like "Hello world!" in my model the "world" is marked, i.e. there is a yellow line below it. What do I need to do if I only want to check the keyword, so in this case, only "Hello"? I've tried quite a few things, and all I have to do is mark the whole "Hello world!" Line. or just "peace".

Thank!

+3


source to share


2 answers


check out other methods for warning / error reporting. there is one that takes offset and length. you can use node model to get them for a keyword



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
                    )
                }
            }

        }
    }
}

      

+2


source


I found another very simple solution that I hadn't thought of, which is to change the DSL a bit, i.e. add a keyword as an attribute.

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

      



Then the validator works as in the question:

@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)
    }
}

      

+1


source







All Articles