xtextxtend

Xtext. Get object by string name


Has some lang like this.

language sample.linking.SampleLang;
generate SampleLang "http://sample/linking/samplelang/v1"
Model:
    entity_node = Entity
;

Entity:
    type = ('blabla1' | 'blabla2') ':' name = ID (annotation = Annotation)? '{'
    (parts += EntityPart)*
    '}'
;

Annotation:
    'deprecated' ( '->' name = ID )?
;

//SomeOtherRools
EntityPart:
    'createNewEntity' '(' entity=STRING ')'
;

I have multiple files, which must be checked

name1.ext
blabla2:name1
{
    ...
}

name2.ext
blabla2:name2 deprecated -> name1
{
    ...
}

name3.ext
blabla1:name3
{
    createNewEntity("name2") - show warning about deprecation
    createNewEntity("name1")
}

Need to check is Entity, which I'm try to "create" from some other entity deprecated or not. Can't do it through the cross-reference, because I've must specify the name by string. How can I write checker for this situation?

@Check
def checkDeprecation(EntityPart entityPart) {
    /*???*/
}

Solution

  • As Christian Dietrich suggest in comment for such task EntityPart can be changed to

    EntityPart:
        'createNewEntity' '(' entity=[Entity|STRING] ')'
    ;
    

    and add to *validator.xtend

       @Check
       def checkDeprecation(EntityPart entityPart) {
          if(entityPart.getEntity().getAnnotation() != null) {
              var warningString = "Usage of deprecated entity";
              if(entityPart.getEntity().getAnnotation().name != null) {
                   warningString = "Usage of deprecated entity, use "+entityPart.getEntity().getAnnotation().name+" instead"
              }
              warning(warningString, null);
          }
       }
    

    Why this may not work...

    For Eclipse you need:

    1. xtext project nature
    2. enabled Project - Properties - Builders - Xtext Project Puilder
    3. enabled Project - Build Automatically

    For Intellj Idea you need:

    1. facet of you'r dsl lang on module
    2. work only under folders marked as source