or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-processing.mdindex.mdlanguage-support.mdmetrics.mdrule-framework.mdsymbols-types.md

ast-processing.mddocs/

0

# AST Processing

1

2

The PMD Java module provides comprehensive Abstract Syntax Tree (AST) processing capabilities with 187+ node types covering all Java language constructs. This includes support for modern Java features like records, pattern matching, sealed classes, and preview features through Java 24.

3

4

## Capabilities

5

6

### Core AST Interface

7

8

The foundation of AST processing is the `JavaNode` interface, which all Java AST nodes implement.

9

10

```java { .api }

11

/**

12

* Root interface for all Nodes of the Java AST

13

*/

14

public interface JavaNode extends JjtreeNode<JavaNode> {

15

/**

16

* Returns the node representing the type declaration this node is found in

17

* @return The enclosing type declaration or null if not inside a type

18

*/

19

ASTTypeDeclaration getEnclosingType();

20

21

/**

22

* Returns the compilation unit this node belongs to

23

*/

24

@NonNull ASTCompilationUnit getRoot();

25

26

/**

27

* Returns the symbol table for the program point represented by this node

28

*/

29

@NonNull JSymbolTable getSymbolTable();

30

31

/**

32

* Returns the type system with which this node was created

33

*/

34

TypeSystem getTypeSystem();

35

}

36

```

37

38

### Abstract Base Node

39

40

All concrete AST nodes extend `AbstractJavaNode` which provides the base implementation.

41

42

```java { .api }

43

/**

44

* Base implementation for all Java AST nodes

45

*/

46

public abstract class AbstractJavaNode implements JavaNode {

47

/**

48

* Accept method for the visitor pattern

49

*/

50

protected abstract <P, R> R acceptVisitor(JavaVisitor<? super P, ? extends R> visitor, P data);

51

}

52

```

53

54

### Compilation Unit

55

56

The root node of all Java ASTs representing a complete source file.

57

58

```java { .api }

59

/**

60

* The root node of all Java ASTs

61

*/

62

public final class ASTCompilationUnit extends AbstractJavaNode implements RootNode {

63

/**

64

* Returns the package declaration, if there is one

65

*/

66

@Nullable ASTPackageDeclaration getPackageDeclaration();

67

68

/**

69

* Returns the package name of this compilation unit

70

* @return Package name or empty string if no package declaration

71

*/

72

@NonNull String getPackageName();

73

74

/**

75

* Returns the top-level type declarations declared in this compilation unit

76

*/

77

NodeStream<ASTTypeDeclaration> getTypeDeclarations();

78

79

/**

80

* Returns the module declaration, if this is a modular compilation unit

81

*/

82

@Nullable ASTModuleDeclaration getModuleDeclaration();

83

84

/**

85

* Returns comments associated with this compilation unit

86

*/

87

List<JavaComment> getComments();

88

89

/**

90

* Checks if this is a simple compilation unit (Java 22+ preview feature)

91

*/

92

boolean isSimpleCompilationUnit();

93

}

94

```

95

96

## Type Declaration Nodes

97

98

### Class Declarations

99

100

```java { .api }

101

/**

102

* Represents a class declaration

103

*/

104

public final class ASTClassDeclaration extends AbstractTypeDeclaration

105

implements ASTAnyTypeDeclaration, ModifierOwner, Annotatable {

106

107

/**

108

* Returns the simple name of this class

109

*/

110

@NonNull String getSimpleName();

111

112

/**

113

* Returns the superclass type, or null if this extends Object implicitly

114

*/

115

@Nullable ASTClassType getSuperClassTypeNode();

116

117

/**

118

* Returns the implemented interfaces

119

*/

120

NodeStream<ASTClassType> getSuperInterfaceTypeNodes();

121

122

/**

123

* Returns the type parameters of this class

124

*/

125

@Nullable ASTTypeParameters getTypeParameters();

126

127

/**

128

* Returns the body of this class containing field and method declarations

129

*/

130

ASTClassBody getBody();

131

132

/**

133

* Returns the class symbol for symbol resolution

134

*/

135

JClassSymbol getSymbol();

136

137

/**

138

* Checks if this is a local class (defined within a method or initializer)

139

*/

140

boolean isLocal();

141

142

/**

143

* Checks if this is a nested class (not top-level)

144

*/

145

boolean isNested();

146

}

147

```

148

149

### Interface Declarations

150

151

```java { .api }

152

/**

153

* Represents an interface declaration

154

*/

155

public final class ASTInterfaceDeclaration extends AbstractTypeDeclaration

156

implements ASTAnyTypeDeclaration, ModifierOwner, Annotatable {

157

158

/**

159

* Returns the simple name of this interface

160

*/

161

@NonNull String getSimpleName();

162

163

/**

164

* Returns the extended interfaces

165

*/

166

NodeStream<ASTClassType> getSuperInterfaceTypeNodes();

167

168

/**

169

* Returns the type parameters of this interface

170

*/

171

@Nullable ASTTypeParameters getTypeParameters();

172

173

/**

174

* Returns the body of this interface

175

*/

176

ASTInterfaceBody getBody();

177

178

/**

179

* Returns the interface symbol

180

*/

181

JClassSymbol getSymbol();

182

}

183

```

184

185

### Record Declarations (Java 14+)

186

187

```java { .api }

188

/**

189

* Represents a record declaration (Java 14+)

190

*/

191

public final class ASTRecordDeclaration extends AbstractTypeDeclaration

192

implements ASTAnyTypeDeclaration, ModifierOwner, Annotatable {

193

194

/**

195

* Returns the simple name of this record

196

*/

197

@NonNull String getSimpleName();

198

199

/**

200

* Returns the record components (parameters)

201

*/

202

ASTRecordComponentList getComponentList();

203

204

/**

205

* Returns the implemented interfaces

206

*/

207

NodeStream<ASTClassType> getSuperInterfaceTypeNodes();

208

209

/**

210

* Returns the type parameters of this record

211

*/

212

@Nullable ASTTypeParameters getTypeParameters();

213

214

/**

215

* Returns the body of this record

216

*/

217

ASTRecordBody getBody();

218

219

/**

220

* Returns the record symbol

221

*/

222

JClassSymbol getSymbol();

223

}

224

```

225

226

### Enum Declarations

227

228

```java { .api }

229

/**

230

* Represents an enum declaration

231

*/

232

public final class ASTEnumDeclaration extends AbstractTypeDeclaration

233

implements ASTAnyTypeDeclaration, ModifierOwner, Annotatable {

234

235

/**

236

* Returns the simple name of this enum

237

*/

238

@NonNull String getSimpleName();

239

240

/**

241

* Returns the implemented interfaces

242

*/

243

NodeStream<ASTClassType> getSuperInterfaceTypeNodes();

244

245

/**

246

* Returns the type parameters (for generic enums - rare)

247

*/

248

@Nullable ASTTypeParameters getTypeParameters();

249

250

/**

251

* Returns the body of this enum

252

*/

253

ASTEnumBody getBody();

254

255

/**

256

* Returns the enum symbol

257

*/

258

JClassSymbol getSymbol();

259

}

260

```

261

262

## Expression Nodes

263

264

### Method Calls

265

266

```java { .api }

267

/**

268

* A method invocation expression (qualified and unqualified)

269

*/

270

public final class ASTMethodCall extends AbstractInvocationExpr

271

implements QualifiableExpression {

272

273

/**

274

* Returns the name of the invoked method

275

*/

276

@NonNull String getMethodName();

277

278

/**

279

* Returns the argument list of this method call

280

*/

281

@NonNull ASTArgumentList getArguments();

282

283

/**

284

* Returns explicit type arguments if present (e.g., obj.<String>method())

285

*/

286

@Nullable ASTTypeArguments getExplicitTypeArguments();

287

288

/**

289

* Returns the qualifier expression (left side of the dot)

290

*/

291

@Nullable ASTExpression getQualifier();

292

293

/**

294

* Returns the resolved method symbol

295

*/

296

JMethodSymbol getMethodType();

297

298

/**

299

* Returns the return type of this method call

300

*/

301

JTypeMirror getTypeMirror();

302

}

303

```

304

305

### Field Access

306

307

```java { .api }

308

/**

309

* A field access expression

310

*/

311

public final class ASTFieldAccess extends AbstractJavaExpr

312

implements QualifiableExpression, AssignmentTarget {

313

314

/**

315

* Returns the name of the accessed field

316

*/

317

@NonNull String getName();

318

319

/**

320

* Returns the qualifier expression (object whose field is accessed)

321

*/

322

@Nullable ASTExpression getQualifier();

323

324

/**

325

* Returns the resolved field symbol

326

*/

327

JFieldSymbol getReferencedSym();

328

329

/**

330

* Returns the type of this field access

331

*/

332

JTypeMirror getTypeMirror();

333

}

334

```

335

336

### Variable Access

337

338

```java { .api }

339

/**

340

* A variable access expression (local variables, parameters)

341

*/

342

public final class ASTVariableAccess extends AbstractJavaExpr

343

implements AssignmentTarget {

344

345

/**

346

* Returns the name of the accessed variable

347

*/

348

@NonNull String getName();

349

350

/**

351

* Returns the resolved variable symbol

352

*/

353

JVariableSymbol getReferencedSym();

354

355

/**

356

* Returns the type of this variable

357

*/

358

JTypeMirror getTypeMirror();

359

}

360

```

361

362

### Lambda Expressions (Java 8+)

363

364

```java { .api }

365

/**

366

* A lambda expression (Java 8+)

367

*/

368

public final class ASTLambdaExpression extends AbstractJavaExpr {

369

/**

370

* Returns the parameter list of this lambda

371

*/

372

ASTLambdaParameterList getParameters();

373

374

/**

375

* Returns the body of this lambda (expression or block)

376

*/

377

JavaNode getBody();

378

379

/**

380

* Checks if the body is a block statement

381

*/

382

boolean isBlockBody();

383

384

/**

385

* Checks if the body is an expression

386

*/

387

boolean isExpressionBody();

388

389

/**

390

* Returns the functional interface type this lambda implements

391

*/

392

JTypeMirror getTypeMirror();

393

}

394

```

395

396

### Literal Expressions

397

398

```java { .api }

399

/**

400

* Base class for all literal expressions

401

*/

402

public abstract class ASTLiteral extends AbstractJavaExpr {

403

/**

404

* Returns the constant value represented by this literal

405

*/

406

Object getConstValue();

407

408

/**

409

* Returns the type of this literal

410

*/

411

JTypeMirror getTypeMirror();

412

}

413

414

/**

415

* A string literal

416

*/

417

public final class ASTStringLiteral extends ASTLiteral {

418

/**

419

* Returns the string value (with escape sequences processed)

420

*/

421

String getConstValue();

422

423

/**

424

* Checks if this is a text block (Java 15+)

425

*/

426

boolean isTextBlock();

427

}

428

429

/**

430

* A numeric literal (integers, floats, etc.)

431

*/

432

public final class ASTNumericLiteral extends ASTLiteral {

433

/**

434

* Returns the numeric value as Number

435

*/

436

Number getConstValue();

437

438

/**

439

* Returns the base of this numeric literal (2, 8, 10, or 16)

440

*/

441

int getBase();

442

443

/**

444

* Checks if this literal has a suffix (L, F, D, etc.)

445

*/

446

boolean hasSuffix();

447

}

448

449

/**

450

* A boolean literal (true/false)

451

*/

452

public final class ASTBooleanLiteral extends ASTLiteral {

453

/**

454

* Returns the boolean value

455

*/

456

boolean isTrue();

457

}

458

```

459

460

## Statement Nodes

461

462

### Control Flow Statements

463

464

```java { .api }

465

/**

466

* An if statement

467

*/

468

public final class ASTIfStatement extends AbstractJavaStatement {

469

/**

470

* Returns the condition expression

471

*/

472

ASTExpression getCondition();

473

474

/**

475

* Returns the then-branch statement

476

*/

477

ASTStatement getThenBranch();

478

479

/**

480

* Returns the else-branch statement, if present

481

*/

482

@Nullable ASTStatement getElseBranch();

483

484

/**

485

* Checks if this if statement has an else clause

486

*/

487

boolean hasElse();

488

}

489

490

/**

491

* A for statement

492

*/

493

public final class ASTForStatement extends AbstractJavaStatement {

494

/**

495

* Returns the init clause (traditional for loop)

496

*/

497

@Nullable ASTForInit getInit();

498

499

/**

500

* Returns the condition expression

501

*/

502

@Nullable ASTExpression getCondition();

503

504

/**

505

* Returns the update clause

506

*/

507

@Nullable ASTForUpdate getUpdate();

508

509

/**

510

* Returns the loop body

511

*/

512

ASTStatement getBody();

513

}

514

515

/**

516

* An enhanced for statement (for-each, Java 5+)

517

*/

518

public final class ASTForeachStatement extends AbstractJavaStatement {

519

/**

520

* Returns the loop variable declaration

521

*/

522

ASTForeachVariable getVariable();

523

524

/**

525

* Returns the iterable expression

526

*/

527

ASTExpression getIterable();

528

529

/**

530

* Returns the loop body

531

*/

532

ASTStatement getBody();

533

}

534

```

535

536

### Switch Statements

537

538

```java { .api }

539

/**

540

* A switch statement with modern pattern matching support

541

*/

542

public final class ASTSwitchStatement extends AbstractJavaStatement {

543

/**

544

* Returns the switch expression (what we're switching on)

545

*/

546

ASTExpression getTestedExpression();

547

548

/**

549

* Returns all switch branches (cases and default)

550

*/

551

NodeStream<ASTSwitchBranch> getBranches();

552

553

/**

554

* Checks if this is a switch expression (returns a value)

555

*/

556

boolean isExpressionSwitch();

557

}

558

559

/**

560

* A switch branch (case or default)

561

*/

562

public abstract class ASTSwitchBranch extends AbstractJavaNode {

563

/**

564

* Returns the statements in this branch

565

*/

566

NodeStream<ASTStatement> getStatements();

567

568

/**

569

* Checks if this branch is a switch arrow branch (->)

570

*/

571

boolean isArrowBranch();

572

}

573

574

/**

575

* A switch labeled rule (case with arrow syntax)

576

*/

577

public final class ASTSwitchArrowBranch extends ASTSwitchBranch {

578

/**

579

* Returns the case labels for this branch

580

*/

581

NodeStream<ASTSwitchLabel> getLabels();

582

583

/**

584

* Returns the right-hand side (expression or statement)

585

*/

586

JavaNode getRightHandSide();

587

}

588

```

589

590

## Type System Nodes

591

592

### Type Nodes

593

594

```java { .api }

595

/**

596

* Base class for all type nodes in the AST

597

*/

598

public abstract class ASTType extends AbstractJavaNode implements Iterable<ASTType> {

599

/**

600

* Returns the type mirror this AST node represents

601

*/

602

JTypeMirror getTypeMirror();

603

}

604

605

/**

606

* A primitive type (int, boolean, etc.)

607

*/

608

public final class ASTPrimitiveType extends ASTType {

609

/**

610

* Returns the kind of primitive type

611

*/

612

JPrimitiveType.PrimitiveTypeKind getKind();

613

}

614

615

/**

616

* A class or interface type (possibly generic)

617

*/

618

public final class ASTClassType extends ASTType {

619

/**

620

* Returns the simple name of this type

621

*/

622

@NonNull String getSimpleName();

623

624

/**

625

* Returns the type arguments if this is a parameterized type

626

*/

627

@Nullable ASTTypeArguments getTypeArguments();

628

629

/**

630

* Returns the qualifier if this is a qualified type name

631

*/

632

@Nullable ASTClassType getQualifier();

633

634

/**

635

* Returns the resolved type symbol

636

*/

637

JClassSymbol getReferencedSym();

638

}

639

640

/**

641

* An array type

642

*/

643

public final class ASTArrayType extends ASTType {

644

/**

645

* Returns the element type of this array

646

*/

647

ASTType getElementType();

648

649

/**

650

* Returns the array dimensions

651

*/

652

ASTArrayDimensions getDimensions();

653

654

/**

655

* Returns the number of dimensions

656

*/

657

int getArrayDepth();

658

}

659

```

660

661

## Visitor Pattern

662

663

### Base Visitor

664

665

```java { .api }

666

/**

667

* Base visitor implementation for traversing Java ASTs

668

*/

669

public abstract class JavaVisitorBase<P, R> implements JavaVisitor<P, R> {

670

// Visit methods for all AST node types (187+ methods)

671

672

// Compilation unit and top-level declarations

673

public R visit(ASTCompilationUnit node, P data);

674

public R visit(ASTPackageDeclaration node, P data);

675

public R visit(ASTImportDeclaration node, P data);

676

677

// Type declarations

678

public R visit(ASTClassDeclaration node, P data);

679

public R visit(ASTInterfaceDeclaration node, P data);

680

public R visit(ASTEnumDeclaration node, P data);

681

public R visit(ASTRecordDeclaration node, P data);

682

public R visit(ASTAnnotationTypeDeclaration node, P data);

683

684

// Method and field declarations

685

public R visit(ASTMethodDeclaration node, P data);

686

public R visit(ASTConstructorDeclaration node, P data);

687

public R visit(ASTFieldDeclaration node, P data);

688

689

// Expressions (30+ visit methods)

690

public R visit(ASTMethodCall node, P data);

691

public R visit(ASTFieldAccess node, P data);

692

public R visit(ASTVariableAccess node, P data);

693

public R visit(ASTLambdaExpression node, P data);

694

public R visit(ASTMethodReference node, P data);

695

696

// Literals

697

public R visit(ASTStringLiteral node, P data);

698

public R visit(ASTNumericLiteral node, P data);

699

public R visit(ASTBooleanLiteral node, P data);

700

public R visit(ASTNullLiteral node, P data);

701

702

// Statements (25+ visit methods)

703

public R visit(ASTIfStatement node, P data);

704

public R visit(ASTForStatement node, P data);

705

public R visit(ASTForeachStatement node, P data);

706

public R visit(ASTWhileStatement node, P data);

707

public R visit(ASTSwitchStatement node, P data);

708

public R visit(ASTTryStatement node, P data);

709

710

// Type nodes

711

public R visit(ASTPrimitiveType node, P data);

712

public R visit(ASTClassType node, P data);

713

public R visit(ASTArrayType node, P data);

714

public R visit(ASTWildcardType node, P data);

715

716

// Pattern nodes (Java 14+)

717

public R visit(ASTTypePattern node, P data);

718

public R visit(ASTRecordPattern node, P data);

719

720

// Default delegation method

721

protected R visitJavaNode(JavaNode node, P data);

722

}

723

```

724

725

**Usage Examples:**

726

727

```java

728

// Example visitor to find all method calls

729

public class MethodCallVisitor extends JavaVisitorBase<Void, Void> {

730

private List<String> methodNames = new ArrayList<>();

731

732

@Override

733

public Void visit(ASTMethodCall node, Void data) {

734

methodNames.add(node.getMethodName());

735

return super.visit(node, data); // Continue traversing children

736

}

737

738

public List<String> getMethodNames() {

739

return methodNames;

740

}

741

}

742

743

// Example visitor to calculate complexity

744

public class ComplexityVisitor extends JavaVisitorBase<Void, Integer> {

745

@Override

746

public Integer visit(ASTIfStatement node, Void data) {

747

int complexity = 1; // Base complexity for if

748

if (node.hasElse()) {

749

complexity += 1; // Additional for else

750

}

751

return complexity + super.visit(node, data);

752

}

753

754

@Override

755

public Integer visit(ASTForStatement node, Void data) {

756

return 1 + super.visit(node, data); // Add 1 for loop

757

}

758

759

@Override

760

protected Integer visitJavaNode(JavaNode node, Void data) {

761

int total = 0;

762

for (JavaNode child : node.children()) {

763

Integer childComplexity = child.acceptVisitor(this, data);

764

if (childComplexity != null) {

765

total += childComplexity;

766

}

767

}

768

return total;

769

}

770

}

771

```

772

773

## Common Interfaces

774

775

### Modifier Support

776

777

```java { .api }

778

/**

779

* Interface for nodes that can have modifiers

780

*/

781

public interface ModifierOwner {

782

/**

783

* Returns the modifier list

784

*/

785

ASTModifierList getModifiers();

786

787

/**

788

* Returns the visibility of this declaration

789

*/

790

Visibility getVisibility();

791

792

/**

793

* Returns the effective visibility (considering enclosing scopes)

794

*/

795

Visibility getEffectiveVisibility();

796

797

/**

798

* Checks if this declaration has the specified modifiers

799

*/

800

boolean hasModifiers(JModifier... modifiers);

801

802

/**

803

* Checks if this declaration has explicit (written) modifiers

804

*/

805

boolean hasExplicitModifiers(JModifier... modifiers);

806

}

807

```

808

809

### Annotation Support

810

811

```java { .api }

812

/**

813

* Interface for nodes that can be annotated

814

*/

815

public interface Annotatable {

816

/**

817

* Returns all declared annotations on this element

818

*/

819

NodeStream<ASTAnnotation> getDeclaredAnnotations();

820

821

/**

822

* Checks if an annotation is present by binary name

823

*/

824

boolean isAnnotationPresent(String binaryName);

825

826

/**

827

* Checks if an annotation is present by class

828

*/

829

boolean isAnnotationPresent(Class<? extends java.lang.annotation.Annotation> clazz);

830

831

/**

832

* Returns a specific annotation by binary name

833

*/

834

@Nullable ASTAnnotation getAnnotation(String binaryName);

835

836

/**

837

* Returns a specific annotation by class

838

*/

839

@Nullable ASTAnnotation getAnnotation(Class<? extends java.lang.annotation.Annotation> clazz);

840

}

841

```