or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-types.mdcompilation.mderror-handling.mdindex.mdtransforms.mdutilities.md

utilities.mddocs/

0

# Utilities and Helpers

1

2

Vue Compiler Core provides a comprehensive set of utility functions for AST manipulation, type checking, identifier analysis, and common compiler operations.

3

4

## Capabilities

5

6

### AST Node Utilities

7

8

Functions for working with and analyzing AST nodes.

9

10

```typescript { .api }

11

/**

12

* Type guard for static expression nodes

13

* @param p - AST node to check

14

* @returns True if node is a static simple expression

15

*/

16

function isStaticExp(p: JSChildNode): p is SimpleExpressionNode;

17

18

/**

19

* Checks if a template child node is text or interpolation

20

* @param node - Node to check

21

* @returns True if node is TextNode or InterpolationNode

22

*/

23

function isText(node: TemplateChildNode): node is TextNode | InterpolationNode;

24

25

/**

26

* Type guard for v-slot directive

27

* @param p - Element prop to check

28

* @returns True if prop is a v-slot directive

29

*/

30

function isVSlot(p: ElementNode['props'][0]): p is DirectiveNode;

31

```

32

33

**Usage Examples:**

34

35

```typescript

36

import { isStaticExp, isText, isVSlot } from "@vue/compiler-core";

37

38

// Check if expression is static

39

if (isStaticExp(expression)) {

40

console.log('Static value:', expression.content);

41

}

42

43

// Filter text nodes from children

44

const textNodes = element.children.filter(isText);

45

46

// Find v-slot directives

47

const slotDirectives = element.props.filter(isVSlot);

48

```

49

50

### Element and Directive Queries

51

52

Functions for finding and working with element attributes and directives.

53

54

```typescript { .api }

55

/**

56

* Finds a directive on an element node

57

* @param node - Element node to search

58

* @param name - Directive name or pattern to match

59

* @param allowEmpty - Whether to match directives without expressions

60

* @returns Found directive node or undefined

61

*/

62

function findDir(

63

node: ElementNode,

64

name: string | RegExp,

65

allowEmpty?: boolean

66

): DirectiveNode | undefined;

67

68

/**

69

* Finds a prop or attribute on an element node

70

* @param node - Element node to search

71

* @param name - Prop/attribute name to find

72

* @param dynamicOnly - Only match dynamic props (v-bind)

73

* @param allowEmpty - Whether to match props without values

74

* @returns Found prop/attribute or undefined

75

*/

76

function findProp(

77

node: ElementNode,

78

name: string,

79

dynamicOnly?: boolean,

80

allowEmpty?: boolean

81

): ElementNode['props'][0] | undefined;

82

83

/**

84

* Checks if directive argument is static and matches name

85

* @param arg - Directive argument to check

86

* @param name - Name to match against

87

* @returns True if argument is static and matches

88

*/

89

function isStaticArgOf(arg: DirectiveNode['arg'], name: string): boolean;

90

91

/**

92

* Checks if element has dynamic key v-bind

93

* @param node - Element node to check

94

* @returns True if has dynamic v-bind:key

95

*/

96

function hasDynamicKeyVBind(node: ElementNode): boolean;

97

```

98

99

**Usage Examples:**

100

101

```typescript

102

import { findDir, findProp, isStaticArgOf, hasDynamicKeyVBind } from "@vue/compiler-core";

103

104

// Find v-if directive

105

const ifDir = findDir(element, 'if');

106

if (ifDir) {

107

console.log('v-if condition:', ifDir.exp?.content);

108

}

109

110

// Find class attribute or v-bind:class

111

const classProp = findProp(element, 'class');

112

113

// Check if v-on argument is static 'click'

114

if (isStaticArgOf(onDirective.arg, 'click')) {

115

console.log('Static click handler');

116

}

117

118

// Check for dynamic key binding

119

if (hasDynamicKeyVBind(element)) {

120

console.log('Element has dynamic key');

121

}

122

```

123

124

### Component and Asset Utilities

125

126

Functions for working with Vue components and assets.

127

128

```typescript { .api }

129

/**

130

* Checks if tag name refers to a core Vue component

131

* @param tag - Tag name to check

132

* @returns Symbol for core component or void

133

*/

134

function isCoreComponent(tag: string): symbol | void;

135

136

/**

137

* Converts name to valid asset identifier

138

* @param name - Asset name to convert

139

* @param type - Type of asset (component, directive, filter)

140

* @returns Valid JavaScript identifier

141

*/

142

function toValidAssetId(name: string, type: 'component' | 'directive' | 'filter'): string;

143

```

144

145

**Usage Examples:**

146

147

```typescript

148

import { isCoreComponent, toValidAssetId } from "@vue/compiler-core";

149

150

// Check for core components

151

const coreSymbol = isCoreComponent('Teleport');

152

if (coreSymbol) {

153

console.log('Teleport is a core component');

154

}

155

156

// Convert component name to valid identifier

157

const componentId = toValidAssetId('my-component', 'component');

158

// Result: "_component_my_component"

159

160

const directiveId = toValidAssetId('custom-directive', 'directive');

161

// Result: "_directive_custom_directive"

162

```

163

164

### Expression Analysis

165

166

Functions for analyzing JavaScript expressions in templates.

167

168

```typescript { .api }

169

/**

170

* Checks if name is a simple JavaScript identifier

171

* @param name - String to check

172

* @returns True if valid simple identifier

173

*/

174

function isSimpleIdentifier(name: string): boolean;

175

176

/**

177

* Checks if expression is a member access expression

178

* @param exp - Expression node to check

179

* @param context - Transform context

180

* @returns True if expression is member access

181

*/

182

function isMemberExpression(exp: ExpressionNode, context: TransformContext): boolean;

183

184

/**

185

* Checks if expression is a function expression

186

* @param exp - Expression node to check

187

* @param context - Transform context

188

* @returns True if expression is a function

189

*/

190

function isFnExpression(exp: ExpressionNode, context: TransformContext): boolean;

191

```

192

193

**Usage Examples:**

194

195

```typescript

196

import { isSimpleIdentifier, isMemberExpression, isFnExpression } from "@vue/compiler-core";

197

198

// Validate identifier names

199

if (isSimpleIdentifier('userName')) {

200

console.log('Valid identifier');

201

}

202

203

// Analyze expression types

204

if (isMemberExpression(expression, context)) {

205

console.log('Member access: obj.prop');

206

}

207

208

if (isFnExpression(expression, context)) {

209

console.log('Function expression');

210

}

211

```

212

213

### Advanced Expression Analysis

214

215

Browser and Node.js specific expression analysis functions for different runtime environments.

216

217

```typescript { .api }

218

/**

219

* Browser-specific member expression checker (lexical analysis)

220

* @param exp - Expression node to check

221

* @returns True if expression is member access

222

*/

223

function isMemberExpressionBrowser(exp: ExpressionNode): boolean;

224

225

/**

226

* Browser-specific function expression checker (lexical analysis)

227

* @param exp - Expression node to check

228

* @returns True if expression is a function

229

*/

230

function isFnExpressionBrowser(exp: ExpressionNode): boolean;

231

232

/**

233

* Checks if node contains expressions that reference current context scope ids

234

* @param node - Template child node, branch node, or expression to check

235

* @param ids - Transform context identifiers map

236

* @returns True if node references scope identifiers

237

*/

238

function hasScopeRef(

239

node: TemplateChildNode | IfBranchNode | ExpressionNode | CacheExpression | undefined,

240

ids: TransformContext['identifiers']

241

): boolean;

242

243

/**

244

* Regular expression for parsing v-for alias syntax

245

*/

246

const forAliasRE: RegExp;

247

```

248

249

### VNode and Prop Utilities

250

251

Functions for manipulating VNode calls and injecting properties.

252

253

```typescript { .api }

254

/**

255

* Injects a property into a VNode or RenderSlot call

256

* @param node - VNode call or render slot call to modify

257

* @param prop - Property to inject

258

* @param context - Transform context

259

*/

260

function injectProp(

261

node: VNodeCall | RenderSlotCall,

262

prop: Property,

263

context: TransformContext

264

): void;

265

266

/**

267

* Extracts VNode call from memo expression or returns node directly

268

* @param node - Block codegen node or memo expression

269

* @returns The underlying VNode or RenderSlot call

270

*/

271

function getMemoedVNodeCall(

272

node: BlockCodegenNode | MemoExpression

273

): VNodeCall | RenderSlotCall;

274

```

275

276

**Usage Examples:**

277

278

```typescript

279

import {

280

hasScopeRef,

281

injectProp,

282

getMemoedVNodeCall,

283

forAliasRE

284

} from "@vue/compiler-core";

285

286

// Check scope references

287

if (hasScopeRef(expression, context.identifiers)) {

288

console.log('Expression references scoped variables');

289

}

290

291

// Parse v-for syntax

292

const match = expression.match(forAliasRE);

293

if (match) {

294

const [, LHS, RHS] = match;

295

console.log('v-for alias:', LHS, 'in', RHS);

296

}

297

298

// Inject key property

299

const keyProperty = createProperty('key', createSimpleExpression('item.id'));

300

injectProp(vnodeCall, keyProperty, context);

301

302

// Extract VNode from memo

303

const actualVNode = getMemoedVNodeCall(memoOrVNode);

304

```

305

306

### Position and Location Utilities

307

308

Functions for working with source code positions and locations.

309

310

```typescript { .api }

311

/**

312

* Advances position and returns new Position (immutable)

313

* @param pos - Starting position

314

* @param source - Source text being advanced through

315

* @param numberOfCharacters - Number of characters to advance

316

* @returns New Position object

317

*/

318

function advancePositionWithClone(

319

pos: Position,

320

source: string,

321

numberOfCharacters?: number

322

): Position;

323

324

/**

325

* Advances position in-place (mutable)

326

* @param pos - Position to modify

327

* @param source - Source text being advanced through

328

* @param numberOfCharacters - Number of characters to advance

329

* @returns The same Position object (modified)

330

*/

331

function advancePositionWithMutation(

332

pos: Position,

333

source: string,

334

numberOfCharacters?: number

335

): Position;

336

```

337

338

**Usage Examples:**

339

340

```typescript

341

import { advancePositionWithClone, advancePositionWithMutation } from "@vue/compiler-core";

342

343

const startPos = { offset: 0, line: 1, column: 1 };

344

const source = "Hello\nWorld";

345

346

// Immutable advance

347

const newPos = advancePositionWithClone(startPos, source, 6);

348

console.log(newPos); // { offset: 6, line: 2, column: 1 }

349

console.log(startPos); // Still { offset: 0, line: 1, column: 1 }

350

351

// Mutable advance

352

const pos = { offset: 0, line: 1, column: 1 };

353

advancePositionWithMutation(pos, source, 6);

354

console.log(pos); // { offset: 6, line: 2, column: 1 }

355

```

356

357

### Assertion and Debugging

358

359

Utility functions for debugging and validation.

360

361

```typescript { .api }

362

/**

363

* Runtime assertion helper

364

* @param condition - Condition that should be true

365

* @param msg - Error message if assertion fails

366

* @throws Error if condition is false

367

*/

368

function assert(condition: boolean, msg?: string): void;

369

```

370

371

**Usage Examples:**

372

373

```typescript

374

import { assert } from "@vue/compiler-core";

375

376

// Validate assumptions during compilation

377

assert(node.type === NodeTypes.ELEMENT, 'Expected element node');

378

assert(directive.name === 'if', 'Expected v-if directive');

379

380

// Debug mode assertions

381

if (__DEV__) {

382

assert(context.currentNode !== null, 'Current node should not be null');

383

}

384

```

385

386

## Babel Integration Utilities

387

388

Functions for working with Babel AST nodes and JavaScript analysis.

389

390

### Identifier Walking

391

392

Functions for traversing and analyzing JavaScript identifiers.

393

394

```typescript { .api }

395

/**

396

* Walks AST and calls callback for each identifier

397

* @param root - Babel AST node to walk

398

* @param onIdentifier - Callback for each identifier found

399

* @param includeAll - Whether to include all identifiers or just references

400

* @param parentStack - Stack of parent nodes

401

* @param knownIds - Set of known identifier names

402

*/

403

function walkIdentifiers(

404

root: Node,

405

onIdentifier: (

406

node: Identifier,

407

parent: Node,

408

parentStack: Node[],

409

isReference: boolean,

410

isLocal: boolean

411

) => void,

412

includeAll?: boolean,

413

parentStack?: Node[],

414

knownIds?: Record<string, number>

415

): void;

416

417

/**

418

* Checks if identifier is being referenced (not declared)

419

* @param id - Identifier node

420

* @param parent - Parent node

421

* @param parentStack - Stack of ancestor nodes

422

* @returns True if identifier is a reference

423

*/

424

function isReferencedIdentifier(

425

id: Identifier,

426

parent: Node | null,

427

parentStack: Node[]

428

): boolean;

429

430

/**

431

* Extracts all identifier nodes from a parameter pattern

432

* @param param - Parameter node (can be pattern)

433

* @param nodes - Array to collect identifiers into

434

* @returns Array of identifier nodes

435

*/

436

function extractIdentifiers(

437

param: Node,

438

nodes?: Identifier[]

439

): Identifier[];

440

```

441

442

**Usage Examples:**

443

444

```typescript

445

import { walkIdentifiers, isReferencedIdentifier, extractIdentifiers } from "@vue/compiler-core";

446

447

// Walk expression and collect references

448

const references = new Set<string>();

449

walkIdentifiers(babelAst, (id, parent, parentStack, isReference) => {

450

if (isReference) {

451

references.add(id.name);

452

}

453

});

454

455

// Check specific identifier

456

if (isReferencedIdentifier(identifier, parent, parentStack)) {

457

console.log('Identifier is being referenced');

458

}

459

460

// Extract parameter names

461

const params = extractIdentifiers(functionNode.params[0]);

462

console.log('Parameter names:', params.map(p => p.name));

463

```

464

465

### Node Type Checking

466

467

Functions for checking Babel AST node types.

468

469

```typescript { .api }

470

/**

471

* Type guard for function nodes

472

* @param node - Node to check

473

* @returns True if node is any kind of function

474

*/

475

function isFunctionType(node: Node): node is Function;

476

477

/**

478

* Type guard for static object properties

479

* @param node - Node to check

480

* @returns True if node is a static object property

481

*/

482

function isStaticProperty(node: Node): node is ObjectProperty;

483

484

/**

485

* Unwraps TypeScript AST nodes to get underlying JavaScript

486

* @param node - Potentially wrapped TS node

487

* @returns Unwrapped JavaScript node

488

*/

489

function unwrapTSNode(node: Node): Node;

490

```

491

492

**Usage Examples:**

493

494

```typescript

495

import { isFunctionType, isStaticProperty, unwrapTSNode } from "@vue/compiler-core";

496

497

// Check for function nodes

498

if (isFunctionType(node)) {

499

console.log('Found function:', node.type);

500

}

501

502

// Filter static properties

503

const staticProps = objectExpression.properties.filter(isStaticProperty);

504

505

// Unwrap TypeScript annotations

506

const jsNode = unwrapTSNode(tsNode);

507

```

508

509

## Runtime Helpers

510

511

System for managing Vue runtime helper functions.

512

513

### Helper Symbols

514

515

Symbols representing Vue runtime helper functions.

516

517

```typescript { .api }

518

// Core VNode creation helpers

519

const FRAGMENT: unique symbol;

520

const TELEPORT: unique symbol;

521

const SUSPENSE: unique symbol;

522

const KEEP_ALIVE: unique symbol;

523

const BASE_TRANSITION: unique symbol;

524

525

// VNode creation functions

526

const OPEN_BLOCK: unique symbol;

527

const CREATE_BLOCK: unique symbol;

528

const CREATE_ELEMENT_BLOCK: unique symbol;

529

const CREATE_VNODE: unique symbol;

530

const CREATE_ELEMENT_VNODE: unique symbol;

531

const CREATE_COMMENT: unique symbol;

532

const CREATE_TEXT: unique symbol;

533

const CREATE_STATIC: unique symbol;

534

535

// Component resolution

536

const RESOLVE_COMPONENT: unique symbol;

537

const RESOLVE_DYNAMIC_COMPONENT: unique symbol;

538

const RESOLVE_DIRECTIVE: unique symbol;

539

const RESOLVE_FILTER: unique symbol;

540

541

// Directive helpers

542

const WITH_DIRECTIVES: unique symbol;

543

544

// List rendering

545

const RENDER_LIST: unique symbol;

546

const RENDER_SLOT: unique symbol;

547

const CREATE_SLOTS: unique symbol;

548

549

// Utility helpers

550

const TO_DISPLAY_STRING: unique symbol;

551

const MERGE_PROPS: unique symbol;

552

const NORMALIZE_CLASS: unique symbol;

553

const NORMALIZE_STYLE: unique symbol;

554

const NORMALIZE_PROPS: unique symbol;

555

const GUARD_REACTIVE_PROPS: unique symbol;

556

const TO_HANDLERS: unique symbol;

557

const CAMELIZE: unique symbol;

558

const CAPITALIZE: unique symbol;

559

const TO_HANDLER_KEY: unique symbol;

560

561

// Optimization helpers

562

const SET_BLOCK_TRACKING: unique symbol;

563

const WITH_CTX: unique symbol;

564

const UNREF: unique symbol;

565

const IS_REF: unique symbol;

566

const WITH_MEMO: unique symbol;

567

const IS_MEMO_SAME: unique symbol;

568

569

// Deprecated helpers (kept for backwards compatibility)

570

const PUSH_SCOPE_ID: unique symbol;

571

const POP_SCOPE_ID: unique symbol;

572

```

573

574

### Helper Management

575

576

Functions for working with runtime helpers.

577

578

```typescript { .api }

579

/**

580

* Maps helper symbols to their runtime names

581

*/

582

const helperNameMap: Record<symbol, string>;

583

584

/**

585

* Registers additional runtime helpers

586

* @param helpers - Map of helper symbols to names

587

*/

588

function registerRuntimeHelpers(helpers: Record<symbol, string>): void;

589

```

590

591

**Usage Examples:**

592

593

```typescript

594

import {

595

CREATE_VNODE,

596

RESOLVE_COMPONENT,

597

helperNameMap,

598

registerRuntimeHelpers

599

} from "@vue/compiler-core";

600

601

// Get helper name

602

const vnodeHelper = helperNameMap[CREATE_VNODE]; // "createVNode"

603

const resolveHelper = helperNameMap[RESOLVE_COMPONENT]; // "resolveComponent"

604

605

// Register custom helpers

606

const customHelpers = {

607

[Symbol('CUSTOM_HELPER')]: 'customHelper'

608

};

609

registerRuntimeHelpers(customHelpers);

610

```

611

612

## Vue 2.x Compatibility

613

614

Functions for handling Vue 2.x compatibility features.

615

616

### Compatibility Checking

617

618

```typescript { .api }

619

/**

620

* Checks if a compatibility feature is enabled (without warnings)

621

* @param key - Compatibility feature key

622

* @param context - Transform context

623

* @returns True if feature is enabled

624

*/

625

function isCompatEnabled(

626

key: CompilerDeprecationTypes,

627

context: TransformContext | ParserContext

628

): boolean;

629

630

/**

631

* Checks if a compatibility feature is enabled and warns if deprecated

632

* @param key - Compatibility feature key

633

* @param context - Transform context

634

* @param loc - Source location for warning

635

* @param args - Additional arguments for warning message

636

* @returns True if feature is enabled

637

*/

638

function checkCompatEnabled(

639

key: CompilerDeprecationTypes,

640

context: TransformContext | ParserContext,

641

loc: SourceLocation | null,

642

...args: any[]

643

): boolean;

644

645

/**

646

* Issues a deprecation warning

647

* @param key - Deprecation type

648

* @param context - Transform context

649

* @param message - Additional warning message

650

*/

651

function warnDeprecation(

652

key: CompilerDeprecationTypes,

653

context: TransformContext | ParserContext,

654

message?: string

655

): void;

656

657

/**

658

* Types of compiler deprecations for Vue 2.x compatibility

659

*/

660

enum CompilerDeprecationTypes {

661

COMPILER_IS_ON_ELEMENT = "COMPILER_IS_ON_ELEMENT",

662

COMPILER_V_BIND_SYNC = "COMPILER_V_BIND_SYNC",

663

COMPILER_V_BIND_PROP = "COMPILER_V_BIND_PROP",

664

COMPILER_V_BIND_OBJECT_ORDER = "COMPILER_V_BIND_OBJECT_ORDER",

665

COMPILER_V_ON_NATIVE = "COMPILER_V_ON_NATIVE",

666

COMPILER_V_IF_V_FOR_PRECEDENCE = "COMPILER_V_IF_V_FOR_PRECEDENCE",

667

COMPILER_NATIVE_TEMPLATE = "COMPILER_NATIVE_TEMPLATE",

668

COMPILER_INLINE_TEMPLATE = "COMPILER_INLINE_TEMPLATE",

669

COMPILER_FILTER = "COMPILER_FILTER"

670

}

671

```

672

673

**Usage Examples:**

674

675

```typescript

676

import {

677

checkCompatEnabled,

678

warnDeprecation,

679

CompilerDeprecationTypes

680

} from "@vue/compiler-core";

681

682

// Check if filters are enabled (Vue 2.x feature)

683

if (checkCompatEnabled(CompilerDeprecationTypes.COMPILER_FILTER, context)) {

684

// Process filter syntax

685

processFilter(node, context);

686

} else {

687

warnDeprecation(

688

CompilerDeprecationTypes.COMPILER_FILTER,

689

context,

690

'Filters are removed in Vue 3. Use computed properties or methods instead.'

691

);

692

}

693

```

694

695

## Common Utility Patterns

696

697

### Template Analysis

698

699

```typescript

700

// Check if element has Vue directives

701

function hasDirectives(element: ElementNode): boolean {

702

return element.props.some(prop => prop.type === NodeTypes.DIRECTIVE);

703

}

704

705

// Get all directive names on element

706

function getDirectiveNames(element: ElementNode): string[] {

707

return element.props

708

.filter((prop): prop is DirectiveNode => prop.type === NodeTypes.DIRECTIVE)

709

.map(dir => dir.name);

710

}

711

712

// Check if element is a Vue component

713

function isComponent(element: ElementNode): boolean {

714

return element.tagType === ElementTypes.COMPONENT;

715

}

716

```

717

718

### Expression Validation

719

720

```typescript

721

// Validate v-for expression format

722

function validateVForExpression(exp: string): boolean {

723

const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;

724

return forAliasRE.test(exp);

725

}

726

727

// Check if expression uses reserved keywords

728

function hasReservedKeywords(exp: string): boolean {

729

const reserved = ['arguments', 'eval', 'undefined', 'NaN', 'Infinity'];

730

return reserved.some(keyword => exp.includes(keyword));

731

}

732

```