• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import {
2    ConciseBody, Debug, EmitFlags, Expression, factory, FunctionBody, getEmitFlags, getEmitScriptTarget, Identifier,
3    isAnnotationElement, isArray, isArrayBindingElement, isAssertClause, isAssertEntry, isAssertionKey, isAssertsKeyword, isAsteriskToken,
4    isAwaitKeyword, isBinaryOperatorToken, isBindingElement, isBindingName, isBindingPattern, isBlock, isCallChain,
5    isCaseBlock, isCaseOrDefaultClause, isCatchClause, isClassElement, isColonToken, isConciseBody, isDotDotDotToken,
6    isElementAccessChain, isEntityName, isEnumMember, isEqualsGreaterThanToken, isExclamationToken, isExportSpecifier,
7    isExpression, isExpressionWithTypeArguments, isForInitializer, isHeritageClause, isIdentifier,
8    isIdentifierOrThisTypeNode, isImportClause, isImportSpecifier, isImportTypeAssertionContainer, isJsxAttributeLike,
9    isJsxAttributes, isJsxChild, isJsxClosingElement, isJsxClosingFragment, isJsxOpeningElement, isJsxOpeningFragment,
10    isJsxTagNameExpression, isMemberName, isModifier, isModifierLike, isModuleBody, isModuleName, isModuleReference,
11    isNamedExportBindings, isNamedImportBindings, isObjectLiteralElementLike, isOptionalChain, isParameterDeclaration,
12    isPropertyAccessChain, isPropertyName, isQuestionDotToken, isQuestionOrExclamationToken,
13    isQuestionOrPlusOrMinusToken, isQuestionToken, isReadonlyKeywordOrPlusOrMinusToken, isStatement,
14    isStringLiteralOrJsxExpression, isTemplateHead, isTemplateLiteral, isTemplateLiteralTypeSpan,
15    isTemplateMiddleOrTemplateTail, isTemplateSpan, isToken, isTypeElement, isTypeNode, isTypeNodeOrTypeParameterDeclaration, isTypeParameterDeclaration, isVariableDeclaration,
16    isVariableDeclarationList, LexicalEnvironmentFlags, Node, NodeArray, NodesVisitor, NodeVisitor, ParameterDeclaration, ScriptTarget,
17    setEmitFlags, setTextRange, setTextRangePosEnd, singleOrUndefined, some, Statement, SyntaxKind,
18    TransformationContext, Visitor, VisitEachChildNodes
19} from "./_namespaces/ts";
20
21/**
22 * Visits a Node using the supplied visitor, possibly returning a new Node in its place.
23 *
24 * @param node The Node to visit.
25 * @param visitor The callback used to visit the Node.
26 * @param test A callback to execute to verify the Node is valid.
27 * @param lift An optional callback to execute to lift a NodeArray into a valid Node.
28 */
29export function visitNode<T extends Node>(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T;
30
31/**
32 * Visits a Node using the supplied visitor, possibly returning a new Node in its place.
33 *
34 * @param node The Node to visit.
35 * @param visitor The callback used to visit the Node.
36 * @param test A callback to execute to verify the Node is valid.
37 * @param lift An optional callback to execute to lift a NodeArray into a valid Node.
38 */
39export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined;
40
41export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined {
42    if (node === undefined || visitor === undefined) {
43        return node;
44    }
45
46    const visited = visitor(node);
47    if (visited === node) {
48        return node;
49    }
50
51    let visitedNode: Node | undefined;
52    if (visited === undefined) {
53        return undefined;
54    }
55    else if (isArray(visited)) {
56        visitedNode = (lift || extractSingleNode)(visited);
57    }
58    else {
59        visitedNode = visited;
60    }
61
62    Debug.assertNode(visitedNode, test);
63    return visitedNode as T;
64}
65
66/** @internal */
67export function visitNodes<T extends Node, U extends T>(nodes: NodeArray<T>, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): NodeArray<U>;
68
69/**
70 * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
71 *
72 * @param nodes The NodeArray to visit.
73 * @param visitor The callback used to visit a Node.
74 * @param test A node test to execute for each node.
75 * @param start An optional value indicating the starting offset at which to start visiting.
76 * @param count An optional value indicating the maximum number of nodes to visit.
77 */
78export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
79
80/** @internal */
81export function visitNodes<T extends Node, U extends T>(nodes: NodeArray<T> | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): NodeArray<U> | undefined;
82
83/**
84 * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
85 *
86 * @param nodes The NodeArray to visit.
87 * @param visitor The callback used to visit a Node.
88 * @param test A node test to execute for each node.
89 * @param start An optional value indicating the starting offset at which to start visiting.
90 * @param count An optional value indicating the maximum number of nodes to visit.
91 */
92export function visitNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined;
93
94/**
95 * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
96 *
97 * @param nodes The NodeArray to visit.
98 * @param visitor The callback used to visit a Node.
99 * @param test A node test to execute for each node.
100 * @param start An optional value indicating the starting offset at which to start visiting.
101 * @param count An optional value indicating the maximum number of nodes to visit.
102 */
103export function visitNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> | undefined {
104    if (nodes === undefined || visitor === undefined) {
105        return nodes;
106    }
107
108    // Ensure start and count have valid values
109    const length = nodes.length;
110    if (start === undefined || start < 0) {
111        start = 0;
112    }
113
114    if (count === undefined || count > length - start) {
115        count = length - start;
116    }
117
118    let hasTrailingComma: boolean | undefined;
119    let pos = -1;
120    let end = -1;
121    if (start > 0 || count < length) {
122        // Since this is a fragment of a node array, we do not copy over the previous location
123        // and will only copy over `hasTrailingComma` if we are including the last element.
124        hasTrailingComma = nodes.hasTrailingComma && start + count === length;
125    }
126    else {
127        pos = nodes.pos;
128        end = nodes.end;
129        hasTrailingComma = nodes.hasTrailingComma;
130    }
131
132    const updated = visitArrayWorker(nodes, visitor, test, start, count);
133    if (updated !== nodes as readonly T[]) {
134        // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory.
135        const updatedArray = factory.createNodeArray(updated, hasTrailingComma);
136        setTextRangePosEnd(updatedArray, pos, end);
137        return updatedArray;
138    }
139
140    return nodes;
141}
142
143/** @internal */
144export function visitArray<T extends Node, U extends T>(nodes: T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): U[] | undefined;
145/** @internal */
146export function visitArray<T extends Node, U extends T>(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): readonly U[] | undefined;
147/** @internal */
148export function visitArray<T extends Node>(nodes: T[] | undefined, visitor: Visitor, test: (node: Node) => node is T, start?: number, count?: number): T[] | undefined;
149/** @internal */
150export function visitArray<T extends Node>(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is T, start?: number, count?: number): readonly T[] | undefined;
151export function visitArray<T extends Node, U extends T>(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number) {
152    if (nodes === undefined) {
153        return nodes;
154    }
155
156    // Ensure start and count have valid values
157    const length = nodes.length;
158    if (start === undefined || start < 0) {
159        start = 0;
160    }
161
162    if (count === undefined || count > length - start) {
163        count = length - start;
164    }
165
166    return visitArrayWorker(nodes, visitor, test, start, count) as readonly U[];
167}
168
169/** @internal */
170function visitArrayWorker<T extends Node>(nodes: readonly T[], visitor: Visitor, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly T[] | undefined {
171    let updated: T[] | undefined;
172
173    const length = nodes.length;
174    if (start > 0 || count < length) {
175        // If we are not visiting all of the original nodes, we must always create a new array.
176        updated = [];
177    }
178
179    // Visit each original node.
180    for (let i = 0; i < count; i++) {
181        const node: T = nodes[i + start];
182        const visited = node !== undefined ? visitor(node) : undefined;
183        if (updated !== undefined || visited === undefined || visited !== node) {
184            if (updated === undefined) {
185                // Ensure we have a copy of `nodes`, up to the current index.
186                updated = nodes.slice(0, i);
187            }
188            if (visited) {
189                if (isArray(visited)) {
190                    for (const visitedNode of visited) {
191                        void Debug.assertNode(visitedNode, test);
192                        updated.push(visitedNode as T);
193                    }
194                }
195                else {
196                    void Debug.assertNode(visited, test);
197                    updated.push(visited as T);
198                }
199            }
200        }
201    }
202
203    return updated ?? nodes;
204}
205
206/**
207 * Starts a new lexical environment and visits a statement list, ending the lexical environment
208 * and merging hoisted declarations upon completion.
209 */
210export function visitLexicalEnvironment(statements: NodeArray<Statement>, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) {
211    context.startLexicalEnvironment();
212    statements = nodesVisitor(statements, visitor, isStatement, start);
213    if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements);
214    return factory.mergeLexicalEnvironment(statements, context.endLexicalEnvironment());
215}
216
217/**
218 * Starts a new lexical environment and visits a parameter list, suspending the lexical
219 * environment upon completion.
220 */
221export function visitParameterList(nodes: NodeArray<ParameterDeclaration>, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray<ParameterDeclaration>;
222export function visitParameterList(nodes: NodeArray<ParameterDeclaration> | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray<ParameterDeclaration> | undefined;
223export function visitParameterList(nodes: NodeArray<ParameterDeclaration> | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) {
224    let updated: NodeArray<ParameterDeclaration> | undefined;
225    context.startLexicalEnvironment();
226    if (nodes) {
227        context.setLexicalEnvironmentFlags(LexicalEnvironmentFlags.InParameters, true);
228        updated = nodesVisitor(nodes, visitor, isParameterDeclaration);
229
230        // As of ES2015, any runtime execution of that occurs in for a parameter (such as evaluating an
231        // initializer or a binding pattern), occurs in its own lexical scope. As a result, any expression
232        // that we might transform that introduces a temporary variable would fail as the temporary variable
233        // exists in a different lexical scope. To address this, we move any binding patterns and initializers
234        // in a parameter list to the body if we detect a variable being hoisted while visiting a parameter list
235        // when the emit target is greater than ES2015.
236        if (context.getLexicalEnvironmentFlags() & LexicalEnvironmentFlags.VariablesHoistedInParameters &&
237            getEmitScriptTarget(context.getCompilerOptions()) >= ScriptTarget.ES2015) {
238            updated = addDefaultValueAssignmentsIfNeeded(updated, context);
239        }
240        context.setLexicalEnvironmentFlags(LexicalEnvironmentFlags.InParameters, false);
241    }
242    context.suspendLexicalEnvironment();
243    return updated;
244}
245
246function addDefaultValueAssignmentsIfNeeded(parameters: NodeArray<ParameterDeclaration>, context: TransformationContext) {
247    let result: ParameterDeclaration[] | undefined;
248    for (let i = 0; i < parameters.length; i++) {
249        const parameter = parameters[i];
250        const updated = addDefaultValueAssignmentIfNeeded(parameter, context);
251        if (result || updated !== parameter) {
252            if (!result) result = parameters.slice(0, i);
253            result[i] = updated;
254        }
255    }
256    if (result) {
257        return setTextRange(context.factory.createNodeArray(result, parameters.hasTrailingComma), parameters);
258    }
259    return parameters;
260}
261
262function addDefaultValueAssignmentIfNeeded(parameter: ParameterDeclaration, context: TransformationContext) {
263    // A rest parameter cannot have a binding pattern or an initializer,
264    // so let's just ignore it.
265    return parameter.dotDotDotToken ? parameter :
266        isBindingPattern(parameter.name) ? addDefaultValueAssignmentForBindingPattern(parameter, context) :
267        parameter.initializer ? addDefaultValueAssignmentForInitializer(parameter, parameter.name, parameter.initializer, context) :
268        parameter;
269}
270
271function addDefaultValueAssignmentForBindingPattern(parameter: ParameterDeclaration, context: TransformationContext) {
272    const { factory } = context;
273    context.addInitializationStatement(
274        factory.createVariableStatement(
275            /*modifiers*/ undefined,
276            factory.createVariableDeclarationList([
277                factory.createVariableDeclaration(
278                    parameter.name,
279                    /*exclamationToken*/ undefined,
280                    parameter.type,
281                    parameter.initializer ?
282                        factory.createConditionalExpression(
283                            factory.createStrictEquality(
284                                factory.getGeneratedNameForNode(parameter),
285                                factory.createVoidZero()
286                            ),
287                            /*questionToken*/ undefined,
288                            parameter.initializer,
289                            /*colonToken*/ undefined,
290                            factory.getGeneratedNameForNode(parameter)
291                        ) :
292                        factory.getGeneratedNameForNode(parameter)
293                ),
294            ])
295        )
296    );
297    return factory.updateParameterDeclaration(parameter,
298        parameter.modifiers,
299        parameter.dotDotDotToken,
300        factory.getGeneratedNameForNode(parameter),
301        parameter.questionToken,
302        parameter.type,
303        /*initializer*/ undefined);
304}
305
306function addDefaultValueAssignmentForInitializer(parameter: ParameterDeclaration, name: Identifier, initializer: Expression, context: TransformationContext) {
307    const factory = context.factory;
308    context.addInitializationStatement(
309        factory.createIfStatement(
310            factory.createTypeCheck(factory.cloneNode(name), "undefined"),
311            setEmitFlags(
312                setTextRange(
313                    factory.createBlock([
314                        factory.createExpressionStatement(
315                            setEmitFlags(
316                                setTextRange(
317                                    factory.createAssignment(
318                                        setEmitFlags(factory.cloneNode(name), EmitFlags.NoSourceMap),
319                                        setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer) | EmitFlags.NoComments)
320                                    ),
321                                    parameter
322                                ),
323                                EmitFlags.NoComments
324                            )
325                        )
326                    ]),
327                    parameter
328                ),
329                EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments
330            )
331        )
332    );
333    return factory.updateParameterDeclaration(parameter,
334        parameter.modifiers,
335        parameter.dotDotDotToken,
336        parameter.name,
337        parameter.questionToken,
338        parameter.type,
339        /*initializer*/ undefined);
340}
341
342/**
343 * Resumes a suspended lexical environment and visits a function body, ending the lexical
344 * environment and merging hoisted declarations upon completion.
345 */
346export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody;
347/**
348 * Resumes a suspended lexical environment and visits a function body, ending the lexical
349 * environment and merging hoisted declarations upon completion.
350 */
351export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined;
352/**
353 * Resumes a suspended lexical environment and visits a concise body, ending the lexical
354 * environment and merging hoisted declarations upon completion.
355 */
356export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody;
357/** @internal */ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures
358/** @internal */ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
359/** @internal */ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures
360export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined {
361    context.resumeLexicalEnvironment();
362    const updated = nodeVisitor(node, visitor, isConciseBody);
363    const declarations = context.endLexicalEnvironment();
364    if (some(declarations)) {
365        if (!updated) {
366            return context.factory.createBlock(declarations);
367        }
368        const block = context.factory.converters.convertToFunctionBlock(updated);
369        const statements = factory.mergeLexicalEnvironment(block.statements, declarations);
370        return context.factory.updateBlock(block, statements);
371    }
372    return updated;
373}
374
375/**
376 * Visits an iteration body, adding any block-scoped variables required by the transformation.
377 */
378export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement;
379/** @internal */
380export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures
381export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement {
382    context.startBlockScope();
383    const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock);
384    const declarations = context.endBlockScope();
385    if (some(declarations)) {
386        if (isBlock(updated)) {
387            declarations.push(...updated.statements);
388            return context.factory.updateBlock(updated, declarations);
389        }
390        declarations.push(updated);
391        return context.factory.createBlock(declarations);
392    }
393    return updated;
394}
395
396/**
397 * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
398 *
399 * @param node The Node whose children will be visited.
400 * @param visitor The callback used to visit each child.
401 * @param context A lexical environment context for the visitor.
402 */
403export function visitEachChild<T extends Node>(node: T, visitor: Visitor, context: TransformationContext): T;
404/** @internal */
405export function visitEachChild<T extends Node>(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures
406/**
407 * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place.
408 *
409 * @param node The Node whose children will be visited.
410 * @param visitor The callback used to visit each child.
411 * @param context A lexical environment context for the visitor.
412 */
413export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined;
414/** @internal */
415export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures
416export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined {
417    if (node === undefined) {
418        return undefined;
419    }
420
421    const fn = (visitEachChildTable as Record<SyntaxKind, VisitEachChildFunction<any> | undefined>)[node.kind];
422    return fn === undefined ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor);
423}
424
425type VisitEachChildFunction<T extends Node> = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T;
426
427// A type that correlates a `SyntaxKind` to a `VisitEachChildFunction<T>`, for nodes in the `HasChildren` union.
428// This looks something like:
429//
430//  {
431//      [SyntaxKind.Identifier]: VisitEachChildFunction<Identifier>;
432//      [SyntaxKind.QualifiedName]: VisitEachChildFunction<QualifiedName>;
433//      [SyntaxKind.ComputedPropertyName]: VisitEachChildFunction<ComputedPropertyName>;
434//      ...
435//  }
436//
437// This is then used as the expected type for `visitEachChildTable`.
438type VisitEachChildTable = { [TNode in VisitEachChildNodes as TNode["kind"]]: VisitEachChildFunction<TNode> };
439
440// NOTE: Before you can add a new method to `visitEachChildTable`, you must first ensure the `Node` subtype you
441//       wish to add is defined in the `HasChildren` union in types.ts.
442const visitEachChildTable: VisitEachChildTable = {
443    [SyntaxKind.Identifier]: function visitEachChildOfIdentifier(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
444        return context.factory.updateIdentifier(node,
445            nodesVisitor(node.typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration));
446    },
447
448    [SyntaxKind.QualifiedName]: function visitEachChildOfQualifiedName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
449        return context.factory.updateQualifiedName(node,
450            nodeVisitor(node.left, visitor, isEntityName),
451            nodeVisitor(node.right, visitor, isIdentifier));
452    },
453
454    [SyntaxKind.ComputedPropertyName]: function visitEachChildOfComputedPropertyName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
455        return context.factory.updateComputedPropertyName(node,
456            nodeVisitor(node.expression, visitor, isExpression));
457    },
458
459    // Signature elements
460    [SyntaxKind.TypeParameter]: function visitEachChildOfTypeParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
461        return context.factory.updateTypeParameterDeclaration(node,
462            nodesVisitor(node.modifiers, visitor, isModifier),
463            nodeVisitor(node.name, visitor, isIdentifier),
464            nodeVisitor(node.constraint, visitor, isTypeNode),
465            nodeVisitor(node.default, visitor, isTypeNode));
466    },
467
468    [SyntaxKind.Parameter]: function visitEachChildOfParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
469        return context.factory.updateParameterDeclaration(node,
470            nodesVisitor(node.modifiers, visitor, isModifierLike),
471            nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken),
472            nodeVisitor(node.name, visitor, isBindingName),
473            nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken),
474            nodeVisitor(node.type, visitor, isTypeNode),
475            nodeVisitor(node.initializer, visitor, isExpression));
476    },
477
478    [SyntaxKind.Decorator]: function visitEachChildOfDecorator(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
479        return context.factory.updateDecorator(node,
480            nodeVisitor(node.expression, visitor, isExpression), node.annotationDeclaration);
481    },
482
483    // Type elements
484    [SyntaxKind.PropertySignature]: function visitEachChildOfPropertySignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
485        return context.factory.updatePropertySignature(node,
486            nodesVisitor(node.modifiers, visitor, isModifier),
487            nodeVisitor(node.name, visitor, isPropertyName),
488            nodeVisitor(node.questionToken, tokenVisitor, isToken),
489            nodeVisitor(node.type, visitor, isTypeNode));
490    },
491
492    [SyntaxKind.PropertyDeclaration]: function visitEachChildOfPropertyDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
493        return context.factory.updatePropertyDeclaration(node,
494            nodesVisitor(node.modifiers, visitor, isModifierLike),
495            nodeVisitor(node.name, visitor, isPropertyName),
496            // QuestionToken and ExclamationToken are mutually exclusive in PropertyDeclaration
497            nodeVisitor(node.questionToken ?? node.exclamationToken, tokenVisitor, isQuestionOrExclamationToken),
498            nodeVisitor(node.type, visitor, isTypeNode),
499            nodeVisitor(node.initializer, visitor, isExpression));
500    },
501
502    [SyntaxKind.AnnotationPropertyDeclaration]: function visitEachChildOfAnnotationPropertyDeclaration(node, visitor, context,
503        _nodesVisitor, nodeVisitor, _tokenVisitor) {
504        return context.factory.updateAnnotationPropertyDeclaration(node,
505            nodeVisitor(node.name, visitor, isPropertyName),
506            nodeVisitor(node.type, visitor, isTypeNode),
507            nodeVisitor(node.initializer, visitor, isExpression));
508    },
509
510    [SyntaxKind.MethodSignature]: function visitEachChildOfMethodSignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
511        return context.factory.updateMethodSignature(node,
512            nodesVisitor(node.modifiers, visitor, isModifier),
513            nodeVisitor(node.name, visitor, isPropertyName),
514            nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken),
515            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
516            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
517            nodeVisitor(node.type, visitor, isTypeNode));
518    },
519
520    [SyntaxKind.MethodDeclaration]: function visitEachChildOfMethodDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
521        return context.factory.updateMethodDeclaration(node,
522            nodesVisitor(node.modifiers, visitor, isModifierLike),
523            nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken),
524            nodeVisitor(node.name, visitor, isPropertyName),
525            nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken),
526            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
527            visitParameterList(node.parameters, visitor, context, nodesVisitor),
528            nodeVisitor(node.type, visitor, isTypeNode),
529            visitFunctionBody(node.body!, visitor, context, nodeVisitor));
530    },
531
532    [SyntaxKind.Constructor]: function visitEachChildOfConstructorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
533        return context.factory.updateConstructorDeclaration(node,
534            nodesVisitor(node.modifiers, visitor, isModifier),
535            visitParameterList(node.parameters, visitor, context, nodesVisitor),
536            visitFunctionBody(node.body!, visitor, context, nodeVisitor));
537    },
538
539    [SyntaxKind.GetAccessor]: function visitEachChildOfGetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
540        /** If the lexical environment is suspended, then we visit it as a type node*/
541        if (context.isLexicalEnvironmentSuspended && context.isLexicalEnvironmentSuspended()) {
542            return context.factory.updateGetAccessorDeclaration(node,
543                nodesVisitor(node.modifiers, visitor, isModifierLike),
544                nodeVisitor(node.name, visitor, isPropertyName),
545                nodesVisitor(node.parameters, visitor, isParameterDeclaration),
546                nodeVisitor(node.type, visitor, isTypeNode),
547                nodeVisitor(node.body, visitor, isConciseBody));
548        } else {
549            return context.factory.updateGetAccessorDeclaration(node,
550                nodesVisitor(node.modifiers, visitor, isModifierLike),
551                nodeVisitor(node.name, visitor, isPropertyName),
552                visitParameterList(node.parameters, visitor, context, nodesVisitor),
553                nodeVisitor(node.type, visitor, isTypeNode),
554                visitFunctionBody(node.body!, visitor, context, nodeVisitor));
555        }
556    },
557
558    [SyntaxKind.SetAccessor]: function visitEachChildOfSetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
559        /** If the lexical environment is suspended, then we visit it as a type node*/
560        if (context.isLexicalEnvironmentSuspended && context.isLexicalEnvironmentSuspended()) {
561            return context.factory.updateSetAccessorDeclaration(node,
562                nodesVisitor(node.modifiers, visitor, isModifierLike),
563                nodeVisitor(node.name, visitor, isPropertyName),
564                nodesVisitor(node.parameters, visitor, isParameterDeclaration),
565                nodeVisitor(node.body, visitor, isConciseBody));
566        } else {
567            return context.factory.updateSetAccessorDeclaration(node,
568                nodesVisitor(node.modifiers, visitor, isModifierLike),
569                nodeVisitor(node.name, visitor, isPropertyName),
570                visitParameterList(node.parameters, visitor, context, nodesVisitor),
571                visitFunctionBody(node.body!, visitor, context, nodeVisitor));
572        }
573    },
574
575    [SyntaxKind.ClassStaticBlockDeclaration]: function visitEachChildOfClassStaticBlockDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
576        context.startLexicalEnvironment();
577        context.suspendLexicalEnvironment();
578        return context.factory.updateClassStaticBlockDeclaration(node,
579            visitFunctionBody(node.body, visitor, context, nodeVisitor));
580    },
581
582    [SyntaxKind.CallSignature]: function visitEachChildOfCallSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
583        return context.factory.updateCallSignature(node,
584            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
585            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
586            nodeVisitor(node.type, visitor, isTypeNode));
587    },
588
589    [SyntaxKind.ConstructSignature]: function visitEachChildOfConstructSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
590        return context.factory.updateConstructSignature(node,
591            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
592            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
593            nodeVisitor(node.type, visitor, isTypeNode));
594    },
595
596    [SyntaxKind.IndexSignature]: function visitEachChildOfIndexSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
597        return context.factory.updateIndexSignature(node,
598            nodesVisitor(node.modifiers, visitor, isModifier),
599            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
600            nodeVisitor(node.type, visitor, isTypeNode));
601    },
602
603    // Types
604    [SyntaxKind.TypePredicate]: function visitEachChildOfTypePredicateNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
605        return context.factory.updateTypePredicateNode(node,
606            nodeVisitor(node.assertsModifier, visitor, isAssertsKeyword),
607            nodeVisitor(node.parameterName, visitor, isIdentifierOrThisTypeNode),
608            nodeVisitor(node.type, visitor, isTypeNode));
609    },
610
611    [SyntaxKind.TypeReference]: function visitEachChildOfTypeReferenceNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
612        return context.factory.updateTypeReferenceNode(node,
613            nodeVisitor(node.typeName, visitor, isEntityName),
614            nodesVisitor(node.typeArguments, visitor, isTypeNode));
615    },
616
617    [SyntaxKind.FunctionType]: function visitEachChildOfFunctionTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
618        return context.factory.updateFunctionTypeNode(node,
619            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
620            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
621            nodeVisitor(node.type, visitor, isTypeNode));
622    },
623
624    [SyntaxKind.ConstructorType]: function visitEachChildOfConstructorTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
625        return context.factory.updateConstructorTypeNode(node,
626            nodesVisitor(node.modifiers, visitor, isModifier),
627            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
628            nodesVisitor(node.parameters, visitor, isParameterDeclaration),
629            nodeVisitor(node.type, visitor, isTypeNode));
630    },
631
632    [SyntaxKind.TypeQuery]: function visitEachChildOfTypeQueryNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
633        return context.factory.updateTypeQueryNode(node,
634            nodeVisitor(node.exprName, visitor, isEntityName),
635            nodesVisitor(node.typeArguments, visitor, isTypeNode));
636    },
637
638    [SyntaxKind.TypeLiteral]: function visitEachChildOfTypeLiteralNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
639        return context.factory.updateTypeLiteralNode(node,
640            nodesVisitor(node.members, visitor, isTypeElement));
641    },
642
643    [SyntaxKind.ArrayType]: function visitEachChildOfArrayTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
644        return context.factory.updateArrayTypeNode(node,
645            nodeVisitor(node.elementType, visitor, isTypeNode));
646    },
647
648    [SyntaxKind.TupleType]: function visitEachChildOfTupleTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
649        return context.factory.updateTupleTypeNode(node,
650            nodesVisitor(node.elements, visitor, isTypeNode));
651    },
652
653    [SyntaxKind.OptionalType]: function visitEachChildOfOptionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
654        return context.factory.updateOptionalTypeNode(node,
655            nodeVisitor(node.type, visitor, isTypeNode));
656    },
657
658    [SyntaxKind.RestType]: function visitEachChildOfRestTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
659        return context.factory.updateRestTypeNode(node,
660            nodeVisitor(node.type, visitor, isTypeNode));
661    },
662
663    [SyntaxKind.UnionType]: function visitEachChildOfUnionTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
664        return context.factory.updateUnionTypeNode(node,
665            nodesVisitor(node.types, visitor, isTypeNode));
666    },
667
668    [SyntaxKind.IntersectionType]: function visitEachChildOfIntersectionTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
669        return context.factory.updateIntersectionTypeNode(node,
670            nodesVisitor(node.types, visitor, isTypeNode));
671    },
672
673    [SyntaxKind.ConditionalType]: function visitEachChildOfConditionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
674        return context.factory.updateConditionalTypeNode(node,
675            nodeVisitor(node.checkType, visitor, isTypeNode),
676            nodeVisitor(node.extendsType, visitor, isTypeNode),
677            nodeVisitor(node.trueType, visitor, isTypeNode),
678            nodeVisitor(node.falseType, visitor, isTypeNode));
679    },
680
681    [SyntaxKind.InferType]: function visitEachChildOfInferTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
682        return context.factory.updateInferTypeNode(node,
683            nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration));
684    },
685
686    [SyntaxKind.ImportType]: function visitEachChildOfImportTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
687        return context.factory.updateImportTypeNode(node,
688            nodeVisitor(node.argument, visitor, isTypeNode),
689            nodeVisitor(node.assertions, visitor, isImportTypeAssertionContainer),
690            nodeVisitor(node.qualifier, visitor, isEntityName),
691            nodesVisitor(node.typeArguments, visitor, isTypeNode),
692            node.isTypeOf
693        );
694    },
695
696    [SyntaxKind.ImportTypeAssertionContainer]: function visitEachChildOfImportTypeAssertionContainer(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
697        return context.factory.updateImportTypeAssertionContainer(node,
698            nodeVisitor(node.assertClause, visitor, isAssertClause),
699            node.multiLine
700        );
701    },
702
703    [SyntaxKind.NamedTupleMember]: function visitEachChildOfNamedTupleMember(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
704        return context.factory.updateNamedTupleMember(node,
705            nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken),
706            nodeVisitor(node.name, visitor, isIdentifier),
707            nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken),
708            nodeVisitor(node.type, visitor, isTypeNode),
709        );
710    },
711
712    [SyntaxKind.ParenthesizedType]: function visitEachChildOfParenthesizedType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
713        return context.factory.updateParenthesizedType(node,
714            nodeVisitor(node.type, visitor, isTypeNode));
715    },
716
717    [SyntaxKind.TypeOperator]: function visitEachChildOfTypeOperatorNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
718        return context.factory.updateTypeOperatorNode(node,
719            nodeVisitor(node.type, visitor, isTypeNode));
720    },
721
722    [SyntaxKind.IndexedAccessType]: function visitEachChildOfIndexedAccessType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
723        return context.factory.updateIndexedAccessTypeNode(node,
724            nodeVisitor(node.objectType, visitor, isTypeNode),
725            nodeVisitor(node.indexType, visitor, isTypeNode));
726    },
727
728    [SyntaxKind.MappedType]: function visitEachChildOfMappedType(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
729        return context.factory.updateMappedTypeNode(node,
730            nodeVisitor(node.readonlyToken, tokenVisitor, isReadonlyKeywordOrPlusOrMinusToken),
731            nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration),
732            nodeVisitor(node.nameType, visitor, isTypeNode),
733            nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken),
734            nodeVisitor(node.type, visitor, isTypeNode),
735            nodesVisitor(node.members, visitor, isTypeElement));
736    },
737
738    [SyntaxKind.LiteralType]: function visitEachChildOfLiteralTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
739        return context.factory.updateLiteralTypeNode(node,
740            nodeVisitor(node.literal, visitor, isExpression));
741    },
742
743    [SyntaxKind.TemplateLiteralType]: function visitEachChildOfTemplateLiteralType(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
744        return context.factory.updateTemplateLiteralType(node,
745            nodeVisitor(node.head, visitor, isTemplateHead),
746            nodesVisitor(node.templateSpans, visitor, isTemplateLiteralTypeSpan));
747    },
748
749    [SyntaxKind.TemplateLiteralTypeSpan]: function visitEachChildOfTemplateLiteralTypeSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
750        return context.factory.updateTemplateLiteralTypeSpan(node,
751            nodeVisitor(node.type, visitor, isTypeNode),
752            nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail));
753    },
754
755    // Binding patterns
756    [SyntaxKind.ObjectBindingPattern]: function visitEachChildOfObjectBindingPattern(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
757        return context.factory.updateObjectBindingPattern(node,
758            nodesVisitor(node.elements, visitor, isBindingElement));
759    },
760
761    [SyntaxKind.ArrayBindingPattern]: function visitEachChildOfArrayBindingPattern(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
762        return context.factory.updateArrayBindingPattern(node,
763            nodesVisitor(node.elements, visitor, isArrayBindingElement));
764    },
765
766    [SyntaxKind.BindingElement]: function visitEachChildOfBindingElement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
767        return context.factory.updateBindingElement(node,
768            nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken),
769            nodeVisitor(node.propertyName, visitor, isPropertyName),
770            nodeVisitor(node.name, visitor, isBindingName),
771            nodeVisitor(node.initializer, visitor, isExpression));
772    },
773
774    // Expression
775    [SyntaxKind.ArrayLiteralExpression]: function visitEachChildOfArrayLiteralExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
776        return context.factory.updateArrayLiteralExpression(node,
777            nodesVisitor(node.elements, visitor, isExpression));
778    },
779
780    [SyntaxKind.ObjectLiteralExpression]: function visitEachChildOfObjectLiteralExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
781        return context.factory.updateObjectLiteralExpression(node,
782            nodesVisitor(node.properties, visitor, isObjectLiteralElementLike));
783    },
784
785    [SyntaxKind.PropertyAccessExpression]: function visitEachChildOfPropertyAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
786        return isPropertyAccessChain(node) ?
787            context.factory.updatePropertyAccessChain(node,
788                nodeVisitor(node.expression, visitor, isExpression),
789                nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken),
790                nodeVisitor(node.name, visitor, isMemberName)) :
791            context.factory.updatePropertyAccessExpression(node,
792                nodeVisitor(node.expression, visitor, isExpression),
793                nodeVisitor(node.name, visitor, isMemberName));
794    },
795
796    [SyntaxKind.ElementAccessExpression]: function visitEachChildOfElementAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
797        return isElementAccessChain(node) ?
798            context.factory.updateElementAccessChain(node,
799                nodeVisitor(node.expression, visitor, isExpression),
800                nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken),
801                nodeVisitor(node.argumentExpression, visitor, isExpression)) :
802            context.factory.updateElementAccessExpression(node,
803                nodeVisitor(node.expression, visitor, isExpression),
804                nodeVisitor(node.argumentExpression, visitor, isExpression));
805    },
806
807    [SyntaxKind.CallExpression]: function visitEachChildOfCallExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
808        return isCallChain(node) ?
809            context.factory.updateCallChain(node,
810                nodeVisitor(node.expression, visitor, isExpression),
811                nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken),
812                nodesVisitor(node.typeArguments, visitor, isTypeNode),
813                nodesVisitor(node.arguments, visitor, isExpression)) :
814            context.factory.updateCallExpression(node,
815                nodeVisitor(node.expression, visitor, isExpression),
816                nodesVisitor(node.typeArguments, visitor, isTypeNode),
817                nodesVisitor(node.arguments, visitor, isExpression));
818    },
819
820    [SyntaxKind.EtsComponentExpression]: function visitEachChildOfEtsComponentExpression(node, visitor, context, nodesVisitor, nodeVisitor) {
821        return context.factory.updateEtsComponentExpression(node,
822            nodeVisitor(node.expression, visitor, isExpression),
823            //nodesVisitor(node.typeArguments, visitor, isTypeNode),
824            nodesVisitor(node.arguments, visitor, isExpression),
825            nodeVisitor(node.body, visitor, isBlock));
826    },
827
828    [SyntaxKind.NewExpression]: function visitEachChildOfNewExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
829        return context.factory.updateNewExpression(node,
830            nodeVisitor(node.expression, visitor, isExpression),
831            nodesVisitor(node.typeArguments, visitor, isTypeNode),
832            nodesVisitor(node.arguments, visitor, isExpression));
833    },
834
835    [SyntaxKind.TaggedTemplateExpression]: function visitEachChildOfTaggedTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
836        return context.factory.updateTaggedTemplateExpression(node,
837            nodeVisitor(node.tag, visitor, isExpression),
838            nodesVisitor(node.typeArguments, visitor, isTypeNode),
839            nodeVisitor(node.template, visitor, isTemplateLiteral));
840    },
841
842    [SyntaxKind.TypeAssertionExpression]: function visitEachChildOfTypeAssertionExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
843        return context.factory.updateTypeAssertion(node,
844            nodeVisitor(node.type, visitor, isTypeNode),
845            nodeVisitor(node.expression, visitor, isExpression));
846    },
847
848    [SyntaxKind.ParenthesizedExpression]: function visitEachChildOfParenthesizedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
849        return context.factory.updateParenthesizedExpression(node,
850            nodeVisitor(node.expression, visitor, isExpression));
851    },
852
853    [SyntaxKind.FunctionExpression]: function visitEachChildOfFunctionExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
854        return context.factory.updateFunctionExpression(node,
855            nodesVisitor(node.modifiers, visitor, isModifier),
856            nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken),
857            nodeVisitor(node.name, visitor, isIdentifier),
858            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
859            visitParameterList(node.parameters, visitor, context, nodesVisitor),
860            nodeVisitor(node.type, visitor, isTypeNode),
861            visitFunctionBody(node.body, visitor, context, nodeVisitor));
862    },
863
864    [SyntaxKind.ArrowFunction]: function visitEachChildOfArrowFunction(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
865        return context.factory.updateArrowFunction(node,
866            nodesVisitor(node.modifiers, visitor, isModifier),
867            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
868            visitParameterList(node.parameters, visitor, context, nodesVisitor),
869            nodeVisitor(node.type, visitor, isTypeNode),
870            nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken),
871            visitFunctionBody(node.body, visitor, context, nodeVisitor));
872    },
873
874    [SyntaxKind.DeleteExpression]: function visitEachChildOfDeleteExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
875        return context.factory.updateDeleteExpression(node,
876            nodeVisitor(node.expression, visitor, isExpression));
877    },
878
879    [SyntaxKind.TypeOfExpression]: function visitEachChildOfTypeOfExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
880        return context.factory.updateTypeOfExpression(node,
881            nodeVisitor(node.expression, visitor, isExpression));
882    },
883
884    [SyntaxKind.VoidExpression]: function visitEachChildOfVoidExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
885        return context.factory.updateVoidExpression(node,
886            nodeVisitor(node.expression, visitor, isExpression));
887    },
888
889    [SyntaxKind.AwaitExpression]: function visitEachChildOfAwaitExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
890        return context.factory.updateAwaitExpression(node,
891            nodeVisitor(node.expression, visitor, isExpression));
892    },
893
894    [SyntaxKind.PrefixUnaryExpression]: function visitEachChildOfPrefixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
895        return context.factory.updatePrefixUnaryExpression(node,
896            nodeVisitor(node.operand, visitor, isExpression));
897    },
898
899    [SyntaxKind.PostfixUnaryExpression]: function visitEachChildOfPostfixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
900        return context.factory.updatePostfixUnaryExpression(node,
901            nodeVisitor(node.operand, visitor, isExpression));
902    },
903
904    [SyntaxKind.BinaryExpression]: function visitEachChildOfBinaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
905        return context.factory.updateBinaryExpression(node,
906            nodeVisitor(node.left, visitor, isExpression),
907            nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken),
908            nodeVisitor(node.right, visitor, isExpression));
909    },
910
911    [SyntaxKind.ConditionalExpression]: function visitEachChildOfConditionalExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
912        return context.factory.updateConditionalExpression(node,
913            nodeVisitor(node.condition, visitor, isExpression),
914            nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken),
915            nodeVisitor(node.whenTrue, visitor, isExpression),
916            nodeVisitor(node.colonToken, tokenVisitor, isColonToken),
917            nodeVisitor(node.whenFalse, visitor, isExpression));
918    },
919
920    [SyntaxKind.TemplateExpression]: function visitEachChildOfTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
921        return context.factory.updateTemplateExpression(node,
922            nodeVisitor(node.head, visitor, isTemplateHead),
923            nodesVisitor(node.templateSpans, visitor, isTemplateSpan));
924    },
925
926    [SyntaxKind.YieldExpression]: function visitEachChildOfYieldExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
927        return context.factory.updateYieldExpression(node,
928            nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken),
929            nodeVisitor(node.expression, visitor, isExpression));
930    },
931
932    [SyntaxKind.SpreadElement]: function visitEachChildOfSpreadElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
933        return context.factory.updateSpreadElement(node,
934            nodeVisitor(node.expression, visitor, isExpression));
935    },
936
937    [SyntaxKind.ClassExpression]: function visitEachChildOfClassExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
938        return context.factory.updateClassExpression(node,
939            nodesVisitor(node.modifiers, visitor, isModifierLike),
940            nodeVisitor(node.name, visitor, isIdentifier),
941            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
942            nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
943            nodesVisitor(node.members, visitor, isClassElement));
944    },
945
946    [SyntaxKind.ExpressionWithTypeArguments]: function visitEachChildOfExpressionWithTypeArguments(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
947        return context.factory.updateExpressionWithTypeArguments(node,
948            nodeVisitor(node.expression, visitor, isExpression),
949            nodesVisitor(node.typeArguments, visitor, isTypeNode));
950    },
951
952    [SyntaxKind.AsExpression]: function visitEachChildOfAsExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
953        return context.factory.updateAsExpression(node,
954            nodeVisitor(node.expression, visitor, isExpression),
955            nodeVisitor(node.type, visitor, isTypeNode));
956    },
957
958    [SyntaxKind.SatisfiesExpression]: function visitEachChildOfSatisfiesExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
959        return context.factory.updateSatisfiesExpression(node,
960            nodeVisitor(node.expression, visitor, isExpression),
961            nodeVisitor(node.type, visitor, isTypeNode));
962    },
963
964    [SyntaxKind.NonNullExpression]: function visitEachChildOfNonNullExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
965        return isOptionalChain(node) ?
966            context.factory.updateNonNullChain(node,
967                nodeVisitor(node.expression, visitor, isExpression)) :
968            context.factory.updateNonNullExpression(node,
969                nodeVisitor(node.expression, visitor, isExpression));
970    },
971
972    [SyntaxKind.MetaProperty]: function visitEachChildOfMetaProperty(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
973        return context.factory.updateMetaProperty(node,
974            nodeVisitor(node.name, visitor, isIdentifier));
975    },
976
977    // Misc
978    [SyntaxKind.TemplateSpan]: function visitEachChildOfTemplateSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
979        return context.factory.updateTemplateSpan(node,
980            nodeVisitor(node.expression, visitor, isExpression),
981            nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail));
982    },
983
984    // Element
985    [SyntaxKind.Block]: function visitEachChildOfBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
986        return context.factory.updateBlock(node,
987            nodesVisitor(node.statements, visitor, isStatement));
988    },
989
990    [SyntaxKind.VariableStatement]: function visitEachChildOfVariableStatement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
991        return context.factory.updateVariableStatement(node,
992            nodesVisitor(node.modifiers, visitor, isModifier),
993            nodeVisitor(node.declarationList, visitor, isVariableDeclarationList));
994    },
995
996    [SyntaxKind.ExpressionStatement]: function visitEachChildOfExpressionStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
997        return context.factory.updateExpressionStatement(node,
998            nodeVisitor(node.expression, visitor, isExpression));
999    },
1000
1001    [SyntaxKind.IfStatement]: function visitEachChildOfIfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1002        return context.factory.updateIfStatement(node,
1003            nodeVisitor(node.expression, visitor, isExpression),
1004            nodeVisitor(node.thenStatement, visitor, isStatement, context.factory.liftToBlock),
1005            nodeVisitor(node.elseStatement, visitor, isStatement, context.factory.liftToBlock));
1006    },
1007
1008    [SyntaxKind.DoStatement]: function visitEachChildOfDoStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1009        return context.factory.updateDoStatement(node,
1010            visitIterationBody(node.statement, visitor, context, nodeVisitor),
1011            nodeVisitor(node.expression, visitor, isExpression));
1012    },
1013
1014    [SyntaxKind.WhileStatement]: function visitEachChildOfWhileStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1015        return context.factory.updateWhileStatement(node,
1016            nodeVisitor(node.expression, visitor, isExpression),
1017            visitIterationBody(node.statement, visitor, context, nodeVisitor));
1018    },
1019
1020    [SyntaxKind.ForStatement]: function visitEachChildOfForStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1021        return context.factory.updateForStatement(node,
1022            nodeVisitor(node.initializer, visitor, isForInitializer),
1023            nodeVisitor(node.condition, visitor, isExpression),
1024            nodeVisitor(node.incrementor, visitor, isExpression),
1025            visitIterationBody(node.statement, visitor, context, nodeVisitor));
1026    },
1027
1028    [SyntaxKind.ForInStatement]: function visitEachChildOfForInStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1029        return context.factory.updateForInStatement(node,
1030            nodeVisitor(node.initializer, visitor, isForInitializer),
1031            nodeVisitor(node.expression, visitor, isExpression),
1032            visitIterationBody(node.statement, visitor, context, nodeVisitor));
1033    },
1034
1035    [SyntaxKind.ForOfStatement]: function visitEachChildOfForOfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
1036        return context.factory.updateForOfStatement(node,
1037            nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword),
1038            nodeVisitor(node.initializer, visitor, isForInitializer),
1039            nodeVisitor(node.expression, visitor, isExpression),
1040            visitIterationBody(node.statement, visitor, context, nodeVisitor));
1041    },
1042
1043    [SyntaxKind.ContinueStatement]: function visitEachChildOfContinueStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1044        return context.factory.updateContinueStatement(node,
1045            nodeVisitor(node.label, visitor, isIdentifier));
1046    },
1047
1048    [SyntaxKind.BreakStatement]: function visitEachChildOfBreakStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1049        return context.factory.updateBreakStatement(node,
1050            nodeVisitor(node.label, visitor, isIdentifier));
1051    },
1052
1053    [SyntaxKind.ReturnStatement]: function visitEachChildOfReturnStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1054        return context.factory.updateReturnStatement(node,
1055            nodeVisitor(node.expression, visitor, isExpression));
1056    },
1057
1058    [SyntaxKind.WithStatement]: function visitEachChildOfWithStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1059        return context.factory.updateWithStatement(node,
1060            nodeVisitor(node.expression, visitor, isExpression),
1061            nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock));
1062    },
1063
1064    [SyntaxKind.SwitchStatement]: function visitEachChildOfSwitchStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1065        return context.factory.updateSwitchStatement(node,
1066            nodeVisitor(node.expression, visitor, isExpression),
1067            nodeVisitor(node.caseBlock, visitor, isCaseBlock));
1068    },
1069
1070    [SyntaxKind.LabeledStatement]: function visitEachChildOfLabeledStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1071        return context.factory.updateLabeledStatement(node,
1072            nodeVisitor(node.label, visitor, isIdentifier),
1073            nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock));
1074    },
1075
1076    [SyntaxKind.ThrowStatement]: function visitEachChildOfThrowStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1077        return context.factory.updateThrowStatement(node,
1078            nodeVisitor(node.expression, visitor, isExpression));
1079    },
1080
1081    [SyntaxKind.TryStatement]: function visitEachChildOfTryStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1082        return context.factory.updateTryStatement(node,
1083            nodeVisitor(node.tryBlock, visitor, isBlock),
1084            nodeVisitor(node.catchClause, visitor, isCatchClause),
1085            nodeVisitor(node.finallyBlock, visitor, isBlock));
1086    },
1087
1088    [SyntaxKind.VariableDeclaration]: function visitEachChildOfVariableDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) {
1089        return context.factory.updateVariableDeclaration(node,
1090            nodeVisitor(node.name, visitor, isBindingName),
1091            nodeVisitor(node.exclamationToken, tokenVisitor, isExclamationToken),
1092            nodeVisitor(node.type, visitor, isTypeNode),
1093            nodeVisitor(node.initializer, visitor, isExpression));
1094    },
1095
1096    [SyntaxKind.VariableDeclarationList]: function visitEachChildOfVariableDeclarationList(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1097        return context.factory.updateVariableDeclarationList(node,
1098            nodesVisitor(node.declarations, visitor, isVariableDeclaration));
1099    },
1100
1101    [SyntaxKind.FunctionDeclaration]: function visitEachChildOfFunctionDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) {
1102        return context.factory.updateFunctionDeclaration(node,
1103            nodesVisitor(node.modifiers, visitor, isModifier),
1104            nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken),
1105            nodeVisitor(node.name, visitor, isIdentifier),
1106            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
1107            visitParameterList(node.parameters, visitor, context, nodesVisitor),
1108            nodeVisitor(node.type, visitor, isTypeNode),
1109            visitFunctionBody(node.body, visitor, context, nodeVisitor));
1110    },
1111
1112    [SyntaxKind.ClassDeclaration]: function visitEachChildOfClassDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1113        return context.factory.updateClassDeclaration(node,
1114            nodesVisitor(node.modifiers, visitor, isModifierLike),
1115            nodeVisitor(node.name, visitor, isIdentifier),
1116            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
1117            nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
1118            nodesVisitor(node.members, visitor, isClassElement));
1119    },
1120
1121    [SyntaxKind.StructDeclaration]: function visitEachChildOfStructDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1122        return context.factory.updateStructDeclaration(node,
1123            nodesVisitor(node.modifiers, visitor, isModifier),
1124            nodeVisitor(node.name, visitor, isIdentifier),
1125            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
1126            nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
1127            nodesVisitor(node.members, visitor, isClassElement));
1128    },
1129
1130    [SyntaxKind.AnnotationDeclaration]: function visitEachChildOfAnnotationDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1131        return context.factory.updateAnnotationDeclaration(node,
1132            nodesVisitor(node.modifiers, visitor, isModifier),
1133            nodeVisitor(node.name, visitor, isIdentifier),
1134            nodesVisitor(node.members, visitor, isAnnotationElement));
1135    },
1136
1137    [SyntaxKind.InterfaceDeclaration]: function visitEachChildOfInterfaceDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1138        return context.factory.updateInterfaceDeclaration(node,
1139            nodesVisitor(node.modifiers, visitor, isModifier),
1140            nodeVisitor(node.name, visitor, isIdentifier),
1141            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
1142            nodesVisitor(node.heritageClauses, visitor, isHeritageClause),
1143            nodesVisitor(node.members, visitor, isTypeElement));
1144    },
1145
1146    [SyntaxKind.TypeAliasDeclaration]: function visitEachChildOfTypeAliasDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1147        return context.factory.updateTypeAliasDeclaration(node,
1148            nodesVisitor(node.modifiers, visitor, isModifier),
1149            nodeVisitor(node.name, visitor, isIdentifier),
1150            nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration),
1151            nodeVisitor(node.type, visitor, isTypeNode));
1152    },
1153
1154    [SyntaxKind.EnumDeclaration]: function visitEachChildOfEnumDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1155        return context.factory.updateEnumDeclaration(node,
1156            nodesVisitor(node.modifiers, visitor, isModifier),
1157            nodeVisitor(node.name, visitor, isIdentifier),
1158            nodesVisitor(node.members, visitor, isEnumMember));
1159    },
1160
1161    [SyntaxKind.ModuleDeclaration]: function visitEachChildOfModuleDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1162        return context.factory.updateModuleDeclaration(node,
1163            nodesVisitor(node.modifiers, visitor, isModifier),
1164            nodeVisitor(node.name, visitor, isModuleName),
1165            nodeVisitor(node.body, visitor, isModuleBody));
1166    },
1167
1168    [SyntaxKind.ModuleBlock]: function visitEachChildOfModuleBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1169        return context.factory.updateModuleBlock(node,
1170            nodesVisitor(node.statements, visitor, isStatement));
1171    },
1172
1173    [SyntaxKind.CaseBlock]: function visitEachChildOfCaseBlock(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1174        return context.factory.updateCaseBlock(node,
1175            nodesVisitor(node.clauses, visitor, isCaseOrDefaultClause));
1176    },
1177
1178    [SyntaxKind.NamespaceExportDeclaration]: function visitEachChildOfNamespaceExportDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1179        return context.factory.updateNamespaceExportDeclaration(node,
1180            nodeVisitor(node.name, visitor, isIdentifier));
1181    },
1182
1183    [SyntaxKind.ImportEqualsDeclaration]: function visitEachChildOfImportEqualsDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1184        return context.factory.updateImportEqualsDeclaration(node,
1185            nodesVisitor(node.modifiers, visitor, isModifier),
1186            node.isTypeOnly,
1187            nodeVisitor(node.name, visitor, isIdentifier),
1188            nodeVisitor(node.moduleReference, visitor, isModuleReference));
1189    },
1190
1191    [SyntaxKind.ImportDeclaration]: function visitEachChildOfImportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1192        return context.factory.updateImportDeclaration(node,
1193            nodesVisitor(node.modifiers, visitor, isModifier),
1194            nodeVisitor(node.importClause, visitor, isImportClause),
1195            nodeVisitor(node.moduleSpecifier, visitor, isExpression),
1196            nodeVisitor(node.assertClause, visitor, isAssertClause));
1197    },
1198
1199    [SyntaxKind.AssertClause]: function visitEachChildOfAssertClause(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1200        return context.factory.updateAssertClause(node,
1201            nodesVisitor(node.elements, visitor, isAssertEntry),
1202            node.multiLine);
1203    },
1204
1205    [SyntaxKind.AssertEntry]: function visitEachChildOfAssertEntry(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1206        return context.factory.updateAssertEntry(node,
1207            nodeVisitor(node.name, visitor, isAssertionKey),
1208            nodeVisitor(node.value, visitor, isExpression));
1209    },
1210
1211    [SyntaxKind.ImportClause]: function visitEachChildOfImportClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1212        return context.factory.updateImportClause(node,
1213            node.isTypeOnly,
1214            nodeVisitor(node.name, visitor, isIdentifier),
1215            nodeVisitor(node.namedBindings, visitor, isNamedImportBindings));
1216    },
1217
1218    [SyntaxKind.NamespaceImport]: function visitEachChildOfNamespaceImport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1219        return context.factory.updateNamespaceImport(node,
1220            nodeVisitor(node.name, visitor, isIdentifier));
1221    },
1222
1223    [SyntaxKind.NamespaceExport]: function visitEachChildOfNamespaceExport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1224        return context.factory.updateNamespaceExport(node,
1225            nodeVisitor(node.name, visitor, isIdentifier));
1226    },
1227
1228    [SyntaxKind.NamedImports]: function visitEachChildOfNamedImports(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1229        return context.factory.updateNamedImports(node,
1230            nodesVisitor(node.elements, visitor, isImportSpecifier));
1231    },
1232
1233    [SyntaxKind.ImportSpecifier]: function visitEachChildOfImportSpecifier(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1234        return context.factory.updateImportSpecifier(node,
1235            node.isTypeOnly,
1236            nodeVisitor(node.propertyName, visitor, isIdentifier),
1237            nodeVisitor(node.name, visitor, isIdentifier));
1238    },
1239
1240    [SyntaxKind.ExportAssignment]: function visitEachChildOfExportAssignment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1241        return context.factory.updateExportAssignment(node,
1242            nodesVisitor(node.modifiers, visitor, isModifier),
1243            nodeVisitor(node.expression, visitor, isExpression));
1244    },
1245
1246    [SyntaxKind.ExportDeclaration]: function visitEachChildOfExportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1247        return context.factory.updateExportDeclaration(node,
1248            nodesVisitor(node.modifiers, visitor, isModifier),
1249            node.isTypeOnly,
1250            nodeVisitor(node.exportClause, visitor, isNamedExportBindings),
1251            nodeVisitor(node.moduleSpecifier, visitor, isExpression),
1252            nodeVisitor(node.assertClause, visitor, isAssertClause));
1253    },
1254
1255    [SyntaxKind.NamedExports]: function visitEachChildOfNamedExports(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1256        return context.factory.updateNamedExports(node,
1257            nodesVisitor(node.elements, visitor, isExportSpecifier));
1258    },
1259
1260    [SyntaxKind.ExportSpecifier]: function visitEachChildOfExportSpecifier(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1261        return context.factory.updateExportSpecifier(node,
1262            node.isTypeOnly,
1263            nodeVisitor(node.propertyName, visitor, isIdentifier),
1264            nodeVisitor(node.name, visitor, isIdentifier));
1265    },
1266
1267    // Module references
1268    [SyntaxKind.ExternalModuleReference]: function visitEachChildOfExternalModuleReference(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1269        return context.factory.updateExternalModuleReference(node,
1270            nodeVisitor(node.expression, visitor, isExpression));
1271    },
1272
1273    // JSX
1274    [SyntaxKind.JsxElement]: function visitEachChildOfJsxElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1275        return context.factory.updateJsxElement(node,
1276            nodeVisitor(node.openingElement, visitor, isJsxOpeningElement),
1277            nodesVisitor(node.children, visitor, isJsxChild),
1278            nodeVisitor(node.closingElement, visitor, isJsxClosingElement));
1279    },
1280
1281    [SyntaxKind.JsxSelfClosingElement]: function visitEachChildOfJsxSelfClosingElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1282        return context.factory.updateJsxSelfClosingElement(node,
1283            nodeVisitor(node.tagName, visitor, isJsxTagNameExpression),
1284            nodesVisitor(node.typeArguments, visitor, isTypeNode),
1285            nodeVisitor(node.attributes, visitor, isJsxAttributes));
1286    },
1287
1288    [SyntaxKind.JsxOpeningElement]: function visitEachChildOfJsxOpeningElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1289        return context.factory.updateJsxOpeningElement(node,
1290            nodeVisitor(node.tagName, visitor, isJsxTagNameExpression),
1291            nodesVisitor(node.typeArguments, visitor, isTypeNode),
1292            nodeVisitor(node.attributes, visitor, isJsxAttributes));
1293    },
1294
1295    [SyntaxKind.JsxClosingElement]: function visitEachChildOfJsxClosingElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1296        return context.factory.updateJsxClosingElement(node,
1297            nodeVisitor(node.tagName, visitor, isJsxTagNameExpression));
1298    },
1299
1300    [SyntaxKind.JsxFragment]: function visitEachChildOfJsxFragment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1301        return context.factory.updateJsxFragment(node,
1302            nodeVisitor(node.openingFragment, visitor, isJsxOpeningFragment),
1303            nodesVisitor(node.children, visitor, isJsxChild),
1304            nodeVisitor(node.closingFragment, visitor, isJsxClosingFragment));
1305    },
1306
1307    [SyntaxKind.JsxAttribute]: function visitEachChildOfJsxAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1308        return context.factory.updateJsxAttribute(node,
1309            nodeVisitor(node.name, visitor, isIdentifier),
1310            nodeVisitor(node.initializer, visitor, isStringLiteralOrJsxExpression));
1311    },
1312
1313    [SyntaxKind.JsxAttributes]: function visitEachChildOfJsxAttributes(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1314        return context.factory.updateJsxAttributes(node,
1315            nodesVisitor(node.properties, visitor, isJsxAttributeLike));
1316    },
1317
1318    [SyntaxKind.JsxSpreadAttribute]: function visitEachChildOfJsxSpreadAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1319        return context.factory.updateJsxSpreadAttribute(node,
1320            nodeVisitor(node.expression, visitor, isExpression));
1321    },
1322
1323    [SyntaxKind.JsxExpression]: function visitEachChildOfJsxExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1324        return context.factory.updateJsxExpression(node,
1325            nodeVisitor(node.expression, visitor, isExpression));
1326    },
1327
1328    // Clauses
1329    [SyntaxKind.CaseClause]: function visitEachChildOfCaseClause(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) {
1330        return context.factory.updateCaseClause(node,
1331            nodeVisitor(node.expression, visitor, isExpression),
1332            nodesVisitor(node.statements, visitor, isStatement));
1333    },
1334
1335    [SyntaxKind.DefaultClause]: function visitEachChildOfDefaultClause(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1336        return context.factory.updateDefaultClause(node,
1337            nodesVisitor(node.statements, visitor, isStatement));
1338    },
1339
1340    [SyntaxKind.HeritageClause]: function visitEachChildOfHeritageClause(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1341        return context.factory.updateHeritageClause(node,
1342            nodesVisitor(node.types, visitor, isExpressionWithTypeArguments));
1343    },
1344
1345    [SyntaxKind.CatchClause]: function visitEachChildOfCatchClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1346        return context.factory.updateCatchClause(node,
1347            nodeVisitor(node.variableDeclaration, visitor, isVariableDeclaration),
1348            nodeVisitor(node.block, visitor, isBlock));
1349    },
1350
1351    // Property assignments
1352    [SyntaxKind.PropertyAssignment]: function visitEachChildOfPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1353        return context.factory.updatePropertyAssignment(node,
1354            nodeVisitor(node.name, visitor, isPropertyName),
1355            nodeVisitor(node.initializer, visitor, isExpression));
1356    },
1357
1358    [SyntaxKind.ShorthandPropertyAssignment]: function visitEachChildOfShorthandPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1359        return context.factory.updateShorthandPropertyAssignment(node,
1360            nodeVisitor(node.name, visitor, isIdentifier),
1361            nodeVisitor(node.objectAssignmentInitializer, visitor, isExpression));
1362    },
1363
1364    [SyntaxKind.SpreadAssignment]: function visitEachChildOfSpreadAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1365        return context.factory.updateSpreadAssignment(node,
1366            nodeVisitor(node.expression, visitor, isExpression));
1367    },
1368
1369    // Enum
1370    [SyntaxKind.EnumMember]: function visitEachChildOfEnumMember(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1371        return context.factory.updateEnumMember(node,
1372            nodeVisitor(node.name, visitor, isPropertyName),
1373            nodeVisitor(node.initializer, visitor, isExpression));
1374    },
1375
1376    // Top-level nodes
1377    [SyntaxKind.SourceFile]: function visitEachChildOfSourceFile(node, visitor, context, _nodesVisitor, _nodeVisitor, _tokenVisitor) {
1378        return context.factory.updateSourceFile(node,
1379            visitLexicalEnvironment(node.statements, visitor, context));
1380    },
1381
1382    // Transformation nodes
1383    [SyntaxKind.PartiallyEmittedExpression]: function visitEachChildOfPartiallyEmittedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
1384        return context.factory.updatePartiallyEmittedExpression(node,
1385            nodeVisitor(node.expression, visitor, isExpression));
1386    },
1387
1388    [SyntaxKind.CommaListExpression]: function visitEachChildOfCommaListExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) {
1389        return context.factory.updateCommaListExpression(node,
1390            nodesVisitor(node.elements, visitor, isExpression));
1391    },
1392};
1393
1394/**
1395 * Extracts the single node from a NodeArray.
1396 *
1397 * @param nodes The NodeArray.
1398 */
1399function extractSingleNode(nodes: readonly Node[]): Node | undefined {
1400    Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
1401    return singleOrUndefined(nodes);
1402}
1403