Saturday, November 9, 2013

Default enum literals for Xtext generated EMF models

Xtext allows to easily build fully-fledged editors for domain specific languages (DSL) which are based on the Eclipse Modeling Framework (EMF). While existing Ecore models may be used, Xtext is also able to infer an Ecore model from the Xtext grammar. For complex Ecore models, it should certainly be considered to manage them independently, e.g. with Xcore. However, a few simple tweaks of grammar rules can influence the automatically generated Ecore model quite remarkably (e.g. the inheritance hierarchy) and may delay the point in time where it may be better to manage them independently. This example shows how to influence the generation of enumerators (enums) and default literals with grammar rules.

The code example below assumes that there's a model element with an optional "visibility" attribute of type enum and that the DSL must be able to capture the case where no visibility enum at all was given.

As the default literal of a generated enum is the first literal, an enum rule is added to the grammar which uses, say, "unspecified" for that. However, the user of the DSL editor should simply be able to enter nothing at all instead of "unspecified" which would look odd in the editor. This can be achieved by adding a second rule which returns the aforementioned enum, but only contains the literals allowed for the user. Please note that the order of the enum rules is important for generated models.

MyModelElement:
 // ...
 // user may specify enum or nothing at all
 visibility=Visibility? 
 // ...
;

// rule for the generated Ecore model
enum VisibilityEnum:
 unspecified | // first literal is the default
 public |
 private
;

// rule for the DSL editor
enum Visibility returns VisibilityEnum:
 public | 
 private
;

Thursday, April 11, 2013

Multiple Validators in Xtext

Early validation of domain specific languages (DSLs) and suggestions on how to fix these errors ('quickfixes') are key for a good end user experience and for avoiding problems in the toolchain, for instance in generators that use DSL models: The more editor validations, the better. This description shows how to improve the maintainability and modularity of validation code for Xtext DSLs by simply splitting them. In the generated [MyDsl]JavaValidator, an annotation referring to other custom validators has to be added as shown below:
@ComposedChecks(validators =
{MyCustomValidator.class, MyOthercustomValidator.class})
public class MyDslJavaValidator extends AbstractMyDslJavaValidator {

// check method as usual inside the generated Java Validator
@Check
public void checkMyDslElement(MyEntity myEntity) { // ...
Please note that the custom validator has to override the register()-method. Apart from that, the checks look exactly as they would if they were in the generated validator.
// Example for a split custom validator written in Xtend
public class MyCustomValidator extends AbstractDeclarativeValidator {

override register(EValidatorRegistrar registrar) {
//not needed for classes used as ComposedCheck
}

// additional check method in separate validator
@Check
def void checkMyDslElement(MyEntity myEntity) {
[...] // validation code