or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/maven-org-apache-groovy--groovy-contracts

Design by contract support for Groovy with @Invariant, @Requires, and @Ensures annotations

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.apache.groovy/groovy-contracts@5.0.x

To install, run

npx @tessl/cli install tessl/maven-org-apache-groovy--groovy-contracts@5.0.0

0

# Groovy Contracts

1

2

Groovy Contracts provides design-by-contract support for the Groovy programming language through annotations that define class invariants, method preconditions, and postconditions. These contracts are automatically enforced at runtime through AST transformations that inject Java assertion statements, enabling explicit specification and verification of method contracts.

3

4

## Package Information

5

6

- **Package Name**: groovy-contracts

7

- **Package Type**: maven

8

- **Language**: Java/Groovy

9

- **Installation**: Add dependency to your Gradle or Maven project:

10

11

```gradle

12

dependencies {

13

implementation 'org.apache.groovy:groovy-contracts:5.0.0'

14

}

15

```

16

17

```xml

18

<dependency>

19

<groupId>org.apache.groovy</groupId>

20

<artifactId>groovy-contracts</artifactId>

21

<version>5.0.0</version>

22

</dependency>

23

```

24

25

## Core Imports

26

27

```groovy

28

import groovy.contracts.*

29

```

30

31

## Basic Usage

32

33

```groovy

34

@Contracted

35

package com.example.contracts

36

37

import groovy.contracts.*

38

39

@Invariant({ elements != null && size >= 0 })

40

class Stack {

41

private def elements = []

42

private int size = 0

43

44

@Requires({ element != null })

45

@Ensures({ result == old.size + 1 })

46

def push(element) {

47

elements.add(element)

48

size++

49

return size

50

}

51

52

@Requires({ !isEmpty() })

53

@Ensures({ result != null && size == old.size - 1 })

54

def pop() {

55

def result = elements.removeLast()

56

size--

57

return result

58

}

59

60

def isEmpty() {

61

return size == 0

62

}

63

}

64

```

65

66

## Architecture

67

68

Groovy Contracts is built around several key components:

69

70

- **Contract Annotations**: Core annotations (@Invariant, @Requires, @Ensures) for defining contracts

71

- **AST Transformations**: Compile-time processing that injects assertion statements into bytecode

72

- **Exception System**: Specialized exception classes for different types of contract violations

73

- **Violation Tracking**: Runtime tracking system for managing multiple contract violations

74

- **Inheritance Support**: Contract inheritance rules for class hierarchies and interfaces

75

76

## Capabilities

77

78

### Contract Annotations

79

80

Core annotations for defining design-by-contract specifications on classes and methods. These annotations use closure expressions to define contract conditions.

81

82

```groovy { .api }

83

@Target([ElementType.PACKAGE, ElementType.TYPE])

84

@interface Contracted

85

86

@Target([ElementType.TYPE])

87

@Repeatable(Invariants.class)

88

@interface Invariant {

89

Class value()

90

}

91

92

@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])

93

@Repeatable(RequiresConditions.class)

94

@interface Requires {

95

Class value()

96

}

97

98

@Target([ElementType.CONSTRUCTOR, ElementType.METHOD])

99

@Repeatable(EnsuresConditions.class)

100

@interface Ensures {

101

Class value()

102

}

103

```

104

105

[Contract Annotations](./annotations.md)

106

107

### Exception Handling

108

109

Exception classes thrown when contract violations occur, with specialized types for different violation scenarios and utilities for tracking multiple violations.

110

111

```groovy { .api }

112

abstract class AssertionViolation extends AssertionError

113

114

class PreconditionViolation extends AssertionViolation

115

class PostconditionViolation extends AssertionViolation

116

class ClassInvariantViolation extends AssertionViolation

117

class CircularAssertionCallException extends RuntimeException

118

119

class ViolationTracker {

120

static ThreadLocal<ViolationTracker> INSTANCE

121

static void init()

122

static void deinit()

123

static boolean violationsOccurred()

124

static void rethrowFirst()

125

static void rethrowLast()

126

}

127

```

128

129

[Exception Handling](./exceptions.md)

130

131

## Types

132

133

### Annotation Containers

134

135

```groovy { .api }

136

@interface Invariants {

137

Invariant[] value()

138

}

139

140

@interface RequiresConditions {

141

Requires[] value()

142

}

143

144

@interface EnsuresConditions {

145

Ensures[] value()

146

}

147

```

148

149

### Contract Variables

150

151

Special variables available in contract expressions:

152

153

- **Preconditions (@Requires)**: Access to method arguments and class fields

154

- **Postconditions (@Ensures)**: Access to method arguments, class fields, `result` (return value), and `old` (map of previous field values)

155

- **Invariants (@Invariant)**: Access to class fields only

156

157

### Supported Old Value Types

158

159

The `old` variable in postconditions supports automatic cloning for:

160

- Primitive types and their wrapper classes

161

- `Cloneable` types

162

- `BigInteger` and `BigDecimal`

163

- `String` and `GString`

164

165

## Contract Inheritance Rules

166

167

- **Class Invariants**: Combined with parent invariants using logical AND

168

- **Preconditions**: Combined with parent preconditions using logical OR (weakening)

169

- **Postconditions**: Combined with parent postconditions using logical AND (strengthening)

170

171

## JVM Integration

172

173

Contracts are implemented as Java assertion statements and can be controlled using standard JVM assertion parameters:

174

- Enable assertions: `-ea` or `-enableassertions`

175

- Disable assertions: `-da` or `-disableassertions`

176

- Package-specific control: `-ea:com.example.contracts.*`

177

178

## API Stability

179

180

**Important**: All contract annotations (except `@Contracted`) are marked with `@Incubating`, indicating they are subject to breaking changes in future versions until the API is stabilized. The exception classes and `ViolationTracker` are not marked as incubating and are considered stable.