or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

concurrency.mdconstant-value.mdcontracts.mdframework.mdindex-bounds.mdindex.mdnullness.mdoptional.mdresources.mdsignedness.mdstring-format.mdunits.md

index-bounds.mddocs/

0

# Index and Bounds Annotations

1

2

Index and bounds checking annotations prevent array bounds exceptions and index-related errors through static analysis. These annotations track relationships between indices, array lengths, and numeric bounds to ensure safe array access.

3

4

## Capabilities

5

6

### Index Validity Annotations

7

8

Annotations that specify valid indices for arrays and collections.

9

10

```java { .api }

11

/**

12

* Indicates that the annotated expression is a valid index for the specified arrays

13

*/

14

@Documented

15

@Retention(RetentionPolicy.RUNTIME)

16

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

17

@SubtypeOf(LowerBoundUnknown.class)

18

public @interface IndexFor {

19

String[] value();

20

}

21

22

/**

23

* Valid index or the length of specified arrays (useful for insertion operations)

24

*/

25

@Documented

26

@Retention(RetentionPolicy.RUNTIME)

27

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

28

@SubtypeOf(UpperBoundUnknown.class)

29

public @interface IndexOrHigh {

30

String[] value();

31

}

32

33

/**

34

* Valid index or -1 for specified arrays (useful for search operations)

35

*/

36

@Documented

37

@Retention(RetentionPolicy.RUNTIME)

38

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

39

@SubtypeOf(LowerBoundUnknown.class)

40

public @interface IndexOrLow {

41

String[] value();

42

}

43

```

44

45

**Usage Examples:**

46

47

```java

48

import org.checkerframework.checker.index.qual.*;

49

50

public class IndexExample {

51

public void processArray(int[] array, @IndexFor("#1") int index) {

52

System.out.println(array[index]); // Safe - index is valid for array

53

}

54

55

public void insertAt(int[] array, @IndexOrHigh("#1") int position, int value) {

56

// Can insert at any valid index or at the end (position == array.length)

57

if (position < array.length) {

58

array[position] = value; // Safe insertion

59

}

60

}

61

62

public @IndexOrLow("#1") int find(int[] array, int target) {

63

for (int i = 0; i < array.length; i++) {

64

if (array[i] == target) {

65

return i; // Returns valid index

66

}

67

}

68

return -1; // Returns -1 if not found

69

}

70

}

71

```

72

73

### Numeric Range Annotations

74

75

Annotations for specifying numeric ranges and constraints.

76

77

```java { .api }

78

/**

79

* Indicates that the annotated expression evaluates to an integer >= 0

80

*/

81

@Documented

82

@Retention(RetentionPolicy.RUNTIME)

83

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

84

@SubtypeOf(GTENegativeOne.class)

85

public @interface NonNegative {}

86

87

/**

88

* Indicates that the annotated expression evaluates to an integer > 0

89

*/

90

@Documented

91

@Retention(RetentionPolicy.RUNTIME)

92

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

93

@SubtypeOf(NonNegative.class)

94

public @interface Positive {}

95

96

/**

97

* Indicates that the annotated expression evaluates to an integer >= -1

98

*/

99

@Documented

100

@Retention(RetentionPolicy.RUNTIME)

101

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

102

@SubtypeOf(LowerBoundUnknown.class)

103

public @interface GTENegativeOne {}

104

```

105

106

**Usage Examples:**

107

108

```java

109

import org.checkerframework.checker.index.qual.*;

110

111

public class RangeExample {

112

// Array size must be non-negative

113

public int[] createArray(@NonNegative int size) {

114

return new int[size]; // Safe - size >= 0

115

}

116

117

// Count must be positive for meaningful operations

118

public void repeat(@Positive int count, Runnable action) {

119

for (int i = 0; i < count; i++) {

120

action.run();

121

}

122

}

123

124

// Search result: valid index or -1

125

public @GTENegativeOne int binarySearch(int[] array, int target) {

126

// Implementation returns valid index or -1

127

return java.util.Arrays.binarySearch(array, target);

128

}

129

}

130

```

131

132

### Length Relationship Annotations

133

134

Annotations that express relationships between array lengths and indices.

135

136

```java { .api }

137

/**

138

* Indicates arrays have the same length

139

*/

140

@Documented

141

@Retention(RetentionPolicy.RUNTIME)

142

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

143

@SubtypeOf(SameLenUnknown.class)

144

public @interface SameLen {

145

String[] value();

146

}

147

148

/**

149

* Expression is the length of specified arrays

150

*/

151

@Documented

152

@Retention(RetentionPolicy.RUNTIME)

153

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

154

@SubtypeOf(UpperBoundUnknown.class)

155

public @interface LengthOf {

156

String[] value();

157

}

158

159

/**

160

* Expression is less than the length of specified arrays

161

*/

162

@Documented

163

@Retention(RetentionPolicy.RUNTIME)

164

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

165

@SubtypeOf(LTEqLengthOf.class)

166

public @interface LTLengthOf {

167

String[] value();

168

}

169

170

/**

171

* Expression is less than or equal to the length of specified arrays

172

*/

173

@Documented

174

@Retention(RetentionPolicy.RUNTIME)

175

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

176

@SubtypeOf(UpperBoundUnknown.class)

177

public @interface LTEqLengthOf {

178

String[] value();

179

}

180

181

/**

182

* Expression is less than the length minus one of specified arrays

183

*/

184

@Documented

185

@Retention(RetentionPolicy.RUNTIME)

186

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

187

@SubtypeOf(LTLengthOf.class)

188

public @interface LTOMLengthOf {

189

String[] value();

190

}

191

```

192

193

**Usage Examples:**

194

195

```java

196

import org.checkerframework.checker.index.qual.*;

197

198

public class LengthExample {

199

// Process arrays of same length

200

public void processParallel(@SameLen("#2") int[] array1, int[] array2) {

201

for (int i = 0; i < array1.length; i++) {

202

// Safe - arrays have same length

203

System.out.println(array1[i] + array2[i]);

204

}

205

}

206

207

// Size parameter represents array length

208

public void processWithSize(int[] array, @LengthOf("#1") int size) {

209

for (int i = 0; i < size; i++) {

210

System.out.println(array[i]); // Safe - i < size == array.length

211

}

212

}

213

214

// Index is less than array length

215

public void safeAccess(int[] array, @LTLengthOf("#1") int index) {

216

System.out.println(array[index]); // Safe - index < array.length

217

}

218

}

219

```

220

221

### Search and Substring Operations

222

223

Specialized annotations for search operations and string manipulation.

224

225

```java { .api }

226

/**

227

* Result of a search operation: valid index or -1

228

*/

229

@Documented

230

@Retention(RetentionPolicy.RUNTIME)

231

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

232

@SubtypeOf(SearchIndexUnknown.class)

233

public @interface SearchIndexFor {

234

String[] value();

235

}

236

237

/**

238

* Result of substring operations

239

*/

240

@Documented

241

@Retention(RetentionPolicy.RUNTIME)

242

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

243

@SubtypeOf(SubstringIndexUnknown.class)

244

public @interface SubstringIndexFor {

245

String[] value();

246

}

247

248

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

249

@SubtypeOf(SearchIndexFor.class)

250

public @interface SearchIndexBottom {}

251

252

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

253

@DefaultQualifierInHierarchy

254

public @interface SearchIndexUnknown {}

255

256

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

257

@SubtypeOf(SubstringIndexFor.class)

258

public @interface SubstringIndexBottom {}

259

260

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

261

@DefaultQualifierInHierarchy

262

public @interface SubstringIndexUnknown {}

263

```

264

265

**Usage Examples:**

266

267

```java

268

import org.checkerframework.checker.index.qual.*;

269

270

public class SearchExample {

271

public @SearchIndexFor("#1") int findValue(int[] array, int target) {

272

for (int i = 0; i < array.length; i++) {

273

if (array[i] == target) {

274

return i;

275

}

276

}

277

return -1;

278

}

279

280

public @SubstringIndexFor("#1") int findSubstring(String text, String pattern) {

281

return text.indexOf(pattern); // Returns valid index or -1

282

}

283

284

public void useSearchResult(String text, String pattern) {

285

@SubstringIndexFor("text") int index = findSubstring(text, pattern);

286

if (index >= 0) {

287

// Safe to use index for substring operations

288

String found = text.substring(index, index + pattern.length());

289

System.out.println("Found: " + found);

290

}

291

}

292

}

293

```

294

295

### Comparison and Ordering Annotations

296

297

Annotations for expressing ordering relationships between expressions.

298

299

```java { .api }

300

/**

301

* Expression is less than the specified expressions

302

*/

303

@Documented

304

@Retention(RetentionPolicy.RUNTIME)

305

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

306

@SubtypeOf(LessThanUnknown.class)

307

public @interface LessThan {

308

String[] value();

309

}

310

311

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

312

@SubtypeOf(LessThan.class)

313

public @interface LessThanBottom {}

314

315

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

316

@DefaultQualifierInHierarchy

317

public @interface LessThanUnknown {}

318

```

319

320

**Usage Examples:**

321

322

```java

323

import org.checkerframework.checker.index.qual.*;

324

325

public class ComparisonExample {

326

// Ensure start is less than end for valid ranges

327

public void processRange(@LessThan("#2") int start, int end) {

328

for (int i = start; i < end; i++) {

329

System.out.println("Processing item: " + i);

330

}

331

}

332

333

// Binary search with ordered bounds

334

public int binarySearch(int[] array, int target,

335

@LessThan("#4") int low, int high) {

336

while (low < high) {

337

int mid = (low + high) / 2;

338

if (array[mid] < target) {

339

low = mid + 1;

340

} else {

341

high = mid;

342

}

343

}

344

return low;

345

}

346

}

347

```

348

349

### Polymorphic Index Qualifiers

350

351

Polymorphic qualifiers that adapt based on context.

352

353

```java { .api }

354

/**

355

* Polymorphic index qualifier

356

*/

357

@Documented

358

@Retention(RetentionPolicy.RUNTIME)

359

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

360

@PolymorphicQualifier(LowerBoundUnknown.class)

361

public @interface PolyIndex {}

362

363

/**

364

* Polymorphic length qualifier

365

*/

366

@Documented

367

@Retention(RetentionPolicy.RUNTIME)

368

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

369

@PolymorphicQualifier(UpperBoundUnknown.class)

370

public @interface PolyLength {}

371

372

/**

373

* Polymorphic same-length qualifier

374

*/

375

@Documented

376

@Retention(RetentionPolicy.RUNTIME)

377

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

378

@PolymorphicQualifier(SameLenUnknown.class)

379

public @interface PolySameLen {}

380

381

/**

382

* Polymorphic lower bound qualifier

383

*/

384

@Documented

385

@Retention(RetentionPolicy.RUNTIME)

386

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

387

@PolymorphicQualifier(LowerBoundUnknown.class)

388

public @interface PolyLowerBound {}

389

390

/**

391

* Polymorphic upper bound qualifier

392

*/

393

@Documented

394

@Retention(RetentionPolicy.RUNTIME)

395

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

396

@PolymorphicQualifier(UpperBoundUnknown.class)

397

public @interface PolyUpperBound {}

398

```

399

400

**Usage Examples:**

401

402

```java

403

import org.checkerframework.checker.index.qual.*;

404

405

public class PolymorphicExample {

406

// Return type adapts to parameter index properties

407

public static @PolyIndex int identity(@PolyIndex int value) {

408

return value;

409

}

410

411

// Works with different index types

412

public void example(int[] array) {

413

@IndexFor("array") int validIndex = 5;

414

@NonNegative int nonNegValue = 10;

415

416

int result1 = identity(validIndex); // result1 is @IndexFor("array")

417

int result2 = identity(nonNegValue); // result2 is @NonNegative

418

}

419

}

420

```

421

422

### Method Contract Annotations

423

424

Annotations for expressing index-related method contracts.

425

426

```java { .api }

427

/**

428

* Method postcondition: ensures the specified expression is less than the length of specified arrays

429

*/

430

@Target(ElementType.METHOD)

431

@Retention(RetentionPolicy.RUNTIME)

432

@InheritedAnnotation

433

public @interface EnsuresLTLengthOf {

434

String[] value();

435

String[] targetValue();

436

}

437

438

/**

439

* Conditional method postcondition for length relationships

440

*/

441

@Target(ElementType.METHOD)

442

@Retention(RetentionPolicy.RUNTIME)

443

@InheritedAnnotation

444

public @interface EnsuresLTLengthOfIf {

445

String[] expression();

446

boolean result();

447

String[] targetValue();

448

}

449

```

450

451

**Usage Examples:**

452

453

```java

454

import org.checkerframework.checker.index.qual.*;

455

456

public class ContractExample {

457

private int currentIndex = 0;

458

private int[] data = new int[100];

459

460

@EnsuresLTLengthOf(value = "currentIndex", targetValue = "data")

461

public void reset() {

462

currentIndex = 0; // Ensures currentIndex < data.length

463

}

464

465

@EnsuresLTLengthOfIf(expression = "currentIndex", result = true, targetValue = "data")

466

public boolean hasNext() {

467

return currentIndex < data.length;

468

}

469

470

public void safeIteration() {

471

reset();

472

while (hasNext()) {

473

// Safe - postcondition ensures currentIndex < data.length

474

System.out.println(data[currentIndex]);

475

currentIndex++;

476

}

477

}

478

}

479

```

480

481

### Additional Utility Annotations

482

483

Supporting annotations for complex index relationships.

484

485

```java { .api }

486

/**

487

* Indicates that one array has a subsequence relationship with another

488

*/

489

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

490

@Retention(RetentionPolicy.RUNTIME)

491

public @interface HasSubsequence {

492

String[] subsequence();

493

String[] from();

494

String[] to();

495

}

496

497

/**

498

* Indicates a negative index for specified arrays (for reverse indexing)

499

*/

500

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

501

@Retention(RetentionPolicy.RUNTIME)

502

public @interface NegativeIndexFor {

503

String[] value();

504

}

505

506

/**

507

* Literal value for upper bound constraints

508

*/

509

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

510

@Retention(RetentionPolicy.RUNTIME)

511

public @interface UpperBoundLiteral {

512

String[] value();

513

}

514

```

515

516

**Usage Examples:**

517

518

```java

519

import org.checkerframework.checker.index.qual.*;

520

521

public class UtilityExample {

522

// Subsequence operations

523

public void copySubsequence(int[] source, int[] dest,

524

@HasSubsequence(subsequence = "dest", from = "#3", to = "#4")

525

int[] target,

526

int fromIndex, int toIndex) {

527

System.arraycopy(source, fromIndex, dest, 0, toIndex - fromIndex);

528

}

529

530

// Reverse indexing (Python-style negative indices)

531

public int getFromEnd(int[] array, @NegativeIndexFor("#1") int negativeIndex) {

532

return array[array.length + negativeIndex]; // Safe reverse access

533

}

534

}

535

```