Search code examples
xtextxtend

Xtext 2.8+ formatter, formatting simple rule


I am Xtend/Xtext newbie. Currently I am working with new formatter API, and i am trying to format rule, which looks like this:

Expression:
    Error|Warning|Enum|Text
;

with xtend dispatch method like this

def dispatch void format(Expression e){
        if (e instanceof ErrorImpl)
            ((ErrorImpl)e).format
}

Problem is, that type of expression e is uncovertable, I am recieving this error

Type mismatch: cannot convert from Class<ErrorImpl> to Expression

Why i cannot do this conversion (i suspect xTend semantics of course)(even Eclipse tells me that Expression is just interface from which children are created.) and how can i call format method for every child of this rule? Thanks.

enter image description here


Solution

  • The syntax of Xtend for type casts is different: instead of (ErrorImpl) e you write e as ErrorImpl. In this case the type case is not even necessary: due to the preceding instanceof check, the variable e is implicitly casted to ErrorImpl, so you can write the same code as

    def dispatch void format(Expression e) {
        if (e instanceof ErrorImpl)
            e.format
    }
    

    However, this code would cause a stack overflow because the format(EObject) method is called recursively with the same input. In order to properly exploit the power of dispatch methods you should write your code like this:

    def dispatch void format(Error error) {
        // Code for handling Errors
    }
    def dispatch void format(Warning warning) {
        // Code for handling Warnings
    }
    def dispatch void format(Enum enum) {
        // Code for handling Enums
    }
    def dispatch void format(Text text) {
        // Code for handling Texts
    }
    

    This generates a method format(Expression) that automatically dispatches to the more specific methods depending on the argument type.

    Note that formatter dispatch methods also need a second argument of type IFormattableDocument, so they should look like

    def dispatch void format(Error error, extension IFormattableDocument document) {
        // Code for handling Errors
    }
    ...