or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-line-config.mdindex.mdlanguage-services.mdnode-factory-transformers.mdparser-ast.mdprogram-compilation.mdtranspilation.mdtype-checker.mdutilities-helpers.md

parser-ast.mddocs/

0

# Parser and AST

1

2

Core parsing functionality that converts TypeScript source code into Abstract Syntax Trees (AST). Essential for any tool that needs to analyze or manipulate TypeScript code.

3

4

## Capabilities

5

6

### Source File Creation

7

8

Creates a TypeScript AST from source code text.

9

10

```typescript { .api }

11

/**

12

* Parse source text into a TypeScript AST

13

* @param fileName - Name of the file (used for error reporting)

14

* @param sourceText - TypeScript source code to parse

15

* @param languageVersionOrOptions - Target language version or parsing options

16

* @param setParentNodes - Whether to set parent references on nodes (default: false)

17

* @param scriptKind - Type of script being parsed

18

* @returns Parsed source file AST

19

*/

20

function createSourceFile(

21

fileName: string,

22

sourceText: string,

23

languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions,

24

setParentNodes?: boolean,

25

scriptKind?: ScriptKind

26

): SourceFile;

27

28

interface CreateSourceFileOptions {

29

languageVersion: ScriptTarget;

30

impliedNodeFormat?: ResolutionMode;

31

setExternalModuleIndicator?: (file: SourceFile) => void;

32

jsDocParsingMode?: JSDocParsingMode;

33

}

34

35

enum ScriptTarget {

36

ES3 = 0,

37

ES5 = 1,

38

ES2015 = 2,

39

ES2016 = 3,

40

ES2017 = 4,

41

ES2018 = 5,

42

ES2019 = 6,

43

ES2020 = 7,

44

ES2021 = 8,

45

ES2022 = 9,

46

ESNext = 99,

47

Latest = ESNext

48

}

49

50

enum ScriptKind {

51

Unknown = 0,

52

JS = 1,

53

JSX = 2,

54

TS = 3,

55

TSX = 4,

56

External = 5,

57

JSON = 6,

58

Deferred = 7

59

}

60

61

enum ResolutionMode {

62

Imports = 0,

63

Require = 1

64

}

65

66

enum JSDocParsingMode {

67

ParseAll = 0,

68

ParseNone = 1,

69

ParseForTypeErrors = 2,

70

ParseForTypeInfo = 3

71

}

72

```

73

74

**Usage Examples:**

75

76

```typescript

77

import * as ts from "typescript";

78

79

// Parse a simple TypeScript file

80

const sourceFile = ts.createSourceFile(

81

"example.ts",

82

`

83

interface User {

84

name: string;

85

age: number;

86

}

87

88

function greet(user: User): string {

89

return \`Hello, \${user.name}!\`;

90

}

91

`,

92

ts.ScriptTarget.ES2020,

93

true // Set parent nodes for easier traversal

94

);

95

96

console.log(sourceFile.statements.length); // Number of top-level statements

97

```

98

99

### AST Traversal

100

101

Traverse and visit AST nodes using various patterns.

102

103

```typescript { .api }

104

/**

105

* Visit each child of an AST node

106

* @param node - AST node to traverse

107

* @param cbNode - Callback for individual nodes

108

* @param cbNodes - Optional callback for node arrays

109

* @returns Result from first successful callback

110

*/

111

function forEachChild<T>(

112

node: Node,

113

cbNode: (node: Node) => T | undefined,

114

cbNodes?: (nodes: NodeArray<Node>) => T | undefined

115

): T | undefined;

116

117

/**

118

* Recursively traverse AST with depth-first search

119

* @param node - Starting AST node

120

* @param cbNode - Callback for individual nodes

121

* @param cbNodes - Optional callback for node arrays

122

* @returns Result from first successful callback

123

*/

124

function forEachChildRecursively<T>(

125

node: Node,

126

cbNode: (node: Node) => T | undefined,

127

cbNodes?: (nodes: NodeArray<Node>) => T | undefined

128

): T | undefined;

129

130

/**

131

* Visit a single AST node with a visitor function

132

* @param node - Node to visit

133

* @param visitor - Visitor function

134

* @param test - Optional type guard test

135

* @param lift - Optional lifting function

136

* @returns Visited node or array

137

*/

138

function visitNode<T extends Node>(

139

node: T | undefined,

140

visitor: Visitor,

141

test?: (node: Node) => boolean,

142

lift?: (node: NodeArray<Node>) => T

143

): T;

144

145

/**

146

* Visit an array of AST nodes

147

* @param nodes - Array of nodes to visit

148

* @param visitor - Visitor function

149

* @param test - Optional type guard test

150

* @param start - Starting index

151

* @param count - Number of nodes to visit

152

* @returns Visited node array

153

*/

154

function visitNodes<T extends Node>(

155

nodes: NodeArray<T> | undefined,

156

visitor: Visitor,

157

test?: (node: Node) => boolean,

158

start?: number,

159

count?: number

160

): NodeArray<T>;

161

```

162

163

**Usage Examples:**

164

165

```typescript

166

import * as ts from "typescript";

167

168

const sourceFile = ts.createSourceFile(

169

"example.ts",

170

"function add(a: number, b: number): number { return a + b; }",

171

ts.ScriptTarget.Latest

172

);

173

174

// Find all identifiers in the AST

175

const identifiers: string[] = [];

176

function visit(node: ts.Node) {

177

if (ts.isIdentifier(node)) {

178

identifiers.push(node.text);

179

}

180

ts.forEachChild(node, visit);

181

}

182

visit(sourceFile);

183

console.log(identifiers); // ['add', 'a', 'number', 'b', 'number', 'number', 'a', 'b']

184

185

// Find function declarations

186

const functions: ts.FunctionDeclaration[] = [];

187

ts.forEachChild(sourceFile, (node) => {

188

if (ts.isFunctionDeclaration(node)) {

189

functions.push(node);

190

}

191

});

192

```

193

194

### Incremental Parsing

195

196

Update existing source files efficiently for editor scenarios.

197

198

```typescript { .api }

199

/**

200

* Incrementally update a source file with new text

201

* @param sourceFile - Existing source file

202

* @param newText - New source text

203

* @param textChangeRange - Range of text that changed

204

* @param aggressiveChecks - Whether to perform aggressive validation

205

* @returns Updated source file

206

*/

207

function updateSourceFile(

208

sourceFile: SourceFile,

209

newText: string,

210

textChangeRange: TextChangeRange,

211

aggressiveChecks?: boolean

212

): SourceFile;

213

214

interface TextChangeRange {

215

span: TextSpan;

216

newLength: number;

217

}

218

219

interface TextSpan {

220

start: number;

221

length: number;

222

}

223

```

224

225

### Module Detection

226

227

Determine module characteristics of source files.

228

229

```typescript { .api }

230

/**

231

* Check if a source file is an external module (has imports/exports)

232

* @param file - Source file to check

233

* @returns True if file is an external module

234

*/

235

function isExternalModule(file: SourceFile): boolean;

236

237

/**

238

* Check if a filename represents a declaration file

239

* @param fileName - File name to check

240

* @returns True if filename ends with .d.ts

241

*/

242

function isDeclarationFileName(fileName: string): boolean;

243

```

244

245

### JSON Parsing

246

247

Parse JSON with TypeScript-specific handling.

248

249

```typescript { .api }

250

/**

251

* Parse JSON text with TypeScript-specific error handling

252

* @param fileName - Name of JSON file

253

* @param sourceText - JSON source text

254

* @returns Parsed JSON source file

255

*/

256

function parseJsonText(fileName: string, sourceText: string): JsonSourceFile;

257

258

interface JsonSourceFile extends SourceFile {

259

statements: NodeArray<JsonObjectExpressionStatement>;

260

}

261

```

262

263

### JSDoc Parsing

264

265

Parse JSDoc type expressions for testing and analysis.

266

267

```typescript { .api }

268

/**

269

* Parse JSDoc type expressions for testing purposes

270

* @param content - JSDoc type expression content

271

* @param start - Starting position

272

* @param length - Length of content to parse

273

* @returns Parsed JSDoc type expression

274

*/

275

function parseJSDocTypeExpressionForTests(

276

content: string,

277

start?: number,

278

length?: number

279

): { jsDocTypeExpression: JSDocTypeExpression; diagnostics: Diagnostic[] };

280

```

281

282

## Types

283

284

### Core Node Types

285

286

```typescript { .api }

287

interface Node {

288

kind: SyntaxKind;

289

flags: NodeFlags;

290

pos: number;

291

end: number;

292

parent: Node;

293

}

294

295

interface SourceFile extends Declaration {

296

kind: SyntaxKind.SourceFile;

297

statements: NodeArray<Statement>;

298

endOfFileToken: Token<SyntaxKind.EndOfFileToken>;

299

fileName: string;

300

text: string;

301

languageVersion: ScriptTarget;

302

scriptKind: ScriptKind;

303

isDeclarationFile: boolean;

304

hasNoDefaultLib: boolean;

305

externalModuleIndicator?: Node;

306

}

307

308

interface Statement extends Node {

309

_statementBrand: any;

310

}

311

312

interface Expression extends Node {

313

_expressionBrand: any;

314

}

315

316

interface Declaration extends Node {

317

_declarationBrand: any;

318

}

319

320

interface Identifier extends Declaration {

321

kind: SyntaxKind.Identifier;

322

text: string;

323

originalKeywordKind: SyntaxKind;

324

}

325

```

326

327

### Node Arrays

328

329

```typescript { .api }

330

interface NodeArray<T extends Node> extends ReadonlyArray<T> {

331

pos: number;

332

end: number;

333

hasTrailingComma: boolean;

334

}

335

336

/**

337

* Create a node array from elements

338

* @param elements - Array elements

339

* @param hasTrailingComma - Whether array has trailing comma

340

* @returns Node array

341

*/

342

function createNodeArray<T extends Node>(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray<T>;

343

```

344

345

### Scanner API

346

347

Create and use lexical scanners for tokenization.

348

349

```typescript { .api }

350

/**

351

* Create a lexical scanner for tokenizing TypeScript source

352

* @param languageVersion - Target language version

353

* @param skipTrivia - Whether to skip whitespace and comments

354

* @param languageVariant - Language variant (TypeScript, JSX, etc.)

355

* @param textInitial - Initial text to scan

356

* @param onError - Error reporting callback

357

* @param start - Starting position

358

* @param length - Length to scan

359

* @returns Scanner instance

360

*/

361

function createScanner(

362

languageVersion: ScriptTarget,

363

skipTrivia: boolean,

364

languageVariant?: LanguageVariant,

365

textInitial?: string,

366

onError?: ErrorCallback,

367

start?: number,

368

length?: number

369

): Scanner;

370

371

interface Scanner {

372

/** Get next token */

373

scan(): SyntaxKind;

374

375

/** Get current token kind */

376

getToken(): SyntaxKind;

377

378

/** Get current token position */

379

getTokenPos(): number;

380

381

/** Get current text position */

382

getTextPos(): number;

383

384

/** Get text of current token */

385

getTokenText(): string;

386

387

/** Get numeric value of token */

388

getTokenValue(): string;

389

390

/** Check if token has extended unicode escape */

391

hasUnicodeEscape(): boolean;

392

393

/** Check if token has extended unicode escape */

394

hasExtendedUnicodeEscape(): boolean;

395

396

/** Check if preceding line break */

397

hasPrecedingLineBreak(): boolean;

398

399

/** Set text to scan */

400

setText(text: string | undefined, start?: number, length?: number): void;

401

402

/** Set text position */

403

setTextPos(textPos: number): void;

404

405

/** Look ahead for next token */

406

lookAhead<T>(callback: () => T): T;

407

408

/** Scan range of text */

409

scanRange<T>(start: number, length: number, callback: () => T): T;

410

411

/** Try scan */

412

tryScan<T>(callback: () => T): T;

413

}

414

415

/**

416

* Check if character can start an identifier

417

* @param ch - Character code to check

418

* @param languageVersion - Language version context

419

* @returns True if character can start identifier

420

*/

421

function isIdentifierStart(ch: number, languageVersion?: ScriptTarget): boolean;

422

423

/**

424

* Check if character can be part of an identifier

425

* @param ch - Character code to check

426

* @param languageVersion - Language version context

427

* @returns True if character can be part of identifier

428

*/

429

function isIdentifierPart(ch: number, languageVersion?: ScriptTarget): boolean;

430

431

/**

432

* Check if character is whitespace-like

433

* @param ch - Character code to check

434

* @returns True if whitespace-like

435

*/

436

function isWhiteSpaceLike(ch: number): boolean;

437

438

/**

439

* Check if character is a line break

440

* @param ch - Character code to check

441

* @returns True if line break

442

*/

443

function isLineBreak(ch: number): boolean;

444

```

445

446

### Text Ranges

447

448

```typescript { .api }

449

interface TextRange {

450

pos: number;

451

end: number;

452

}

453

454

interface ReadonlyTextRange {

455

readonly pos: number;

456

readonly end: number;

457

}

458

459

/**

460

* Create text span from start and length

461

* @param start - Starting position

462

* @param length - Length of span

463

* @returns Text span object

464

*/

465

function createTextSpan(start: number, length: number): TextSpan;

466

467

/**

468

* Create text change range

469

* @param span - Text span that changed

470

* @param newLength - New length after change

471

* @returns Text change range

472

*/

473

function createTextChangeRange(span: TextSpan, newLength: number): TextChangeRange;

474

```