or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-navigation.mdconfiguration.mdindex.mdparsing.mdprinting.mdserialization.mdsymbol-resolution.mdvisitors.md

ast-navigation.mddocs/

0

# AST Navigation and Manipulation

1

2

JavaParser provides a comprehensive Abstract Syntax Tree (AST) model with over 100 node types representing all Java language constructs. The AST supports navigation, search, modification, and observation of changes.

3

4

## Capabilities

5

6

### Base Node Functionality

7

8

All AST nodes extend the abstract Node class, providing common functionality for traversal, search, and manipulation.

9

10

```java { .api }

11

/**

12

* Base class for all AST nodes

13

*/

14

public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable, NodeWithRange<Node>, NodeWithTokenRange<Node> {

15

16

/**

17

* Accept a generic visitor that returns a value

18

* @param v The visitor to accept

19

* @param arg Argument passed to visitor methods

20

* @return Value returned by visitor

21

*/

22

public <R, A> R accept(GenericVisitor<R, A> v, A arg);

23

24

/**

25

* Accept a void visitor for side effects

26

* @param v The visitor to accept

27

* @param arg Argument passed to visitor methods

28

*/

29

public <A> void accept(VoidVisitor<A> v, A arg);

30

31

/**

32

* Find all descendant nodes of a specific type

33

* @param clazz Class of nodes to find

34

* @return List of nodes matching the type

35

*/

36

public <T extends Node> List<T> findAll(Class<T> clazz);

37

38

/**

39

* Find first descendant node of a specific type

40

* @param clazz Class of node to find

41

* @return Optional containing first match, empty if none found

42

*/

43

public <T extends Node> Optional<T> findFirst(Class<T> clazz);

44

45

/**

46

* Get parent node

47

* @return Optional containing parent, empty if this is root

48

*/

49

public Optional<Node> getParentNode();

50

51

/**

52

* Replace this node with another node

53

* @param node Replacement node

54

* @return true if replacement was successful

55

*/

56

public boolean replace(Node node);

57

58

/**

59

* Remove this node from its parent

60

* @return true if removal was successful

61

*/

62

public boolean remove();

63

64

/**

65

* Create deep copy of this node

66

* @return Cloned node

67

*/

68

public Node clone();

69

70

/**

71

* Get range of this node in source code

72

* @return Optional containing range, empty if not available

73

*/

74

public Optional<Range> getRange();

75

76

/**

77

* Set data associated with this node

78

* @param key Data key

79

* @param value Data value

80

*/

81

public <T> void setData(DataKey<T> key, T value);

82

83

/**

84

* Get data associated with this node

85

* @param key Data key

86

* @return Data value

87

* @throws IllegalStateException if key is not found

88

*/

89

public <T> T getData(DataKey<T> key);

90

91

/**

92

* Find data associated with this node

93

* @param key Data key

94

* @return Optional containing data value, empty if not found

95

*/

96

public <T> Optional<T> findData(DataKey<T> key);

97

98

/**

99

* Get token range of this node in source code

100

* @return Optional containing token range, empty if not available

101

*/

102

public Optional<TokenRange> getTokenRange();

103

104

/**

105

* Stream all descendant nodes

106

* @return Stream of all descendant nodes

107

*/

108

public Stream<Node> stream();

109

110

/**

111

* Stream descendant nodes with specific traversal strategy

112

* @param traversal Tree traversal strategy

113

* @return Stream of nodes using specified traversal

114

*/

115

public Stream<Node> stream(TreeTraversal traversal);

116

117

/**

118

* Walk the AST tree and apply consumer to each node

119

* @param consumer Function to apply to each node

120

*/

121

public void walk(Consumer<Node> consumer);

122

123

/**

124

* Walk the AST tree with specific traversal and apply consumer

125

* @param traversal Tree traversal strategy

126

* @param consumer Function to apply to each node

127

*/

128

public void walk(TreeTraversal traversal, Consumer<Node> consumer);

129

130

/**

131

* Find all descendant nodes matching predicate

132

* @param clazz Class of nodes to find

133

* @param predicate Condition to match

134

* @return List of matching nodes

135

*/

136

public <T extends Node> List<T> findAll(Class<T> clazz, Predicate<T> predicate);

137

138

/**

139

* Find first descendant node matching predicate

140

* @param clazz Class of node to find

141

* @param predicate Condition to match

142

* @return Optional containing first match, empty if none found

143

*/

144

public <T extends Node> Optional<T> findFirst(Class<T> clazz, Predicate<T> predicate);

145

146

/**

147

* Check if this node contains data for the given key

148

* @param key Data key to check

149

* @return true if data exists for key

150

*/

151

public boolean containsData(DataKey<?> key);

152

153

/**

154

* Remove data associated with key

155

* @param key Data key to remove

156

*/

157

public void removeData(DataKey<?> key);

158

159

/**

160

* Get all data keys associated with this node

161

* @return Set of data keys

162

*/

163

public Set<DataKey<?>> getDataKeys();

164

165

/**

166

* Find the root node of the AST

167

* @return Root node of the tree

168

*/

169

public Node findRootNode();

170

171

/**

172

* Find the CompilationUnit containing this node

173

* @return Optional containing CompilationUnit, empty if not found

174

*/

175

public Optional<CompilationUnit> findCompilationUnit();

176

}

177

```

178

179

**Usage Examples:**

180

181

```java

182

CompilationUnit cu = StaticJavaParser.parse(code);

183

184

// Find all method declarations

185

List<MethodDeclaration> methods = cu.findAll(MethodDeclaration.class);

186

187

// Find first class declaration

188

Optional<ClassOrInterfaceDeclaration> firstClass =

189

cu.findFirst(ClassOrInterfaceDeclaration.class);

190

191

// Navigate parent-child relationships

192

for (MethodDeclaration method : methods) {

193

Optional<Node> parent = method.getParentNode();

194

if (parent.isPresent() && parent.get() instanceof ClassOrInterfaceDeclaration) {

195

ClassOrInterfaceDeclaration owner = (ClassOrInterfaceDeclaration) parent.get();

196

System.out.println("Method " + method.getNameAsString() +

197

" belongs to class " + owner.getNameAsString());

198

}

199

}

200

201

// Clone nodes

202

MethodDeclaration originalMethod = methods.get(0);

203

MethodDeclaration clonedMethod = originalMethod.clone();

204

```

205

206

### CompilationUnit - Root AST Node

207

208

The CompilationUnit represents a complete Java source file and serves as the root of the AST.

209

210

```java { .api }

211

/**

212

* Root AST node representing a Java source file

213

*/

214

public class CompilationUnit extends Node {

215

216

/**

217

* Get all type declarations (classes, interfaces, enums, annotations)

218

* @return NodeList of type declarations

219

*/

220

public NodeList<TypeDeclaration<?>> getTypes();

221

222

/**

223

* Get all import declarations

224

* @return NodeList of import declarations

225

*/

226

public NodeList<ImportDeclaration> getImports();

227

228

/**

229

* Get package declaration

230

* @return Optional containing package declaration, empty if default package

231

*/

232

public Optional<PackageDeclaration> getPackageDeclaration();

233

234

/**

235

* Get primary type declaration (usually first public type)

236

* @return Optional containing primary type

237

*/

238

public Optional<TypeDeclaration<?>> getPrimaryType();

239

240

/**

241

* Get primary type name

242

* @return Optional containing primary type name

243

*/

244

public Optional<String> getPrimaryTypeName();

245

246

/**

247

* Get module declaration

248

* @return Optional containing module declaration, empty if not a module

249

*/

250

public Optional<ModuleDeclaration> getModule();

251

252

/**

253

* Set module declaration

254

* @param module Module declaration to set

255

* @return This CompilationUnit for chaining

256

*/

257

public CompilationUnit setModule(ModuleDeclaration module);

258

259

/**

260

* Set module by name

261

* @param name Module name

262

* @return This CompilationUnit for chaining

263

*/

264

public CompilationUnit setModule(String name);

265

266

/**

267

* Remove module declaration

268

* @return This CompilationUnit for chaining

269

*/

270

public CompilationUnit removeModule();

271

272

/**

273

* Get class declaration by name

274

* @param className Name of class to find

275

* @return Optional containing class declaration

276

*/

277

public Optional<ClassOrInterfaceDeclaration> getClassByName(String className);

278

279

/**

280

* Get interface declaration by name

281

* @param interfaceName Name of interface to find

282

* @return Optional containing interface declaration

283

*/

284

public Optional<ClassOrInterfaceDeclaration> getInterfaceByName(String interfaceName);

285

286

/**

287

* Get enum declaration by name

288

* @param enumName Name of enum to find

289

* @return Optional containing enum declaration

290

*/

291

public Optional<EnumDeclaration> getEnumByName(String enumName);

292

293

/**

294

* Get annotation declaration by name

295

* @param annotationName Name of annotation to find

296

* @return Optional containing annotation declaration

297

*/

298

public Optional<AnnotationDeclaration> getAnnotationDeclarationByName(String annotationName);

299

300

/**

301

* Get record declaration by name (Java 14+)

302

* @param recordName Name of record to find

303

* @return Optional containing record declaration

304

*/

305

public Optional<RecordDeclaration> getRecordByName(String recordName);

306

307

/**

308

* Add a new class to this compilation unit

309

* @param name Class name

310

* @return Created ClassOrInterfaceDeclaration

311

*/

312

public ClassOrInterfaceDeclaration addClass(String name);

313

314

/**

315

* Add a new interface to this compilation unit

316

* @param name Interface name

317

* @return Created ClassOrInterfaceDeclaration

318

*/

319

public ClassOrInterfaceDeclaration addInterface(String name);

320

321

/**

322

* Add a new enum to this compilation unit

323

* @param name Enum name

324

* @return Created EnumDeclaration

325

*/

326

public EnumDeclaration addEnum(String name);

327

328

/**

329

* Set package declaration

330

* @param packageDeclaration Package declaration to set

331

* @return This CompilationUnit for chaining

332

*/

333

public CompilationUnit setPackageDeclaration(PackageDeclaration packageDeclaration);

334

335

/**

336

* Set package name

337

* @param name Package name

338

* @return This CompilationUnit for chaining

339

*/

340

public CompilationUnit setPackageDeclaration(String name);

341

342

/**

343

* Add import declaration

344

* @param importDeclaration Import to add

345

* @return This CompilationUnit for chaining

346

*/

347

public CompilationUnit addImport(ImportDeclaration importDeclaration);

348

349

/**

350

* Add import by name

351

* @param name Import name (e.g., "java.util.List")

352

* @return This CompilationUnit for chaining

353

*/

354

public CompilationUnit addImport(String name);

355

356

/**

357

* Add static import

358

* @param name Static import name

359

* @return This CompilationUnit for chaining

360

*/

361

public CompilationUnit addStaticImport(String name);

362

}

363

```

364

365

**Usage Examples:**

366

367

```java

368

CompilationUnit cu = StaticJavaParser.parse(sourceCode);

369

370

// Access package and imports

371

Optional<PackageDeclaration> pkg = cu.getPackageDeclaration();

372

NodeList<ImportDeclaration> imports = cu.getImports();

373

374

// Get all types

375

NodeList<TypeDeclaration<?>> types = cu.getTypes();

376

for (TypeDeclaration<?> type : types) {

377

System.out.println("Found type: " + type.getNameAsString());

378

}

379

380

// Modify compilation unit

381

CompilationUnit newCu = new CompilationUnit();

382

newCu.setPackageDeclaration("com.example");

383

newCu.addImport("java.util.List");

384

newCu.addImport("java.util.ArrayList");

385

386

ClassOrInterfaceDeclaration newClass = newCu.addClass("MyClass");

387

newClass.addField("String", "name").setPrivate(true);

388

```

389

390

### Observable NodeList

391

392

JavaParser uses NodeList, an observable list implementation, for collections of AST nodes.

393

394

```java { .api }

395

/**

396

* Observable list for AST nodes

397

*/

398

public class NodeList<T> extends ArrayList<T> implements Observable {

399

400

/**

401

* Create empty node list

402

*/

403

public NodeList();

404

405

/**

406

* Create node list from collection

407

* @param collection Initial elements

408

*/

409

public NodeList(Collection<? extends T> collection);

410

411

/**

412

* Register observer for changes

413

* @param observer Observer to register

414

*/

415

public void register(AstObserver observer);

416

417

/**

418

* Unregister observer

419

* @param observer Observer to unregister

420

*/

421

public void unregister(AstObserver observer);

422

423

// Standard List interface methods...

424

// All methods fire change notifications to observers

425

}

426

```

427

428

### AST Node Search and Filtering

429

430

Advanced search capabilities for finding specific nodes in the AST.

431

432

```java { .api }

433

/**

434

* Find nodes matching a predicate

435

* @param predicate Condition to match

436

* @return List of matching nodes

437

*/

438

public <T> List<T> findAll(Class<T> clazz, Predicate<T> predicate);

439

440

/**

441

* Check if any descendant nodes match condition

442

* @param predicate Condition to check

443

* @return true if any nodes match

444

*/

445

public boolean containsData(Predicate<Node> predicate);

446

447

/**

448

* Walk the AST tree and collect results

449

* @param visitor Function to apply to each node

450

* @return Stream of results

451

*/

452

public <T> Stream<T> walk(Function<Node, Stream<T>> visitor);

453

```

454

455

**Usage Examples:**

456

457

```java

458

// Find all public methods

459

List<MethodDeclaration> publicMethods = cu.findAll(MethodDeclaration.class,

460

method -> method.isPublic());

461

462

// Find methods with specific name

463

List<MethodDeclaration> getMethods = cu.findAll(MethodDeclaration.class,

464

method -> method.getNameAsString().startsWith("get"));

465

466

// Find all string literals

467

List<StringLiteralExpr> strings = cu.findAll(StringLiteralExpr.class);

468

469

// Check for specific patterns

470

boolean hasMainMethod = cu.findAll(MethodDeclaration.class).stream()

471

.anyMatch(method -> method.getNameAsString().equals("main")

472

&& method.isStatic()

473

&& method.isPublic());

474

```

475

476

### AST Modification

477

478

Modify AST nodes by adding, removing, or replacing elements.

479

480

```java { .api }

481

// Add new elements to classes

482

ClassOrInterfaceDeclaration clazz = cu.findFirst(ClassOrInterfaceDeclaration.class).get();

483

484

// Add field

485

FieldDeclaration field = clazz.addField(String.class, "newField");

486

field.setPrivate(true);

487

488

// Add method

489

MethodDeclaration method = clazz.addMethod("getValue", Modifier.Keyword.PUBLIC);

490

method.setType("String");

491

method.setBody(StaticJavaParser.parseBlock("{ return this.value; }"));

492

493

// Add constructor

494

ConstructorDeclaration constructor = clazz.addConstructor(Modifier.Keyword.PUBLIC);

495

constructor.addParameter("String", "value");

496

constructor.setBody(StaticJavaParser.parseBlock("{ this.value = value; }"));

497

498

// Remove elements

499

field.remove(); // Remove from parent

500

method.replace(newMethod); // Replace with new method

501

```

502

503

## Key AST Node Types

504

505

```java { .api }

506

// Type declarations

507

public class ClassOrInterfaceDeclaration extends TypeDeclaration<ClassOrInterfaceDeclaration> {

508

public boolean isInterface();

509

public NodeList<ClassOrInterfaceType> getExtendedTypes();

510

public NodeList<ClassOrInterfaceType> getImplementedTypes();

511

}

512

513

public class MethodDeclaration extends CallableDeclaration<MethodDeclaration> {

514

public Type getType();

515

public NodeList<Parameter> getParameters();

516

public Optional<BlockStmt> getBody();

517

}

518

519

public class FieldDeclaration extends BodyDeclaration<FieldDeclaration> {

520

public NodeList<VariableDeclarator> getVariables();

521

}

522

523

// Expressions

524

public abstract class Expression extends Node {

525

public boolean isAssignExpr();

526

public boolean isBinaryExpr();

527

public boolean isMethodCallExpr();

528

// ... type checking methods for all expression types

529

}

530

531

// Statements

532

public abstract class Statement extends Node {

533

public boolean isBlockStmt();

534

public boolean isIfStmt();

535

public boolean isForStmt();

536

// ... type checking methods for all statement types

537

}

538

```