Search code examples
xtextxtend

Why does the error method return an error?


I want to validate input corresponding to the following grammar snippet:

Declaration:
    name = ID "=" brCon=BracketContent
;

    BracketContent:
        decCon=DecContent (comp+=COMPARATOR content+=DecContent)*
    ;

        DecContent:
            (neg=("!"|"not"))? singleContent=VarContent (op+=OPERATOR nextCon+=VarContent)*
        ;

My validation looks like that:

  @Check
  def checkNoCycleInHierarchy(Declaration dec) {
    if(dec.decCon.singleContent.reference == null) {
        return
    }

    var names = newArrayList

    var con = dec.decCon.singleContent

    while(con.reference != null) {
        con = getThatReference(con).singleContent

        if(names.contains(getParentName(con))) {
            val errorMsg = "Cycle in hierarchy!"
            error(errorMsg, 
                SQFPackage.eINSTANCE.bracketContent_DecCon,
                CYCLE_IN_HIERARCHY)

            return
        }

        names.add(getParentName(con))
    }
  }

But when I test this validation with a testCaseit returns me an error message:

Expected ERROR 'raven.sqf.CycleInHierarchy' on Declaration at [-1:-1] but got
ERROR (org.eclipse.emf.ecore.impl.EClassImpl@5a7fe64f (name: Declaration) (instanceClassName: null) (abstract: false, interface: false).0) 'Error executing EValidator', offset null, length null
ERROR (org.eclipse.emf.ecore.impl.EClassImpl@5a7fe64f (name: Declaration) (instanceClassName: null) (abstract: false, interface: false).0) 'Error executing EValidator', offset null, length null

I just can't figure out what's wrong with it so I hope that someone of you might have an idea.

Greetings Krzmbrzl


Solution

  • It turned out it was an internal error...I'm still not exactly sure what went wrong but I have rewritten my validation method and now it works as expected.
    Now the method looks like this:

    enter code here@Check
      def checkNoCycleInHierarchy(Declaration dec) {
        if(dec.varContent.reference == null) {
            //proceed only if there is a reference
            return
        }
    
        var content = dec.varContent
    
        var names = newArrayList
    
        while(content.reference != null && !names.contains(getParentName(content))) {
            names.add(getParentName(content))
            content = content.reference.varContent
    
            if(names.contains(getParentName(content))) {
                val errorMsg = "Cycle in hierarchy!"
                error(errorMsg,
                    SQFPackage.eINSTANCE.declaration_BrCon,
                    CYCLE_IN_HIERARCHY)
    
                    return
            }
        }
      }
    

    I have the suspicion that there was a problem with the usage of my "getThatReference" in this case.

    Greeting Krzmbrzl