Package org.apache.groovy.contracts.ast

# Class LoopVariantASTTransformation

java.lang.Object
org.apache.groovy.contracts.ast.LoopVariantASTTransformation

All Implemented Interfaces:
  `ASTTransformation`

public class LoopVariantASTTransformation extends Object implements ASTTransformation
Handles `Decreases` annotations placed on loop statements (`for`, `while`, `do-while`). The closure must return a value that strictly decreases on every iteration and remains non-negative.

The transformation injects code to:

1. Save the expression value at the start of each iteration.
2. Re-evaluate it at the end of the iteration.
3. Assert the value has strictly decreased.
4. Assert the value is non-negative.

Example:

     int n = 10
     @Decreases({ n })
     while (n > 0) {
         n--
     }

Since:
  6.0.0
See Also:
  - `Decreases`
  - `LoopVariantViolation`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `LoopVariantASTTransformation()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static void`
  `checkDecreased(Object prev, Object curr)`
  Runtime check called from generated code.
  `void`
  `visit(ASTNode[] nodes, SourceUnit source)`
  Rewrites a loop-level `Decreases` annotation into variant bookkeeping and runtime checks.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### LoopVariantASTTransformation

    public LoopVariantASTTransformation()

- ## Method Details

  - ### visit

    public void visit(ASTNode[] nodes, SourceUnit source)
    Rewrites a loop-level `Decreases` annotation into variant bookkeeping and runtime checks.
    Specified by:
      `visit` in interface `ASTTransformation`
    Parameters:
      `nodes` - the annotated AST nodes supplied by the compiler
      `source` - the current source unit

  - ### checkDecreased

    public static void checkDecreased(Object prev, Object curr)
    Runtime check called from generated code. Throws `LoopVariantViolation` if the variant did not strictly decrease or became negative.

    If both values are `List`s, they are compared lexicographically: the first position where values differ must show a strict decrease; all earlier positions must be equal. If all positions are equal, the variant has not decreased and a violation is thrown.