%%%
 %% Declare Declarations
 %%
 %% @author  Martin Bravenboer <martin.bravenboer@gmail.com>
 %%%
module languages/aspectj/aspect/DeclareDeclaration[Ctx PointcutCtx]
exports
  sorts DeclareDec
  context-free syntax
    Anno[[Ctx]]* "declare" "parents" ":" TopTypePattern Parent ";"
      -> DeclareDec {cons("DecParent")}

    Anno[[Ctx]]* "declare" "warning" ":" PointcutExpr ":" StringLiteral[[PointcutCtx]] ";"
      -> DeclareDec {cons("DecWarning")}

    Anno[[Ctx]]* "declare" "error" ":" PointcutExpr ":" StringLiteral[[PointcutCtx]] ";"
      -> DeclareDec {cons("DecError")}

    Anno[[Ctx]]* "declare" "soft" ":" Type[[PointcutCtx]] ":" PointcutExpr ";"
      -> DeclareDec {cons("DecSoft")}
      
    %% Strange parenthesis in ajc testsuite ....
    Anno[[Ctx]]* "declare" "soft" ":" "(" Type[[PointcutCtx]] ")" ":" PointcutExpr ";"
      -> DeclareDec {cons("DecSoft")}

    Anno[[Ctx]]* "declare" "precedence" ":" {TopTypePattern ","}+ ";"
      -> DeclareDec {cons("DecPrecedence")}

    Anno[[Ctx]]* "declare" AnnoDeclKind ":" ElementPattern ":" Anno[[AspectCtx]] ";"
      -> DeclareDec {cons("DecAnno")}

  sorts AnnoDeclKind
  context-free syntax
           "@type" -> AnnoDeclKind {cons("DecAnnoType")}
    "@constructor" -> AnnoDeclKind {cons("DecAnnoConstructor")}
         "@method" -> AnnoDeclKind {cons("DecAnnoMethod")}
          "@field" -> AnnoDeclKind {cons("DecAnnoField")}

  sorts Parent
  context-free syntax
    Super[[PointcutCtx]]             -> Parent
    Interfaces[[PointcutCtx]]        -> Parent
    
    %%%
     %% Undocumented feature (AspectJ guide) : add interfaces with extends.
     %%%
    ExtendsInterfaces[[PointcutCtx]] -> Parent {avoid}