John
John

Reputation: 815

Check type in Xtend validator

I want to check the type of an feature inside my Xtend validator.

The Xtext grammar looks like the following:

Element:
    'Element' name=ID
    'feature' feature=DOUBLE
    'end' 'Element'
;

This is how it is used:

Element MyElement
    feature 2.5
end Element

If trying to use a INTEGER value instead of DOUBLE for feature, the editor shows the error:

mismatched input '84900' expecting RULE_DOUBLE

I would like to overwrite the message. Therefore I've created a validation method inside my validator. In the method I would like to check the type of the feature. This is what I am trying to do:

@Check
def checkFeatureType(Element element) {
    if (element.feature instanceof Double) {
        // shows error!
    }
}

The instanceof check shows the following error:

Incompatible conditional operand types double or Double and Double or double

How can I perform a type check or is there a better way to override the standard message mentioned above?

Upvotes: 1

Views: 1813

Answers (2)

John
John

Reputation: 815

Thanks to Sebastian, I've found the solution.

First of all, it is necessary to add an SyntaxErrorMessageProvider to the RuntimeModule, which has the name <LanguageName>RuntimeModule. In case of the given example in my opening post, it would be MyLanguageRuntimeModule.

public class MyLanguageRuntimeModule extends my.language.AbstractMyLanguageRuntimeModule {
    public Class<? extends org.eclipse.xtext.generator.IGenerator> bindIGenerator() {
        return my.language.generator.MyLanguageGenerator.class;
    }

    public Class<? extends ISyntaxErrorMessageProvider> bindISyntaxErrorMessageProvider() {
        return MyLanguageSyntaxErrorMessageProvider.class;
    }
}

After that, the new class should be created. In my case the class name is MyLanguageSyntaxErrorMessageProvider.java. This class should then be filled with logic. For example, to overwrite the message I mentioned in my first post, the getSyntaxErrorMessage() in MyLanguageSyntaxErrorMessageProvider could look like this:

@Override
public SyntaxErrorMessage getSyntaxErrorMessage(IParserErrorContext context) {
    if (context.getRecognitionException() instanceof MismatchedTokenException) {
        MismatchedTokenException exception = (MismatchedTokenException) context.getRecognitionException();
        String value = exception.token.getText();
        return new SyntaxErrorMessage("The type of " + value + " is wrong.", IssueCodes.FALSE_PARAMETER_TYPE);
    }
    // additional implementations
    return null;
}

My class IssueCodes.java looks like the following (and can be extended with additional issue codes):

public interface IssueCodes {
    String PREFIX = "my.language.";

    String UNCAPITALIZED_ENTITY_NAME = "UncapitalizedEntityName";
    String FALSE_PARAMETER_TYPE = "FalseParameterType";
}

Upvotes: 1

Sebastian Zarnekow
Sebastian Zarnekow

Reputation: 6729

To override the message that the parser produced, you need to specialize the org.eclipse.xtext.parser.antlr.ISyntaxErrorMessageProvider and bind your own implementation in the runtime module of your language.

Upvotes: 1

Related Questions