or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-generation.mdbuilders.mdextensions.mdindex.mdmemoization.mdpretty-strings.mdserialization.mdstandalone-builders.mdtagged-unions.mdvalue-classes.md

annotation-generation.mddocs/

0

# Annotation Generation

1

2

AutoAnnotation generates proper implementations of annotation interfaces with correct equals(), hashCode(), and toString() methods that conform to the Java annotation specification.

3

4

## Basic Annotation Generation

5

6

```java { .api }

7

// Annotation interface

8

public @interface Named {

9

String value();

10

}

11

12

// Factory method with @AutoAnnotation

13

public class Annotations {

14

@AutoAnnotation

15

public static Named named(String value) {

16

return new AutoAnnotation_Annotations_named(value);

17

}

18

}

19

```

20

21

## Usage Example

22

23

```java

24

Named annotation = Annotations.named("example");

25

System.out.println(annotation); // @Named(value="example")

26

System.out.println(annotation.value()); // "example"

27

28

// Proper equals() behavior

29

Named same = Annotations.named("example");

30

Named different = Annotations.named("other");

31

System.out.println(annotation.equals(same)); // true

32

System.out.println(annotation.equals(different)); // false

33

```

34

35

## Multi-Parameter Annotations

36

37

```java { .api }

38

// Complex annotation

39

public @interface ApiEndpoint {

40

String path();

41

String method() default "GET";

42

boolean authenticated() default true;

43

String[] produces() default {};

44

}

45

46

// Factory method

47

public class Annotations {

48

@AutoAnnotation

49

public static ApiEndpoint apiEndpoint(

50

String path,

51

String method,

52

boolean authenticated,

53

String[] produces) {

54

return new AutoAnnotation_Annotations_apiEndpoint(path, method, authenticated, produces);

55

}

56

}

57

```

58

59

Usage:

60

61

```java

62

ApiEndpoint endpoint = Annotations.apiEndpoint(

63

"/api/users",

64

"POST",

65

true,

66

new String[]{"application/json"});

67

68

System.out.println(endpoint.path()); // "/api/users"

69

System.out.println(endpoint.method()); // "POST"

70

System.out.println(endpoint.authenticated()); // true

71

System.out.println(Arrays.toString(endpoint.produces())); // ["application/json"]

72

```

73

74

## Annotations with Default Values

75

76

Factory methods can omit parameters that have default values:

77

78

```java { .api }

79

public @interface RequestMapping {

80

String path();

81

String method() default "GET";

82

int timeout() default 5000;

83

}

84

85

public class Annotations {

86

// Full parameter version

87

@AutoAnnotation

88

public static RequestMapping requestMapping(String path, String method, int timeout) {

89

return new AutoAnnotation_Annotations_requestMapping(path, method, timeout);

90

}

91

92

// Convenience method using defaults

93

@AutoAnnotation

94

public static RequestMapping requestMapping(String path) {

95

return new AutoAnnotation_Annotations_requestMapping(path, "GET", 5000);

96

}

97

98

// Partial defaults

99

@AutoAnnotation

100

public static RequestMapping requestMapping(String path, String method) {

101

return new AutoAnnotation_Annotations_requestMapping(path, method, 5000);

102

}

103

}

104

```

105

106

Usage:

107

108

```java

109

RequestMapping simple = Annotations.requestMapping("/api/data");

110

RequestMapping withMethod = Annotations.requestMapping("/api/data", "POST");

111

RequestMapping full = Annotations.requestMapping("/api/data", "POST", 10000);

112

```

113

114

## Array-Valued Annotations

115

116

AutoAnnotation properly handles array-valued annotation elements:

117

118

```java { .api }

119

public @interface Tags {

120

String[] value();

121

int[] priorities() default {};

122

}

123

124

public class Annotations {

125

@AutoAnnotation

126

public static Tags tags(String[] value, int[] priorities) {

127

return new AutoAnnotation_Annotations_tags(value, priorities);

128

}

129

130

// Convenience method for single tag

131

public static Tags tag(String tag) {

132

return tags(new String[]{tag}, new int[]{});

133

}

134

}

135

```

136

137

Usage:

138

139

```java

140

Tags multipleTags = Annotations.tags(

141

new String[]{"web", "api", "rest"},

142

new int[]{1, 2, 3});

143

144

Tags singleTag = Annotations.tag("important");

145

146

// Arrays are properly cloned for immutability

147

String[] originalArray = {"test"};

148

Tags tagsFromArray = Annotations.tags(originalArray, new int[]{});

149

originalArray[0] = "modified"; // Doesn't affect the annotation

150

System.out.println(tagsFromArray.value()[0]); // Still "test"

151

```

152

153

## Nested Annotation Types

154

155

AutoAnnotation works with annotations that contain other annotations:

156

157

```java { .api }

158

public @interface Validation {

159

String message();

160

int code();

161

}

162

163

public @interface Field {

164

String name();

165

Validation[] validations() default {};

166

}

167

168

public class Annotations {

169

@AutoAnnotation

170

public static Validation validation(String message, int code) {

171

return new AutoAnnotation_Annotations_validation(message, code);

172

}

173

174

@AutoAnnotation

175

public static Field field(String name, Validation[] validations) {

176

return new AutoAnnotation_Annotations_field(name, validations);

177

}

178

}

179

```

180

181

Usage:

182

183

```java

184

Validation required = Annotations.validation("Field is required", 1001);

185

Validation minLength = Annotations.validation("Minimum length is 3", 1002);

186

187

Field nameField = Annotations.field("username", new Validation[]{required, minLength});

188

```

189

190

## Enum-Valued Annotations

191

192

AutoAnnotation handles enum values correctly:

193

194

```java { .api }

195

public enum Priority {

196

LOW, MEDIUM, HIGH, CRITICAL

197

}

198

199

public @interface Task {

200

String description();

201

Priority priority() default Priority.MEDIUM;

202

}

203

204

public class Annotations {

205

@AutoAnnotation

206

public static Task task(String description, Priority priority) {

207

return new AutoAnnotation_Annotations_task(description, priority);

208

}

209

210

// Convenience method with default priority

211

public static Task task(String description) {

212

return task(description, Priority.MEDIUM);

213

}

214

}

215

```

216

217

Usage:

218

219

```java

220

Task normalTask = Annotations.task("Implement feature");

221

Task urgentTask = Annotations.task("Fix critical bug", Priority.CRITICAL);

222

```

223

224

## Class-Valued Annotations

225

226

AutoAnnotation supports Class<?> annotation elements:

227

228

```java { .api }

229

public @interface Converter {

230

Class<?> from();

231

Class<?> to();

232

Class<? extends TypeConverter> converter();

233

}

234

235

public class Annotations {

236

@AutoAnnotation

237

public static Converter converter(Class<?> from, Class<?> to, Class<? extends TypeConverter> converter) {

238

return new AutoAnnotation_Annotations_converter(from, to, converter);

239

}

240

}

241

```

242

243

Usage:

244

245

```java

246

Converter stringToInt = Annotations.converter(String.class, Integer.class, StringToIntConverter.class);

247

```

248

249

## Generic Factory Methods

250

251

Factory methods can be generic for flexibility:

252

253

```java { .api }

254

public @interface TypedAnnotation {

255

Class<?> value();

256

}

257

258

public class Annotations {

259

@AutoAnnotation

260

public static TypedAnnotation typedAnnotation(Class<?> value) {

261

return new AutoAnnotation_Annotations_typedAnnotation(value);

262

}

263

264

// Generic convenience method

265

public static <T> TypedAnnotation typedAnnotation(Class<T> type) {

266

return typedAnnotation((Class<?>) type);

267

}

268

}

269

```

270

271

## Private Factory Methods

272

273

AutoAnnotation methods can have any visibility:

274

275

```java { .api }

276

public class InternalAnnotations {

277

@AutoAnnotation

278

private static Internal internal(String value) {

279

return new AutoAnnotation_InternalAnnotations_internal(value);

280

}

281

282

// Public wrapper method

283

public static Internal createInternal(String value) {

284

validateInternalValue(value);

285

return internal(value);

286

}

287

288

private static void validateInternalValue(String value) {

289

if (value.isEmpty()) {

290

throw new IllegalArgumentException("Internal value cannot be empty");

291

}

292

}

293

}

294

```

295

296

## Integration with Builders

297

298

Combine AutoAnnotation with AutoBuilder for fluent annotation creation:

299

300

```java { .api }

301

public @interface Configuration {

302

String name();

303

String value();

304

boolean required() default false;

305

String description() default "";

306

}

307

308

public class Annotations {

309

@AutoAnnotation

310

public static Configuration configuration(String name, String value, boolean required, String description) {

311

return new AutoAnnotation_Annotations_configuration(name, value, required, description);

312

}

313

}

314

315

@AutoBuilder(callMethod = "configuration", ofClass = Annotations.class)

316

public abstract class ConfigurationBuilder {

317

public static ConfigurationBuilder builder() {

318

return new AutoBuilder_ConfigurationBuilder()

319

.setRequired(false)

320

.setDescription("");

321

}

322

323

public abstract ConfigurationBuilder setName(String name);

324

public abstract ConfigurationBuilder setValue(String value);

325

public abstract ConfigurationBuilder setRequired(boolean required);

326

public abstract ConfigurationBuilder setDescription(String description);

327

public abstract Configuration build();

328

}

329

```

330

331

Usage:

332

333

```java

334

Configuration config = ConfigurationBuilder.builder()

335

.setName("database.url")

336

.setValue("jdbc:postgresql://localhost:5432/mydb")

337

.setRequired(true)

338

.setDescription("Database connection URL")

339

.build();

340

```

341

342

## Null Handling

343

344

AutoAnnotation validates non-null parameters:

345

346

```java { .api }

347

public @interface Description {

348

String value();

349

String author();

350

}

351

352

public class Annotations {

353

@AutoAnnotation

354

public static Description description(String value, String author) {

355

return new AutoAnnotation_Annotations_description(value, author);

356

}

357

}

358

```

359

360

```java

361

// This will throw NullPointerException

362

Description desc = Annotations.description(null, "Alice"); // NPE: value cannot be null

363

Description desc2 = Annotations.description("text", null); // NPE: author cannot be null

364

```

365

366

## Performance Characteristics

367

368

- Generated annotation implementations use efficient equals() and hashCode()

369

- Array parameters are cloned to ensure immutability

370

- No reflection is used at runtime

371

- toString() provides standard annotation string format

372

- Generated classes are optimized for the specific annotation interface