or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-utilities.mddependency-management.mdindex.mdschematics.mdstandalone-utilities.mdworkspace-utilities.md

ast-utilities.mddocs/

0

# AST Utilities

1

2

Utilities for parsing, analyzing, and modifying TypeScript Abstract Syntax Trees (AST) to programmatically update Angular code. These functions enable precise code modifications for schematics.

3

4

## Capabilities

5

6

### Node Finding

7

8

Functions for locating specific nodes within TypeScript AST structures.

9

10

```typescript { .api }

11

/**

12

* Finds a node of a specific kind with required text content

13

* @param node - Root node to search from

14

* @param kind - TypeScript syntax kind to find

15

* @param text - Text content to match (required)

16

* @returns Found node or null if not found

17

*/

18

function findNode(

19

node: ts.Node,

20

kind: ts.SyntaxKind,

21

text: string

22

): ts.Node | null;

23

24

/**

25

* Gets all nodes from a source file

26

* @param sourceFile - TypeScript source file

27

* @returns Array of all nodes in the file

28

*/

29

function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[];

30

31

/**

32

* Finds all nodes of a specific kind

33

* @param node - Root node to search from

34

* @param kind - TypeScript syntax kind to find

35

* @param max - Maximum number of nodes to find

36

* @returns Array of found nodes

37

*/

38

function findNodes(

39

node: ts.Node,

40

kind: ts.SyntaxKind,

41

max?: number

42

): ts.Node[];

43

```

44

45

**Usage Example:**

46

47

```typescript

48

import { findNode, findNodes } from '@schematics/angular/utility/ast-utils';

49

import * as ts from 'typescript';

50

51

export function findImports(): Rule {

52

return (tree: Tree) => {

53

const source = tree.readText('/src/app/app.module.ts');

54

const sourceFile = ts.createSourceFile('app.module.ts', source, ts.ScriptTarget.Latest);

55

56

// Find import declarations

57

const imports = findNodes(sourceFile, ts.SyntaxKind.ImportDeclaration);

58

59

// Find specific import

60

const angularCoreImport = findNode(sourceFile, ts.SyntaxKind.ImportDeclaration, '@angular/core');

61

62

return tree;

63

};

64

}

65

```

66

67

### Module Modifications

68

69

Functions for adding imports, declarations, and providers to Angular modules.

70

71

```typescript { .api }

72

/**

73

* Adds an import statement to an Angular module

74

* @param source - Source file containing the module

75

* @param modulePath - Path to the module file

76

* @param symbolName - Name of the symbol to import

77

* @param fileName - File to import from

78

* @returns Array of changes to apply

79

*/

80

function addImportToModule(

81

source: ts.SourceFile,

82

modulePath: string,

83

symbolName: string,

84

fileName: string

85

): Change[];

86

87

/**

88

* Adds a declaration to an Angular module's declarations array

89

* @param source - Source file containing the module

90

* @param modulePath - Path to the module file

91

* @param classifiedName - Name of the component/directive/pipe

92

* @param importPath - Path to import the declaration from

93

* @returns Array of changes to apply

94

*/

95

function addDeclarationToModule(

96

source: ts.SourceFile,

97

modulePath: string,

98

classifiedName: string,

99

importPath: string

100

): Change[];

101

102

/**

103

* Adds an export to an Angular module's exports array

104

* @param source - Source file containing the module

105

* @param modulePath - Path to the module file

106

* @param classifiedName - Name of the item to export

107

* @param importPath - Path to import the export from

108

* @returns Array of changes to apply

109

*/

110

function addExportToModule(

111

source: ts.SourceFile,

112

modulePath: string,

113

classifiedName: string,

114

importPath: string

115

): Change[];

116

117

/**

118

* Adds a provider to an Angular module's providers array

119

* @param source - Source file containing the module

120

* @param modulePath - Path to the module file

121

* @param classifiedName - Name of the provider

122

* @param importPath - Path to import the provider from

123

* @returns Array of changes to apply

124

*/

125

function addProviderToModule(

126

source: ts.SourceFile,

127

modulePath: string,

128

classifiedName: string,

129

importPath: string

130

): Change[];

131

132

/**

133

* Adds a component to bootstrap array in Angular module

134

* @param source - Source file containing the module

135

* @param modulePath - Path to the module file

136

* @param classifiedName - Name of the component to bootstrap

137

* @param importPath - Path to import the component from

138

* @returns Array of changes to apply

139

*/

140

function addBootstrapToModule(

141

source: ts.SourceFile,

142

modulePath: string,

143

classifiedName: string,

144

importPath: string

145

): Change[];

146

```

147

148

**Usage Example:**

149

150

```typescript

151

import {

152

addDeclarationToModule,

153

addImportToModule

154

} from '@schematics/angular/utility/ast-utils';

155

import { applyToUpdateRecorder } from '@schematics/angular/utility/change';

156

157

export function addComponentToModule(): Rule {

158

return (tree: Tree) => {

159

const modulePath = '/src/app/app.module.ts';

160

const source = tree.readText(modulePath);

161

const sourceFile = ts.createSourceFile(modulePath, source, ts.ScriptTarget.Latest);

162

163

// Add import and declaration

164

const changes = [

165

...addImportToModule(sourceFile, modulePath, 'MyComponent', './my-component/my-component'),

166

...addDeclarationToModule(sourceFile, modulePath, 'MyComponent', './my-component/my-component')

167

];

168

169

// Apply changes

170

const recorder = tree.beginUpdate(modulePath);

171

applyToUpdateRecorder(recorder, changes);

172

tree.commitUpdate(recorder);

173

174

return tree;

175

};

176

}

177

```

178

179

### Import Management

180

181

Functions for adding and managing import statements.

182

183

```typescript { .api }

184

/**

185

* Inserts an import statement into a source file

186

* @param source - Source file to modify

187

* @param fileToEdit - Path to the file being edited

188

* @param symbolName - Name of the symbol to import

189

* @param fileName - File to import from

190

* @param isDefault - Whether this is a default import

191

* @returns Change object representing the import insertion

192

*/

193

function insertImport(

194

source: ts.SourceFile,

195

fileToEdit: string,

196

symbolName: string,

197

fileName: string,

198

isDefault?: boolean

199

): Change;

200

201

/**

202

* Inserts text after the last occurrence of specified nodes

203

* @param nodes - Array of nodes to search through

204

* @param toInsert - Text to insert

205

* @param file - File path for the change

206

* @param fallbackPos - Position to use if no nodes found

207

* @returns Change object representing the insertion

208

*/

209

function insertAfterLastOccurrence(

210

nodes: ts.Node[],

211

toInsert: string,

212

file: string,

213

fallbackPos?: number

214

): Change;

215

```

216

217

### Decorator Analysis

218

219

Functions for analyzing and working with TypeScript decorators.

220

221

```typescript { .api }

222

/**

223

* Gets decorator metadata from a source file

224

* @param source - Source file to analyze

225

* @param identifier - Decorator name to find (e.g., 'Component')

226

* @param module - Module the decorator is imported from (e.g., '@angular/core')

227

* @returns Array of nodes representing decorator metadata

228

*/

229

function getDecoratorMetadata(

230

source: ts.SourceFile,

231

identifier: string,

232

module: string

233

): ts.Node[];

234

235

/**

236

* Adds a symbol to NgModule metadata (imports, declarations, providers, etc.)

237

* @param source - Source file containing NgModule

238

* @param ngModulePath - Path to the NgModule file

239

* @param metadataField - Field to add to ('imports', 'declarations', 'providers', etc.)

240

* @param symbolName - Name of the symbol to add

241

* @param importPath - Optional import path for the symbol

242

* @returns Array of changes to apply

243

*/

244

function addSymbolToNgModuleMetadata(

245

source: ts.SourceFile,

246

ngModulePath: string,

247

metadataField: string,

248

symbolName: string,

249

importPath?: string

250

): Change[];

251

```

252

253

### Module Discovery

254

255

Functions for finding and working with Angular modules.

256

257

```typescript { .api }

258

/**

259

* Gets the path to the app module from main.ts

260

* @param host - Tree host

261

* @param mainPath - Path to main.ts file

262

* @returns Path to the app module

263

*/

264

function getAppModulePath(host: Tree, mainPath: string): string;

265

266

/**

267

* Finds the module file from options and directory structure

268

* @param host - Tree host

269

* @param generateDir - Directory where files are being generated

270

* @returns Path to the module file

271

*/

272

function findModule(host: Tree, generateDir: string): string;

273

274

/**

275

* Finds module from schematic options

276

* @param host - Tree host

277

* @param options - Options containing module information

278

* @returns Path to module file or undefined

279

*/

280

function findModuleFromOptions(host:Tree, options: ModuleOptions): string | undefined;

281

282

interface ModuleOptions {

283

module?: string;

284

name: string;

285

path?: string;

286

flat?: boolean;

287

}

288

```

289

290

### Routing Utilities

291

292

Functions for working with Angular routing configuration.

293

294

```typescript { .api }

295

/**

296

* Adds a route declaration to a module

297

* @param source - Source file containing routes

298

* @param fileToAdd - File path being modified

299

* @param routeLiteral - Route configuration as string

300

* @returns Array of changes to apply

301

*/

302

function addRouteDeclarationToModule(

303

source: ts.SourceFile,

304

fileToAdd: string,

305

routeLiteral: string

306

): Change[];

307

308

/**

309

* Gets the RouterModule declaration from a source file

310

* @param source - Source file to search

311

* @returns Expression node for RouterModule or undefined

312

*/

313

function getRouterModuleDeclaration(source: ts.SourceFile): ts.Expression | undefined;

314

315

/**

316

* Checks if an import is already present in the source file

317

* @param source - Source file to check

318

* @param className - Class name to look for

319

* @param importPath - Import path to look for

320

* @returns True if import already exists

321

*/

322

function isImported(

323

source: ts.SourceFile,

324

className: string,

325

importPath: string

326

): boolean;

327

328

/**

329

* Gets metadata field from decorator

330

* @param source - Source file containing decorator

331

* @param identifier - Decorator name

332

* @param module - Module the decorator is from

333

* @param field - Metadata field to get

334

* @returns Array of nodes for the field

335

*/

336

function getMetadataField(

337

source: ts.SourceFile,

338

identifier: string,

339

module: string,

340

field: string

341

): ts.Node[];

342

343

/**

344

* Checks if source file has a top-level identifier

345

* @param source - Source file to check

346

* @param name - Identifier name to look for

347

* @returns True if identifier exists at top level

348

*/

349

function hasTopLevelIdentifier(source: ts.SourceFile, name: string): boolean;

350

```

351

352

## Change System

353

354

### Change Types

355

356

```typescript { .api }

357

/**

358

* Abstract base class for representing code changes

359

*/

360

abstract class Change {

361

/** File path this change applies to */

362

readonly path: string | null;

363

/** Order for applying multiple changes */

364

readonly order: number;

365

/** Human-readable description of the change */

366

readonly description: string;

367

368

/**

369

* Applies this change to an UpdateRecorder

370

* @param host - UpdateRecorder to apply changes to

371

* @returns Modified UpdateRecorder

372

*/

373

abstract apply(host: UpdateRecorder): UpdateRecorder;

374

}

375

376

/**

377

* Change that inserts text at a specific position

378

*/

379

class InsertChange extends Change {

380

constructor(path: string, pos: number, toAdd: string);

381

}

382

383

/**

384

* Change that removes text from a specific position and length

385

*/

386

class RemoveChange extends Change {

387

constructor(path: string, pos: number, length: number);

388

}

389

390

/**

391

* Change that replaces text at a specific position

392

*/

393

class ReplaceChange extends Change {

394

constructor(path: string, pos: number, oldText: string, newText: string);

395

}

396

397

/**

398

* Change that does nothing (no-op)

399

*/

400

class NoopChange extends Change {

401

constructor();

402

}

403

```

404

405

### Applying Changes

406

407

```typescript { .api }

408

/**

409

* Applies an array of changes to an UpdateRecorder

410

* @param recorder - UpdateRecorder to apply changes to

411

* @param changes - Array of changes to apply

412

*/

413

function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[]): void;

414

```

415

416

**Usage Example:**

417

418

```typescript

419

import { applyToUpdateRecorder, InsertChange } from '@schematics/angular/utility/change';

420

421

export function addImport(): Rule {

422

return (tree: Tree) => {

423

const filePath = '/src/app/app.component.ts';

424

const changes = [

425

new InsertChange(filePath, 0, "import { Component } from '@angular/core';\n")

426

];

427

428

const recorder = tree.beginUpdate(filePath);

429

applyToUpdateRecorder(recorder, changes);

430

tree.commitUpdate(recorder);

431

432

return tree;

433

};

434

}

435

```