or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdlanguage.mdparser.mdquery.mdtree-cursor.mdtree-node.md

tree-cursor.mddocs/

0

# Tree Cursor

1

2

Efficient tree traversal using stateful cursors for performance-critical applications. TreeCursor provides a low-level, memory-efficient way to walk syntax trees without creating intermediate Node objects.

3

4

## Capabilities

5

6

### Cursor Creation and Management

7

8

Create and manage tree cursor instances.

9

10

```typescript { .api }

11

/**

12

* Create a deep copy of the tree cursor (allocates new memory)

13

* @returns New TreeCursor instance

14

*/

15

copy(): TreeCursor;

16

17

/**

18

* Delete the tree cursor and free its resources

19

*/

20

delete(): void;

21

```

22

23

**Usage Example:**

24

25

```typescript

26

const tree = parser.parse("let x = 1 + 2;");

27

const cursor = tree.walk();

28

29

// Create a copy for parallel traversal

30

const cursorCopy = cursor.copy();

31

32

// Clean up when done

33

cursor.delete();

34

cursorCopy.delete();

35

```

36

37

### Current Node Access

38

39

Access information about the current node without creating Node objects.

40

41

```typescript { .api }

42

/**

43

* Get the tree cursor's current Node

44

* @returns Current node (creates Node object)

45

*/

46

get currentNode(): Node;

47

48

/**

49

* Get the numerical field id of this tree cursor's current node

50

* @returns Field ID or 0 if no field

51

*/

52

get currentFieldId(): number;

53

54

/**

55

* Get the field name of this tree cursor's current node

56

* @returns Field name or null if no field

57

*/

58

get currentFieldName(): string | null;

59

```

60

61

### Position Information

62

63

Get cursor position and depth information.

64

65

```typescript { .api }

66

/**

67

* Get the depth of the cursor's current node relative to the original node

68

* @returns Depth from root node

69

*/

70

get currentDepth(): number;

71

72

/**

73

* Get the index of the cursor's current node out of all descendants

74

* @returns Descendant index

75

*/

76

get currentDescendantIndex(): number;

77

```

78

79

### Node Type Information

80

81

Access type information for the current node efficiently.

82

83

```typescript { .api }

84

/**

85

* Get the type of the cursor's current node

86

* @returns Node type as string

87

*/

88

get nodeType(): string;

89

90

/**

91

* Get the type id of the cursor's current node

92

* @returns Node type ID

93

*/

94

get nodeTypeId(): number;

95

96

/**

97

* Get the state id of the cursor's current node

98

* @returns Parse state ID

99

*/

100

get nodeStateId(): number;

101

102

/**

103

* Get the id of the cursor's current node

104

* @returns Unique node ID

105

*/

106

get nodeId(): number;

107

```

108

109

### Node Classification

110

111

Check node properties without creating Node objects.

112

113

```typescript { .api }

114

/**

115

* Check if the cursor's current node is named

116

* @returns True if node corresponds to named rule in grammar

117

*/

118

get nodeIsNamed(): boolean;

119

120

/**

121

* Check if the cursor's current node is missing

122

* @returns True if node was inserted for error recovery

123

*/

124

get nodeIsMissing(): boolean;

125

```

126

127

### Content and Position Access

128

129

Get node content and position information.

130

131

```typescript { .api }

132

/**

133

* Get the string content of the cursor's current node

134

* @returns Text content of current node

135

*/

136

get nodeText(): string;

137

138

/**

139

* Get the start position of the cursor's current node

140

* @returns Start position

141

*/

142

get startPosition(): Point;

143

144

/**

145

* Get the end position of the cursor's current node

146

* @returns End position

147

*/

148

get endPosition(): Point;

149

150

/**

151

* Get the start index of the cursor's current node

152

* @returns Start byte index

153

*/

154

get startIndex(): number;

155

156

/**

157

* Get the end index of the cursor's current node

158

* @returns End byte index

159

*/

160

get endIndex(): number;

161

```

162

163

**Usage Example:**

164

165

```typescript

166

const cursor = tree.walk();

167

168

console.log("Current node type:", cursor.nodeType);

169

console.log("Text:", cursor.nodeText);

170

console.log("Position:", cursor.startPosition, "to", cursor.endPosition);

171

console.log("Depth:", cursor.currentDepth);

172

console.log("Is named:", cursor.nodeIsNamed);

173

```

174

175

### Tree Navigation

176

177

Navigate through the tree structure efficiently.

178

179

```typescript { .api }

180

/**

181

* Move cursor to the first child of current node

182

* @returns True if successfully moved, false if no children

183

*/

184

gotoFirstChild(): boolean;

185

186

/**

187

* Move cursor to the last child of current node

188

* @returns True if successfully moved, false if no children

189

*/

190

gotoLastChild(): boolean;

191

192

/**

193

* Move cursor to the parent of current node

194

* @returns True if successfully moved, false if already at root

195

*/

196

gotoParent(): boolean;

197

198

/**

199

* Move cursor to the next sibling of current node

200

* @returns True if successfully moved, false if no next sibling

201

*/

202

gotoNextSibling(): boolean;

203

204

/**

205

* Move cursor to the previous sibling of current node

206

* @returns True if successfully moved, false if no previous sibling

207

*/

208

gotoPreviousSibling(): boolean;

209

```

210

211

**Usage Example:**

212

213

```typescript

214

const cursor = tree.walk();

215

216

// Walk through all children of root

217

if (cursor.gotoFirstChild()) {

218

do {

219

console.log("Child:", cursor.nodeType, cursor.nodeText);

220

221

// Visit grandchildren

222

if (cursor.gotoFirstChild()) {

223

do {

224

console.log(" Grandchild:", cursor.nodeType);

225

} while (cursor.gotoNextSibling());

226

cursor.gotoParent(); // Back to child level

227

}

228

} while (cursor.gotoNextSibling());

229

}

230

```

231

232

### Advanced Navigation

233

234

Navigate to specific positions and descendants.

235

236

```typescript { .api }

237

/**

238

* Move cursor to the nth descendant of the original node

239

* @param goalDescendantIndex - Index of target descendant (0 = original node)

240

*/

241

gotoDescendant(goalDescendantIndex: number): void;

242

243

/**

244

* Move cursor to first child containing or starting after given byte offset

245

* @param goalIndex - Target byte offset

246

* @returns True if found and moved, false if no such child

247

*/

248

gotoFirstChildForIndex(goalIndex: number): boolean;

249

250

/**

251

* Move cursor to first child containing or starting after given position

252

* @param goalPosition - Target position

253

* @returns True if found and moved, false if no such child

254

*/

255

gotoFirstChildForPosition(goalPosition: Point): boolean;

256

```

257

258

**Usage Example:**

259

260

```typescript

261

// Find node at specific byte offset

262

const cursor = tree.walk();

263

if (cursor.gotoFirstChildForIndex(15)) {

264

console.log("Found node at offset 15:", cursor.nodeType);

265

}

266

267

// Navigate to specific descendant

268

cursor.gotoDescendant(5); // Go to 5th descendant

269

console.log("5th descendant:", cursor.nodeType);

270

```

271

272

### Cursor Reset Operations

273

274

Reset cursor position and state.

275

276

```typescript { .api }

277

/**

278

* Re-initialize cursor to start at the given node

279

* @param node - Node to reset cursor to

280

*/

281

reset(node: Node): void;

282

283

/**

284

* Re-initialize cursor to the same position as another cursor

285

* @param cursor - Cursor to copy position from

286

*/

287

resetTo(cursor: TreeCursor): void;

288

```

289

290

**Usage Example:**

291

292

```typescript

293

const cursor1 = tree.walk();

294

const cursor2 = tree.walk();

295

296

// Move cursor1 to some position

297

cursor1.gotoFirstChild();

298

cursor1.gotoFirstChild();

299

300

// Copy position to cursor2

301

cursor2.resetTo(cursor1);

302

303

console.log("Both cursors at same position:");

304

console.log("Cursor1:", cursor1.nodeType);

305

console.log("Cursor2:", cursor2.nodeType);

306

307

// Reset cursor1 to root

308

cursor1.reset(tree.rootNode);

309

```

310

311

## Performance Benefits

312

313

TreeCursor provides significant performance advantages for tree traversal:

314

315

- **Memory Efficient**: No intermediate Node object creation during navigation

316

- **Cache Friendly**: Maintains position state without repeated tree walks

317

- **Fast Iteration**: Direct access to node properties without object allocation

318

- **Stateful Navigation**: Remembers position for complex traversal patterns

319

320

## Usage Patterns

321

322

### Full Tree Traversal

323

324

```typescript

325

function traverseTree(cursor: TreeCursor, depth: number = 0) {

326

const indent = " ".repeat(depth);

327

console.log(`${indent}${cursor.nodeType}: ${cursor.nodeText}`);

328

329

if (cursor.gotoFirstChild()) {

330

do {

331

traverseTree(cursor, depth + 1);

332

} while (cursor.gotoNextSibling());

333

cursor.gotoParent();

334

}

335

}

336

337

const cursor = tree.walk();

338

traverseTree(cursor);

339

cursor.delete();

340

```

341

342

### Find All Nodes of Type

343

344

```typescript

345

function findNodesOfType(tree: Tree, targetType: string): string[] {

346

const results: string[] = [];

347

const cursor = tree.walk();

348

349

function visit() {

350

if (cursor.nodeType === targetType) {

351

results.push(cursor.nodeText);

352

}

353

354

if (cursor.gotoFirstChild()) {

355

do {

356

visit();

357

} while (cursor.gotoNextSibling());

358

cursor.gotoParent();

359

}

360

}

361

362

visit();

363

cursor.delete();

364

return results;

365

}

366

367

const identifiers = findNodesOfType(tree, "identifier");

368

console.log("Found identifiers:", identifiers);

369

```

370

371

### Range-Based Processing

372

373

```typescript

374

function processRange(tree: Tree, startIndex: number, endIndex: number) {

375

const cursor = tree.walk();

376

377

// Find first node in range

378

if (cursor.gotoFirstChildForIndex(startIndex)) {

379

while (cursor.startIndex <= endIndex) {

380

if (cursor.endIndex >= startIndex) {

381

console.log("Processing:", cursor.nodeType, cursor.nodeText);

382

}

383

384

if (!cursor.gotoNextSibling()) {

385

break;

386

}

387

}

388

}

389

390

cursor.delete();

391

}

392

```