// Code generated by _scripts/generate-go-ast.ts. DO NOT EDIT.

package ast

import (
	"sync/atomic"

	"github.com/microsoft/typescript-go/internal/core"
)

var (
	_ = core.Same[string] // prevent unused import
	_ atomic.Uint32       // prevent unused import
)

// ──────────────────────────────────────────────────────────────────────
// NodeFactory
// ──────────────────────────────────────────────────────────────────────

type NodeFactory struct {
	hooks                              NodeFactoryHooks
	arrayTypeNodeArena                 core.Arena[ArrayTypeNode]
	binaryExpressionArena              core.Arena[BinaryExpression]
	blockArena                         core.Arena[Block]
	callExpressionArena                core.Arena[CallExpression]
	conditionalExpressionArena         core.Arena[ConditionalExpression]
	constructSignatureDeclarationArena core.Arena[ConstructSignatureDeclaration]
	elementAccessExpressionArena       core.Arena[ElementAccessExpression]
	expressionStatementArena           core.Arena[ExpressionStatement]
	expressionWithTypeArgumentsArena   core.Arena[ExpressionWithTypeArguments]
	functionDeclarationArena           core.Arena[FunctionDeclaration]
	functionTypeNodeArena              core.Arena[FunctionTypeNode]
	heritageClauseArena                core.Arena[HeritageClause]
	identifierArena                    core.Arena[Identifier]
	ifStatementArena                   core.Arena[IfStatement]
	importSpecifierArena               core.Arena[ImportSpecifier]
	indexedAccessTypeNodeArena         core.Arena[IndexedAccessTypeNode]
	interfaceDeclarationArena          core.Arena[InterfaceDeclaration]
	intersectionTypeNodeArena          core.Arena[IntersectionTypeNode]
	jsdocArena                         core.Arena[JSDoc]
	jsdocDeprecatedTagArena            core.Arena[JSDocDeprecatedTag]
	jsdocTextArena                     core.Arena[JSDocText]
	jsdocUnknownTagArena               core.Arena[JSDocUnknownTag]
	keywordExpressionArena             core.Arena[KeywordExpression]
	keywordTypeNodeArena               core.Arena[KeywordTypeNode]
	literalTypeNodeArena               core.Arena[LiteralTypeNode]
	methodSignatureDeclarationArena    core.Arena[MethodSignatureDeclaration]
	modifierListArena                  core.Arena[ModifierList]
	nodeListArena                      core.Arena[NodeList]
	numericLiteralArena                core.Arena[NumericLiteral]
	parameterDeclarationArena          core.Arena[ParameterDeclaration]
	parenthesizedExpressionArena       core.Arena[ParenthesizedExpression]
	parenthesizedTypeNodeArena         core.Arena[ParenthesizedTypeNode]
	prefixUnaryExpressionArena         core.Arena[PrefixUnaryExpression]
	propertyAccessExpressionArena      core.Arena[PropertyAccessExpression]
	propertyAssignmentArena            core.Arena[PropertyAssignment]
	propertySignatureDeclarationArena  core.Arena[PropertySignatureDeclaration]
	returnStatementArena               core.Arena[ReturnStatement]
	stringLiteralArena                 core.Arena[StringLiteral]
	tokenArena                         core.Arena[Token]
	typeAliasDeclarationArena          core.Arena[TypeAliasDeclaration]
	typeLiteralNodeArena               core.Arena[TypeLiteralNode]
	typeOperatorNodeArena              core.Arena[TypeOperatorNode]
	typeParameterDeclarationArena      core.Arena[TypeParameterDeclaration]
	typeReferenceNodeArena             core.Arena[TypeReferenceNode]
	unionTypeNodeArena                 core.Arena[UnionTypeNode]
	variableDeclarationArena           core.Arena[VariableDeclaration]
	variableDeclarationListArena       core.Arena[VariableDeclarationList]
	variableStatementArena             core.Arena[VariableStatement]

	nodeCount int
	textCount int
}

// ──────────────────────────────────────────────────────────────────────
// Base struct definitions
// ──────────────────────────────────────────────────────────────────────

type StatementBase struct {
	NodeBase
	FlowNodeBase
}

type IterationStatementBase struct {
	StatementBase
	Statement *Statement
}

type ExpressionBase struct {
	NodeBase
}

type UnaryExpressionBase struct {
	ExpressionBase
}

type UpdateExpressionBase struct {
	UnaryExpressionBase
}

type LeftHandSideExpressionBase struct {
	UpdateExpressionBase
}

type MemberExpressionBase struct {
	LeftHandSideExpressionBase
}

type PrimaryExpressionBase struct {
	MemberExpressionBase
}

type TypeNodeBase struct {
	NodeBase
	TypeSyntaxBase
}

type NodeWithTypeArgumentsBase struct {
	TypeNodeBase
	TypeArguments *TypeList // Optional
}

type JSDocTypeBase struct {
	TypeNodeBase
}

type DeclarationBase struct {
	Symbol *Symbol
}

type ExportableBase struct {
	LocalSymbol *Symbol
}

type ModifiersBase struct {
	modifiers *ModifierList // Optional
}

type LocalsContainerBase struct {
	Locals        SymbolTable
	NextContainer *Node
}

type FlowNodeBase struct {
	FlowNode *FlowNode
}

type CompositeBase struct {
	facts atomic.Uint32
}

type TypeSyntaxBase struct{}

type FunctionLikeBase struct {
	DeclarationBase
	LocalsContainerBase
	TypeParameters *TypeParameterList // Optional
	Parameters     *ParameterList
	Type           *TypeNode // Optional
	FullSignature  *TypeNode // Optional
}

type BodyBase struct {
	AsteriskToken *AsteriskToken // Optional
	Body          *NodeBody      // Optional
	EndFlowNode   *FlowNode
}

type FunctionLikeWithBodyBase struct {
	FunctionLikeBase
	BodyBase
}

type ClassLikeBase struct {
	DeclarationBase
	ExportableBase
	ModifiersBase
	LocalsContainerBase
	CompositeBase
	name            *IdentifierNode     // Optional
	TypeParameters  *TypeParameterList  // Optional
	HeritageClauses *HeritageClauseList // Optional
	Members         *ClassElementList
}

type LiteralLikeNodeBase struct {
	Text       string
	TokenFlags TokenFlags
}

type LiteralExpressionBase struct {
	LiteralLikeNodeBase
	PrimaryExpressionBase
}

type TemplateLiteralLikeNodeBase struct {
	LiteralLikeNodeBase
	RawText       string
	TemplateFlags TokenFlags
}

type TypeElementBase struct{}

type ClassElementBase struct{}

type NamedMemberBase struct {
	DeclarationBase
	ModifiersBase
	name         *PropertyName
	PostfixToken *TokenNode // Optional
}

type ObjectLiteralElementBase struct{}

type AccessorDeclarationBase struct {
	NamedMemberBase
	FunctionLikeWithBodyBase
	FlowNodeBase
	TypeElementBase
	ClassElementBase
	ObjectLiteralElementBase
	CompositeBase
	NodeBase
}

type FunctionOrConstructorTypeNodeBase struct {
	TypeNodeBase
	ModifiersBase
	FunctionLikeBase
}

type UnionOrIntersectionTypeNodeBase struct {
	TypeNodeBase
	Types *TypeList
}

type JSDocTagBase struct {
	NodeBase
	TagName *IdentifierNode
	Comment *NodeList // Optional
}

type JSDocCommentBase struct {
	NodeBase
	text []string
}

// ──────────────────────────────────────────────────────────────────────
// Node type aliases
// ──────────────────────────────────────────────────────────────────────

type (
	TokenNode                         = Node
	IdentifierNode                    = Node
	PrivateIdentifierNode             = Node
	QualifiedNameNode                 = Node
	ComputedPropertyNameNode          = Node
	DecoratorNode                     = Node
	EmptyStatementNode                = Node
	IfStatementNode                   = Node
	DoStatementNode                   = Node
	WhileStatementNode                = Node
	ForStatementNode                  = Node
	ForInOrOfStatementNode            = Node
	BreakStatementNode                = Node
	ContinueStatementNode             = Node
	ReturnStatementNode               = Node
	WithStatementNode                 = Node
	SwitchStatementNode               = Node
	CaseBlockNode                     = Node
	CaseOrDefaultClauseNode           = Node
	ThrowStatementNode                = Node
	TryStatementNode                  = Node
	CatchClauseNode                   = Node
	DebuggerStatementNode             = Node
	LabeledStatementNode              = Node
	ExpressionStatementNode           = Node
	BlockNode                         = Node
	VariableStatementNode             = Node
	VariableDeclarationNode           = Node
	VariableDeclarationListNode       = Node
	BindingPatternNode                = Node
	ParameterDeclarationNode          = Node
	BindingElementNode                = Node
	MissingDeclarationNode            = Node
	FunctionDeclarationNode           = Node
	ClassDeclarationNode              = Node
	ClassExpressionNode               = Node
	HeritageClauseNode                = Node
	InterfaceDeclarationNode          = Node
	TypeAliasDeclarationNode          = Node
	EnumMemberNode                    = Node
	EnumDeclarationNode               = Node
	ModuleBlockNode                   = Node
	NotEmittedStatementNode           = Node
	NotEmittedTypeElementNode         = Node
	ImportDeclarationNode             = Node
	ExternalModuleReferenceNode       = Node
	NamespaceImportNode               = Node
	NamedImportsNode                  = Node
	ExportAssignmentNode              = Node
	NamespaceExportDeclarationNode    = Node
	NamespaceExportNode               = Node
	NamedExportsNode                  = Node
	ExportSpecifierNode               = Node
	CallSignatureDeclarationNode      = Node
	ConstructSignatureDeclarationNode = Node
	ConstructorDeclarationNode        = Node
	GetAccessorDeclarationNode        = Node
	SetAccessorDeclarationNode        = Node
	IndexSignatureDeclarationNode     = Node
	MethodSignatureDeclarationNode    = Node
	MethodDeclarationNode             = Node
	PropertySignatureDeclarationNode  = Node
	PropertyDeclarationNode           = Node
	SemicolonClassElementNode         = Node
	ClassStaticBlockDeclarationNode   = Node
	OmittedExpressionNode             = Node
	KeywordExpressionNode             = Node
	StringLiteralNode                 = Node
	NumericLiteralNode                = Node
	BigIntLiteralNode                 = Node
	RegularExpressionLiteralNode      = Node
	NoSubstitutionTemplateLiteralNode = Node
	BinaryExpressionNode              = Node
	PrefixUnaryExpressionNode         = Node
	PostfixUnaryExpressionNode        = Node
	YieldExpressionNode               = Node
	ArrowFunctionNode                 = Node
	FunctionExpressionNode            = Node
	AsExpressionNode                  = Node
	SatisfiesExpressionNode           = Node
	ConditionalExpressionNode         = Node
	PropertyAccessExpressionNode      = Node
	ElementAccessExpressionNode       = Node
	CallExpressionNode                = Node
	NewExpressionNode                 = Node
	MetaPropertyNode                  = Node
	NonNullExpressionNode             = Node
	SpreadElementNode                 = Node
	TemplateExpressionNode            = Node
	TemplateSpanNode                  = Node
	TaggedTemplateExpressionNode      = Node
	ParenthesizedExpressionNode       = Node
	ArrayLiteralExpressionNode        = Node
	ObjectLiteralExpressionNode       = Node
	SpreadAssignmentNode              = Node
	PropertyAssignmentNode            = Node
	ShorthandPropertyAssignmentNode   = Node
	DeleteExpressionNode              = Node
	TypeOfExpressionNode              = Node
	VoidExpressionNode                = Node
	AwaitExpressionNode               = Node
	TypeAssertionNode                 = Node
	KeywordTypeNodeNode               = Node
	UnionTypeNodeNode                 = Node
	IntersectionTypeNodeNode          = Node
	ConditionalTypeNodeNode           = Node
	TypeOperatorNodeNode              = Node
	InferTypeNodeNode                 = Node
	ArrayTypeNodeNode                 = Node
	IndexedAccessTypeNodeNode         = Node
	TypeReferenceNodeNode             = Node
	ExpressionWithTypeArgumentsNode   = Node
	LiteralTypeNodeNode               = Node
	ThisTypeNodeNode                  = Node
	TypePredicateNodeNode             = Node
	ImportAttributeNode               = Node
	ImportAttributesNode              = Node
	TypeQueryNodeNode                 = Node
	MappedTypeNodeNode                = Node
	TypeLiteralNodeNode               = Node
	TupleTypeNodeNode                 = Node
	NamedTupleMemberNode              = Node
	OptionalTypeNodeNode              = Node
	RestTypeNodeNode                  = Node
	ParenthesizedTypeNodeNode         = Node
	FunctionTypeNodeNode              = Node
	ConstructorTypeNodeNode           = Node
	TemplateHeadNode                  = Node
	TemplateMiddleNode                = Node
	TemplateTailNode                  = Node
	TemplateLiteralTypeNodeNode       = Node
	TemplateLiteralTypeSpanNode       = Node
	SyntheticExpressionNode           = Node
	PartiallyEmittedExpressionNode    = Node
	JsxElementNode                    = Node
	JsxAttributesNode                 = Node
	JsxNamespacedNameNode             = Node
	JsxOpeningElementNode             = Node
	JsxSelfClosingElementNode         = Node
	JsxFragmentNode                   = Node
	JsxOpeningFragmentNode            = Node
	JsxClosingFragmentNode            = Node
	JsxAttributeNode                  = Node
	JsxSpreadAttributeNode            = Node
	JsxClosingElementNode             = Node
	JsxExpressionNode                 = Node
	JsxTextNode                       = Node
	SyntaxListNode                    = Node
	JSDocNode                         = Node
	JSDocTypeExpressionNode           = Node
	JSDocNonNullableTypeNode          = Node
	JSDocNullableTypeNode             = Node
	JSDocAllTypeNode                  = Node
	JSDocVariadicTypeNode             = Node
	JSDocOptionalTypeNode             = Node
	JSDocTypeTagNode                  = Node
	JSDocUnknownTagNode               = Node
	JSDocTemplateTagNode              = Node
	JSDocReturnTagNode                = Node
	JSDocPublicTagNode                = Node
	JSDocPrivateTagNode               = Node
	JSDocProtectedTagNode             = Node
	JSDocReadonlyTagNode              = Node
	JSDocOverrideTagNode              = Node
	JSDocDeprecatedTagNode            = Node
	JSDocSeeTagNode                   = Node
	JSDocImplementsTagNode            = Node
	JSDocAugmentsTagNode              = Node
	JSDocSatisfiesTagNode             = Node
	JSDocThrowsTagNode                = Node
	JSDocThisTagNode                  = Node
	JSDocImportTagNode                = Node
	JSDocCallbackTagNode              = Node
	JSDocOverloadTagNode              = Node
	JSDocTypedefTagNode               = Node
	JSDocSignatureNode                = Node
	JSDocNameReferenceNode            = Node
	SourceFileNode                    = Node
	ModuleDeclarationNode             = Node
	ImportEqualsDeclarationNode       = Node
	ExportDeclarationNode             = Node
	ImportTypeNodeNode                = Node
	ImportClauseNode                  = Node
	ImportSpecifierNode               = Node
	JSDocTextNode                     = Node
	JSDocLinkNode                     = Node
	JSDocLinkPlainNode                = Node
	JSDocLinkCodeNode                 = Node
	TypeParameterDeclarationNode      = Node
	SyntheticReferenceExpressionNode  = Node
	JSDocTypeLiteralNode              = Node
	JSDocParameterOrPropertyTagNode   = Node
	EndOfFile                         = Node
	DotToken                          = Node
	DotDotDotToken                    = Node
	QuestionToken                     = Node
	ExclamationToken                  = Node
	ColonToken                        = Node
	EqualsToken                       = Node
	AsteriskToken                     = Node
	EqualsGreaterThanToken            = Node
	PlusToken                         = Node
	MinusToken                        = Node
	QuestionDotToken                  = Node
	AssertsKeyword                    = Node
	AssertKeyword                     = Node
	AwaitKeyword                      = Node
	CaseKeyword                       = Node
	AbstractKeyword                   = Node
	AccessorKeyword                   = Node
	AsyncKeyword                      = Node
	ConstKeyword                      = Node
	DeclareKeyword                    = Node
	DefaultKeyword                    = Node
	ExportKeyword                     = Node
	InKeyword                         = Node
	PrivateKeyword                    = Node
	ProtectedKeyword                  = Node
	PublicKeyword                     = Node
	ReadonlyKeyword                   = Node
	OutKeyword                        = Node
	OverrideKeyword                   = Node
	StaticKeyword                     = Node
	BinaryOperatorToken               = Node
	AssignmentOperatorToken           = Node
	NullLiteral                       = Node
	TrueLiteral                       = Node
	FalseLiteral                      = Node
	ThisExpression                    = Node
	SuperExpression                   = Node
	ImportExpression                  = Node
)

type (
	StatementList                   = NodeList // NodeList[*Statement]
	CaseClausesList                 = NodeList // NodeList[*CaseOrDefaultClause]
	VariableDeclarationNodeList     = NodeList // NodeList[*VariableDeclaration]
	BindingElementList              = NodeList // NodeList[*BindingElement]
	TypeParameterList               = NodeList // NodeList[*TypeParameterDeclaration]
	ParameterList                   = NodeList // NodeList[*ParameterDeclaration]
	HeritageClauseList              = NodeList // NodeList[*HeritageClause]
	ClassElementList                = NodeList // NodeList[*ClassElement]
	TypeElementList                 = NodeList // NodeList[*TypeElement]
	ExpressionWithTypeArgumentsList = NodeList // NodeList[*ExpressionWithTypeArguments]
	EnumMemberList                  = NodeList // NodeList[*EnumMember]
	ImportSpecifierList             = NodeList // NodeList[*ImportSpecifier]
	ExportSpecifierList             = NodeList // NodeList[*ExportSpecifier]
	TypeArgumentList                = NodeList // NodeList[*TypeNode]
	ArgumentList                    = NodeList // NodeList[*Expression]
	TemplateSpanList                = NodeList // NodeList[*TemplateSpan]
	ElementList                     = NodeList // NodeList[*Expression]
	PropertyDefinitionList          = NodeList // NodeList[*ObjectLiteralElement]
	TypeList                        = NodeList // NodeList[*TypeNode]
	ImportAttributeList             = NodeList // NodeList[*ImportAttribute]
	TemplateLiteralTypeSpanList     = NodeList // NodeList[*TemplateLiteralTypeSpan]
	JsxChildList                    = NodeList // NodeList[*JsxChild]
	JsxAttributeList                = NodeList // NodeList[*JsxAttributeLike]
)

// ──────────────────────────────────────────────────────────────────────
// Node union aliases
// ──────────────────────────────────────────────────────────────────────

type (
	Expression                     = Node // Node with ExpressionBase
	Statement                      = Node // Node with StatementBase
	TypeNode                       = Node // Node with TypeNodeBase
	BlockOrExpression              = Node // Block | Expression
	NodeBody                       = Node // Block | Expression | ModuleBlock | ModuleDeclaration
	AccessExpression               = Node // PropertyAccessExpression | ElementAccessExpression
	DeclarationName                = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression
	ModuleName                     = Node // Identifier | StringLiteral
	ModuleExportName               = Node // Identifier | StringLiteral
	PropertyName                   = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral
	ModuleBody                     = Node // ModuleBlock | ModuleDeclaration
	JSDocFullName                  = Node // Identifier | ModuleDeclaration
	ForInitializer                 = Node // Expression | MissingDeclaration | VariableDeclarationList
	ModuleReference                = Node // Identifier | QualifiedName | ExternalModuleReference
	NamedImportBindings            = Node // NamespaceImport | NamedImports
	NamedExportBindings            = Node // NamespaceExport | NamedExports
	MemberName                     = Node // Identifier | PrivateIdentifier
	EntityName                     = Node // Identifier | QualifiedName
	BindingName                    = Node // Identifier | BindingPattern
	ModifierLike                   = Node // Modifier | Decorator
	JsxChild                       = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
	JsxAttributeLike               = Node // JsxAttribute | JsxSpreadAttribute
	JsxAttributeName               = Node // Identifier | JsxNamespacedName
	JsxAttributeValue              = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment
	JsxTagNameExpression           = Node // Identifier | ThisExpression | JsxTagNamePropertyAccess | JsxNamespacedName
	ClassLikeDeclaration           = Node // ClassDeclaration | ClassExpression
	AccessorDeclaration            = Node // GetAccessorDeclaration | SetAccessorDeclaration
	LiteralLikeNode                = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText
	LiteralExpression              = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
	UnionOrIntersectionTypeNode    = Node // UnionTypeNode | IntersectionTypeNode
	TemplateLiteralLikeNode        = Node // PseudoLiteralSyntaxKind
	TemplateMiddleOrTail           = Node // TemplateMiddle | TemplateTail
	TemplateLiteral                = Node // TemplateExpression | NoSubstitutionTemplateLiteral
	TypePredicateParameterName     = Node // Identifier | ThisTypeNode
	ImportAttributeName            = Node // Identifier | StringLiteral
	LeftHandSideExpression         = Node // Node with LeftHandSideExpressionBase
	JSDocComment                   = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain
	SignatureDeclaration           = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignatureDeclaration | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction
	StringLiteralLikeNode          = Node // StringLiteral | NoSubstitutionTemplateLiteral
	NumericOrStringLikeLiteral     = Node // StringLiteralLikeNode | NumericLiteral
	ObjectLiteralLikeNode          = Node // ObjectLiteralExpression | ObjectBindingPattern
	ObjectTypeDeclaration          = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode
	JsxOpeningLikeElement          = Node // JsxOpeningElement | JsxSelfClosingElement
	NamedImportsOrExports          = Node // NamedImports | NamedExports
	BreakOrContinueStatement       = Node // BreakStatement | ContinueStatement
	CallLikeExpression             = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement | BinaryExpression
	FunctionLikeDeclaration        = Node // FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction
	VariableOrParameterDeclaration = Node // VariableDeclaration | ParameterDeclaration
	VariableOrPropertyDeclaration  = Node // VariableDeclaration | PropertyDeclaration
	CallOrNewExpression            = Node // CallExpression | NewExpression
	ImportClauseOrBindingPattern   = Node // ImportClause | BindingPattern
	AnyImportSyntax                = Node // ImportDeclaration | ImportEqualsDeclaration
	Declaration                    = Node // Node with DeclarationBase
	ClassElement                   = Node // Node with ClassElementBase
	TypeElement                    = Node // Node with TypeElementBase
	ObjectLiteralElement           = Node // Node with ObjectLiteralElementBase
	JSDocTag                       = Node // Node with JSDocTagBase
	ArrayBindingElement            = Node // BindingElement | OmittedExpression
	AssertionExpression            = Node // TypeAssertion | AsExpression
	BooleanLiteral                 = Node // TrueLiteral | FalseLiteral
	ConciseBody                    = Node // Block | Expression
	DestructuringAssignment        = Node // ObjectDestructuringAssignment | ArrayDestructuringAssignment
	LiteralToken                   = Node // NumericLiteral | BigIntLiteral | StringLiteral | JsxText | RegularExpressionLiteral | NoSubstitutionTemplateLiteral
	Modifier                       = Node // ModifierSyntaxKind
	ObjectLiteralElementLike       = Node // PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration
	PropertyNameLiteral            = Node // Identifier | StringLiteral | NumericLiteral
	PseudoLiteralToken             = Node // PseudoLiteralSyntaxKind
	TemplateLiteralToken           = Node // NoSubstitutionTemplateLiteral | PseudoLiteralToken
	ArrayDestructuringAssignment   = Node // BinaryExpression
	ObjectDestructuringAssignment  = Node // BinaryExpression
	FunctionBody                   = Node // Block
	IncrementExpression            = Node // UpdateExpressionBase
)

// ──────────────────────────────────────────────────────────────────────
// Token
// ──────────────────────────────────────────────────────────────────────

type Token struct {
	NodeBase
}

func (f *NodeFactory) NewToken(kind TokenSyntaxKind) *Node {
	data := f.tokenArena.New()
	return f.newNode(kind, data)
}

func (node *Token) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewToken(node.Kind), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsToken(node *Node) bool {
	switch node.Kind {
	case KindUnknown, KindEndOfFile, KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia, KindNonTextFileMarkerTrivia, KindNumericLiteral, KindBigIntLiteral, KindStringLiteral, KindJsxText, KindJsxTextAllWhiteSpaces, KindRegularExpressionLiteral, KindNoSubstitutionTemplateLiteral, KindTemplateHead, KindTemplateMiddle, KindTemplateTail, KindOpenBraceToken, KindCloseBraceToken, KindOpenParenToken, KindCloseParenToken, KindOpenBracketToken, KindCloseBracketToken, KindDotToken, KindDotDotDotToken, KindSemicolonToken, KindCommaToken, KindQuestionDotToken, KindLessThanToken, KindLessThanSlashToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindEqualsGreaterThanToken, KindPlusToken, KindMinusToken, KindAsteriskToken, KindAsteriskAsteriskToken, KindSlashToken, KindPercentToken, KindPlusPlusToken, KindMinusMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindExclamationToken, KindTildeToken, KindAmpersandAmpersandToken, KindBarBarToken, KindQuestionToken, KindColonToken, KindAtToken, KindQuestionQuestionToken, KindBacktickToken, KindHashToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskEqualsToken, KindAsteriskAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCaretEqualsToken, KindIdentifier, KindPrivateIdentifier, KindJSDocCommentTextToken, KindBreakKeyword, KindCaseKeyword, KindCatchKeyword, KindClassKeyword, KindConstKeyword, KindContinueKeyword, KindDebuggerKeyword, KindDefaultKeyword, KindDeleteKeyword, KindDoKeyword, KindElseKeyword, KindEnumKeyword, KindExportKeyword, KindExtendsKeyword, KindFalseKeyword, KindFinallyKeyword, KindForKeyword, KindFunctionKeyword, KindIfKeyword, KindImportKeyword, KindInKeyword, KindInstanceOfKeyword, KindNewKeyword, KindNullKeyword, KindReturnKeyword, KindSuperKeyword, KindSwitchKeyword, KindThisKeyword, KindThrowKeyword, KindTrueKeyword, KindTryKeyword, KindTypeOfKeyword, KindVarKeyword, KindVoidKeyword, KindWhileKeyword, KindWithKeyword, KindImplementsKeyword, KindInterfaceKeyword, KindLetKeyword, KindPackageKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindStaticKeyword, KindYieldKeyword, KindAbstractKeyword, KindAccessorKeyword, KindAsKeyword, KindAssertsKeyword, KindAssertKeyword, KindAnyKeyword, KindAsyncKeyword, KindAwaitKeyword, KindBooleanKeyword, KindConstructorKeyword, KindDeclareKeyword, KindGetKeyword, KindImmediateKeyword, KindInferKeyword, KindIntrinsicKeyword, KindIsKeyword, KindKeyOfKeyword, KindModuleKeyword, KindNamespaceKeyword, KindNeverKeyword, KindOutKeyword, KindReadonlyKeyword, KindRequireKeyword, KindNumberKeyword, KindObjectKeyword, KindSatisfiesKeyword, KindSetKeyword, KindStringKeyword, KindSymbolKeyword, KindTypeKeyword, KindUndefinedKeyword, KindUniqueKeyword, KindUnknownKeyword, KindUsingKeyword, KindFromKeyword, KindGlobalKeyword, KindBigIntKeyword, KindOverrideKeyword, KindOfKeyword, KindDeferKeyword:
		return true
	}
	return false
}

// ──────────────────────────────────────────────────────────────────────
// Identifier
// ──────────────────────────────────────────────────────────────────────

type Identifier struct {
	PrimaryExpressionBase
	FlowNodeBase
	Text string
}

func (f *NodeFactory) NewIdentifier(text string) *Node {
	data := f.identifierArena.New()
	data.Text = text
	f.textCount++
	return f.newNode(KindIdentifier, data)
}

func (node *Identifier) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewIdentifier(node.Text), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsIdentifier(node *Node) bool {
	return node.Kind == KindIdentifier
}

// ──────────────────────────────────────────────────────────────────────
// PrivateIdentifier
// ──────────────────────────────────────────────────────────────────────

type PrivateIdentifier struct {
	PrimaryExpressionBase
	Text string
}

func (f *NodeFactory) NewPrivateIdentifier(text string) *Node {
	data := &PrivateIdentifier{}
	data.Text = text
	f.textCount++
	return f.newNode(KindPrivateIdentifier, data)
}

func (node *PrivateIdentifier) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPrivateIdentifier(node.Text), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsPrivateIdentifier(node *Node) bool {
	return node.Kind == KindPrivateIdentifier
}

// ──────────────────────────────────────────────────────────────────────
// QualifiedName
// ──────────────────────────────────────────────────────────────────────

type QualifiedName struct {
	NodeBase
	FlowNodeBase
	CompositeBase
	Left  *EntityName
	Right *IdentifierNode
}

func (f *NodeFactory) NewQualifiedName(left *EntityName, right *IdentifierNode) *Node {
	data := &QualifiedName{}
	data.Left = left
	data.Right = right
	return f.newNode(KindQualifiedName, data)
}

func (f *NodeFactory) UpdateQualifiedName(node *QualifiedName, left *EntityName, right *IdentifierNode) *Node {
	if left != node.Left || right != node.Right {
		return updateNode(f.NewQualifiedName(left, right), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *QualifiedName) ForEachChild(v Visitor) bool {
	return visit(v, node.Left) || visit(v, node.Right)
}

func (node *QualifiedName) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateQualifiedName(node, v.visitNode(node.Left), v.visitNode(node.Right))
}

func (node *QualifiedName) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewQualifiedName(node.Left, node.Right), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *QualifiedName) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Left) |
		propagateSubtreeFacts(node.Right)
}

func IsQualifiedName(node *Node) bool {
	return node.Kind == KindQualifiedName
}

// ──────────────────────────────────────────────────────────────────────
// ComputedPropertyName
// ──────────────────────────────────────────────────────────────────────

type ComputedPropertyName struct {
	NodeBase
	CompositeBase
	Expression *Expression
}

func (f *NodeFactory) NewComputedPropertyName(expression *Expression) *Node {
	data := &ComputedPropertyName{}
	data.Expression = expression
	return f.newNode(KindComputedPropertyName, data)
}

func (f *NodeFactory) UpdateComputedPropertyName(node *ComputedPropertyName, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewComputedPropertyName(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ComputedPropertyName) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ComputedPropertyName) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateComputedPropertyName(node, v.visitNode(node.Expression))
}

func (node *ComputedPropertyName) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewComputedPropertyName(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ComputedPropertyName) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsComputedPropertyName(node *Node) bool {
	return node.Kind == KindComputedPropertyName
}

// ──────────────────────────────────────────────────────────────────────
// Decorator
// ──────────────────────────────────────────────────────────────────────

type Decorator struct {
	NodeBase
	CompositeBase
	Expression *LeftHandSideExpression
}

func (f *NodeFactory) NewDecorator(expression *LeftHandSideExpression) *Node {
	data := &Decorator{}
	data.Expression = expression
	return f.newNode(KindDecorator, data)
}

func (f *NodeFactory) UpdateDecorator(node *Decorator, expression *LeftHandSideExpression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewDecorator(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *Decorator) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *Decorator) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateDecorator(node, v.visitNode(node.Expression))
}

func (node *Decorator) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewDecorator(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsDecorator(node *Node) bool {
	return node.Kind == KindDecorator
}

// ──────────────────────────────────────────────────────────────────────
// EmptyStatement
// ──────────────────────────────────────────────────────────────────────

type EmptyStatement struct {
	StatementBase
}

func (f *NodeFactory) NewEmptyStatement() *Node {
	data := &EmptyStatement{}
	return f.newNode(KindEmptyStatement, data)
}

func (node *EmptyStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewEmptyStatement(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsEmptyStatement(node *Node) bool {
	return node.Kind == KindEmptyStatement
}

// ──────────────────────────────────────────────────────────────────────
// IfStatement
// ──────────────────────────────────────────────────────────────────────

type IfStatement struct {
	StatementBase
	CompositeBase
	Expression    *Expression
	ThenStatement *Statement
	ElseStatement *Statement // Optional
}

func (f *NodeFactory) NewIfStatement(expression *Expression, thenStatement *Statement, elseStatement *Statement) *Node {
	data := f.ifStatementArena.New()
	data.Expression = expression
	data.ThenStatement = thenStatement
	data.ElseStatement = elseStatement
	return f.newNode(KindIfStatement, data)
}

func (f *NodeFactory) UpdateIfStatement(node *IfStatement, expression *Expression, thenStatement *Statement, elseStatement *Statement) *Node {
	if expression != node.Expression || thenStatement != node.ThenStatement || elseStatement != node.ElseStatement {
		return updateNode(f.NewIfStatement(expression, thenStatement, elseStatement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *IfStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.ThenStatement) || visit(v, node.ElseStatement)
}

func (node *IfStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateIfStatement(node, v.visitNode(node.Expression), v.visitEmbeddedStatement(node.ThenStatement), v.visitEmbeddedStatement(node.ElseStatement))
}

func (node *IfStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewIfStatement(node.Expression, node.ThenStatement, node.ElseStatement), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *IfStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.ThenStatement) |
		propagateSubtreeFacts(node.ElseStatement)
}

func IsIfStatement(node *Node) bool {
	return node.Kind == KindIfStatement
}

// ──────────────────────────────────────────────────────────────────────
// DoStatement
// ──────────────────────────────────────────────────────────────────────

type DoStatement struct {
	IterationStatementBase
	CompositeBase
	Expression *Expression
}

func (f *NodeFactory) NewDoStatement(statement *Statement, expression *Expression) *Node {
	data := &DoStatement{}
	data.Statement = statement
	data.Expression = expression
	return f.newNode(KindDoStatement, data)
}

func (f *NodeFactory) UpdateDoStatement(node *DoStatement, statement *Statement, expression *Expression) *Node {
	if statement != node.Statement || expression != node.Expression {
		return updateNode(f.NewDoStatement(statement, expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *DoStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Statement) || visit(v, node.Expression)
}

func (node *DoStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateDoStatement(node, v.visitIterationBody(node.Statement), v.visitNode(node.Expression))
}

func (node *DoStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewDoStatement(node.Statement, node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *DoStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Statement) |
		propagateSubtreeFacts(node.Expression)
}

func IsDoStatement(node *Node) bool {
	return node.Kind == KindDoStatement
}

// ──────────────────────────────────────────────────────────────────────
// WhileStatement
// ──────────────────────────────────────────────────────────────────────

type WhileStatement struct {
	IterationStatementBase
	CompositeBase
	Expression *Expression
}

func (f *NodeFactory) NewWhileStatement(expression *Expression, statement *Statement) *Node {
	data := &WhileStatement{}
	data.Expression = expression
	data.Statement = statement
	return f.newNode(KindWhileStatement, data)
}

func (f *NodeFactory) UpdateWhileStatement(node *WhileStatement, expression *Expression, statement *Statement) *Node {
	if expression != node.Expression || statement != node.Statement {
		return updateNode(f.NewWhileStatement(expression, statement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *WhileStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.Statement)
}

func (node *WhileStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateWhileStatement(node, v.visitNode(node.Expression), v.visitIterationBody(node.Statement))
}

func (node *WhileStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewWhileStatement(node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *WhileStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.Statement)
}

func IsWhileStatement(node *Node) bool {
	return node.Kind == KindWhileStatement
}

// ──────────────────────────────────────────────────────────────────────
// ForStatement
// ──────────────────────────────────────────────────────────────────────

type ForStatement struct {
	IterationStatementBase
	LocalsContainerBase
	CompositeBase
	Initializer *ForInitializer // Optional
	Condition   *Expression     // Optional
	Incrementor *Expression     // Optional
}

func (f *NodeFactory) NewForStatement(initializer *ForInitializer, condition *Expression, incrementor *Expression, statement *Statement) *Node {
	data := &ForStatement{}
	data.Initializer = initializer
	data.Condition = condition
	data.Incrementor = incrementor
	data.Statement = statement
	return f.newNode(KindForStatement, data)
}

func (f *NodeFactory) UpdateForStatement(node *ForStatement, initializer *ForInitializer, condition *Expression, incrementor *Expression, statement *Statement) *Node {
	if initializer != node.Initializer || condition != node.Condition || incrementor != node.Incrementor || statement != node.Statement {
		return updateNode(f.NewForStatement(initializer, condition, incrementor, statement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ForStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Initializer) ||
		visit(v, node.Condition) ||
		visit(v, node.Incrementor) ||
		visit(v, node.Statement)
}

func (node *ForStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateForStatement(node, v.visitNode(node.Initializer), v.visitNode(node.Condition), v.visitNode(node.Incrementor), v.visitIterationBody(node.Statement))
}

func (node *ForStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewForStatement(node.Initializer, node.Condition, node.Incrementor, node.Statement), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ForStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Initializer) |
		propagateSubtreeFacts(node.Condition) |
		propagateSubtreeFacts(node.Incrementor) |
		propagateSubtreeFacts(node.Statement)
}

func IsForStatement(node *Node) bool {
	return node.Kind == KindForStatement
}

// ──────────────────────────────────────────────────────────────────────
// ForInOrOfStatement
// ──────────────────────────────────────────────────────────────────────

type ForInOrOfStatement struct {
	StatementBase
	LocalsContainerBase
	CompositeBase
	AwaitModifier *AwaitKeyword // Optional
	Initializer   *ForInitializer
	Expression    *Expression
	Statement     *Statement
}

func (f *NodeFactory) NewForInOrOfStatement(kind Kind, awaitModifier *AwaitKeyword, initializer *ForInitializer, expression *Expression, statement *Statement) *Node {
	data := &ForInOrOfStatement{}
	data.AwaitModifier = awaitModifier
	data.Initializer = initializer
	data.Expression = expression
	data.Statement = statement
	return f.newNode(kind, data)
}

func (f *NodeFactory) UpdateForInOrOfStatement(node *ForInOrOfStatement, awaitModifier *AwaitKeyword, initializer *ForInitializer, expression *Expression, statement *Statement) *Node {
	if awaitModifier != node.AwaitModifier || initializer != node.Initializer || expression != node.Expression || statement != node.Statement {
		return updateNode(f.NewForInOrOfStatement(node.Kind, awaitModifier, initializer, expression, statement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ForInOrOfStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.AwaitModifier) ||
		visit(v, node.Initializer) ||
		visit(v, node.Expression) ||
		visit(v, node.Statement)
}

func (node *ForInOrOfStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateForInOrOfStatement(node, v.visitNode(node.AwaitModifier), v.visitNode(node.Initializer), v.visitNode(node.Expression), v.visitIterationBody(node.Statement))
}

func (node *ForInOrOfStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewForInOrOfStatement(node.Kind, node.AwaitModifier, node.Initializer, node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsForInStatement(node *Node) bool {
	return node.Kind == KindForInStatement
}

func IsForOfStatement(node *Node) bool {
	return node.Kind == KindForOfStatement
}

// ──────────────────────────────────────────────────────────────────────
// BreakStatement
// ──────────────────────────────────────────────────────────────────────

type BreakStatement struct {
	StatementBase
	Label *IdentifierNode // Optional
}

func (f *NodeFactory) NewBreakStatement(label *IdentifierNode) *Node {
	data := &BreakStatement{}
	data.Label = label
	return f.newNode(KindBreakStatement, data)
}

func (f *NodeFactory) UpdateBreakStatement(node *BreakStatement, label *IdentifierNode) *Node {
	if label != node.Label {
		return updateNode(f.NewBreakStatement(label), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *BreakStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Label)
}

func (node *BreakStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateBreakStatement(node, v.visitNode(node.Label))
}

func (node *BreakStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBreakStatement(node.Label), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsBreakStatement(node *Node) bool {
	return node.Kind == KindBreakStatement
}

// ──────────────────────────────────────────────────────────────────────
// ContinueStatement
// ──────────────────────────────────────────────────────────────────────

type ContinueStatement struct {
	StatementBase
	Label *IdentifierNode // Optional
}

func (f *NodeFactory) NewContinueStatement(label *IdentifierNode) *Node {
	data := &ContinueStatement{}
	data.Label = label
	return f.newNode(KindContinueStatement, data)
}

func (f *NodeFactory) UpdateContinueStatement(node *ContinueStatement, label *IdentifierNode) *Node {
	if label != node.Label {
		return updateNode(f.NewContinueStatement(label), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ContinueStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Label)
}

func (node *ContinueStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateContinueStatement(node, v.visitNode(node.Label))
}

func (node *ContinueStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewContinueStatement(node.Label), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsContinueStatement(node *Node) bool {
	return node.Kind == KindContinueStatement
}

// ──────────────────────────────────────────────────────────────────────
// ReturnStatement
// ──────────────────────────────────────────────────────────────────────

type ReturnStatement struct {
	StatementBase
	CompositeBase
	Expression *Expression // Optional
}

func (f *NodeFactory) NewReturnStatement(expression *Expression) *Node {
	data := f.returnStatementArena.New()
	data.Expression = expression
	return f.newNode(KindReturnStatement, data)
}

func (f *NodeFactory) UpdateReturnStatement(node *ReturnStatement, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewReturnStatement(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ReturnStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ReturnStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateReturnStatement(node, v.visitNode(node.Expression))
}

func (node *ReturnStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewReturnStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsReturnStatement(node *Node) bool {
	return node.Kind == KindReturnStatement
}

// ──────────────────────────────────────────────────────────────────────
// WithStatement
// ──────────────────────────────────────────────────────────────────────

type WithStatement struct {
	StatementBase
	CompositeBase
	Expression *Expression
	Statement  *Statement
}

func (f *NodeFactory) NewWithStatement(expression *Expression, statement *Statement) *Node {
	data := &WithStatement{}
	data.Expression = expression
	data.Statement = statement
	return f.newNode(KindWithStatement, data)
}

func (f *NodeFactory) UpdateWithStatement(node *WithStatement, expression *Expression, statement *Statement) *Node {
	if expression != node.Expression || statement != node.Statement {
		return updateNode(f.NewWithStatement(expression, statement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *WithStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.Statement)
}

func (node *WithStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateWithStatement(node, v.visitNode(node.Expression), v.visitEmbeddedStatement(node.Statement))
}

func (node *WithStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewWithStatement(node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *WithStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.Statement)
}

func IsWithStatement(node *Node) bool {
	return node.Kind == KindWithStatement
}

// ──────────────────────────────────────────────────────────────────────
// SwitchStatement
// ──────────────────────────────────────────────────────────────────────

type SwitchStatement struct {
	StatementBase
	CompositeBase
	Expression *Expression
	CaseBlock  *CaseBlockNode
}

func (f *NodeFactory) NewSwitchStatement(expression *Expression, caseBlock *CaseBlockNode) *Node {
	data := &SwitchStatement{}
	data.Expression = expression
	data.CaseBlock = caseBlock
	return f.newNode(KindSwitchStatement, data)
}

func (f *NodeFactory) UpdateSwitchStatement(node *SwitchStatement, expression *Expression, caseBlock *CaseBlockNode) *Node {
	if expression != node.Expression || caseBlock != node.CaseBlock {
		return updateNode(f.NewSwitchStatement(expression, caseBlock), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SwitchStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.CaseBlock)
}

func (node *SwitchStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSwitchStatement(node, v.visitNode(node.Expression), v.visitNode(node.CaseBlock))
}

func (node *SwitchStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSwitchStatement(node.Expression, node.CaseBlock), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *SwitchStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.CaseBlock)
}

func IsSwitchStatement(node *Node) bool {
	return node.Kind == KindSwitchStatement
}

// ──────────────────────────────────────────────────────────────────────
// CaseBlock
// ──────────────────────────────────────────────────────────────────────

type CaseBlock struct {
	NodeBase
	LocalsContainerBase
	CompositeBase
	Clauses *CaseClausesList
}

func (f *NodeFactory) NewCaseBlock(clauses *CaseClausesList) *Node {
	data := &CaseBlock{}
	data.Clauses = clauses
	return f.newNode(KindCaseBlock, data)
}

func (f *NodeFactory) UpdateCaseBlock(node *CaseBlock, clauses *CaseClausesList) *Node {
	if clauses != node.Clauses {
		return updateNode(f.NewCaseBlock(clauses), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *CaseBlock) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Clauses)
}

func (node *CaseBlock) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateCaseBlock(node, v.visitNodes(node.Clauses))
}

func (node *CaseBlock) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewCaseBlock(node.Clauses), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *CaseBlock) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Clauses, propagateSubtreeFacts)
}

func IsCaseBlock(node *Node) bool {
	return node.Kind == KindCaseBlock
}

// ──────────────────────────────────────────────────────────────────────
// CaseOrDefaultClause
// ──────────────────────────────────────────────────────────────────────

type CaseOrDefaultClause struct {
	NodeBase
	CompositeBase
	Expression          *Expression
	Statements          *StatementList
	FallthroughFlowNode *FlowNode
}

func (f *NodeFactory) NewCaseOrDefaultClause(kind Kind, expression *Expression, statements *StatementList) *Node {
	data := &CaseOrDefaultClause{}
	data.Expression = expression
	data.Statements = statements
	return f.newNode(kind, data)
}

func (f *NodeFactory) UpdateCaseOrDefaultClause(node *CaseOrDefaultClause, expression *Expression, statements *StatementList) *Node {
	if expression != node.Expression || statements != node.Statements {
		return updateNode(f.NewCaseOrDefaultClause(node.Kind, expression, statements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *CaseOrDefaultClause) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visitNodeList(v, node.Statements)
}

func (node *CaseOrDefaultClause) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateCaseOrDefaultClause(node, v.visitNode(node.Expression), v.visitNodes(node.Statements))
}

func (node *CaseOrDefaultClause) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewCaseOrDefaultClause(node.Kind, node.Expression, node.Statements), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *CaseOrDefaultClause) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts)
}

func IsCaseClause(node *Node) bool {
	return node.Kind == KindCaseClause
}

func IsDefaultClause(node *Node) bool {
	return node.Kind == KindDefaultClause
}

// ──────────────────────────────────────────────────────────────────────
// ThrowStatement
// ──────────────────────────────────────────────────────────────────────

type ThrowStatement struct {
	StatementBase
	CompositeBase
	Expression *Expression
}

func (f *NodeFactory) NewThrowStatement(expression *Expression) *Node {
	data := &ThrowStatement{}
	data.Expression = expression
	return f.newNode(KindThrowStatement, data)
}

func (f *NodeFactory) UpdateThrowStatement(node *ThrowStatement, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewThrowStatement(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ThrowStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ThrowStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateThrowStatement(node, v.visitNode(node.Expression))
}

func (node *ThrowStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewThrowStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ThrowStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsThrowStatement(node *Node) bool {
	return node.Kind == KindThrowStatement
}

// ──────────────────────────────────────────────────────────────────────
// TryStatement
// ──────────────────────────────────────────────────────────────────────

type TryStatement struct {
	StatementBase
	CompositeBase
	TryBlock     *BlockNode
	CatchClause  *CatchClauseNode // Optional
	FinallyBlock *BlockNode       // Optional
}

func (f *NodeFactory) NewTryStatement(tryBlock *BlockNode, catchClause *CatchClauseNode, finallyBlock *BlockNode) *Node {
	data := &TryStatement{}
	data.TryBlock = tryBlock
	data.CatchClause = catchClause
	data.FinallyBlock = finallyBlock
	return f.newNode(KindTryStatement, data)
}

func (f *NodeFactory) UpdateTryStatement(node *TryStatement, tryBlock *BlockNode, catchClause *CatchClauseNode, finallyBlock *BlockNode) *Node {
	if tryBlock != node.TryBlock || catchClause != node.CatchClause || finallyBlock != node.FinallyBlock {
		return updateNode(f.NewTryStatement(tryBlock, catchClause, finallyBlock), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TryStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.TryBlock) || visit(v, node.CatchClause) || visit(v, node.FinallyBlock)
}

func (node *TryStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTryStatement(node, v.visitNode(node.TryBlock), v.visitNode(node.CatchClause), v.visitNode(node.FinallyBlock))
}

func (node *TryStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTryStatement(node.TryBlock, node.CatchClause, node.FinallyBlock), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TryStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.TryBlock) |
		propagateSubtreeFacts(node.CatchClause) |
		propagateSubtreeFacts(node.FinallyBlock)
}

func IsTryStatement(node *Node) bool {
	return node.Kind == KindTryStatement
}

// ──────────────────────────────────────────────────────────────────────
// CatchClause
// ──────────────────────────────────────────────────────────────────────

type CatchClause struct {
	NodeBase
	LocalsContainerBase
	CompositeBase
	VariableDeclaration *VariableDeclarationNode // Optional
	Block               *BlockNode
}

func (f *NodeFactory) NewCatchClause(variableDeclaration *VariableDeclarationNode, block *BlockNode) *Node {
	data := &CatchClause{}
	data.VariableDeclaration = variableDeclaration
	data.Block = block
	return f.newNode(KindCatchClause, data)
}

func (f *NodeFactory) UpdateCatchClause(node *CatchClause, variableDeclaration *VariableDeclarationNode, block *BlockNode) *Node {
	if variableDeclaration != node.VariableDeclaration || block != node.Block {
		return updateNode(f.NewCatchClause(variableDeclaration, block), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *CatchClause) ForEachChild(v Visitor) bool {
	return visit(v, node.VariableDeclaration) || visit(v, node.Block)
}

func (node *CatchClause) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateCatchClause(node, v.visitNode(node.VariableDeclaration), v.visitNode(node.Block))
}

func (node *CatchClause) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewCatchClause(node.VariableDeclaration, node.Block), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsCatchClause(node *Node) bool {
	return node.Kind == KindCatchClause
}

// ──────────────────────────────────────────────────────────────────────
// DebuggerStatement
// ──────────────────────────────────────────────────────────────────────

type DebuggerStatement struct {
	StatementBase
}

func (f *NodeFactory) NewDebuggerStatement() *Node {
	data := &DebuggerStatement{}
	return f.newNode(KindDebuggerStatement, data)
}

func (node *DebuggerStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewDebuggerStatement(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsDebuggerStatement(node *Node) bool {
	return node.Kind == KindDebuggerStatement
}

// ──────────────────────────────────────────────────────────────────────
// LabeledStatement
// ──────────────────────────────────────────────────────────────────────

type LabeledStatement struct {
	StatementBase
	Label     *IdentifierNode
	Statement *Statement
}

func (f *NodeFactory) NewLabeledStatement(label *IdentifierNode, statement *Statement) *Node {
	data := &LabeledStatement{}
	data.Label = label
	data.Statement = statement
	return f.newNode(KindLabeledStatement, data)
}

func (f *NodeFactory) UpdateLabeledStatement(node *LabeledStatement, label *IdentifierNode, statement *Statement) *Node {
	if label != node.Label || statement != node.Statement {
		return updateNode(f.NewLabeledStatement(label, statement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *LabeledStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Label) || visit(v, node.Statement)
}

func (node *LabeledStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateLabeledStatement(node, v.visitNode(node.Label), v.visitEmbeddedStatement(node.Statement))
}

func (node *LabeledStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewLabeledStatement(node.Label, node.Statement), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *LabeledStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Label) |
		propagateSubtreeFacts(node.Statement)
}

func IsLabeledStatement(node *Node) bool {
	return node.Kind == KindLabeledStatement
}

// ──────────────────────────────────────────────────────────────────────
// ExpressionStatement
// ──────────────────────────────────────────────────────────────────────

type ExpressionStatement struct {
	StatementBase
	Expression *Expression
}

func (f *NodeFactory) NewExpressionStatement(expression *Expression) *Node {
	data := f.expressionStatementArena.New()
	data.Expression = expression
	return f.newNode(KindExpressionStatement, data)
}

func (f *NodeFactory) UpdateExpressionStatement(node *ExpressionStatement, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewExpressionStatement(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExpressionStatement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ExpressionStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExpressionStatement(node, v.visitNode(node.Expression))
}

func (node *ExpressionStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExpressionStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ExpressionStatement) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsExpressionStatement(node *Node) bool {
	return node.Kind == KindExpressionStatement
}

// ──────────────────────────────────────────────────────────────────────
// Block
// ──────────────────────────────────────────────────────────────────────

type Block struct {
	StatementBase
	LocalsContainerBase
	CompositeBase
	Statements *StatementList
	MultiLine  bool
}

func (f *NodeFactory) NewBlock(statements *StatementList, multiLine bool) *Node {
	data := f.blockArena.New()
	data.Statements = statements
	data.MultiLine = multiLine
	return f.newNode(KindBlock, data)
}

func (f *NodeFactory) UpdateBlock(node *Block, statements *StatementList, multiLine bool) *Node {
	if statements != node.Statements || multiLine != node.MultiLine {
		return updateNode(f.NewBlock(statements, multiLine), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *Block) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Statements)
}

func (node *Block) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateBlock(node, v.visitNodes(node.Statements), node.MultiLine)
}

func (node *Block) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBlock(node.Statements, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *Block) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts)
}

func IsBlock(node *Node) bool {
	return node.Kind == KindBlock
}

// ──────────────────────────────────────────────────────────────────────
// VariableStatement
// ──────────────────────────────────────────────────────────────────────

type VariableStatement struct {
	StatementBase
	ModifiersBase
	CompositeBase
	DeclarationList *VariableDeclarationListNode
}

func (f *NodeFactory) NewVariableStatement(modifiers *ModifierList, declarationList *VariableDeclarationListNode) *Node {
	data := f.variableStatementArena.New()
	data.modifiers = modifiers
	data.DeclarationList = declarationList
	return f.newNode(KindVariableStatement, data)
}

func (f *NodeFactory) UpdateVariableStatement(node *VariableStatement, modifiers *ModifierList, declarationList *VariableDeclarationListNode) *Node {
	if modifiers != node.modifiers || declarationList != node.DeclarationList {
		return updateNode(f.NewVariableStatement(modifiers, declarationList), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *VariableStatement) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.DeclarationList)
}

func (node *VariableStatement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateVariableStatement(node, v.visitModifiers(node.modifiers), v.visitNode(node.DeclarationList))
}

func (node *VariableStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewVariableStatement(node.Modifiers(), node.DeclarationList), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsVariableStatement(node *Node) bool {
	return node.Kind == KindVariableStatement
}

// ──────────────────────────────────────────────────────────────────────
// VariableDeclaration
// ──────────────────────────────────────────────────────────────────────

type VariableDeclaration struct {
	NodeBase
	DeclarationBase
	ExportableBase
	CompositeBase
	name             *BindingName
	ExclamationToken *ExclamationToken // Optional
	Type             *TypeNode         // Optional
	Initializer      *Expression       // Optional
}

func (f *NodeFactory) NewVariableDeclaration(name *BindingName, exclamationToken *ExclamationToken, typeNode *TypeNode, initializer *Expression) *Node {
	data := f.variableDeclarationArena.New()
	data.name = name
	data.ExclamationToken = exclamationToken
	data.Type = typeNode
	data.Initializer = initializer
	return f.newNode(KindVariableDeclaration, data)
}

func (f *NodeFactory) UpdateVariableDeclaration(node *VariableDeclaration, name *BindingName, exclamationToken *ExclamationToken, typeNode *TypeNode, initializer *Expression) *Node {
	if name != node.name || exclamationToken != node.ExclamationToken || typeNode != node.Type || initializer != node.Initializer {
		return updateNode(f.NewVariableDeclaration(name, exclamationToken, typeNode, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *VariableDeclaration) ForEachChild(v Visitor) bool {
	return visit(v, node.name) ||
		visit(v, node.ExclamationToken) ||
		visit(v, node.Type) ||
		visit(v, node.Initializer)
}

func (node *VariableDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateVariableDeclaration(node, v.visitNode(node.name), v.visitNode(node.ExclamationToken), v.visitNode(node.Type), v.visitNode(node.Initializer))
}

func (node *VariableDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewVariableDeclaration(node.name, node.ExclamationToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *VariableDeclaration) Name() *DeclarationName {
	return node.name
}

func IsVariableDeclaration(node *Node) bool {
	return node.Kind == KindVariableDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// VariableDeclarationList
// ──────────────────────────────────────────────────────────────────────

type VariableDeclarationList struct {
	NodeBase
	CompositeBase
	Declarations *VariableDeclarationNodeList
}

func (f *NodeFactory) NewVariableDeclarationList(declarations *VariableDeclarationNodeList, flags NodeFlags) *Node {
	data := f.variableDeclarationListArena.New()
	data.Declarations = declarations
	node := f.newNode(KindVariableDeclarationList, data)
	node.Flags = flags
	return node
}

func (f *NodeFactory) UpdateVariableDeclarationList(node *VariableDeclarationList, declarations *VariableDeclarationNodeList, flags NodeFlags) *Node {
	if declarations != node.Declarations || flags != node.Flags {
		return updateNode(f.NewVariableDeclarationList(declarations, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *VariableDeclarationList) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Declarations)
}

func (node *VariableDeclarationList) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateVariableDeclarationList(node, v.visitNodes(node.Declarations), node.Flags)
}

func (node *VariableDeclarationList) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewVariableDeclarationList(node.Declarations, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsVariableDeclarationList(node *Node) bool {
	return node.Kind == KindVariableDeclarationList
}

// ──────────────────────────────────────────────────────────────────────
// BindingPattern
// ──────────────────────────────────────────────────────────────────────

type BindingPattern struct {
	NodeBase
	CompositeBase
	Elements *BindingElementList
}

func (f *NodeFactory) NewBindingPattern(kind Kind, elements *BindingElementList) *Node {
	data := &BindingPattern{}
	data.Elements = elements
	return f.newNode(kind, data)
}

func (f *NodeFactory) UpdateBindingPattern(node *BindingPattern, elements *BindingElementList) *Node {
	if elements != node.Elements {
		return updateNode(f.NewBindingPattern(node.Kind, elements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *BindingPattern) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Elements)
}

func (node *BindingPattern) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateBindingPattern(node, v.visitNodes(node.Elements))
}

func (node *BindingPattern) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBindingPattern(node.Kind, node.Elements), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsObjectBindingPattern(node *Node) bool {
	return node.Kind == KindObjectBindingPattern
}

func IsArrayBindingPattern(node *Node) bool {
	return node.Kind == KindArrayBindingPattern
}

// ──────────────────────────────────────────────────────────────────────
// ParameterDeclaration
// ──────────────────────────────────────────────────────────────────────

type ParameterDeclaration struct {
	NodeBase
	DeclarationBase
	ModifiersBase
	CompositeBase
	DotDotDotToken *DotDotDotToken // Optional
	name           *BindingName
	QuestionToken  *QuestionToken // Optional
	Type           *TypeNode      // Optional
	Initializer    *Expression    // Optional
}

func (f *NodeFactory) NewParameterDeclaration(modifiers *ModifierList, dotDotDotToken *DotDotDotToken, name *BindingName, questionToken *QuestionToken, typeNode *TypeNode, initializer *Expression) *Node {
	data := f.parameterDeclarationArena.New()
	data.modifiers = modifiers
	data.DotDotDotToken = dotDotDotToken
	data.name = name
	data.QuestionToken = questionToken
	data.Type = typeNode
	data.Initializer = initializer
	return f.newNode(KindParameter, data)
}

func (f *NodeFactory) UpdateParameterDeclaration(node *ParameterDeclaration, modifiers *ModifierList, dotDotDotToken *DotDotDotToken, name *BindingName, questionToken *QuestionToken, typeNode *TypeNode, initializer *Expression) *Node {
	if modifiers != node.modifiers || dotDotDotToken != node.DotDotDotToken || name != node.name || questionToken != node.QuestionToken || typeNode != node.Type || initializer != node.Initializer {
		return updateNode(f.NewParameterDeclaration(modifiers, dotDotDotToken, name, questionToken, typeNode, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ParameterDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.DotDotDotToken) ||
		visit(v, node.name) ||
		visit(v, node.QuestionToken) ||
		visit(v, node.Type) ||
		visit(v, node.Initializer)
}

func (node *ParameterDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateParameterDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.DotDotDotToken), v.visitNode(node.name), v.visitNode(node.QuestionToken), v.visitNode(node.Type), v.visitNode(node.Initializer))
}

func (node *ParameterDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewParameterDeclaration(node.Modifiers(), node.DotDotDotToken, node.name, node.QuestionToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ParameterDeclaration) Name() *DeclarationName {
	return node.name
}

func IsParameterDeclaration(node *Node) bool {
	return node.Kind == KindParameter
}

// ──────────────────────────────────────────────────────────────────────
// BindingElement
// ──────────────────────────────────────────────────────────────────────

type BindingElement struct {
	NodeBase
	DeclarationBase
	ExportableBase
	FlowNodeBase
	CompositeBase
	DotDotDotToken *DotDotDotToken // Optional
	PropertyName   *PropertyName   // Optional
	name           *BindingName    // Optional
	Initializer    *Expression     // Optional
}

func (f *NodeFactory) NewBindingElement(dotDotDotToken *DotDotDotToken, propertyName *PropertyName, name *BindingName, initializer *Expression) *Node {
	data := &BindingElement{}
	data.DotDotDotToken = dotDotDotToken
	data.PropertyName = propertyName
	data.name = name
	data.Initializer = initializer
	return f.newNode(KindBindingElement, data)
}

func (f *NodeFactory) UpdateBindingElement(node *BindingElement, dotDotDotToken *DotDotDotToken, propertyName *PropertyName, name *BindingName, initializer *Expression) *Node {
	if dotDotDotToken != node.DotDotDotToken || propertyName != node.PropertyName || name != node.name || initializer != node.Initializer {
		return updateNode(f.NewBindingElement(dotDotDotToken, propertyName, name, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *BindingElement) ForEachChild(v Visitor) bool {
	return visit(v, node.DotDotDotToken) ||
		visit(v, node.PropertyName) ||
		visit(v, node.name) ||
		visit(v, node.Initializer)
}

func (node *BindingElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateBindingElement(node, v.visitNode(node.DotDotDotToken), v.visitNode(node.PropertyName), v.visitNode(node.name), v.visitNode(node.Initializer))
}

func (node *BindingElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBindingElement(node.DotDotDotToken, node.PropertyName, node.name, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *BindingElement) Name() *DeclarationName {
	return node.name
}

func IsBindingElement(node *Node) bool {
	return node.Kind == KindBindingElement
}

// ──────────────────────────────────────────────────────────────────────
// MissingDeclaration
// ──────────────────────────────────────────────────────────────────────

type MissingDeclaration struct {
	StatementBase
	DeclarationBase
	ModifiersBase
}

func (f *NodeFactory) NewMissingDeclaration(modifiers *ModifierList) *Node {
	data := &MissingDeclaration{}
	data.modifiers = modifiers
	return f.newNode(KindMissingDeclaration, data)
}

func (f *NodeFactory) UpdateMissingDeclaration(node *MissingDeclaration, modifiers *ModifierList) *Node {
	if modifiers != node.modifiers {
		return updateNode(f.NewMissingDeclaration(modifiers), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *MissingDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers)
}

func (node *MissingDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateMissingDeclaration(node, v.visitModifiers(node.modifiers))
}

func (node *MissingDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewMissingDeclaration(node.Modifiers()), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsMissingDeclaration(node *Node) bool {
	return node.Kind == KindMissingDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// FunctionDeclaration
// ──────────────────────────────────────────────────────────────────────

type FunctionDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	FunctionLikeWithBodyBase
	CompositeBase
	name           *IdentifierNode // Optional
	ReturnFlowNode *FlowNode
}

func (f *NodeFactory) NewFunctionDeclaration(modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := f.functionDeclarationArena.New()
	data.modifiers = modifiers
	data.AsteriskToken = asteriskToken
	data.name = name
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindFunctionDeclaration, data)
}

func (f *NodeFactory) UpdateFunctionDeclaration(node *FunctionDeclaration, modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *FunctionDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.AsteriskToken) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *FunctionDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateFunctionDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.AsteriskToken), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *FunctionDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewFunctionDeclaration(node.Modifiers(), node.AsteriskToken, node.name, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *FunctionDeclaration) Name() *DeclarationName {
	return node.name
}

func IsFunctionDeclaration(node *Node) bool {
	return node.Kind == KindFunctionDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ClassDeclaration
// ──────────────────────────────────────────────────────────────────────

type ClassDeclaration struct {
	DeclarationBase
	StatementBase
	ClassLikeBase
}

func (f *NodeFactory) NewClassDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node {
	data := &ClassDeclaration{}
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.HeritageClauses = heritageClauses
	data.Members = members
	return f.newNode(KindClassDeclaration, data)
}

func (f *NodeFactory) UpdateClassDeclaration(node *ClassDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members {
		return updateNode(f.NewClassDeclaration(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ClassDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.HeritageClauses) ||
		visitNodeList(v, node.Members)
}

func (node *ClassDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateClassDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNodes(node.HeritageClauses), v.visitNodes(node.Members))
}

func (node *ClassDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewClassDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ClassDeclaration) Name() *DeclarationName {
	return node.name
}

func IsClassDeclaration(node *Node) bool {
	return node.Kind == KindClassDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ClassExpression
// ──────────────────────────────────────────────────────────────────────

type ClassExpression struct {
	PrimaryExpressionBase
	ClassLikeBase
}

func (f *NodeFactory) NewClassExpression(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node {
	data := &ClassExpression{}
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.HeritageClauses = heritageClauses
	data.Members = members
	return f.newNode(KindClassExpression, data)
}

func (f *NodeFactory) UpdateClassExpression(node *ClassExpression, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members {
		return updateNode(f.NewClassExpression(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ClassExpression) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.HeritageClauses) ||
		visitNodeList(v, node.Members)
}

func (node *ClassExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateClassExpression(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNodes(node.HeritageClauses), v.visitNodes(node.Members))
}

func (node *ClassExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewClassExpression(node.Modifiers(), node.name, node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ClassExpression) Name() *DeclarationName {
	return node.name
}

func IsClassExpression(node *Node) bool {
	return node.Kind == KindClassExpression
}

// ──────────────────────────────────────────────────────────────────────
// HeritageClause
// ──────────────────────────────────────────────────────────────────────

type HeritageClause struct {
	NodeBase
	CompositeBase
	Token Kind
	Types *ExpressionWithTypeArgumentsList
}

func (f *NodeFactory) NewHeritageClause(token Kind, types *ExpressionWithTypeArgumentsList) *Node {
	data := f.heritageClauseArena.New()
	data.Token = token
	data.Types = types
	return f.newNode(KindHeritageClause, data)
}

func (f *NodeFactory) UpdateHeritageClause(node *HeritageClause, token Kind, types *ExpressionWithTypeArgumentsList) *Node {
	if token != node.Token || types != node.Types {
		return updateNode(f.NewHeritageClause(token, types), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *HeritageClause) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Types)
}

func (node *HeritageClause) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateHeritageClause(node, node.Token, v.visitNodes(node.Types))
}

func (node *HeritageClause) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewHeritageClause(node.Token, node.Types), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsHeritageClause(node *Node) bool {
	return node.Kind == KindHeritageClause
}

// ──────────────────────────────────────────────────────────────────────
// InterfaceDeclaration
// ──────────────────────────────────────────────────────────────────────

type InterfaceDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	TypeSyntaxBase
	name            *IdentifierNode
	TypeParameters  *TypeParameterList  // Optional
	HeritageClauses *HeritageClauseList // Optional
	Members         *TypeElementList
}

func (f *NodeFactory) NewInterfaceDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *TypeElementList) *Node {
	data := f.interfaceDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.HeritageClauses = heritageClauses
	data.Members = members
	return f.newNode(KindInterfaceDeclaration, data)
}

func (f *NodeFactory) UpdateInterfaceDeclaration(node *InterfaceDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *TypeElementList) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members {
		return updateNode(f.NewInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *InterfaceDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.HeritageClauses) ||
		visitNodeList(v, node.Members)
}

func (node *InterfaceDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateInterfaceDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNodes(node.HeritageClauses), v.visitNodes(node.Members))
}

func (node *InterfaceDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewInterfaceDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *InterfaceDeclaration) Name() *DeclarationName {
	return node.name
}

func IsInterfaceDeclaration(node *Node) bool {
	return node.Kind == KindInterfaceDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// TypeAliasDeclaration
// ──────────────────────────────────────────────────────────────────────

type TypeAliasDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	LocalsContainerBase
	TypeSyntaxBase
	name           *IdentifierNode
	TypeParameters *TypeParameterList // Optional
	Type           *TypeNode
}

func (f *NodeFactory) NewTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node {
	data := f.typeAliasDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.Type = typeNode
	return f.newNode(KindTypeAliasDeclaration, data)
}

func (f *NodeFactory) NewJSTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node {
	data := f.typeAliasDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.Type = typeNode
	return f.newNode(KindJSTypeAliasDeclaration, data)
}

func (f *NodeFactory) UpdateTypeAliasDeclaration(node *TypeAliasDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || typeNode != node.Type {
		switch node.Kind {
		case KindTypeAliasDeclaration:
			return updateNode(f.NewTypeAliasDeclaration(modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks)
		case KindJSTypeAliasDeclaration:
			return updateNode(f.NewJSTypeAliasDeclaration(modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks)
		default:
			panic("unexpected kind in UpdateTypeAliasDeclaration: " + node.Kind.String())
		}
	}
	return node.AsNode()
}

func (node *TypeAliasDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visit(v, node.Type)
}

func (node *TypeAliasDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeAliasDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNode(node.Type))
}

func (node *TypeAliasDeclaration) Clone(f NodeFactoryCoercible) *Node {
	switch node.Kind {
	case KindTypeAliasDeclaration:
		return cloneNode(f.AsNodeFactory().NewTypeAliasDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
	case KindJSTypeAliasDeclaration:
		return cloneNode(f.AsNodeFactory().NewJSTypeAliasDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
	default:
		panic("unexpected kind in TypeAliasDeclaration.Clone: " + node.Kind.String())
	}
}

func (node *TypeAliasDeclaration) Name() *DeclarationName {
	return node.name
}

func IsTypeAliasDeclaration(node *Node) bool {
	return node.Kind == KindTypeAliasDeclaration
}

func IsJSTypeAliasDeclaration(node *Node) bool {
	return node.Kind == KindJSTypeAliasDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// EnumMember
// ──────────────────────────────────────────────────────────────────────

type EnumMember struct {
	NodeBase
	NamedMemberBase
	CompositeBase
	Initializer *Expression // Optional
}

func (f *NodeFactory) NewEnumMember(name *PropertyName, initializer *Expression) *Node {
	data := &EnumMember{}
	data.name = name
	data.Initializer = initializer
	return f.newNode(KindEnumMember, data)
}

func (f *NodeFactory) UpdateEnumMember(node *EnumMember, name *PropertyName, initializer *Expression) *Node {
	if name != node.name || initializer != node.Initializer {
		return updateNode(f.NewEnumMember(name, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *EnumMember) ForEachChild(v Visitor) bool {
	return visit(v, node.name) || visit(v, node.Initializer)
}

func (node *EnumMember) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateEnumMember(node, v.visitNode(node.name), v.visitNode(node.Initializer))
}

func (node *EnumMember) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewEnumMember(node.name, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *EnumMember) Name() *DeclarationName {
	return node.name
}

func IsEnumMember(node *Node) bool {
	return node.Kind == KindEnumMember
}

// ──────────────────────────────────────────────────────────────────────
// EnumDeclaration
// ──────────────────────────────────────────────────────────────────────

type EnumDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	CompositeBase
	name    *IdentifierNode
	Members *EnumMemberList
}

func (f *NodeFactory) NewEnumDeclaration(modifiers *ModifierList, name *IdentifierNode, members *EnumMemberList) *Node {
	data := &EnumDeclaration{}
	data.modifiers = modifiers
	data.name = name
	data.Members = members
	return f.newNode(KindEnumDeclaration, data)
}

func (f *NodeFactory) UpdateEnumDeclaration(node *EnumDeclaration, modifiers *ModifierList, name *IdentifierNode, members *EnumMemberList) *Node {
	if modifiers != node.modifiers || name != node.name || members != node.Members {
		return updateNode(f.NewEnumDeclaration(modifiers, name, members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *EnumDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.Members)
}

func (node *EnumDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateEnumDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.Members))
}

func (node *EnumDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewEnumDeclaration(node.Modifiers(), node.name, node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *EnumDeclaration) Name() *DeclarationName {
	return node.name
}

func IsEnumDeclaration(node *Node) bool {
	return node.Kind == KindEnumDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ModuleBlock
// ──────────────────────────────────────────────────────────────────────

type ModuleBlock struct {
	StatementBase
	CompositeBase
	Statements *StatementList
}

func (f *NodeFactory) NewModuleBlock(statements *StatementList) *Node {
	data := &ModuleBlock{}
	data.Statements = statements
	return f.newNode(KindModuleBlock, data)
}

func (f *NodeFactory) UpdateModuleBlock(node *ModuleBlock, statements *StatementList) *Node {
	if statements != node.Statements {
		return updateNode(f.NewModuleBlock(statements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ModuleBlock) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Statements)
}

func (node *ModuleBlock) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateModuleBlock(node, v.visitNodes(node.Statements))
}

func (node *ModuleBlock) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewModuleBlock(node.Statements), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ModuleBlock) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts)
}

func IsModuleBlock(node *Node) bool {
	return node.Kind == KindModuleBlock
}

// ──────────────────────────────────────────────────────────────────────
// NotEmittedStatement
// ──────────────────────────────────────────────────────────────────────

type NotEmittedStatement struct {
	StatementBase
}

func (f *NodeFactory) NewNotEmittedStatement() *Node {
	data := &NotEmittedStatement{}
	return f.newNode(KindNotEmittedStatement, data)
}

func (node *NotEmittedStatement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNotEmittedStatement(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNotEmittedStatement(node *Node) bool {
	return node.Kind == KindNotEmittedStatement
}

// ──────────────────────────────────────────────────────────────────────
// NotEmittedTypeElement
// ──────────────────────────────────────────────────────────────────────

type NotEmittedTypeElement struct {
	NodeBase
	TypeElementBase
}

func (f *NodeFactory) NewNotEmittedTypeElement() *Node {
	data := &NotEmittedTypeElement{}
	return f.newNode(KindNotEmittedTypeElement, data)
}

func (node *NotEmittedTypeElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNotEmittedTypeElement(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNotEmittedTypeElement(node *Node) bool {
	return node.Kind == KindNotEmittedTypeElement
}

// ──────────────────────────────────────────────────────────────────────
// ImportDeclaration
// ──────────────────────────────────────────────────────────────────────

type ImportDeclaration struct {
	StatementBase
	ModifiersBase
	CompositeBase
	DeclarationBase
	ImportClause    *ImportClauseNode // Optional
	ModuleSpecifier *Expression
	Attributes      *ImportAttributesNode // Optional
}

func (f *NodeFactory) NewImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
	data := &ImportDeclaration{}
	data.modifiers = modifiers
	data.ImportClause = importClause
	data.ModuleSpecifier = moduleSpecifier
	data.Attributes = attributes
	return f.newNode(KindImportDeclaration, data)
}

func (f *NodeFactory) NewJSImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
	data := &ImportDeclaration{}
	data.modifiers = modifiers
	data.ImportClause = importClause
	data.ModuleSpecifier = moduleSpecifier
	data.Attributes = attributes
	return f.newNode(KindJSImportDeclaration, data)
}

func (f *NodeFactory) UpdateImportDeclaration(node *ImportDeclaration, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
	if modifiers != node.modifiers || importClause != node.ImportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes {
		switch node.Kind {
		case KindImportDeclaration:
			return updateNode(f.NewImportDeclaration(modifiers, importClause, moduleSpecifier, attributes), node.AsNode(), f.hooks)
		case KindJSImportDeclaration:
			return updateNode(f.NewJSImportDeclaration(modifiers, importClause, moduleSpecifier, attributes), node.AsNode(), f.hooks)
		default:
			panic("unexpected kind in UpdateImportDeclaration: " + node.Kind.String())
		}
	}
	return node.AsNode()
}

func (node *ImportDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.ImportClause) ||
		visit(v, node.ModuleSpecifier) ||
		visit(v, node.Attributes)
}

func (node *ImportDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.ImportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes))
}

func (node *ImportDeclaration) Clone(f NodeFactoryCoercible) *Node {
	switch node.Kind {
	case KindImportDeclaration:
		return cloneNode(f.AsNodeFactory().NewImportDeclaration(node.Modifiers(), node.ImportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
	case KindJSImportDeclaration:
		return cloneNode(f.AsNodeFactory().NewJSImportDeclaration(node.Modifiers(), node.ImportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
	default:
		panic("unexpected kind in ImportDeclaration.Clone: " + node.Kind.String())
	}
}

func (node *ImportDeclaration) computeSubtreeFacts() SubtreeFacts {
	return propagateModifierListSubtreeFacts(node.modifiers) |
		propagateSubtreeFacts(node.ImportClause) |
		propagateSubtreeFacts(node.ModuleSpecifier) |
		propagateSubtreeFacts(node.Attributes)
}

func IsImportDeclaration(node *Node) bool {
	return node.Kind == KindImportDeclaration
}

func IsJSImportDeclaration(node *Node) bool {
	return node.Kind == KindJSImportDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ExternalModuleReference
// ──────────────────────────────────────────────────────────────────────

type ExternalModuleReference struct {
	NodeBase
	Expression *Expression
}

func (f *NodeFactory) NewExternalModuleReference(expression *Expression) *Node {
	data := &ExternalModuleReference{}
	data.Expression = expression
	return f.newNode(KindExternalModuleReference, data)
}

func (f *NodeFactory) UpdateExternalModuleReference(node *ExternalModuleReference, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewExternalModuleReference(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExternalModuleReference) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ExternalModuleReference) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExternalModuleReference(node, v.visitNode(node.Expression))
}

func (node *ExternalModuleReference) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExternalModuleReference(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ExternalModuleReference) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsExternalModuleReference(node *Node) bool {
	return node.Kind == KindExternalModuleReference
}

// ──────────────────────────────────────────────────────────────────────
// NamespaceImport
// ──────────────────────────────────────────────────────────────────────

type NamespaceImport struct {
	NodeBase
	DeclarationBase
	ExportableBase
	name *IdentifierNode
}

func (f *NodeFactory) NewNamespaceImport(name *IdentifierNode) *Node {
	data := &NamespaceImport{}
	data.name = name
	return f.newNode(KindNamespaceImport, data)
}

func (f *NodeFactory) UpdateNamespaceImport(node *NamespaceImport, name *IdentifierNode) *Node {
	if name != node.name {
		return updateNode(f.NewNamespaceImport(name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamespaceImport) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *NamespaceImport) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamespaceImport(node, v.visitNode(node.name))
}

func (node *NamespaceImport) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamespaceImport(node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamespaceImport) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.name)
}

func (node *NamespaceImport) Name() *DeclarationName {
	return node.name
}

func IsNamespaceImport(node *Node) bool {
	return node.Kind == KindNamespaceImport
}

// ──────────────────────────────────────────────────────────────────────
// NamedImports
// ──────────────────────────────────────────────────────────────────────

type NamedImports struct {
	NodeBase
	CompositeBase
	Elements *ImportSpecifierList
}

func (f *NodeFactory) NewNamedImports(elements *ImportSpecifierList) *Node {
	data := &NamedImports{}
	data.Elements = elements
	return f.newNode(KindNamedImports, data)
}

func (f *NodeFactory) UpdateNamedImports(node *NamedImports, elements *ImportSpecifierList) *Node {
	if elements != node.Elements {
		return updateNode(f.NewNamedImports(elements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamedImports) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Elements)
}

func (node *NamedImports) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamedImports(node, v.visitNodes(node.Elements))
}

func (node *NamedImports) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamedImports(node.Elements), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamedImports) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts)
}

func IsNamedImports(node *Node) bool {
	return node.Kind == KindNamedImports
}

// ──────────────────────────────────────────────────────────────────────
// ExportAssignment
// ──────────────────────────────────────────────────────────────────────

type ExportAssignment struct {
	DeclarationBase
	StatementBase
	ModifiersBase
	CompositeBase
	IsExportEquals bool
	Type           *TypeNode
	Expression     *Expression
}

func (f *NodeFactory) NewExportAssignment(modifiers *ModifierList, isExportEquals bool, typeNode *TypeNode, expression *Expression) *Node {
	data := &ExportAssignment{}
	data.modifiers = modifiers
	data.IsExportEquals = isExportEquals
	data.Type = typeNode
	data.Expression = expression
	return f.newNode(KindExportAssignment, data)
}

func (f *NodeFactory) UpdateExportAssignment(node *ExportAssignment, modifiers *ModifierList, isExportEquals bool, typeNode *TypeNode, expression *Expression) *Node {
	if modifiers != node.modifiers || isExportEquals != node.IsExportEquals || typeNode != node.Type || expression != node.Expression {
		return updateNode(f.NewExportAssignment(modifiers, isExportEquals, typeNode, expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExportAssignment) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.Type) || visit(v, node.Expression)
}

func (node *ExportAssignment) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExportAssignment(node, v.visitModifiers(node.modifiers), node.IsExportEquals, v.visitNode(node.Type), v.visitNode(node.Expression))
}

func (node *ExportAssignment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExportAssignment(node.Modifiers(), node.IsExportEquals, node.Type, node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsExportAssignment(node *Node) bool {
	return node.Kind == KindExportAssignment
}

// ──────────────────────────────────────────────────────────────────────
// NamespaceExportDeclaration
// ──────────────────────────────────────────────────────────────────────

type NamespaceExportDeclaration struct {
	DeclarationBase
	StatementBase
	ModifiersBase
	TypeSyntaxBase
	name *IdentifierNode
}

func (f *NodeFactory) NewNamespaceExportDeclaration(modifiers *ModifierList, name *IdentifierNode) *Node {
	data := &NamespaceExportDeclaration{}
	data.modifiers = modifiers
	data.name = name
	return f.newNode(KindNamespaceExportDeclaration, data)
}

func (f *NodeFactory) UpdateNamespaceExportDeclaration(node *NamespaceExportDeclaration, modifiers *ModifierList, name *IdentifierNode) *Node {
	if modifiers != node.modifiers || name != node.name {
		return updateNode(f.NewNamespaceExportDeclaration(modifiers, name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamespaceExportDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.name)
}

func (node *NamespaceExportDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamespaceExportDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name))
}

func (node *NamespaceExportDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamespaceExportDeclaration(node.Modifiers(), node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamespaceExportDeclaration) Name() *DeclarationName {
	return node.name
}

func IsNamespaceExportDeclaration(node *Node) bool {
	return node.Kind == KindNamespaceExportDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// NamespaceExport
// ──────────────────────────────────────────────────────────────────────

type NamespaceExport struct {
	NodeBase
	DeclarationBase
	name *ModuleExportName
}

func (f *NodeFactory) NewNamespaceExport(name *ModuleExportName) *Node {
	data := &NamespaceExport{}
	data.name = name
	return f.newNode(KindNamespaceExport, data)
}

func (f *NodeFactory) UpdateNamespaceExport(node *NamespaceExport, name *ModuleExportName) *Node {
	if name != node.name {
		return updateNode(f.NewNamespaceExport(name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamespaceExport) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *NamespaceExport) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamespaceExport(node, v.visitNode(node.name))
}

func (node *NamespaceExport) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamespaceExport(node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamespaceExport) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.name)
}

func (node *NamespaceExport) Name() *DeclarationName {
	return node.name
}

func IsNamespaceExport(node *Node) bool {
	return node.Kind == KindNamespaceExport
}

// ──────────────────────────────────────────────────────────────────────
// NamedExports
// ──────────────────────────────────────────────────────────────────────

type NamedExports struct {
	NodeBase
	CompositeBase
	Elements *ExportSpecifierList
}

func (f *NodeFactory) NewNamedExports(elements *ExportSpecifierList) *Node {
	data := &NamedExports{}
	data.Elements = elements
	return f.newNode(KindNamedExports, data)
}

func (f *NodeFactory) UpdateNamedExports(node *NamedExports, elements *ExportSpecifierList) *Node {
	if elements != node.Elements {
		return updateNode(f.NewNamedExports(elements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamedExports) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Elements)
}

func (node *NamedExports) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamedExports(node, v.visitNodes(node.Elements))
}

func (node *NamedExports) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamedExports(node.Elements), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamedExports) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts)
}

func IsNamedExports(node *Node) bool {
	return node.Kind == KindNamedExports
}

// ──────────────────────────────────────────────────────────────────────
// ExportSpecifier
// ──────────────────────────────────────────────────────────────────────

type ExportSpecifier struct {
	NodeBase
	DeclarationBase
	ExportableBase
	CompositeBase
	IsTypeOnly   bool
	PropertyName *ModuleExportName // Optional
	name         *ModuleExportName
}

func (f *NodeFactory) NewExportSpecifier(isTypeOnly bool, propertyName *ModuleExportName, name *ModuleExportName) *Node {
	data := &ExportSpecifier{}
	data.IsTypeOnly = isTypeOnly
	data.PropertyName = propertyName
	data.name = name
	return f.newNode(KindExportSpecifier, data)
}

func (f *NodeFactory) UpdateExportSpecifier(node *ExportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *ModuleExportName) *Node {
	if isTypeOnly != node.IsTypeOnly || propertyName != node.PropertyName || name != node.name {
		return updateNode(f.NewExportSpecifier(isTypeOnly, propertyName, name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExportSpecifier) ForEachChild(v Visitor) bool {
	return visit(v, node.PropertyName) || visit(v, node.name)
}

func (node *ExportSpecifier) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExportSpecifier(node, node.IsTypeOnly, v.visitNode(node.PropertyName), v.visitNode(node.name))
}

func (node *ExportSpecifier) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExportSpecifier(node.IsTypeOnly, node.PropertyName, node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ExportSpecifier) Name() *DeclarationName {
	return node.name
}

func IsExportSpecifier(node *Node) bool {
	return node.Kind == KindExportSpecifier
}

// ──────────────────────────────────────────────────────────────────────
// CallSignatureDeclaration
// ──────────────────────────────────────────────────────────────────────

type CallSignatureDeclaration struct {
	NodeBase
	DeclarationBase
	FunctionLikeBase
	TypeElementBase
	TypeSyntaxBase
}

func (f *NodeFactory) NewCallSignatureDeclaration(typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := &CallSignatureDeclaration{}
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindCallSignature, data)
}

func (f *NodeFactory) UpdateCallSignatureDeclaration(node *CallSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewCallSignatureDeclaration(typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *CallSignatureDeclaration) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type)
}

func (node *CallSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateCallSignatureDeclaration(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *CallSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewCallSignatureDeclaration(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsCallSignatureDeclaration(node *Node) bool {
	return node.Kind == KindCallSignature
}

// ──────────────────────────────────────────────────────────────────────
// ConstructSignatureDeclaration
// ──────────────────────────────────────────────────────────────────────

type ConstructSignatureDeclaration struct {
	NodeBase
	DeclarationBase
	FunctionLikeBase
	TypeElementBase
	TypeSyntaxBase
}

func (f *NodeFactory) NewConstructSignatureDeclaration(typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := f.constructSignatureDeclarationArena.New()
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindConstructSignature, data)
}

func (f *NodeFactory) UpdateConstructSignatureDeclaration(node *ConstructSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewConstructSignatureDeclaration(typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ConstructSignatureDeclaration) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type)
}

func (node *ConstructSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateConstructSignatureDeclaration(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *ConstructSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewConstructSignatureDeclaration(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsConstructSignatureDeclaration(node *Node) bool {
	return node.Kind == KindConstructSignature
}

// ──────────────────────────────────────────────────────────────────────
// ConstructorDeclaration
// ──────────────────────────────────────────────────────────────────────

type ConstructorDeclaration struct {
	NodeBase
	DeclarationBase
	ModifiersBase
	FunctionLikeWithBodyBase
	ClassElementBase
	CompositeBase
	ReturnFlowNode *FlowNode
}

func (f *NodeFactory) NewConstructorDeclaration(modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := &ConstructorDeclaration{}
	data.modifiers = modifiers
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindConstructor, data)
}

func (f *NodeFactory) UpdateConstructorDeclaration(node *ConstructorDeclaration, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewConstructorDeclaration(modifiers, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ConstructorDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *ConstructorDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateConstructorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *ConstructorDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewConstructorDeclaration(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsConstructorDeclaration(node *Node) bool {
	return node.Kind == KindConstructor
}

// ──────────────────────────────────────────────────────────────────────
// GetAccessorDeclaration
// ──────────────────────────────────────────────────────────────────────

type GetAccessorDeclaration struct {
	AccessorDeclarationBase
}

func (f *NodeFactory) NewGetAccessorDeclaration(modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := &GetAccessorDeclaration{}
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindGetAccessor, data)
}

func (f *NodeFactory) UpdateGetAccessorDeclaration(node *GetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewGetAccessorDeclaration(modifiers, name, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *GetAccessorDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *GetAccessorDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateGetAccessorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *GetAccessorDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewGetAccessorDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *GetAccessorDeclaration) Name() *DeclarationName {
	return node.name
}

func IsGetAccessorDeclaration(node *Node) bool {
	return node.Kind == KindGetAccessor
}

// ──────────────────────────────────────────────────────────────────────
// SetAccessorDeclaration
// ──────────────────────────────────────────────────────────────────────

type SetAccessorDeclaration struct {
	AccessorDeclarationBase
}

func (f *NodeFactory) NewSetAccessorDeclaration(modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := &SetAccessorDeclaration{}
	data.modifiers = modifiers
	data.name = name
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindSetAccessor, data)
}

func (f *NodeFactory) UpdateSetAccessorDeclaration(node *SetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewSetAccessorDeclaration(modifiers, name, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SetAccessorDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *SetAccessorDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSetAccessorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *SetAccessorDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSetAccessorDeclaration(node.Modifiers(), node.name, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *SetAccessorDeclaration) Name() *DeclarationName {
	return node.name
}

func IsSetAccessorDeclaration(node *Node) bool {
	return node.Kind == KindSetAccessor
}

// ──────────────────────────────────────────────────────────────────────
// IndexSignatureDeclaration
// ──────────────────────────────────────────────────────────────────────

type IndexSignatureDeclaration struct {
	NodeBase
	DeclarationBase
	ModifiersBase
	FunctionLikeBase
	TypeElementBase
	ClassElementBase
	TypeSyntaxBase
}

func (f *NodeFactory) NewIndexSignatureDeclaration(modifiers *ModifierList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := &IndexSignatureDeclaration{}
	data.modifiers = modifiers
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindIndexSignature, data)
}

func (f *NodeFactory) UpdateIndexSignatureDeclaration(node *IndexSignatureDeclaration, modifiers *ModifierList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if modifiers != node.modifiers || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewIndexSignatureDeclaration(modifiers, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *IndexSignatureDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visitNodeList(v, node.Parameters) || visit(v, node.Type)
}

func (node *IndexSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateIndexSignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *IndexSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewIndexSignatureDeclaration(node.Modifiers(), node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsIndexSignatureDeclaration(node *Node) bool {
	return node.Kind == KindIndexSignature
}

// ──────────────────────────────────────────────────────────────────────
// MethodSignatureDeclaration
// ──────────────────────────────────────────────────────────────────────

type MethodSignatureDeclaration struct {
	NodeBase
	NamedMemberBase
	FunctionLikeBase
	TypeElementBase
	TypeSyntaxBase
}

func (f *NodeFactory) NewMethodSignatureDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := f.methodSignatureDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.PostfixToken = postfixToken
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindMethodSignature, data)
}

func (f *NodeFactory) UpdateMethodSignatureDeclaration(node *MethodSignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewMethodSignatureDeclaration(modifiers, name, postfixToken, typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *MethodSignatureDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type)
}

func (node *MethodSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateMethodSignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *MethodSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewMethodSignatureDeclaration(node.Modifiers(), node.name, node.PostfixToken, node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *MethodSignatureDeclaration) Name() *DeclarationName {
	return node.name
}

func IsMethodSignatureDeclaration(node *Node) bool {
	return node.Kind == KindMethodSignature
}

// ──────────────────────────────────────────────────────────────────────
// MethodDeclaration
// ──────────────────────────────────────────────────────────────────────

type MethodDeclaration struct {
	NodeBase
	NamedMemberBase
	FunctionLikeWithBodyBase
	FlowNodeBase
	ClassElementBase
	ObjectLiteralElementBase
	CompositeBase
}

func (f *NodeFactory) NewMethodDeclaration(modifiers *ModifierList, asteriskToken *AsteriskToken, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := &MethodDeclaration{}
	data.modifiers = modifiers
	data.AsteriskToken = asteriskToken
	data.name = name
	data.PostfixToken = postfixToken
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindMethodDeclaration, data)
}

func (f *NodeFactory) UpdateMethodDeclaration(node *MethodDeclaration, modifiers *ModifierList, asteriskToken *AsteriskToken, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || postfixToken != node.PostfixToken || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewMethodDeclaration(modifiers, asteriskToken, name, postfixToken, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *MethodDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.AsteriskToken) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *MethodDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateMethodDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.AsteriskToken), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *MethodDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewMethodDeclaration(node.Modifiers(), node.AsteriskToken, node.name, node.PostfixToken, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *MethodDeclaration) Name() *DeclarationName {
	return node.name
}

func IsMethodDeclaration(node *Node) bool {
	return node.Kind == KindMethodDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// PropertySignatureDeclaration
// ──────────────────────────────────────────────────────────────────────

type PropertySignatureDeclaration struct {
	NodeBase
	NamedMemberBase
	TypeElementBase
	TypeSyntaxBase
	Type        *TypeNode
	Initializer *Expression
}

func (f *NodeFactory) NewPropertySignatureDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	data := f.propertySignatureDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.PostfixToken = postfixToken
	data.Type = typeNode
	data.Initializer = initializer
	return f.newNode(KindPropertySignature, data)
}

func (f *NodeFactory) UpdatePropertySignatureDeclaration(node *PropertySignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer {
		return updateNode(f.NewPropertySignatureDeclaration(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PropertySignatureDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visit(v, node.Type) ||
		visit(v, node.Initializer)
}

func (node *PropertySignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePropertySignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer))
}

func (node *PropertySignatureDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPropertySignatureDeclaration(node.Modifiers(), node.name, node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PropertySignatureDeclaration) Name() *DeclarationName {
	return node.name
}

func IsPropertySignatureDeclaration(node *Node) bool {
	return node.Kind == KindPropertySignature
}

// ──────────────────────────────────────────────────────────────────────
// PropertyDeclaration
// ──────────────────────────────────────────────────────────────────────

type PropertyDeclaration struct {
	NodeBase
	NamedMemberBase
	ClassElementBase
	CompositeBase
	Type        *TypeNode   // Optional
	Initializer *Expression // Optional
}

func (f *NodeFactory) NewPropertyDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	data := &PropertyDeclaration{}
	data.modifiers = modifiers
	data.name = name
	data.PostfixToken = postfixToken
	data.Type = typeNode
	data.Initializer = initializer
	return f.newNode(KindPropertyDeclaration, data)
}

func (f *NodeFactory) UpdatePropertyDeclaration(node *PropertyDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer {
		return updateNode(f.NewPropertyDeclaration(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PropertyDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visit(v, node.Type) ||
		visit(v, node.Initializer)
}

func (node *PropertyDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePropertyDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer))
}

func (node *PropertyDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPropertyDeclaration(node.Modifiers(), node.name, node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PropertyDeclaration) Name() *DeclarationName {
	return node.name
}

func IsPropertyDeclaration(node *Node) bool {
	return node.Kind == KindPropertyDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// SemicolonClassElement
// ──────────────────────────────────────────────────────────────────────

type SemicolonClassElement struct {
	NodeBase
	DeclarationBase
	ClassElementBase
}

func (f *NodeFactory) NewSemicolonClassElement() *Node {
	data := &SemicolonClassElement{}
	return f.newNode(KindSemicolonClassElement, data)
}

func (node *SemicolonClassElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSemicolonClassElement(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSemicolonClassElement(node *Node) bool {
	return node.Kind == KindSemicolonClassElement
}

// ──────────────────────────────────────────────────────────────────────
// ClassStaticBlockDeclaration
// ──────────────────────────────────────────────────────────────────────

type ClassStaticBlockDeclaration struct {
	NodeBase
	DeclarationBase
	ModifiersBase
	LocalsContainerBase
	ClassElementBase
	CompositeBase
	Body           *BlockNode
	ReturnFlowNode *FlowNode
}

func (f *NodeFactory) NewClassStaticBlockDeclaration(modifiers *ModifierList, body *BlockNode) *Node {
	data := &ClassStaticBlockDeclaration{}
	data.modifiers = modifiers
	data.Body = body
	return f.newNode(KindClassStaticBlockDeclaration, data)
}

func (f *NodeFactory) UpdateClassStaticBlockDeclaration(node *ClassStaticBlockDeclaration, modifiers *ModifierList, body *BlockNode) *Node {
	if modifiers != node.modifiers || body != node.Body {
		return updateNode(f.NewClassStaticBlockDeclaration(modifiers, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ClassStaticBlockDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.Body)
}

func (node *ClassStaticBlockDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateClassStaticBlockDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.Body))
}

func (node *ClassStaticBlockDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewClassStaticBlockDeclaration(node.Modifiers(), node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsClassStaticBlockDeclaration(node *Node) bool {
	return node.Kind == KindClassStaticBlockDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// OmittedExpression
// ──────────────────────────────────────────────────────────────────────

type OmittedExpression struct {
	ExpressionBase
}

func (f *NodeFactory) NewOmittedExpression() *Node {
	data := &OmittedExpression{}
	return f.newNode(KindOmittedExpression, data)
}

func (node *OmittedExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewOmittedExpression(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsOmittedExpression(node *Node) bool {
	return node.Kind == KindOmittedExpression
}

// ──────────────────────────────────────────────────────────────────────
// KeywordExpression
// ──────────────────────────────────────────────────────────────────────

type KeywordExpression struct {
	ExpressionBase
	FlowNodeBase
}

func (f *NodeFactory) NewKeywordExpression(kind KeywordExpressionSyntaxKind) *Node {
	data := f.keywordExpressionArena.New()
	return f.newNode(kind, data)
}

func (node *KeywordExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewKeywordExpression(node.Kind), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsKeywordExpression(node *Node) bool {
	switch node.Kind {
	case KindNullKeyword, KindTrueKeyword, KindFalseKeyword, KindThisKeyword, KindSuperKeyword, KindImportKeyword:
		return true
	}
	return false
}

// ──────────────────────────────────────────────────────────────────────
// StringLiteral
// ──────────────────────────────────────────────────────────────────────

type StringLiteral struct {
	LiteralExpressionBase
}

func (f *NodeFactory) NewStringLiteral(text string, tokenFlags TokenFlags) *Node {
	data := f.stringLiteralArena.New()
	data.Text = text
	data.TokenFlags = tokenFlags & TokenFlagsStringLiteralFlags
	f.textCount++
	return f.newNode(KindStringLiteral, data)
}

func (node *StringLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewStringLiteral(node.Text, node.TokenFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsStringLiteral(node *Node) bool {
	return node.Kind == KindStringLiteral
}

// ──────────────────────────────────────────────────────────────────────
// NumericLiteral
// ──────────────────────────────────────────────────────────────────────

type NumericLiteral struct {
	LiteralExpressionBase
}

func (f *NodeFactory) NewNumericLiteral(text string, tokenFlags TokenFlags) *Node {
	data := f.numericLiteralArena.New()
	data.Text = text
	data.TokenFlags = tokenFlags & TokenFlagsNumericLiteralFlags
	f.textCount++
	return f.newNode(KindNumericLiteral, data)
}

func (node *NumericLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNumericLiteral(node.Text, node.TokenFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNumericLiteral(node *Node) bool {
	return node.Kind == KindNumericLiteral
}

// ──────────────────────────────────────────────────────────────────────
// BigIntLiteral
// ──────────────────────────────────────────────────────────────────────

type BigIntLiteral struct {
	LiteralExpressionBase
}

func (f *NodeFactory) NewBigIntLiteral(text string, tokenFlags TokenFlags) *Node {
	data := &BigIntLiteral{}
	data.Text = text
	data.TokenFlags = tokenFlags & TokenFlagsNumericLiteralFlags
	f.textCount++
	return f.newNode(KindBigIntLiteral, data)
}

func (node *BigIntLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBigIntLiteral(node.Text, node.TokenFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsBigIntLiteral(node *Node) bool {
	return node.Kind == KindBigIntLiteral
}

// ──────────────────────────────────────────────────────────────────────
// RegularExpressionLiteral
// ──────────────────────────────────────────────────────────────────────

type RegularExpressionLiteral struct {
	LiteralExpressionBase
}

func (f *NodeFactory) NewRegularExpressionLiteral(text string, tokenFlags TokenFlags) *Node {
	data := &RegularExpressionLiteral{}
	data.Text = text
	data.TokenFlags = tokenFlags & TokenFlagsRegularExpressionLiteralFlags
	f.textCount++
	return f.newNode(KindRegularExpressionLiteral, data)
}

func (node *RegularExpressionLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewRegularExpressionLiteral(node.Text, node.TokenFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsRegularExpressionLiteral(node *Node) bool {
	return node.Kind == KindRegularExpressionLiteral
}

// ──────────────────────────────────────────────────────────────────────
// NoSubstitutionTemplateLiteral
// ──────────────────────────────────────────────────────────────────────

type NoSubstitutionTemplateLiteral struct {
	ExpressionBase
	TemplateLiteralLikeNodeBase
	DeclarationBase
}

func (f *NodeFactory) NewNoSubstitutionTemplateLiteral(text string, templateFlags TokenFlags) *Node {
	data := &NoSubstitutionTemplateLiteral{}
	data.Text = text
	data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags
	f.textCount++
	return f.newNode(KindNoSubstitutionTemplateLiteral, data)
}

func (node *NoSubstitutionTemplateLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNoSubstitutionTemplateLiteral(node.Text, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNoSubstitutionTemplateLiteral(node *Node) bool {
	return node.Kind == KindNoSubstitutionTemplateLiteral
}

// ──────────────────────────────────────────────────────────────────────
// BinaryExpression
// ──────────────────────────────────────────────────────────────────────

type BinaryExpression struct {
	ExpressionBase
	DeclarationBase
	ModifiersBase
	CompositeBase
	Left          *Expression
	Type          *TypeNode // Optional
	OperatorToken *BinaryOperatorToken
	Right         *Expression
}

func (f *NodeFactory) NewBinaryExpression(modifiers *ModifierList, left *Expression, typeNode *TypeNode, operatorToken *BinaryOperatorToken, right *Expression) *Node {
	data := f.binaryExpressionArena.New()
	data.modifiers = modifiers
	data.Left = left
	data.Type = typeNode
	data.OperatorToken = operatorToken
	data.Right = right
	return f.newNode(KindBinaryExpression, data)
}

func (f *NodeFactory) UpdateBinaryExpression(node *BinaryExpression, modifiers *ModifierList, left *Expression, typeNode *TypeNode, operatorToken *BinaryOperatorToken, right *Expression) *Node {
	if modifiers != node.modifiers || left != node.Left || typeNode != node.Type || operatorToken != node.OperatorToken || right != node.Right {
		return updateNode(f.NewBinaryExpression(modifiers, left, typeNode, operatorToken, right), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *BinaryExpression) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.Left) ||
		visit(v, node.Type) ||
		visit(v, node.OperatorToken) ||
		visit(v, node.Right)
}

func (node *BinaryExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateBinaryExpression(node, v.visitModifiers(node.modifiers), v.visitNode(node.Left), v.visitNode(node.Type), v.visitNode(node.OperatorToken), v.visitNode(node.Right))
}

func (node *BinaryExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewBinaryExpression(node.Modifiers(), node.Left, node.Type, node.OperatorToken, node.Right), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsBinaryExpression(node *Node) bool {
	return node.Kind == KindBinaryExpression
}

// ──────────────────────────────────────────────────────────────────────
// PrefixUnaryExpression
// ──────────────────────────────────────────────────────────────────────

type PrefixUnaryExpression struct {
	UpdateExpressionBase
	Operator Kind
	Operand  *Expression
}

func (f *NodeFactory) NewPrefixUnaryExpression(operator Kind, operand *Expression) *Node {
	data := f.prefixUnaryExpressionArena.New()
	data.Operator = operator
	data.Operand = operand
	return f.newNode(KindPrefixUnaryExpression, data)
}

func (f *NodeFactory) UpdatePrefixUnaryExpression(node *PrefixUnaryExpression, operator Kind, operand *Expression) *Node {
	if operator != node.Operator || operand != node.Operand {
		return updateNode(f.NewPrefixUnaryExpression(operator, operand), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PrefixUnaryExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Operand)
}

func (node *PrefixUnaryExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePrefixUnaryExpression(node, node.Operator, v.visitNode(node.Operand))
}

func (node *PrefixUnaryExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPrefixUnaryExpression(node.Operator, node.Operand), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PrefixUnaryExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Operand)
}

func IsPrefixUnaryExpression(node *Node) bool {
	return node.Kind == KindPrefixUnaryExpression
}

// ──────────────────────────────────────────────────────────────────────
// PostfixUnaryExpression
// ──────────────────────────────────────────────────────────────────────

type PostfixUnaryExpression struct {
	UpdateExpressionBase
	Operand  *Expression
	Operator Kind
}

func (f *NodeFactory) NewPostfixUnaryExpression(operand *Expression, operator Kind) *Node {
	data := &PostfixUnaryExpression{}
	data.Operand = operand
	data.Operator = operator
	return f.newNode(KindPostfixUnaryExpression, data)
}

func (f *NodeFactory) UpdatePostfixUnaryExpression(node *PostfixUnaryExpression, operand *Expression, operator Kind) *Node {
	if operand != node.Operand || operator != node.Operator {
		return updateNode(f.NewPostfixUnaryExpression(operand, operator), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PostfixUnaryExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Operand)
}

func (node *PostfixUnaryExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePostfixUnaryExpression(node, v.visitNode(node.Operand), node.Operator)
}

func (node *PostfixUnaryExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPostfixUnaryExpression(node.Operand, node.Operator), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PostfixUnaryExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Operand)
}

func IsPostfixUnaryExpression(node *Node) bool {
	return node.Kind == KindPostfixUnaryExpression
}

// ──────────────────────────────────────────────────────────────────────
// YieldExpression
// ──────────────────────────────────────────────────────────────────────

type YieldExpression struct {
	ExpressionBase
	AsteriskToken *AsteriskToken // Optional
	Expression    *Expression    // Optional
}

func (f *NodeFactory) NewYieldExpression(asteriskToken *AsteriskToken, expression *Expression) *Node {
	data := &YieldExpression{}
	data.AsteriskToken = asteriskToken
	data.Expression = expression
	return f.newNode(KindYieldExpression, data)
}

func (f *NodeFactory) UpdateYieldExpression(node *YieldExpression, asteriskToken *AsteriskToken, expression *Expression) *Node {
	if asteriskToken != node.AsteriskToken || expression != node.Expression {
		return updateNode(f.NewYieldExpression(asteriskToken, expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *YieldExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.AsteriskToken) || visit(v, node.Expression)
}

func (node *YieldExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateYieldExpression(node, v.visitNode(node.AsteriskToken), v.visitNode(node.Expression))
}

func (node *YieldExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewYieldExpression(node.AsteriskToken, node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsYieldExpression(node *Node) bool {
	return node.Kind == KindYieldExpression
}

// ──────────────────────────────────────────────────────────────────────
// ArrowFunction
// ──────────────────────────────────────────────────────────────────────

type ArrowFunction struct {
	ExpressionBase
	DeclarationBase
	ModifiersBase
	FunctionLikeWithBodyBase
	FlowNodeBase
	CompositeBase
	EqualsGreaterThanToken *EqualsGreaterThanToken
}

func (f *NodeFactory) NewArrowFunction(modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, equalsGreaterThanToken *EqualsGreaterThanToken, body *ConciseBody) *Node {
	data := &ArrowFunction{}
	data.modifiers = modifiers
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.EqualsGreaterThanToken = equalsGreaterThanToken
	data.Body = body
	return f.newNode(KindArrowFunction, data)
}

func (f *NodeFactory) UpdateArrowFunction(node *ArrowFunction, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, equalsGreaterThanToken *EqualsGreaterThanToken, body *ConciseBody) *Node {
	if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || equalsGreaterThanToken != node.EqualsGreaterThanToken || body != node.Body {
		return updateNode(f.NewArrowFunction(modifiers, typeParameters, parameters, typeNode, fullSignature, equalsGreaterThanToken, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ArrowFunction) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.EqualsGreaterThanToken) ||
		visit(v, node.Body)
}

func (node *ArrowFunction) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateArrowFunction(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitNode(node.EqualsGreaterThanToken), v.visitFunctionBody(node.Body))
}

func (node *ArrowFunction) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewArrowFunction(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.EqualsGreaterThanToken, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsArrowFunction(node *Node) bool {
	return node.Kind == KindArrowFunction
}

// ──────────────────────────────────────────────────────────────────────
// FunctionExpression
// ──────────────────────────────────────────────────────────────────────

type FunctionExpression struct {
	PrimaryExpressionBase
	DeclarationBase
	ModifiersBase
	FunctionLikeWithBodyBase
	FlowNodeBase
	CompositeBase
	name           *IdentifierNode // Optional
	ReturnFlowNode *FlowNode
}

func (f *NodeFactory) NewFunctionExpression(modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	data := &FunctionExpression{}
	data.modifiers = modifiers
	data.AsteriskToken = asteriskToken
	data.name = name
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	data.FullSignature = fullSignature
	data.Body = body
	return f.newNode(KindFunctionExpression, data)
}

func (f *NodeFactory) UpdateFunctionExpression(node *FunctionExpression, modifiers *ModifierList, asteriskToken *AsteriskToken, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode, fullSignature *TypeNode, body *FunctionBody) *Node {
	if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type || fullSignature != node.FullSignature || body != node.Body {
		return updateNode(f.NewFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, typeNode, fullSignature, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *FunctionExpression) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.AsteriskToken) ||
		visit(v, node.name) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type) ||
		visit(v, node.FullSignature) ||
		visit(v, node.Body)
}

func (node *FunctionExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateFunctionExpression(node, v.visitModifiers(node.modifiers), v.visitNode(node.AsteriskToken), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body))
}

func (node *FunctionExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewFunctionExpression(node.Modifiers(), node.AsteriskToken, node.name, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *FunctionExpression) Name() *DeclarationName {
	return node.name
}

func IsFunctionExpression(node *Node) bool {
	return node.Kind == KindFunctionExpression
}

// ──────────────────────────────────────────────────────────────────────
// AsExpression
// ──────────────────────────────────────────────────────────────────────

type AsExpression struct {
	ExpressionBase
	Expression *Expression
	Type       *TypeNode
}

func (f *NodeFactory) NewAsExpression(expression *Expression, typeNode *TypeNode) *Node {
	data := &AsExpression{}
	data.Expression = expression
	data.Type = typeNode
	return f.newNode(KindAsExpression, data)
}

func (f *NodeFactory) UpdateAsExpression(node *AsExpression, expression *Expression, typeNode *TypeNode) *Node {
	if expression != node.Expression || typeNode != node.Type {
		return updateNode(f.NewAsExpression(expression, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *AsExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.Type)
}

func (node *AsExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateAsExpression(node, v.visitNode(node.Expression), v.visitNode(node.Type))
}

func (node *AsExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewAsExpression(node.Expression, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsAsExpression(node *Node) bool {
	return node.Kind == KindAsExpression
}

// ──────────────────────────────────────────────────────────────────────
// SatisfiesExpression
// ──────────────────────────────────────────────────────────────────────

type SatisfiesExpression struct {
	ExpressionBase
	Expression *Expression
	Type       *TypeNode
}

func (f *NodeFactory) NewSatisfiesExpression(expression *Expression, typeNode *TypeNode) *Node {
	data := &SatisfiesExpression{}
	data.Expression = expression
	data.Type = typeNode
	return f.newNode(KindSatisfiesExpression, data)
}

func (f *NodeFactory) UpdateSatisfiesExpression(node *SatisfiesExpression, expression *Expression, typeNode *TypeNode) *Node {
	if expression != node.Expression || typeNode != node.Type {
		return updateNode(f.NewSatisfiesExpression(expression, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SatisfiesExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.Type)
}

func (node *SatisfiesExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSatisfiesExpression(node, v.visitNode(node.Expression), v.visitNode(node.Type))
}

func (node *SatisfiesExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSatisfiesExpression(node.Expression, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSatisfiesExpression(node *Node) bool {
	return node.Kind == KindSatisfiesExpression
}

// ──────────────────────────────────────────────────────────────────────
// ConditionalExpression
// ──────────────────────────────────────────────────────────────────────

type ConditionalExpression struct {
	ExpressionBase
	CompositeBase
	Condition     *Expression
	QuestionToken *QuestionToken
	WhenTrue      *Expression
	ColonToken    *ColonToken
	WhenFalse     *Expression
}

func (f *NodeFactory) NewConditionalExpression(condition *Expression, questionToken *QuestionToken, whenTrue *Expression, colonToken *ColonToken, whenFalse *Expression) *Node {
	data := f.conditionalExpressionArena.New()
	data.Condition = condition
	data.QuestionToken = questionToken
	data.WhenTrue = whenTrue
	data.ColonToken = colonToken
	data.WhenFalse = whenFalse
	return f.newNode(KindConditionalExpression, data)
}

func (f *NodeFactory) UpdateConditionalExpression(node *ConditionalExpression, condition *Expression, questionToken *QuestionToken, whenTrue *Expression, colonToken *ColonToken, whenFalse *Expression) *Node {
	if condition != node.Condition || questionToken != node.QuestionToken || whenTrue != node.WhenTrue || colonToken != node.ColonToken || whenFalse != node.WhenFalse {
		return updateNode(f.NewConditionalExpression(condition, questionToken, whenTrue, colonToken, whenFalse), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ConditionalExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Condition) ||
		visit(v, node.QuestionToken) ||
		visit(v, node.WhenTrue) ||
		visit(v, node.ColonToken) ||
		visit(v, node.WhenFalse)
}

func (node *ConditionalExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateConditionalExpression(node, v.visitNode(node.Condition), v.visitNode(node.QuestionToken), v.visitNode(node.WhenTrue), v.visitNode(node.ColonToken), v.visitNode(node.WhenFalse))
}

func (node *ConditionalExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewConditionalExpression(node.Condition, node.QuestionToken, node.WhenTrue, node.ColonToken, node.WhenFalse), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ConditionalExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Condition) |
		propagateSubtreeFacts(node.QuestionToken) |
		propagateSubtreeFacts(node.WhenTrue) |
		propagateSubtreeFacts(node.ColonToken) |
		propagateSubtreeFacts(node.WhenFalse)
}

func IsConditionalExpression(node *Node) bool {
	return node.Kind == KindConditionalExpression
}

// ──────────────────────────────────────────────────────────────────────
// PropertyAccessExpression
// ──────────────────────────────────────────────────────────────────────

type PropertyAccessExpression struct {
	MemberExpressionBase
	FlowNodeBase
	CompositeBase
	Expression       *Expression
	QuestionDotToken *QuestionDotToken // Optional
	name             *MemberName
}

func (f *NodeFactory) NewPropertyAccessExpression(expression *Expression, questionDotToken *QuestionDotToken, name *MemberName, flags NodeFlags) *Node {
	data := f.propertyAccessExpressionArena.New()
	data.Expression = expression
	data.QuestionDotToken = questionDotToken
	data.name = name
	node := f.newNode(KindPropertyAccessExpression, data)
	node.Flags |= flags & NodeFlagsOptionalChain
	return node
}

func (f *NodeFactory) UpdatePropertyAccessExpression(node *PropertyAccessExpression, expression *Expression, questionDotToken *QuestionDotToken, name *MemberName, flags NodeFlags) *Node {
	if expression != node.Expression || questionDotToken != node.QuestionDotToken || name != node.name || flags != node.Flags {
		return updateNode(f.NewPropertyAccessExpression(expression, questionDotToken, name, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PropertyAccessExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.QuestionDotToken) || visit(v, node.name)
}

func (node *PropertyAccessExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePropertyAccessExpression(node, v.visitNode(node.Expression), v.visitNode(node.QuestionDotToken), v.visitNode(node.name), node.Flags)
}

func (node *PropertyAccessExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPropertyAccessExpression(node.Expression, node.QuestionDotToken, node.name, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PropertyAccessExpression) Name() *DeclarationName {
	return node.name
}

func IsPropertyAccessExpression(node *Node) bool {
	return node.Kind == KindPropertyAccessExpression
}

// ──────────────────────────────────────────────────────────────────────
// ElementAccessExpression
// ──────────────────────────────────────────────────────────────────────

type ElementAccessExpression struct {
	MemberExpressionBase
	FlowNodeBase
	CompositeBase
	Expression         *Expression
	QuestionDotToken   *QuestionDotToken // Optional
	ArgumentExpression *Expression
}

func (f *NodeFactory) NewElementAccessExpression(expression *Expression, questionDotToken *QuestionDotToken, argumentExpression *Expression, flags NodeFlags) *Node {
	data := f.elementAccessExpressionArena.New()
	data.Expression = expression
	data.QuestionDotToken = questionDotToken
	data.ArgumentExpression = argumentExpression
	node := f.newNode(KindElementAccessExpression, data)
	node.Flags |= flags & NodeFlagsOptionalChain
	return node
}

func (f *NodeFactory) UpdateElementAccessExpression(node *ElementAccessExpression, expression *Expression, questionDotToken *QuestionDotToken, argumentExpression *Expression, flags NodeFlags) *Node {
	if expression != node.Expression || questionDotToken != node.QuestionDotToken || argumentExpression != node.ArgumentExpression || flags != node.Flags {
		return updateNode(f.NewElementAccessExpression(expression, questionDotToken, argumentExpression, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ElementAccessExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.QuestionDotToken) || visit(v, node.ArgumentExpression)
}

func (node *ElementAccessExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateElementAccessExpression(node, v.visitNode(node.Expression), v.visitNode(node.QuestionDotToken), v.visitNode(node.ArgumentExpression), node.Flags)
}

func (node *ElementAccessExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewElementAccessExpression(node.Expression, node.QuestionDotToken, node.ArgumentExpression, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ElementAccessExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.QuestionDotToken) |
		propagateSubtreeFacts(node.ArgumentExpression)
}

func IsElementAccessExpression(node *Node) bool {
	return node.Kind == KindElementAccessExpression
}

// ──────────────────────────────────────────────────────────────────────
// CallExpression
// ──────────────────────────────────────────────────────────────────────

type CallExpression struct {
	LeftHandSideExpressionBase
	DeclarationBase
	CompositeBase
	Expression       *Expression
	QuestionDotToken *QuestionDotToken // Optional
	TypeArguments    *TypeList         // Optional
	Arguments        *ElementList
}

func (f *NodeFactory) NewCallExpression(expression *Expression, questionDotToken *QuestionDotToken, typeArguments *TypeList, arguments *ElementList, flags NodeFlags) *Node {
	data := f.callExpressionArena.New()
	data.Expression = expression
	data.QuestionDotToken = questionDotToken
	data.TypeArguments = typeArguments
	data.Arguments = arguments
	node := f.newNode(KindCallExpression, data)
	node.Flags |= flags & NodeFlagsOptionalChain
	return node
}

func (f *NodeFactory) UpdateCallExpression(node *CallExpression, expression *Expression, questionDotToken *QuestionDotToken, typeArguments *TypeList, arguments *ElementList, flags NodeFlags) *Node {
	if expression != node.Expression || questionDotToken != node.QuestionDotToken || typeArguments != node.TypeArguments || arguments != node.Arguments || flags != node.Flags {
		return updateNode(f.NewCallExpression(expression, questionDotToken, typeArguments, arguments, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *CallExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) ||
		visit(v, node.QuestionDotToken) ||
		visitNodeList(v, node.TypeArguments) ||
		visitNodeList(v, node.Arguments)
}

func (node *CallExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateCallExpression(node, v.visitNode(node.Expression), v.visitNode(node.QuestionDotToken), v.visitNodes(node.TypeArguments), v.visitNodes(node.Arguments), node.Flags)
}

func (node *CallExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewCallExpression(node.Expression, node.QuestionDotToken, node.TypeArguments, node.Arguments, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsCallExpression(node *Node) bool {
	return node.Kind == KindCallExpression
}

// ──────────────────────────────────────────────────────────────────────
// NewExpression
// ──────────────────────────────────────────────────────────────────────

type NewExpression struct {
	PrimaryExpressionBase
	CompositeBase
	Expression    *Expression
	TypeArguments *TypeList    // Optional
	Arguments     *ElementList // Optional
}

func (f *NodeFactory) NewNewExpression(expression *Expression, typeArguments *TypeList, arguments *ElementList) *Node {
	data := &NewExpression{}
	data.Expression = expression
	data.TypeArguments = typeArguments
	data.Arguments = arguments
	return f.newNode(KindNewExpression, data)
}

func (f *NodeFactory) UpdateNewExpression(node *NewExpression, expression *Expression, typeArguments *TypeList, arguments *ElementList) *Node {
	if expression != node.Expression || typeArguments != node.TypeArguments || arguments != node.Arguments {
		return updateNode(f.NewNewExpression(expression, typeArguments, arguments), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NewExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visitNodeList(v, node.TypeArguments) || visitNodeList(v, node.Arguments)
}

func (node *NewExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNewExpression(node, v.visitNode(node.Expression), v.visitNodes(node.TypeArguments), v.visitNodes(node.Arguments))
}

func (node *NewExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNewExpression(node.Expression, node.TypeArguments, node.Arguments), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNewExpression(node *Node) bool {
	return node.Kind == KindNewExpression
}

// ──────────────────────────────────────────────────────────────────────
// MetaProperty
// ──────────────────────────────────────────────────────────────────────

type MetaProperty struct {
	PrimaryExpressionBase
	FlowNodeBase
	CompositeBase
	KeywordToken Kind
	name         *IdentifierNode
}

func (f *NodeFactory) NewMetaProperty(keywordToken Kind, name *IdentifierNode) *Node {
	data := &MetaProperty{}
	data.KeywordToken = keywordToken
	data.name = name
	return f.newNode(KindMetaProperty, data)
}

func (f *NodeFactory) UpdateMetaProperty(node *MetaProperty, keywordToken Kind, name *IdentifierNode) *Node {
	if keywordToken != node.KeywordToken || name != node.name {
		return updateNode(f.NewMetaProperty(keywordToken, name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *MetaProperty) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *MetaProperty) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateMetaProperty(node, node.KeywordToken, v.visitNode(node.name))
}

func (node *MetaProperty) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewMetaProperty(node.KeywordToken, node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *MetaProperty) Name() *DeclarationName {
	return node.name
}

func IsMetaProperty(node *Node) bool {
	return node.Kind == KindMetaProperty
}

// ──────────────────────────────────────────────────────────────────────
// NonNullExpression
// ──────────────────────────────────────────────────────────────────────

type NonNullExpression struct {
	LeftHandSideExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewNonNullExpression(expression *Expression, flags NodeFlags) *Node {
	data := &NonNullExpression{}
	data.Expression = expression
	node := f.newNode(KindNonNullExpression, data)
	node.Flags |= flags & NodeFlagsOptionalChain
	return node
}

func (f *NodeFactory) UpdateNonNullExpression(node *NonNullExpression, expression *Expression, flags NodeFlags) *Node {
	if expression != node.Expression || flags != node.Flags {
		return updateNode(f.NewNonNullExpression(expression, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NonNullExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *NonNullExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNonNullExpression(node, v.visitNode(node.Expression), node.Flags)
}

func (node *NonNullExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNonNullExpression(node.Expression, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsNonNullExpression(node *Node) bool {
	return node.Kind == KindNonNullExpression
}

// ──────────────────────────────────────────────────────────────────────
// SpreadElement
// ──────────────────────────────────────────────────────────────────────

type SpreadElement struct {
	ExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewSpreadElement(expression *Expression) *Node {
	data := &SpreadElement{}
	data.Expression = expression
	return f.newNode(KindSpreadElement, data)
}

func (f *NodeFactory) UpdateSpreadElement(node *SpreadElement, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewSpreadElement(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SpreadElement) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *SpreadElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSpreadElement(node, v.visitNode(node.Expression))
}

func (node *SpreadElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSpreadElement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSpreadElement(node *Node) bool {
	return node.Kind == KindSpreadElement
}

// ──────────────────────────────────────────────────────────────────────
// TemplateExpression
// ──────────────────────────────────────────────────────────────────────

type TemplateExpression struct {
	PrimaryExpressionBase
	CompositeBase
	Head          *TemplateHeadNode
	TemplateSpans *TemplateSpanList
}

func (f *NodeFactory) NewTemplateExpression(head *TemplateHeadNode, templateSpans *TemplateSpanList) *Node {
	data := &TemplateExpression{}
	data.Head = head
	data.TemplateSpans = templateSpans
	return f.newNode(KindTemplateExpression, data)
}

func (f *NodeFactory) UpdateTemplateExpression(node *TemplateExpression, head *TemplateHeadNode, templateSpans *TemplateSpanList) *Node {
	if head != node.Head || templateSpans != node.TemplateSpans {
		return updateNode(f.NewTemplateExpression(head, templateSpans), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TemplateExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Head) || visitNodeList(v, node.TemplateSpans)
}

func (node *TemplateExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTemplateExpression(node, v.visitNode(node.Head), v.visitNodes(node.TemplateSpans))
}

func (node *TemplateExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateExpression(node.Head, node.TemplateSpans), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TemplateExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Head) |
		propagateNodeListSubtreeFacts(node.TemplateSpans, propagateSubtreeFacts)
}

func IsTemplateExpression(node *Node) bool {
	return node.Kind == KindTemplateExpression
}

// ──────────────────────────────────────────────────────────────────────
// TemplateSpan
// ──────────────────────────────────────────────────────────────────────

type TemplateSpan struct {
	NodeBase
	Expression *Expression
	Literal    *TemplateMiddleOrTail
}

func (f *NodeFactory) NewTemplateSpan(expression *Expression, literal *TemplateMiddleOrTail) *Node {
	data := &TemplateSpan{}
	data.Expression = expression
	data.Literal = literal
	return f.newNode(KindTemplateSpan, data)
}

func (f *NodeFactory) UpdateTemplateSpan(node *TemplateSpan, expression *Expression, literal *TemplateMiddleOrTail) *Node {
	if expression != node.Expression || literal != node.Literal {
		return updateNode(f.NewTemplateSpan(expression, literal), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TemplateSpan) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.Literal)
}

func (node *TemplateSpan) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTemplateSpan(node, v.visitNode(node.Expression), v.visitNode(node.Literal))
}

func (node *TemplateSpan) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateSpan(node.Expression, node.Literal), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TemplateSpan) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.Literal)
}

func IsTemplateSpan(node *Node) bool {
	return node.Kind == KindTemplateSpan
}

// ──────────────────────────────────────────────────────────────────────
// TaggedTemplateExpression
// ──────────────────────────────────────────────────────────────────────

type TaggedTemplateExpression struct {
	MemberExpressionBase
	CompositeBase
	Tag              *Expression
	QuestionDotToken *QuestionDotToken
	TypeArguments    *TypeList // Optional
	Template         *TemplateLiteral
}

func (f *NodeFactory) NewTaggedTemplateExpression(tag *Expression, questionDotToken *QuestionDotToken, typeArguments *TypeList, template *TemplateLiteral, flags NodeFlags) *Node {
	data := &TaggedTemplateExpression{}
	data.Tag = tag
	data.QuestionDotToken = questionDotToken
	data.TypeArguments = typeArguments
	data.Template = template
	node := f.newNode(KindTaggedTemplateExpression, data)
	node.Flags |= flags & NodeFlagsOptionalChain
	return node
}

func (f *NodeFactory) UpdateTaggedTemplateExpression(node *TaggedTemplateExpression, tag *Expression, questionDotToken *QuestionDotToken, typeArguments *TypeList, template *TemplateLiteral, flags NodeFlags) *Node {
	if tag != node.Tag || questionDotToken != node.QuestionDotToken || typeArguments != node.TypeArguments || template != node.Template || flags != node.Flags {
		return updateNode(f.NewTaggedTemplateExpression(tag, questionDotToken, typeArguments, template, flags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TaggedTemplateExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Tag) ||
		visit(v, node.QuestionDotToken) ||
		visitNodeList(v, node.TypeArguments) ||
		visit(v, node.Template)
}

func (node *TaggedTemplateExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTaggedTemplateExpression(node, v.visitNode(node.Tag), v.visitNode(node.QuestionDotToken), v.visitNodes(node.TypeArguments), v.visitNode(node.Template), node.Flags)
}

func (node *TaggedTemplateExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTaggedTemplateExpression(node.Tag, node.QuestionDotToken, node.TypeArguments, node.Template, node.Flags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTaggedTemplateExpression(node *Node) bool {
	return node.Kind == KindTaggedTemplateExpression
}

// ──────────────────────────────────────────────────────────────────────
// ParenthesizedExpression
// ──────────────────────────────────────────────────────────────────────

type ParenthesizedExpression struct {
	PrimaryExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewParenthesizedExpression(expression *Expression) *Node {
	data := f.parenthesizedExpressionArena.New()
	data.Expression = expression
	return f.newNode(KindParenthesizedExpression, data)
}

func (f *NodeFactory) UpdateParenthesizedExpression(node *ParenthesizedExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewParenthesizedExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ParenthesizedExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *ParenthesizedExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateParenthesizedExpression(node, v.visitNode(node.Expression))
}

func (node *ParenthesizedExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewParenthesizedExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ParenthesizedExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsParenthesizedExpression(node *Node) bool {
	return node.Kind == KindParenthesizedExpression
}

// ──────────────────────────────────────────────────────────────────────
// ArrayLiteralExpression
// ──────────────────────────────────────────────────────────────────────

type ArrayLiteralExpression struct {
	PrimaryExpressionBase
	CompositeBase
	Elements  *ElementList
	MultiLine bool
}

func (f *NodeFactory) NewArrayLiteralExpression(elements *ElementList, multiLine bool) *Node {
	data := &ArrayLiteralExpression{}
	data.Elements = elements
	data.MultiLine = multiLine
	return f.newNode(KindArrayLiteralExpression, data)
}

func (f *NodeFactory) UpdateArrayLiteralExpression(node *ArrayLiteralExpression, elements *ElementList, multiLine bool) *Node {
	if elements != node.Elements || multiLine != node.MultiLine {
		return updateNode(f.NewArrayLiteralExpression(elements, multiLine), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ArrayLiteralExpression) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Elements)
}

func (node *ArrayLiteralExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateArrayLiteralExpression(node, v.visitNodes(node.Elements), node.MultiLine)
}

func (node *ArrayLiteralExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewArrayLiteralExpression(node.Elements, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ArrayLiteralExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts)
}

func IsArrayLiteralExpression(node *Node) bool {
	return node.Kind == KindArrayLiteralExpression
}

// ──────────────────────────────────────────────────────────────────────
// ObjectLiteralExpression
// ──────────────────────────────────────────────────────────────────────

type ObjectLiteralExpression struct {
	PrimaryExpressionBase
	DeclarationBase
	CompositeBase
	Properties *NodeList
	MultiLine  bool
}

func (f *NodeFactory) NewObjectLiteralExpression(properties *NodeList, multiLine bool) *Node {
	data := &ObjectLiteralExpression{}
	data.Properties = properties
	data.MultiLine = multiLine
	return f.newNode(KindObjectLiteralExpression, data)
}

func (f *NodeFactory) UpdateObjectLiteralExpression(node *ObjectLiteralExpression, properties *NodeList, multiLine bool) *Node {
	if properties != node.Properties || multiLine != node.MultiLine {
		return updateNode(f.NewObjectLiteralExpression(properties, multiLine), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ObjectLiteralExpression) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Properties)
}

func (node *ObjectLiteralExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateObjectLiteralExpression(node, v.visitNodes(node.Properties), node.MultiLine)
}

func (node *ObjectLiteralExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewObjectLiteralExpression(node.Properties, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ObjectLiteralExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Properties, propagateSubtreeFacts)
}

func IsObjectLiteralExpression(node *Node) bool {
	return node.Kind == KindObjectLiteralExpression
}

// ──────────────────────────────────────────────────────────────────────
// SpreadAssignment
// ──────────────────────────────────────────────────────────────────────

type SpreadAssignment struct {
	NodeBase
	DeclarationBase
	ObjectLiteralElementBase
	Expression *Expression
}

func (f *NodeFactory) NewSpreadAssignment(expression *Expression) *Node {
	data := &SpreadAssignment{}
	data.Expression = expression
	return f.newNode(KindSpreadAssignment, data)
}

func (f *NodeFactory) UpdateSpreadAssignment(node *SpreadAssignment, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewSpreadAssignment(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SpreadAssignment) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *SpreadAssignment) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSpreadAssignment(node, v.visitNode(node.Expression))
}

func (node *SpreadAssignment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSpreadAssignment(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSpreadAssignment(node *Node) bool {
	return node.Kind == KindSpreadAssignment
}

// ──────────────────────────────────────────────────────────────────────
// PropertyAssignment
// ──────────────────────────────────────────────────────────────────────

type PropertyAssignment struct {
	NodeBase
	NamedMemberBase
	ObjectLiteralElementBase
	CompositeBase
	Type        *TypeNode
	Initializer *Expression
}

func (f *NodeFactory) NewPropertyAssignment(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	data := f.propertyAssignmentArena.New()
	data.modifiers = modifiers
	data.name = name
	data.PostfixToken = postfixToken
	data.Type = typeNode
	data.Initializer = initializer
	return f.newNode(KindPropertyAssignment, data)
}

func (f *NodeFactory) UpdatePropertyAssignment(node *PropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node {
	if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer {
		return updateNode(f.NewPropertyAssignment(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PropertyAssignment) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visit(v, node.Type) ||
		visit(v, node.Initializer)
}

func (node *PropertyAssignment) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePropertyAssignment(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer))
}

func (node *PropertyAssignment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPropertyAssignment(node.Modifiers(), node.name, node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PropertyAssignment) Name() *DeclarationName {
	return node.name
}

func IsPropertyAssignment(node *Node) bool {
	return node.Kind == KindPropertyAssignment
}

// ──────────────────────────────────────────────────────────────────────
// ShorthandPropertyAssignment
// ──────────────────────────────────────────────────────────────────────

type ShorthandPropertyAssignment struct {
	NodeBase
	NamedMemberBase
	ObjectLiteralElementBase
	CompositeBase
	Type                        *TypeNode
	EqualsToken                 *EqualsToken // Optional
	ObjectAssignmentInitializer *Expression  // Optional
}

func (f *NodeFactory) NewShorthandPropertyAssignment(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, equalsToken *EqualsToken, objectAssignmentInitializer *Expression) *Node {
	data := &ShorthandPropertyAssignment{}
	data.modifiers = modifiers
	data.name = name
	data.PostfixToken = postfixToken
	data.Type = typeNode
	data.EqualsToken = equalsToken
	data.ObjectAssignmentInitializer = objectAssignmentInitializer
	return f.newNode(KindShorthandPropertyAssignment, data)
}

func (f *NodeFactory) UpdateShorthandPropertyAssignment(node *ShorthandPropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, equalsToken *EqualsToken, objectAssignmentInitializer *Expression) *Node {
	if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || equalsToken != node.EqualsToken || objectAssignmentInitializer != node.ObjectAssignmentInitializer {
		return updateNode(f.NewShorthandPropertyAssignment(modifiers, name, postfixToken, typeNode, equalsToken, objectAssignmentInitializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ShorthandPropertyAssignment) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.PostfixToken) ||
		visit(v, node.Type) ||
		visit(v, node.EqualsToken) ||
		visit(v, node.ObjectAssignmentInitializer)
}

func (node *ShorthandPropertyAssignment) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateShorthandPropertyAssignment(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.EqualsToken), v.visitNode(node.ObjectAssignmentInitializer))
}

func (node *ShorthandPropertyAssignment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewShorthandPropertyAssignment(node.Modifiers(), node.name, node.PostfixToken, node.Type, node.EqualsToken, node.ObjectAssignmentInitializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ShorthandPropertyAssignment) Name() *DeclarationName {
	return node.name
}

func IsShorthandPropertyAssignment(node *Node) bool {
	return node.Kind == KindShorthandPropertyAssignment
}

// ──────────────────────────────────────────────────────────────────────
// DeleteExpression
// ──────────────────────────────────────────────────────────────────────

type DeleteExpression struct {
	UnaryExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewDeleteExpression(expression *Expression) *Node {
	data := &DeleteExpression{}
	data.Expression = expression
	return f.newNode(KindDeleteExpression, data)
}

func (f *NodeFactory) UpdateDeleteExpression(node *DeleteExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewDeleteExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *DeleteExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *DeleteExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateDeleteExpression(node, v.visitNode(node.Expression))
}

func (node *DeleteExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewDeleteExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *DeleteExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsDeleteExpression(node *Node) bool {
	return node.Kind == KindDeleteExpression
}

// ──────────────────────────────────────────────────────────────────────
// TypeOfExpression
// ──────────────────────────────────────────────────────────────────────

type TypeOfExpression struct {
	UnaryExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewTypeOfExpression(expression *Expression) *Node {
	data := &TypeOfExpression{}
	data.Expression = expression
	return f.newNode(KindTypeOfExpression, data)
}

func (f *NodeFactory) UpdateTypeOfExpression(node *TypeOfExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewTypeOfExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeOfExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *TypeOfExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeOfExpression(node, v.visitNode(node.Expression))
}

func (node *TypeOfExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeOfExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TypeOfExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsTypeOfExpression(node *Node) bool {
	return node.Kind == KindTypeOfExpression
}

// ──────────────────────────────────────────────────────────────────────
// VoidExpression
// ──────────────────────────────────────────────────────────────────────

type VoidExpression struct {
	UnaryExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewVoidExpression(expression *Expression) *Node {
	data := &VoidExpression{}
	data.Expression = expression
	return f.newNode(KindVoidExpression, data)
}

func (f *NodeFactory) UpdateVoidExpression(node *VoidExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewVoidExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *VoidExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *VoidExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateVoidExpression(node, v.visitNode(node.Expression))
}

func (node *VoidExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewVoidExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *VoidExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsVoidExpression(node *Node) bool {
	return node.Kind == KindVoidExpression
}

// ──────────────────────────────────────────────────────────────────────
// AwaitExpression
// ──────────────────────────────────────────────────────────────────────

type AwaitExpression struct {
	UnaryExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewAwaitExpression(expression *Expression) *Node {
	data := &AwaitExpression{}
	data.Expression = expression
	return f.newNode(KindAwaitExpression, data)
}

func (f *NodeFactory) UpdateAwaitExpression(node *AwaitExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewAwaitExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *AwaitExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *AwaitExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateAwaitExpression(node, v.visitNode(node.Expression))
}

func (node *AwaitExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewAwaitExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsAwaitExpression(node *Node) bool {
	return node.Kind == KindAwaitExpression
}

// ──────────────────────────────────────────────────────────────────────
// TypeAssertion
// ──────────────────────────────────────────────────────────────────────

type TypeAssertion struct {
	UnaryExpressionBase
	Type       *TypeNode
	Expression *Expression
}

func (f *NodeFactory) NewTypeAssertion(typeNode *TypeNode, expression *Expression) *Node {
	data := &TypeAssertion{}
	data.Type = typeNode
	data.Expression = expression
	return f.newNode(KindTypeAssertionExpression, data)
}

func (f *NodeFactory) UpdateTypeAssertion(node *TypeAssertion, typeNode *TypeNode, expression *Expression) *Node {
	if typeNode != node.Type || expression != node.Expression {
		return updateNode(f.NewTypeAssertion(typeNode, expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeAssertion) ForEachChild(v Visitor) bool {
	return visit(v, node.Type) || visit(v, node.Expression)
}

func (node *TypeAssertion) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeAssertion(node, v.visitNode(node.Type), v.visitNode(node.Expression))
}

func (node *TypeAssertion) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeAssertion(node.Type, node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypeAssertion(node *Node) bool {
	return node.Kind == KindTypeAssertionExpression
}

// ──────────────────────────────────────────────────────────────────────
// KeywordTypeNode
// ──────────────────────────────────────────────────────────────────────

type KeywordTypeNode struct {
	TypeNodeBase
}

func (f *NodeFactory) NewKeywordTypeNode(kind KeywordTypeSyntaxKind) *Node {
	data := f.keywordTypeNodeArena.New()
	return f.newNode(kind, data)
}

func (node *KeywordTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewKeywordTypeNode(node.Kind), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsKeywordTypeNode(node *Node) bool {
	switch node.Kind {
	case KindAnyKeyword, KindBigIntKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindVoidKeyword:
		return true
	}
	return false
}

// ──────────────────────────────────────────────────────────────────────
// UnionTypeNode
// ──────────────────────────────────────────────────────────────────────

type UnionTypeNode struct {
	TypeNodeBase
	UnionOrIntersectionTypeNodeBase
}

func (f *NodeFactory) NewUnionTypeNode(types *TypeList) *Node {
	data := f.unionTypeNodeArena.New()
	data.Types = types
	return f.newNode(KindUnionType, data)
}

func (f *NodeFactory) UpdateUnionTypeNode(node *UnionTypeNode, types *TypeList) *Node {
	if types != node.Types {
		return updateNode(f.NewUnionTypeNode(types), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *UnionTypeNode) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Types)
}

func (node *UnionTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateUnionTypeNode(node, v.visitNodes(node.Types))
}

func (node *UnionTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewUnionTypeNode(node.Types), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsUnionTypeNode(node *Node) bool {
	return node.Kind == KindUnionType
}

// ──────────────────────────────────────────────────────────────────────
// IntersectionTypeNode
// ──────────────────────────────────────────────────────────────────────

type IntersectionTypeNode struct {
	TypeNodeBase
	UnionOrIntersectionTypeNodeBase
}

func (f *NodeFactory) NewIntersectionTypeNode(types *TypeList) *Node {
	data := f.intersectionTypeNodeArena.New()
	data.Types = types
	return f.newNode(KindIntersectionType, data)
}

func (f *NodeFactory) UpdateIntersectionTypeNode(node *IntersectionTypeNode, types *TypeList) *Node {
	if types != node.Types {
		return updateNode(f.NewIntersectionTypeNode(types), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *IntersectionTypeNode) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Types)
}

func (node *IntersectionTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateIntersectionTypeNode(node, v.visitNodes(node.Types))
}

func (node *IntersectionTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewIntersectionTypeNode(node.Types), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsIntersectionTypeNode(node *Node) bool {
	return node.Kind == KindIntersectionType
}

// ──────────────────────────────────────────────────────────────────────
// ConditionalTypeNode
// ──────────────────────────────────────────────────────────────────────

type ConditionalTypeNode struct {
	TypeNodeBase
	LocalsContainerBase
	CheckType   *TypeNode
	ExtendsType *TypeNode
	TrueType    *TypeNode
	FalseType   *TypeNode
}

func (f *NodeFactory) NewConditionalTypeNode(checkType *TypeNode, extendsType *TypeNode, trueType *TypeNode, falseType *TypeNode) *Node {
	data := &ConditionalTypeNode{}
	data.CheckType = checkType
	data.ExtendsType = extendsType
	data.TrueType = trueType
	data.FalseType = falseType
	return f.newNode(KindConditionalType, data)
}

func (f *NodeFactory) UpdateConditionalTypeNode(node *ConditionalTypeNode, checkType *TypeNode, extendsType *TypeNode, trueType *TypeNode, falseType *TypeNode) *Node {
	if checkType != node.CheckType || extendsType != node.ExtendsType || trueType != node.TrueType || falseType != node.FalseType {
		return updateNode(f.NewConditionalTypeNode(checkType, extendsType, trueType, falseType), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ConditionalTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.CheckType) ||
		visit(v, node.ExtendsType) ||
		visit(v, node.TrueType) ||
		visit(v, node.FalseType)
}

func (node *ConditionalTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateConditionalTypeNode(node, v.visitNode(node.CheckType), v.visitNode(node.ExtendsType), v.visitNode(node.TrueType), v.visitNode(node.FalseType))
}

func (node *ConditionalTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewConditionalTypeNode(node.CheckType, node.ExtendsType, node.TrueType, node.FalseType), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsConditionalTypeNode(node *Node) bool {
	return node.Kind == KindConditionalType
}

// ──────────────────────────────────────────────────────────────────────
// TypeOperatorNode
// ──────────────────────────────────────────────────────────────────────

type TypeOperatorNode struct {
	TypeNodeBase
	Operator Kind
	Type     *TypeNode
}

func (f *NodeFactory) NewTypeOperatorNode(operator Kind, typeNode *TypeNode) *Node {
	data := f.typeOperatorNodeArena.New()
	data.Operator = operator
	data.Type = typeNode
	return f.newNode(KindTypeOperator, data)
}

func (f *NodeFactory) UpdateTypeOperatorNode(node *TypeOperatorNode, operator Kind, typeNode *TypeNode) *Node {
	if operator != node.Operator || typeNode != node.Type {
		return updateNode(f.NewTypeOperatorNode(operator, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeOperatorNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *TypeOperatorNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeOperatorNode(node, node.Operator, v.visitNode(node.Type))
}

func (node *TypeOperatorNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeOperatorNode(node.Operator, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypeOperatorNode(node *Node) bool {
	return node.Kind == KindTypeOperator
}

// ──────────────────────────────────────────────────────────────────────
// InferTypeNode
// ──────────────────────────────────────────────────────────────────────

type InferTypeNode struct {
	TypeNodeBase
	TypeParameter *TypeParameterDeclarationNode
}

func (f *NodeFactory) NewInferTypeNode(typeParameter *TypeParameterDeclarationNode) *Node {
	data := &InferTypeNode{}
	data.TypeParameter = typeParameter
	return f.newNode(KindInferType, data)
}

func (f *NodeFactory) UpdateInferTypeNode(node *InferTypeNode, typeParameter *TypeParameterDeclarationNode) *Node {
	if typeParameter != node.TypeParameter {
		return updateNode(f.NewInferTypeNode(typeParameter), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *InferTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.TypeParameter)
}

func (node *InferTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateInferTypeNode(node, v.visitNode(node.TypeParameter))
}

func (node *InferTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewInferTypeNode(node.TypeParameter), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsInferTypeNode(node *Node) bool {
	return node.Kind == KindInferType
}

// ──────────────────────────────────────────────────────────────────────
// ArrayTypeNode
// ──────────────────────────────────────────────────────────────────────

type ArrayTypeNode struct {
	TypeNodeBase
	ElementType *TypeNode
}

func (f *NodeFactory) NewArrayTypeNode(elementType *TypeNode) *Node {
	data := f.arrayTypeNodeArena.New()
	data.ElementType = elementType
	return f.newNode(KindArrayType, data)
}

func (f *NodeFactory) UpdateArrayTypeNode(node *ArrayTypeNode, elementType *TypeNode) *Node {
	if elementType != node.ElementType {
		return updateNode(f.NewArrayTypeNode(elementType), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ArrayTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.ElementType)
}

func (node *ArrayTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateArrayTypeNode(node, v.visitNode(node.ElementType))
}

func (node *ArrayTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewArrayTypeNode(node.ElementType), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsArrayTypeNode(node *Node) bool {
	return node.Kind == KindArrayType
}

// ──────────────────────────────────────────────────────────────────────
// IndexedAccessTypeNode
// ──────────────────────────────────────────────────────────────────────

type IndexedAccessTypeNode struct {
	TypeNodeBase
	ObjectType *TypeNode
	IndexType  *TypeNode
}

func (f *NodeFactory) NewIndexedAccessTypeNode(objectType *TypeNode, indexType *TypeNode) *Node {
	data := f.indexedAccessTypeNodeArena.New()
	data.ObjectType = objectType
	data.IndexType = indexType
	return f.newNode(KindIndexedAccessType, data)
}

func (f *NodeFactory) UpdateIndexedAccessTypeNode(node *IndexedAccessTypeNode, objectType *TypeNode, indexType *TypeNode) *Node {
	if objectType != node.ObjectType || indexType != node.IndexType {
		return updateNode(f.NewIndexedAccessTypeNode(objectType, indexType), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *IndexedAccessTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.ObjectType) || visit(v, node.IndexType)
}

func (node *IndexedAccessTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateIndexedAccessTypeNode(node, v.visitNode(node.ObjectType), v.visitNode(node.IndexType))
}

func (node *IndexedAccessTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewIndexedAccessTypeNode(node.ObjectType, node.IndexType), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsIndexedAccessTypeNode(node *Node) bool {
	return node.Kind == KindIndexedAccessType
}

// ──────────────────────────────────────────────────────────────────────
// TypeReferenceNode
// ──────────────────────────────────────────────────────────────────────

type TypeReferenceNode struct {
	NodeWithTypeArgumentsBase
	TypeName *EntityName
}

func (f *NodeFactory) NewTypeReferenceNode(typeName *EntityName, typeArguments *TypeList) *Node {
	data := f.typeReferenceNodeArena.New()
	data.TypeName = typeName
	data.TypeArguments = typeArguments
	return f.newNode(KindTypeReference, data)
}

func (f *NodeFactory) UpdateTypeReferenceNode(node *TypeReferenceNode, typeName *EntityName, typeArguments *TypeList) *Node {
	if typeName != node.TypeName || typeArguments != node.TypeArguments {
		return updateNode(f.NewTypeReferenceNode(typeName, typeArguments), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeReferenceNode) ForEachChild(v Visitor) bool {
	return visit(v, node.TypeName) || visitNodeList(v, node.TypeArguments)
}

func (node *TypeReferenceNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeReferenceNode(node, v.visitNode(node.TypeName), v.visitNodes(node.TypeArguments))
}

func (node *TypeReferenceNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeReferenceNode(node.TypeName, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypeReferenceNode(node *Node) bool {
	return node.Kind == KindTypeReference
}

// ──────────────────────────────────────────────────────────────────────
// ExpressionWithTypeArguments
// ──────────────────────────────────────────────────────────────────────

type ExpressionWithTypeArguments struct {
	MemberExpressionBase
	CompositeBase
	Expression    *Expression
	TypeArguments *TypeList // Optional
}

func (f *NodeFactory) NewExpressionWithTypeArguments(expression *Expression, typeArguments *TypeList) *Node {
	data := f.expressionWithTypeArgumentsArena.New()
	data.Expression = expression
	data.TypeArguments = typeArguments
	return f.newNode(KindExpressionWithTypeArguments, data)
}

func (f *NodeFactory) UpdateExpressionWithTypeArguments(node *ExpressionWithTypeArguments, expression *Expression, typeArguments *TypeList) *Node {
	if expression != node.Expression || typeArguments != node.TypeArguments {
		return updateNode(f.NewExpressionWithTypeArguments(expression, typeArguments), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExpressionWithTypeArguments) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visitNodeList(v, node.TypeArguments)
}

func (node *ExpressionWithTypeArguments) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExpressionWithTypeArguments(node, v.visitNode(node.Expression), v.visitNodes(node.TypeArguments))
}

func (node *ExpressionWithTypeArguments) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExpressionWithTypeArguments(node.Expression, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsExpressionWithTypeArguments(node *Node) bool {
	return node.Kind == KindExpressionWithTypeArguments
}

// ──────────────────────────────────────────────────────────────────────
// LiteralTypeNode
// ──────────────────────────────────────────────────────────────────────

type LiteralTypeNode struct {
	TypeNodeBase
	Literal *Node
}

func (f *NodeFactory) NewLiteralTypeNode(literal *Node) *Node {
	data := f.literalTypeNodeArena.New()
	data.Literal = literal
	return f.newNode(KindLiteralType, data)
}

func (f *NodeFactory) UpdateLiteralTypeNode(node *LiteralTypeNode, literal *Node) *Node {
	if literal != node.Literal {
		return updateNode(f.NewLiteralTypeNode(literal), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *LiteralTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Literal)
}

func (node *LiteralTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateLiteralTypeNode(node, v.visitNode(node.Literal))
}

func (node *LiteralTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewLiteralTypeNode(node.Literal), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsLiteralTypeNode(node *Node) bool {
	return node.Kind == KindLiteralType
}

// ──────────────────────────────────────────────────────────────────────
// ThisTypeNode
// ──────────────────────────────────────────────────────────────────────

type ThisTypeNode struct {
	TypeNodeBase
}

func (f *NodeFactory) NewThisTypeNode() *Node {
	data := &ThisTypeNode{}
	return f.newNode(KindThisType, data)
}

func (node *ThisTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewThisTypeNode(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsThisTypeNode(node *Node) bool {
	return node.Kind == KindThisType
}

// ──────────────────────────────────────────────────────────────────────
// TypePredicateNode
// ──────────────────────────────────────────────────────────────────────

type TypePredicateNode struct {
	TypeNodeBase
	AssertsModifier *AssertsKeyword // Optional
	ParameterName   *TypePredicateParameterName
	Type            *TypeNode // Optional
}

func (f *NodeFactory) NewTypePredicateNode(assertsModifier *AssertsKeyword, parameterName *TypePredicateParameterName, typeNode *TypeNode) *Node {
	data := &TypePredicateNode{}
	data.AssertsModifier = assertsModifier
	data.ParameterName = parameterName
	data.Type = typeNode
	return f.newNode(KindTypePredicate, data)
}

func (f *NodeFactory) UpdateTypePredicateNode(node *TypePredicateNode, assertsModifier *AssertsKeyword, parameterName *TypePredicateParameterName, typeNode *TypeNode) *Node {
	if assertsModifier != node.AssertsModifier || parameterName != node.ParameterName || typeNode != node.Type {
		return updateNode(f.NewTypePredicateNode(assertsModifier, parameterName, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypePredicateNode) ForEachChild(v Visitor) bool {
	return visit(v, node.AssertsModifier) || visit(v, node.ParameterName) || visit(v, node.Type)
}

func (node *TypePredicateNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypePredicateNode(node, v.visitNode(node.AssertsModifier), v.visitNode(node.ParameterName), v.visitNode(node.Type))
}

func (node *TypePredicateNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypePredicateNode(node.AssertsModifier, node.ParameterName, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypePredicateNode(node *Node) bool {
	return node.Kind == KindTypePredicate
}

// ──────────────────────────────────────────────────────────────────────
// ImportAttribute
// ──────────────────────────────────────────────────────────────────────

type ImportAttribute struct {
	NodeBase
	CompositeBase
	name  *ImportAttributeName
	Value *Expression
}

func (f *NodeFactory) NewImportAttribute(name *ImportAttributeName, value *Expression) *Node {
	data := &ImportAttribute{}
	data.name = name
	data.Value = value
	return f.newNode(KindImportAttribute, data)
}

func (f *NodeFactory) UpdateImportAttribute(node *ImportAttribute, name *ImportAttributeName, value *Expression) *Node {
	if name != node.name || value != node.Value {
		return updateNode(f.NewImportAttribute(name, value), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportAttribute) ForEachChild(v Visitor) bool {
	return visit(v, node.name) || visit(v, node.Value)
}

func (node *ImportAttribute) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportAttribute(node, v.visitNode(node.name), v.visitNode(node.Value))
}

func (node *ImportAttribute) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportAttribute(node.name, node.Value), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportAttribute) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.name) |
		propagateSubtreeFacts(node.Value)
}

func (node *ImportAttribute) Name() *DeclarationName {
	return node.name
}

func IsImportAttribute(node *Node) bool {
	return node.Kind == KindImportAttribute
}

// ──────────────────────────────────────────────────────────────────────
// ImportAttributes
// ──────────────────────────────────────────────────────────────────────

type ImportAttributes struct {
	NodeBase
	CompositeBase
	Token      Kind
	Attributes *ImportAttributeList
	MultiLine  bool
}

func (f *NodeFactory) NewImportAttributes(token Kind, attributes *ImportAttributeList, multiLine bool) *Node {
	data := &ImportAttributes{}
	data.Token = token
	data.Attributes = attributes
	data.MultiLine = multiLine
	return f.newNode(KindImportAttributes, data)
}

func (f *NodeFactory) UpdateImportAttributes(node *ImportAttributes, token Kind, attributes *ImportAttributeList, multiLine bool) *Node {
	if token != node.Token || attributes != node.Attributes || multiLine != node.MultiLine {
		return updateNode(f.NewImportAttributes(token, attributes, multiLine), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportAttributes) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Attributes)
}

func (node *ImportAttributes) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportAttributes(node, node.Token, v.visitNodes(node.Attributes), node.MultiLine)
}

func (node *ImportAttributes) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportAttributes(node.Token, node.Attributes, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportAttributes) computeSubtreeFacts() SubtreeFacts {
	return propagateNodeListSubtreeFacts(node.Attributes, propagateSubtreeFacts)
}

func IsImportAttributes(node *Node) bool {
	return node.Kind == KindImportAttributes
}

// ──────────────────────────────────────────────────────────────────────
// TypeQueryNode
// ──────────────────────────────────────────────────────────────────────

type TypeQueryNode struct {
	NodeWithTypeArgumentsBase
	ExprName *EntityName
}

func (f *NodeFactory) NewTypeQueryNode(exprName *EntityName, typeArguments *TypeList) *Node {
	data := &TypeQueryNode{}
	data.ExprName = exprName
	data.TypeArguments = typeArguments
	return f.newNode(KindTypeQuery, data)
}

func (f *NodeFactory) UpdateTypeQueryNode(node *TypeQueryNode, exprName *EntityName, typeArguments *TypeList) *Node {
	if exprName != node.ExprName || typeArguments != node.TypeArguments {
		return updateNode(f.NewTypeQueryNode(exprName, typeArguments), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeQueryNode) ForEachChild(v Visitor) bool {
	return visit(v, node.ExprName) || visitNodeList(v, node.TypeArguments)
}

func (node *TypeQueryNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeQueryNode(node, v.visitNode(node.ExprName), v.visitNodes(node.TypeArguments))
}

func (node *TypeQueryNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeQueryNode(node.ExprName, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypeQueryNode(node *Node) bool {
	return node.Kind == KindTypeQuery
}

// ──────────────────────────────────────────────────────────────────────
// MappedTypeNode
// ──────────────────────────────────────────────────────────────────────

type MappedTypeNode struct {
	TypeNodeBase
	DeclarationBase
	LocalsContainerBase
	ReadonlyToken *TokenNode // Optional
	TypeParameter *TypeParameterDeclarationNode
	NameType      *TypeNode        // Optional
	QuestionToken *TokenNode       // Optional
	Type          *TypeNode        // Optional
	Members       *TypeElementList // Optional
}

func (f *NodeFactory) NewMappedTypeNode(readonlyToken *TokenNode, typeParameter *TypeParameterDeclarationNode, nameType *TypeNode, questionToken *TokenNode, typeNode *TypeNode, members *TypeElementList) *Node {
	data := &MappedTypeNode{}
	data.ReadonlyToken = readonlyToken
	data.TypeParameter = typeParameter
	data.NameType = nameType
	data.QuestionToken = questionToken
	data.Type = typeNode
	data.Members = members
	return f.newNode(KindMappedType, data)
}

func (f *NodeFactory) UpdateMappedTypeNode(node *MappedTypeNode, readonlyToken *TokenNode, typeParameter *TypeParameterDeclarationNode, nameType *TypeNode, questionToken *TokenNode, typeNode *TypeNode, members *TypeElementList) *Node {
	if readonlyToken != node.ReadonlyToken || typeParameter != node.TypeParameter || nameType != node.NameType || questionToken != node.QuestionToken || typeNode != node.Type || members != node.Members {
		return updateNode(f.NewMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, typeNode, members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *MappedTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.ReadonlyToken) ||
		visit(v, node.TypeParameter) ||
		visit(v, node.NameType) ||
		visit(v, node.QuestionToken) ||
		visit(v, node.Type) ||
		visitNodeList(v, node.Members)
}

func (node *MappedTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateMappedTypeNode(node, v.visitNode(node.ReadonlyToken), v.visitNode(node.TypeParameter), v.visitNode(node.NameType), v.visitNode(node.QuestionToken), v.visitNode(node.Type), v.visitNodes(node.Members))
}

func (node *MappedTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewMappedTypeNode(node.ReadonlyToken, node.TypeParameter, node.NameType, node.QuestionToken, node.Type, node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsMappedTypeNode(node *Node) bool {
	return node.Kind == KindMappedType
}

// ──────────────────────────────────────────────────────────────────────
// TypeLiteralNode
// ──────────────────────────────────────────────────────────────────────

type TypeLiteralNode struct {
	TypeNodeBase
	DeclarationBase
	Members *TypeElementList
}

func (f *NodeFactory) NewTypeLiteralNode(members *TypeElementList) *Node {
	data := f.typeLiteralNodeArena.New()
	data.Members = members
	return f.newNode(KindTypeLiteral, data)
}

func (f *NodeFactory) UpdateTypeLiteralNode(node *TypeLiteralNode, members *TypeElementList) *Node {
	if members != node.Members {
		return updateNode(f.NewTypeLiteralNode(members), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeLiteralNode) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Members)
}

func (node *TypeLiteralNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeLiteralNode(node, v.visitNodes(node.Members))
}

func (node *TypeLiteralNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeLiteralNode(node.Members), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTypeLiteralNode(node *Node) bool {
	return node.Kind == KindTypeLiteral
}

// ──────────────────────────────────────────────────────────────────────
// TupleTypeNode
// ──────────────────────────────────────────────────────────────────────

type TupleTypeNode struct {
	TypeNodeBase
	Elements *TypeList
}

func (f *NodeFactory) NewTupleTypeNode(elements *TypeList) *Node {
	data := &TupleTypeNode{}
	data.Elements = elements
	return f.newNode(KindTupleType, data)
}

func (f *NodeFactory) UpdateTupleTypeNode(node *TupleTypeNode, elements *TypeList) *Node {
	if elements != node.Elements {
		return updateNode(f.NewTupleTypeNode(elements), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TupleTypeNode) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Elements)
}

func (node *TupleTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTupleTypeNode(node, v.visitNodes(node.Elements))
}

func (node *TupleTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTupleTypeNode(node.Elements), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTupleTypeNode(node *Node) bool {
	return node.Kind == KindTupleType
}

// ──────────────────────────────────────────────────────────────────────
// NamedTupleMember
// ──────────────────────────────────────────────────────────────────────

type NamedTupleMember struct {
	TypeNodeBase
	DeclarationBase
	DotDotDotToken *DotDotDotToken // Optional
	name           *IdentifierNode
	QuestionToken  *QuestionToken // Optional
	Type           *TypeNode
}

func (f *NodeFactory) NewNamedTupleMember(dotDotDotToken *DotDotDotToken, name *IdentifierNode, questionToken *QuestionToken, typeNode *TypeNode) *Node {
	data := &NamedTupleMember{}
	data.DotDotDotToken = dotDotDotToken
	data.name = name
	data.QuestionToken = questionToken
	data.Type = typeNode
	return f.newNode(KindNamedTupleMember, data)
}

func (f *NodeFactory) UpdateNamedTupleMember(node *NamedTupleMember, dotDotDotToken *DotDotDotToken, name *IdentifierNode, questionToken *QuestionToken, typeNode *TypeNode) *Node {
	if dotDotDotToken != node.DotDotDotToken || name != node.name || questionToken != node.QuestionToken || typeNode != node.Type {
		return updateNode(f.NewNamedTupleMember(dotDotDotToken, name, questionToken, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *NamedTupleMember) ForEachChild(v Visitor) bool {
	return visit(v, node.DotDotDotToken) ||
		visit(v, node.name) ||
		visit(v, node.QuestionToken) ||
		visit(v, node.Type)
}

func (node *NamedTupleMember) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateNamedTupleMember(node, v.visitNode(node.DotDotDotToken), v.visitNode(node.name), v.visitNode(node.QuestionToken), v.visitNode(node.Type))
}

func (node *NamedTupleMember) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewNamedTupleMember(node.DotDotDotToken, node.name, node.QuestionToken, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *NamedTupleMember) Name() *DeclarationName {
	return node.name
}

func IsNamedTupleMember(node *Node) bool {
	return node.Kind == KindNamedTupleMember
}

// ──────────────────────────────────────────────────────────────────────
// OptionalTypeNode
// ──────────────────────────────────────────────────────────────────────

type OptionalTypeNode struct {
	TypeNodeBase
	Type *TypeNode
}

func (f *NodeFactory) NewOptionalTypeNode(typeNode *TypeNode) *Node {
	data := &OptionalTypeNode{}
	data.Type = typeNode
	return f.newNode(KindOptionalType, data)
}

func (f *NodeFactory) UpdateOptionalTypeNode(node *OptionalTypeNode, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewOptionalTypeNode(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *OptionalTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *OptionalTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateOptionalTypeNode(node, v.visitNode(node.Type))
}

func (node *OptionalTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewOptionalTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsOptionalTypeNode(node *Node) bool {
	return node.Kind == KindOptionalType
}

// ──────────────────────────────────────────────────────────────────────
// RestTypeNode
// ──────────────────────────────────────────────────────────────────────

type RestTypeNode struct {
	TypeNodeBase
	Type *TypeNode
}

func (f *NodeFactory) NewRestTypeNode(typeNode *TypeNode) *Node {
	data := &RestTypeNode{}
	data.Type = typeNode
	return f.newNode(KindRestType, data)
}

func (f *NodeFactory) UpdateRestTypeNode(node *RestTypeNode, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewRestTypeNode(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *RestTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *RestTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateRestTypeNode(node, v.visitNode(node.Type))
}

func (node *RestTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewRestTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsRestTypeNode(node *Node) bool {
	return node.Kind == KindRestType
}

// ──────────────────────────────────────────────────────────────────────
// ParenthesizedTypeNode
// ──────────────────────────────────────────────────────────────────────

type ParenthesizedTypeNode struct {
	TypeNodeBase
	Type *TypeNode
}

func (f *NodeFactory) NewParenthesizedTypeNode(typeNode *TypeNode) *Node {
	data := f.parenthesizedTypeNodeArena.New()
	data.Type = typeNode
	return f.newNode(KindParenthesizedType, data)
}

func (f *NodeFactory) UpdateParenthesizedTypeNode(node *ParenthesizedTypeNode, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewParenthesizedTypeNode(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ParenthesizedTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *ParenthesizedTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateParenthesizedTypeNode(node, v.visitNode(node.Type))
}

func (node *ParenthesizedTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewParenthesizedTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsParenthesizedTypeNode(node *Node) bool {
	return node.Kind == KindParenthesizedType
}

// ──────────────────────────────────────────────────────────────────────
// FunctionTypeNode
// ──────────────────────────────────────────────────────────────────────

type FunctionTypeNode struct {
	TypeNodeBase
	FunctionOrConstructorTypeNodeBase
}

func (f *NodeFactory) NewFunctionTypeNode(typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := f.functionTypeNodeArena.New()
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindFunctionType, data)
}

func (f *NodeFactory) UpdateFunctionTypeNode(node *FunctionTypeNode, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewFunctionTypeNode(typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *FunctionTypeNode) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type)
}

func (node *FunctionTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateFunctionTypeNode(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *FunctionTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewFunctionTypeNode(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsFunctionTypeNode(node *Node) bool {
	return node.Kind == KindFunctionType
}

// ──────────────────────────────────────────────────────────────────────
// ConstructorTypeNode
// ──────────────────────────────────────────────────────────────────────

type ConstructorTypeNode struct {
	TypeNodeBase
	FunctionOrConstructorTypeNodeBase
}

func (f *NodeFactory) NewConstructorTypeNode(modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := &ConstructorTypeNode{}
	data.modifiers = modifiers
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindConstructorType, data)
}

func (f *NodeFactory) UpdateConstructorTypeNode(node *ConstructorTypeNode, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewConstructorTypeNode(modifiers, typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ConstructorTypeNode) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Parameters) ||
		visit(v, node.Type)
}

func (node *ConstructorTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateConstructorTypeNode(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *ConstructorTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewConstructorTypeNode(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsConstructorTypeNode(node *Node) bool {
	return node.Kind == KindConstructorType
}

// ──────────────────────────────────────────────────────────────────────
// TemplateHead
// ──────────────────────────────────────────────────────────────────────

type TemplateHead struct {
	NodeBase
	TemplateLiteralLikeNodeBase
}

func (f *NodeFactory) NewTemplateHead(text string, rawText string, templateFlags TokenFlags) *Node {
	data := &TemplateHead{}
	data.Text = text
	data.RawText = rawText
	data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags
	f.textCount++
	return f.newNode(KindTemplateHead, data)
}

func (node *TemplateHead) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateHead(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTemplateHead(node *Node) bool {
	return node.Kind == KindTemplateHead
}

// ──────────────────────────────────────────────────────────────────────
// TemplateMiddle
// ──────────────────────────────────────────────────────────────────────

type TemplateMiddle struct {
	NodeBase
	TemplateLiteralLikeNodeBase
}

func (f *NodeFactory) NewTemplateMiddle(text string, rawText string, templateFlags TokenFlags) *Node {
	data := &TemplateMiddle{}
	data.Text = text
	data.RawText = rawText
	data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags
	f.textCount++
	return f.newNode(KindTemplateMiddle, data)
}

func (node *TemplateMiddle) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateMiddle(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTemplateMiddle(node *Node) bool {
	return node.Kind == KindTemplateMiddle
}

// ──────────────────────────────────────────────────────────────────────
// TemplateTail
// ──────────────────────────────────────────────────────────────────────

type TemplateTail struct {
	NodeBase
	TemplateLiteralLikeNodeBase
}

func (f *NodeFactory) NewTemplateTail(text string, rawText string, templateFlags TokenFlags) *Node {
	data := &TemplateTail{}
	data.Text = text
	data.RawText = rawText
	data.TemplateFlags = templateFlags & TokenFlagsTemplateLiteralLikeFlags
	f.textCount++
	return f.newNode(KindTemplateTail, data)
}

func (node *TemplateTail) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateTail(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTemplateTail(node *Node) bool {
	return node.Kind == KindTemplateTail
}

// ──────────────────────────────────────────────────────────────────────
// TemplateLiteralTypeNode
// ──────────────────────────────────────────────────────────────────────

type TemplateLiteralTypeNode struct {
	TypeNodeBase
	Head          *TemplateHeadNode
	TemplateSpans *TemplateLiteralTypeSpanList
}

func (f *NodeFactory) NewTemplateLiteralTypeNode(head *TemplateHeadNode, templateSpans *TemplateLiteralTypeSpanList) *Node {
	data := &TemplateLiteralTypeNode{}
	data.Head = head
	data.TemplateSpans = templateSpans
	return f.newNode(KindTemplateLiteralType, data)
}

func (f *NodeFactory) UpdateTemplateLiteralTypeNode(node *TemplateLiteralTypeNode, head *TemplateHeadNode, templateSpans *TemplateLiteralTypeSpanList) *Node {
	if head != node.Head || templateSpans != node.TemplateSpans {
		return updateNode(f.NewTemplateLiteralTypeNode(head, templateSpans), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TemplateLiteralTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Head) || visitNodeList(v, node.TemplateSpans)
}

func (node *TemplateLiteralTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTemplateLiteralTypeNode(node, v.visitNode(node.Head), v.visitNodes(node.TemplateSpans))
}

func (node *TemplateLiteralTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateLiteralTypeNode(node.Head, node.TemplateSpans), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTemplateLiteralTypeNode(node *Node) bool {
	return node.Kind == KindTemplateLiteralType
}

// ──────────────────────────────────────────────────────────────────────
// TemplateLiteralTypeSpan
// ──────────────────────────────────────────────────────────────────────

type TemplateLiteralTypeSpan struct {
	TypeNodeBase
	Type    *TypeNode
	Literal *TemplateMiddleOrTail
}

func (f *NodeFactory) NewTemplateLiteralTypeSpan(typeNode *TypeNode, literal *TemplateMiddleOrTail) *Node {
	data := &TemplateLiteralTypeSpan{}
	data.Type = typeNode
	data.Literal = literal
	return f.newNode(KindTemplateLiteralTypeSpan, data)
}

func (f *NodeFactory) UpdateTemplateLiteralTypeSpan(node *TemplateLiteralTypeSpan, typeNode *TypeNode, literal *TemplateMiddleOrTail) *Node {
	if typeNode != node.Type || literal != node.Literal {
		return updateNode(f.NewTemplateLiteralTypeSpan(typeNode, literal), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TemplateLiteralTypeSpan) ForEachChild(v Visitor) bool {
	return visit(v, node.Type) || visit(v, node.Literal)
}

func (node *TemplateLiteralTypeSpan) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTemplateLiteralTypeSpan(node, v.visitNode(node.Type), v.visitNode(node.Literal))
}

func (node *TemplateLiteralTypeSpan) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTemplateLiteralTypeSpan(node.Type, node.Literal), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsTemplateLiteralTypeSpan(node *Node) bool {
	return node.Kind == KindTemplateLiteralTypeSpan
}

// ──────────────────────────────────────────────────────────────────────
// SyntheticExpression
// ──────────────────────────────────────────────────────────────────────

type SyntheticExpression struct {
	ExpressionBase
	Type            any
	IsSpread        bool
	TupleNameSource *Node // Optional
}

func (f *NodeFactory) NewSyntheticExpression(typeNode any, isSpread bool, tupleNameSource *Node) *Node {
	data := &SyntheticExpression{}
	data.Type = typeNode
	data.IsSpread = isSpread
	data.TupleNameSource = tupleNameSource
	return f.newNode(KindSyntheticExpression, data)
}

func (f *NodeFactory) UpdateSyntheticExpression(node *SyntheticExpression, typeNode any, isSpread bool, tupleNameSource *Node) *Node {
	if typeNode != node.Type || isSpread != node.IsSpread || tupleNameSource != node.TupleNameSource {
		return updateNode(f.NewSyntheticExpression(typeNode, isSpread, tupleNameSource), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SyntheticExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.TupleNameSource)
}

func (node *SyntheticExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSyntheticExpression(node, node.Type, node.IsSpread, v.visitNode(node.TupleNameSource))
}

func (node *SyntheticExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSyntheticExpression(node.Type, node.IsSpread, node.TupleNameSource), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSyntheticExpression(node *Node) bool {
	return node.Kind == KindSyntheticExpression
}

// ──────────────────────────────────────────────────────────────────────
// PartiallyEmittedExpression
// ──────────────────────────────────────────────────────────────────────

type PartiallyEmittedExpression struct {
	LeftHandSideExpressionBase
	Expression *Expression
}

func (f *NodeFactory) NewPartiallyEmittedExpression(expression *Expression) *Node {
	data := &PartiallyEmittedExpression{}
	data.Expression = expression
	return f.newNode(KindPartiallyEmittedExpression, data)
}

func (f *NodeFactory) UpdatePartiallyEmittedExpression(node *PartiallyEmittedExpression, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewPartiallyEmittedExpression(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *PartiallyEmittedExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *PartiallyEmittedExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdatePartiallyEmittedExpression(node, v.visitNode(node.Expression))
}

func (node *PartiallyEmittedExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewPartiallyEmittedExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *PartiallyEmittedExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression)
}

func IsPartiallyEmittedExpression(node *Node) bool {
	return node.Kind == KindPartiallyEmittedExpression
}

// ──────────────────────────────────────────────────────────────────────
// JsxElement
// ──────────────────────────────────────────────────────────────────────

type JsxElement struct {
	PrimaryExpressionBase
	CompositeBase
	OpeningElement *JsxOpeningElementNode
	Children       *JsxChildList
	ClosingElement *JsxClosingElementNode
}

func (f *NodeFactory) NewJsxElement(openingElement *JsxOpeningElementNode, children *JsxChildList, closingElement *JsxClosingElementNode) *Node {
	data := &JsxElement{}
	data.OpeningElement = openingElement
	data.Children = children
	data.ClosingElement = closingElement
	return f.newNode(KindJsxElement, data)
}

func (f *NodeFactory) UpdateJsxElement(node *JsxElement, openingElement *JsxOpeningElementNode, children *JsxChildList, closingElement *JsxClosingElementNode) *Node {
	if openingElement != node.OpeningElement || children != node.Children || closingElement != node.ClosingElement {
		return updateNode(f.NewJsxElement(openingElement, children, closingElement), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxElement) ForEachChild(v Visitor) bool {
	return visit(v, node.OpeningElement) || visitNodeList(v, node.Children) || visit(v, node.ClosingElement)
}

func (node *JsxElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxElement(node, v.visitNode(node.OpeningElement), v.visitNodes(node.Children), v.visitNode(node.ClosingElement))
}

func (node *JsxElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxElement(node.OpeningElement, node.Children, node.ClosingElement), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxElement(node *Node) bool {
	return node.Kind == KindJsxElement
}

// ──────────────────────────────────────────────────────────────────────
// JsxAttributes
// ──────────────────────────────────────────────────────────────────────

type JsxAttributes struct {
	PrimaryExpressionBase
	DeclarationBase
	CompositeBase
	Properties *JsxAttributeList
}

func (f *NodeFactory) NewJsxAttributes(properties *JsxAttributeList) *Node {
	data := &JsxAttributes{}
	data.Properties = properties
	return f.newNode(KindJsxAttributes, data)
}

func (f *NodeFactory) UpdateJsxAttributes(node *JsxAttributes, properties *JsxAttributeList) *Node {
	if properties != node.Properties {
		return updateNode(f.NewJsxAttributes(properties), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxAttributes) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Properties)
}

func (node *JsxAttributes) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxAttributes(node, v.visitNodes(node.Properties))
}

func (node *JsxAttributes) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxAttributes(node.Properties), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxAttributes(node *Node) bool {
	return node.Kind == KindJsxAttributes
}

// ──────────────────────────────────────────────────────────────────────
// JsxNamespacedName
// ──────────────────────────────────────────────────────────────────────

type JsxNamespacedName struct {
	ExpressionBase
	CompositeBase
	Namespace *IdentifierNode
	name      *IdentifierNode
}

func (f *NodeFactory) NewJsxNamespacedName(namespace *IdentifierNode, name *IdentifierNode) *Node {
	data := &JsxNamespacedName{}
	data.Namespace = namespace
	data.name = name
	return f.newNode(KindJsxNamespacedName, data)
}

func (f *NodeFactory) UpdateJsxNamespacedName(node *JsxNamespacedName, namespace *IdentifierNode, name *IdentifierNode) *Node {
	if namespace != node.Namespace || name != node.name {
		return updateNode(f.NewJsxNamespacedName(namespace, name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxNamespacedName) ForEachChild(v Visitor) bool {
	return visit(v, node.Namespace) || visit(v, node.name)
}

func (node *JsxNamespacedName) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxNamespacedName(node, v.visitNode(node.Namespace), v.visitNode(node.name))
}

func (node *JsxNamespacedName) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxNamespacedName(node.Namespace, node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JsxNamespacedName) Name() *DeclarationName {
	return node.name
}

func IsJsxNamespacedName(node *Node) bool {
	return node.Kind == KindJsxNamespacedName
}

// ──────────────────────────────────────────────────────────────────────
// JsxOpeningElement
// ──────────────────────────────────────────────────────────────────────

type JsxOpeningElement struct {
	ExpressionBase
	CompositeBase
	TagName       *JsxTagNameExpression
	TypeArguments *TypeList // Optional
	Attributes    *JsxAttributesNode
}

func (f *NodeFactory) NewJsxOpeningElement(tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node {
	data := &JsxOpeningElement{}
	data.TagName = tagName
	data.TypeArguments = typeArguments
	data.Attributes = attributes
	return f.newNode(KindJsxOpeningElement, data)
}

func (f *NodeFactory) UpdateJsxOpeningElement(node *JsxOpeningElement, tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node {
	if tagName != node.TagName || typeArguments != node.TypeArguments || attributes != node.Attributes {
		return updateNode(f.NewJsxOpeningElement(tagName, typeArguments, attributes), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxOpeningElement) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.TypeArguments) || visit(v, node.Attributes)
}

func (node *JsxOpeningElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxOpeningElement(node, v.visitNode(node.TagName), v.visitNodes(node.TypeArguments), v.visitNode(node.Attributes))
}

func (node *JsxOpeningElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxOpeningElement(node.TagName, node.TypeArguments, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxOpeningElement(node *Node) bool {
	return node.Kind == KindJsxOpeningElement
}

// ──────────────────────────────────────────────────────────────────────
// JsxSelfClosingElement
// ──────────────────────────────────────────────────────────────────────

type JsxSelfClosingElement struct {
	PrimaryExpressionBase
	CompositeBase
	TagName       *JsxTagNameExpression
	TypeArguments *TypeList // Optional
	Attributes    *JsxAttributesNode
}

func (f *NodeFactory) NewJsxSelfClosingElement(tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node {
	data := &JsxSelfClosingElement{}
	data.TagName = tagName
	data.TypeArguments = typeArguments
	data.Attributes = attributes
	return f.newNode(KindJsxSelfClosingElement, data)
}

func (f *NodeFactory) UpdateJsxSelfClosingElement(node *JsxSelfClosingElement, tagName *JsxTagNameExpression, typeArguments *TypeList, attributes *JsxAttributesNode) *Node {
	if tagName != node.TagName || typeArguments != node.TypeArguments || attributes != node.Attributes {
		return updateNode(f.NewJsxSelfClosingElement(tagName, typeArguments, attributes), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxSelfClosingElement) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.TypeArguments) || visit(v, node.Attributes)
}

func (node *JsxSelfClosingElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxSelfClosingElement(node, v.visitNode(node.TagName), v.visitNodes(node.TypeArguments), v.visitNode(node.Attributes))
}

func (node *JsxSelfClosingElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxSelfClosingElement(node.TagName, node.TypeArguments, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxSelfClosingElement(node *Node) bool {
	return node.Kind == KindJsxSelfClosingElement
}

// ──────────────────────────────────────────────────────────────────────
// JsxFragment
// ──────────────────────────────────────────────────────────────────────

type JsxFragment struct {
	PrimaryExpressionBase
	CompositeBase
	OpeningFragment *JsxOpeningFragmentNode
	Children        *JsxChildList
	ClosingFragment *JsxClosingFragmentNode
}

func (f *NodeFactory) NewJsxFragment(openingFragment *JsxOpeningFragmentNode, children *JsxChildList, closingFragment *JsxClosingFragmentNode) *Node {
	data := &JsxFragment{}
	data.OpeningFragment = openingFragment
	data.Children = children
	data.ClosingFragment = closingFragment
	return f.newNode(KindJsxFragment, data)
}

func (f *NodeFactory) UpdateJsxFragment(node *JsxFragment, openingFragment *JsxOpeningFragmentNode, children *JsxChildList, closingFragment *JsxClosingFragmentNode) *Node {
	if openingFragment != node.OpeningFragment || children != node.Children || closingFragment != node.ClosingFragment {
		return updateNode(f.NewJsxFragment(openingFragment, children, closingFragment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxFragment) ForEachChild(v Visitor) bool {
	return visit(v, node.OpeningFragment) || visitNodeList(v, node.Children) || visit(v, node.ClosingFragment)
}

func (node *JsxFragment) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxFragment(node, v.visitNode(node.OpeningFragment), v.visitNodes(node.Children), v.visitNode(node.ClosingFragment))
}

func (node *JsxFragment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxFragment(node.OpeningFragment, node.Children, node.ClosingFragment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxFragment(node *Node) bool {
	return node.Kind == KindJsxFragment
}

// ──────────────────────────────────────────────────────────────────────
// JsxOpeningFragment
// ──────────────────────────────────────────────────────────────────────

type JsxOpeningFragment struct {
	ExpressionBase
}

func (f *NodeFactory) NewJsxOpeningFragment() *Node {
	data := &JsxOpeningFragment{}
	return f.newNode(KindJsxOpeningFragment, data)
}

func (node *JsxOpeningFragment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxOpeningFragment(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxOpeningFragment(node *Node) bool {
	return node.Kind == KindJsxOpeningFragment
}

// ──────────────────────────────────────────────────────────────────────
// JsxClosingFragment
// ──────────────────────────────────────────────────────────────────────

type JsxClosingFragment struct {
	ExpressionBase
}

func (f *NodeFactory) NewJsxClosingFragment() *Node {
	data := &JsxClosingFragment{}
	return f.newNode(KindJsxClosingFragment, data)
}

func (node *JsxClosingFragment) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxClosingFragment(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxClosingFragment(node *Node) bool {
	return node.Kind == KindJsxClosingFragment
}

// ──────────────────────────────────────────────────────────────────────
// JsxAttribute
// ──────────────────────────────────────────────────────────────────────

type JsxAttribute struct {
	NodeBase
	DeclarationBase
	CompositeBase
	name        *JsxAttributeName
	Initializer *JsxAttributeValue // Optional
}

func (f *NodeFactory) NewJsxAttribute(name *JsxAttributeName, initializer *JsxAttributeValue) *Node {
	data := &JsxAttribute{}
	data.name = name
	data.Initializer = initializer
	return f.newNode(KindJsxAttribute, data)
}

func (f *NodeFactory) UpdateJsxAttribute(node *JsxAttribute, name *JsxAttributeName, initializer *JsxAttributeValue) *Node {
	if name != node.name || initializer != node.Initializer {
		return updateNode(f.NewJsxAttribute(name, initializer), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxAttribute) ForEachChild(v Visitor) bool {
	return visit(v, node.name) || visit(v, node.Initializer)
}

func (node *JsxAttribute) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxAttribute(node, v.visitNode(node.name), v.visitNode(node.Initializer))
}

func (node *JsxAttribute) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxAttribute(node.name, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JsxAttribute) Name() *DeclarationName {
	return node.name
}

func IsJsxAttribute(node *Node) bool {
	return node.Kind == KindJsxAttribute
}

// ──────────────────────────────────────────────────────────────────────
// JsxSpreadAttribute
// ──────────────────────────────────────────────────────────────────────

type JsxSpreadAttribute struct {
	ObjectLiteralElementBase
	NodeBase
	Expression *Expression
}

func (f *NodeFactory) NewJsxSpreadAttribute(expression *Expression) *Node {
	data := &JsxSpreadAttribute{}
	data.Expression = expression
	return f.newNode(KindJsxSpreadAttribute, data)
}

func (f *NodeFactory) UpdateJsxSpreadAttribute(node *JsxSpreadAttribute, expression *Expression) *Node {
	if expression != node.Expression {
		return updateNode(f.NewJsxSpreadAttribute(expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxSpreadAttribute) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression)
}

func (node *JsxSpreadAttribute) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxSpreadAttribute(node, v.visitNode(node.Expression))
}

func (node *JsxSpreadAttribute) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxSpreadAttribute(node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxSpreadAttribute(node *Node) bool {
	return node.Kind == KindJsxSpreadAttribute
}

// ──────────────────────────────────────────────────────────────────────
// JsxClosingElement
// ──────────────────────────────────────────────────────────────────────

type JsxClosingElement struct {
	NodeBase
	TagName *JsxTagNameExpression
}

func (f *NodeFactory) NewJsxClosingElement(tagName *JsxTagNameExpression) *Node {
	data := &JsxClosingElement{}
	data.TagName = tagName
	return f.newNode(KindJsxClosingElement, data)
}

func (f *NodeFactory) UpdateJsxClosingElement(node *JsxClosingElement, tagName *JsxTagNameExpression) *Node {
	if tagName != node.TagName {
		return updateNode(f.NewJsxClosingElement(tagName), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxClosingElement) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName)
}

func (node *JsxClosingElement) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxClosingElement(node, v.visitNode(node.TagName))
}

func (node *JsxClosingElement) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxClosingElement(node.TagName), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxClosingElement(node *Node) bool {
	return node.Kind == KindJsxClosingElement
}

// ──────────────────────────────────────────────────────────────────────
// JsxExpression
// ──────────────────────────────────────────────────────────────────────

type JsxExpression struct {
	ExpressionBase
	DotDotDotToken *DotDotDotToken // Optional
	Expression     *Expression     // Optional
}

func (f *NodeFactory) NewJsxExpression(dotDotDotToken *DotDotDotToken, expression *Expression) *Node {
	data := &JsxExpression{}
	data.DotDotDotToken = dotDotDotToken
	data.Expression = expression
	return f.newNode(KindJsxExpression, data)
}

func (f *NodeFactory) UpdateJsxExpression(node *JsxExpression, dotDotDotToken *DotDotDotToken, expression *Expression) *Node {
	if dotDotDotToken != node.DotDotDotToken || expression != node.Expression {
		return updateNode(f.NewJsxExpression(dotDotDotToken, expression), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JsxExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.DotDotDotToken) || visit(v, node.Expression)
}

func (node *JsxExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJsxExpression(node, v.visitNode(node.DotDotDotToken), v.visitNode(node.Expression))
}

func (node *JsxExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxExpression(node.DotDotDotToken, node.Expression), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxExpression(node *Node) bool {
	return node.Kind == KindJsxExpression
}

// ──────────────────────────────────────────────────────────────────────
// JsxText
// ──────────────────────────────────────────────────────────────────────

type JsxText struct {
	ExpressionBase
	LiteralLikeNodeBase
	ContainsOnlyTriviaWhiteSpaces bool
}

func (f *NodeFactory) NewJsxText(text string, containsOnlyTriviaWhiteSpaces bool) *Node {
	data := &JsxText{}
	data.Text = text
	data.ContainsOnlyTriviaWhiteSpaces = containsOnlyTriviaWhiteSpaces
	f.textCount++
	return f.newNode(KindJsxText, data)
}

func (node *JsxText) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJsxText(node.Text, node.ContainsOnlyTriviaWhiteSpaces), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJsxText(node *Node) bool {
	return node.Kind == KindJsxText
}

// ──────────────────────────────────────────────────────────────────────
// SyntaxList
// ──────────────────────────────────────────────────────────────────────

type SyntaxList struct {
	NodeBase
	Children []*Node
}

func (f *NodeFactory) NewSyntaxList(children []*Node) *Node {
	data := &SyntaxList{}
	data.Children = children
	return f.newNode(KindSyntaxList, data)
}

func (f *NodeFactory) UpdateSyntaxList(node *SyntaxList, children []*Node) *Node {
	if !core.Same(children, node.Children) {
		return updateNode(f.NewSyntaxList(children), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SyntaxList) ForEachChild(v Visitor) bool {
	return visitNodes(v, node.Children)
}

func (node *SyntaxList) VisitEachChild(v *NodeVisitor) *Node {
	children := core.SameMap(node.Children, func(n *Node) *Node { return v.visitNode(n) })
	return v.Factory.UpdateSyntaxList(node, children)
}

func (node *SyntaxList) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSyntaxList(node.Children), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsSyntaxList(node *Node) bool {
	return node.Kind == KindSyntaxList
}

// ──────────────────────────────────────────────────────────────────────
// JSDoc
// ──────────────────────────────────────────────────────────────────────

type JSDoc struct {
	NodeBase
	Comment *NodeList
	Tags    *NodeList // Optional
}

func (f *NodeFactory) NewJSDoc(comment *NodeList, tags *NodeList) *Node {
	data := f.jsdocArena.New()
	data.Comment = comment
	data.Tags = tags
	return f.newNode(KindJSDoc, data)
}

func (f *NodeFactory) UpdateJSDoc(node *JSDoc, comment *NodeList, tags *NodeList) *Node {
	if comment != node.Comment || tags != node.Tags {
		return updateNode(f.NewJSDoc(comment, tags), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDoc) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.Comment) || visitNodeList(v, node.Tags)
}

func (node *JSDoc) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDoc(node, v.visitNodes(node.Comment), v.visitNodes(node.Tags))
}

func (node *JSDoc) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDoc(node.Comment, node.Tags), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDoc(node *Node) bool {
	return node.Kind == KindJSDoc
}

// ──────────────────────────────────────────────────────────────────────
// JSDocTypeExpression
// ──────────────────────────────────────────────────────────────────────

type JSDocTypeExpression struct {
	TypeNodeBase
	Type *TypeNode
}

func (f *NodeFactory) NewJSDocTypeExpression(typeNode *TypeNode) *Node {
	data := &JSDocTypeExpression{}
	data.Type = typeNode
	return f.newNode(KindJSDocTypeExpression, data)
}

func (f *NodeFactory) UpdateJSDocTypeExpression(node *JSDocTypeExpression, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewJSDocTypeExpression(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocTypeExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *JSDocTypeExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocTypeExpression(node, v.visitNode(node.Type))
}

func (node *JSDocTypeExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocTypeExpression(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocTypeExpression(node *Node) bool {
	return node.Kind == KindJSDocTypeExpression
}

// ──────────────────────────────────────────────────────────────────────
// JSDocNonNullableType
// ──────────────────────────────────────────────────────────────────────

type JSDocNonNullableType struct {
	JSDocTypeBase
	Type *TypeNode
}

func (f *NodeFactory) NewJSDocNonNullableType(typeNode *TypeNode) *Node {
	data := &JSDocNonNullableType{}
	data.Type = typeNode
	return f.newNode(KindJSDocNonNullableType, data)
}

func (f *NodeFactory) UpdateJSDocNonNullableType(node *JSDocNonNullableType, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewJSDocNonNullableType(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocNonNullableType) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *JSDocNonNullableType) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocNonNullableType(node, v.visitNode(node.Type))
}

func (node *JSDocNonNullableType) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocNonNullableType(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocNonNullableType(node *Node) bool {
	return node.Kind == KindJSDocNonNullableType
}

// ──────────────────────────────────────────────────────────────────────
// JSDocNullableType
// ──────────────────────────────────────────────────────────────────────

type JSDocNullableType struct {
	JSDocTypeBase
	Type *TypeNode
}

func (f *NodeFactory) NewJSDocNullableType(typeNode *TypeNode) *Node {
	data := &JSDocNullableType{}
	data.Type = typeNode
	return f.newNode(KindJSDocNullableType, data)
}

func (f *NodeFactory) UpdateJSDocNullableType(node *JSDocNullableType, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewJSDocNullableType(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocNullableType) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *JSDocNullableType) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocNullableType(node, v.visitNode(node.Type))
}

func (node *JSDocNullableType) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocNullableType(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocNullableType(node *Node) bool {
	return node.Kind == KindJSDocNullableType
}

// ──────────────────────────────────────────────────────────────────────
// JSDocAllType
// ──────────────────────────────────────────────────────────────────────

type JSDocAllType struct {
	JSDocTypeBase
}

func (f *NodeFactory) NewJSDocAllType() *Node {
	data := &JSDocAllType{}
	return f.newNode(KindJSDocAllType, data)
}

func (node *JSDocAllType) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocAllType(), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocAllType(node *Node) bool {
	return node.Kind == KindJSDocAllType
}

// ──────────────────────────────────────────────────────────────────────
// JSDocVariadicType
// ──────────────────────────────────────────────────────────────────────

type JSDocVariadicType struct {
	JSDocTypeBase
	Type *TypeNode
}

func (f *NodeFactory) NewJSDocVariadicType(typeNode *TypeNode) *Node {
	data := &JSDocVariadicType{}
	data.Type = typeNode
	return f.newNode(KindJSDocVariadicType, data)
}

func (f *NodeFactory) UpdateJSDocVariadicType(node *JSDocVariadicType, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewJSDocVariadicType(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocVariadicType) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *JSDocVariadicType) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocVariadicType(node, v.visitNode(node.Type))
}

func (node *JSDocVariadicType) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocVariadicType(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocVariadicType(node *Node) bool {
	return node.Kind == KindJSDocVariadicType
}

// ──────────────────────────────────────────────────────────────────────
// JSDocOptionalType
// ──────────────────────────────────────────────────────────────────────

type JSDocOptionalType struct {
	JSDocTypeBase
	Type *TypeNode
}

func (f *NodeFactory) NewJSDocOptionalType(typeNode *TypeNode) *Node {
	data := &JSDocOptionalType{}
	data.Type = typeNode
	return f.newNode(KindJSDocOptionalType, data)
}

func (f *NodeFactory) UpdateJSDocOptionalType(node *JSDocOptionalType, typeNode *TypeNode) *Node {
	if typeNode != node.Type {
		return updateNode(f.NewJSDocOptionalType(typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocOptionalType) ForEachChild(v Visitor) bool {
	return visit(v, node.Type)
}

func (node *JSDocOptionalType) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocOptionalType(node, v.visitNode(node.Type))
}

func (node *JSDocOptionalType) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocOptionalType(node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocOptionalType(node *Node) bool {
	return node.Kind == KindJSDocOptionalType
}

// ──────────────────────────────────────────────────────────────────────
// JSDocTypeTag
// ──────────────────────────────────────────────────────────────────────

type JSDocTypeTag struct {
	JSDocTagBase
	TypeExpression *Node
}

func (f *NodeFactory) NewJSDocTypeTag(tagName *IdentifierNode, typeExpression *Node, comment *NodeList) *Node {
	data := &JSDocTypeTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocTypeTag, data)
}

func (f *NodeFactory) UpdateJSDocTypeTag(node *JSDocTypeTag, tagName *IdentifierNode, typeExpression *Node, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocTypeTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocTypeTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocTypeTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocTypeTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocTypeTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocTypeTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocTypeTag(node *Node) bool {
	return node.Kind == KindJSDocTypeTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocUnknownTag
// ──────────────────────────────────────────────────────────────────────

type JSDocUnknownTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocUnknownTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := f.jsdocUnknownTagArena.New()
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocUnknownTag, data)
}

func (f *NodeFactory) UpdateJSDocUnknownTag(node *JSDocUnknownTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocUnknownTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocUnknownTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocUnknownTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocUnknownTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocUnknownTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocUnknownTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocUnknownTag(node *Node) bool {
	return node.Kind == KindJSDocUnknownTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocTemplateTag
// ──────────────────────────────────────────────────────────────────────

type JSDocTemplateTag struct {
	JSDocTagBase
	Constraint     *Node
	TypeParameters *TypeParameterList
}

func (f *NodeFactory) NewJSDocTemplateTag(tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node {
	data := &JSDocTemplateTag{}
	data.TagName = tagName
	data.Constraint = constraint
	data.TypeParameters = typeParameters
	data.Comment = comment
	return f.newNode(KindJSDocTemplateTag, data)
}

func (f *NodeFactory) UpdateJSDocTemplateTag(node *JSDocTemplateTag, tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node {
	if tagName != node.TagName || constraint != node.Constraint || typeParameters != node.TypeParameters || comment != node.Comment {
		return updateNode(f.NewJSDocTemplateTag(tagName, constraint, typeParameters, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocTemplateTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) ||
		visit(v, node.Constraint) ||
		visitNodeList(v, node.TypeParameters) ||
		visitNodeList(v, node.Comment)
}

func (node *JSDocTemplateTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocTemplateTag(node, v.visitNode(node.TagName), v.visitNode(node.Constraint), v.visitNodes(node.TypeParameters), v.visitNodes(node.Comment))
}

func (node *JSDocTemplateTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocTemplateTag(node.TagName, node.Constraint, node.TypeParameters, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocTemplateTag(node *Node) bool {
	return node.Kind == KindJSDocTemplateTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocReturnTag
// ──────────────────────────────────────────────────────────────────────

type JSDocReturnTag struct {
	JSDocTagBase
	TypeExpression *TypeNode // Optional
}

func (f *NodeFactory) NewJSDocReturnTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocReturnTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocReturnTag, data)
}

func (f *NodeFactory) UpdateJSDocReturnTag(node *JSDocReturnTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocReturnTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocReturnTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocReturnTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocReturnTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocReturnTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocReturnTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocReturnTag(node *Node) bool {
	return node.Kind == KindJSDocReturnTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocPublicTag
// ──────────────────────────────────────────────────────────────────────

type JSDocPublicTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocPublicTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := &JSDocPublicTag{}
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocPublicTag, data)
}

func (f *NodeFactory) UpdateJSDocPublicTag(node *JSDocPublicTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocPublicTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocPublicTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocPublicTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocPublicTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocPublicTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocPublicTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocPublicTag(node *Node) bool {
	return node.Kind == KindJSDocPublicTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocPrivateTag
// ──────────────────────────────────────────────────────────────────────

type JSDocPrivateTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocPrivateTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := &JSDocPrivateTag{}
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocPrivateTag, data)
}

func (f *NodeFactory) UpdateJSDocPrivateTag(node *JSDocPrivateTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocPrivateTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocPrivateTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocPrivateTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocPrivateTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocPrivateTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocPrivateTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocPrivateTag(node *Node) bool {
	return node.Kind == KindJSDocPrivateTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocProtectedTag
// ──────────────────────────────────────────────────────────────────────

type JSDocProtectedTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocProtectedTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := &JSDocProtectedTag{}
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocProtectedTag, data)
}

func (f *NodeFactory) UpdateJSDocProtectedTag(node *JSDocProtectedTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocProtectedTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocProtectedTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocProtectedTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocProtectedTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocProtectedTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocProtectedTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocProtectedTag(node *Node) bool {
	return node.Kind == KindJSDocProtectedTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocReadonlyTag
// ──────────────────────────────────────────────────────────────────────

type JSDocReadonlyTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocReadonlyTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := &JSDocReadonlyTag{}
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocReadonlyTag, data)
}

func (f *NodeFactory) UpdateJSDocReadonlyTag(node *JSDocReadonlyTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocReadonlyTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocReadonlyTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocReadonlyTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocReadonlyTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocReadonlyTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocReadonlyTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocReadonlyTag(node *Node) bool {
	return node.Kind == KindJSDocReadonlyTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocOverrideTag
// ──────────────────────────────────────────────────────────────────────

type JSDocOverrideTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocOverrideTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := &JSDocOverrideTag{}
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocOverrideTag, data)
}

func (f *NodeFactory) UpdateJSDocOverrideTag(node *JSDocOverrideTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocOverrideTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocOverrideTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocOverrideTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocOverrideTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocOverrideTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocOverrideTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocOverrideTag(node *Node) bool {
	return node.Kind == KindJSDocOverrideTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocDeprecatedTag
// ──────────────────────────────────────────────────────────────────────

type JSDocDeprecatedTag struct {
	JSDocTagBase
}

func (f *NodeFactory) NewJSDocDeprecatedTag(tagName *IdentifierNode, comment *NodeList) *Node {
	data := f.jsdocDeprecatedTagArena.New()
	data.TagName = tagName
	data.Comment = comment
	return f.newNode(KindJSDocDeprecatedTag, data)
}

func (f *NodeFactory) UpdateJSDocDeprecatedTag(node *JSDocDeprecatedTag, tagName *IdentifierNode, comment *NodeList) *Node {
	if tagName != node.TagName || comment != node.Comment {
		return updateNode(f.NewJSDocDeprecatedTag(tagName, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocDeprecatedTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visitNodeList(v, node.Comment)
}

func (node *JSDocDeprecatedTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocDeprecatedTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment))
}

func (node *JSDocDeprecatedTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocDeprecatedTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocDeprecatedTag(node *Node) bool {
	return node.Kind == KindJSDocDeprecatedTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocSeeTag
// ──────────────────────────────────────────────────────────────────────

type JSDocSeeTag struct {
	JSDocTagBase
	NameExpression *TypeNode
}

func (f *NodeFactory) NewJSDocSeeTag(tagName *IdentifierNode, nameExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocSeeTag{}
	data.TagName = tagName
	data.NameExpression = nameExpression
	data.Comment = comment
	return f.newNode(KindJSDocSeeTag, data)
}

func (f *NodeFactory) UpdateJSDocSeeTag(node *JSDocSeeTag, tagName *IdentifierNode, nameExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || nameExpression != node.NameExpression || comment != node.Comment {
		return updateNode(f.NewJSDocSeeTag(tagName, nameExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocSeeTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.NameExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocSeeTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocSeeTag(node, v.visitNode(node.TagName), v.visitNode(node.NameExpression), v.visitNodes(node.Comment))
}

func (node *JSDocSeeTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocSeeTag(node.TagName, node.NameExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocSeeTag(node *Node) bool {
	return node.Kind == KindJSDocSeeTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocImplementsTag
// ──────────────────────────────────────────────────────────────────────

type JSDocImplementsTag struct {
	JSDocTagBase
	ClassName *ExpressionWithTypeArgumentsNode
}

func (f *NodeFactory) NewJSDocImplementsTag(tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node {
	data := &JSDocImplementsTag{}
	data.TagName = tagName
	data.ClassName = className
	data.Comment = comment
	return f.newNode(KindJSDocImplementsTag, data)
}

func (f *NodeFactory) UpdateJSDocImplementsTag(node *JSDocImplementsTag, tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node {
	if tagName != node.TagName || className != node.ClassName || comment != node.Comment {
		return updateNode(f.NewJSDocImplementsTag(tagName, className, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocImplementsTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.ClassName) || visitNodeList(v, node.Comment)
}

func (node *JSDocImplementsTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocImplementsTag(node, v.visitNode(node.TagName), v.visitNode(node.ClassName), v.visitNodes(node.Comment))
}

func (node *JSDocImplementsTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocImplementsTag(node.TagName, node.ClassName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocImplementsTag(node *Node) bool {
	return node.Kind == KindJSDocImplementsTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocAugmentsTag
// ──────────────────────────────────────────────────────────────────────

type JSDocAugmentsTag struct {
	JSDocTagBase
	ClassName *ExpressionWithTypeArgumentsNode
}

func (f *NodeFactory) NewJSDocAugmentsTag(tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node {
	data := &JSDocAugmentsTag{}
	data.TagName = tagName
	data.ClassName = className
	data.Comment = comment
	return f.newNode(KindJSDocAugmentsTag, data)
}

func (f *NodeFactory) UpdateJSDocAugmentsTag(node *JSDocAugmentsTag, tagName *IdentifierNode, className *ExpressionWithTypeArgumentsNode, comment *NodeList) *Node {
	if tagName != node.TagName || className != node.ClassName || comment != node.Comment {
		return updateNode(f.NewJSDocAugmentsTag(tagName, className, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocAugmentsTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.ClassName) || visitNodeList(v, node.Comment)
}

func (node *JSDocAugmentsTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocAugmentsTag(node, v.visitNode(node.TagName), v.visitNode(node.ClassName), v.visitNodes(node.Comment))
}

func (node *JSDocAugmentsTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocAugmentsTag(node.TagName, node.ClassName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocAugmentsTag(node *Node) bool {
	return node.Kind == KindJSDocAugmentsTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocSatisfiesTag
// ──────────────────────────────────────────────────────────────────────

type JSDocSatisfiesTag struct {
	JSDocTagBase
	TypeExpression *TypeNode
}

func (f *NodeFactory) NewJSDocSatisfiesTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocSatisfiesTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocSatisfiesTag, data)
}

func (f *NodeFactory) UpdateJSDocSatisfiesTag(node *JSDocSatisfiesTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocSatisfiesTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocSatisfiesTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocSatisfiesTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocSatisfiesTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocSatisfiesTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocSatisfiesTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocSatisfiesTag(node *Node) bool {
	return node.Kind == KindJSDocSatisfiesTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocThrowsTag
// ──────────────────────────────────────────────────────────────────────

type JSDocThrowsTag struct {
	JSDocTagBase
	TypeExpression *TypeNode // Optional
}

func (f *NodeFactory) NewJSDocThrowsTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocThrowsTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocThrowsTag, data)
}

func (f *NodeFactory) UpdateJSDocThrowsTag(node *JSDocThrowsTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocThrowsTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocThrowsTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocThrowsTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocThrowsTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocThrowsTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocThrowsTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocThrowsTag(node *Node) bool {
	return node.Kind == KindJSDocThrowsTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocThisTag
// ──────────────────────────────────────────────────────────────────────

type JSDocThisTag struct {
	JSDocTagBase
	TypeExpression *TypeNode
}

func (f *NodeFactory) NewJSDocThisTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocThisTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocThisTag, data)
}

func (f *NodeFactory) UpdateJSDocThisTag(node *JSDocThisTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocThisTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocThisTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocThisTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocThisTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocThisTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocThisTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocThisTag(node *Node) bool {
	return node.Kind == KindJSDocThisTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocImportTag
// ──────────────────────────────────────────────────────────────────────

type JSDocImportTag struct {
	JSDocTagBase
	ImportClause    *ImportClauseNode // Optional
	ModuleSpecifier *Expression
	Attributes      *ImportAttributesNode // Optional
}

func (f *NodeFactory) NewJSDocImportTag(tagName *IdentifierNode, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode, comment *NodeList) *Node {
	data := &JSDocImportTag{}
	data.TagName = tagName
	data.ImportClause = importClause
	data.ModuleSpecifier = moduleSpecifier
	data.Attributes = attributes
	data.Comment = comment
	return f.newNode(KindJSDocImportTag, data)
}

func (f *NodeFactory) UpdateJSDocImportTag(node *JSDocImportTag, tagName *IdentifierNode, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode, comment *NodeList) *Node {
	if tagName != node.TagName || importClause != node.ImportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes || comment != node.Comment {
		return updateNode(f.NewJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocImportTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) ||
		visit(v, node.ImportClause) ||
		visit(v, node.ModuleSpecifier) ||
		visit(v, node.Attributes) ||
		visitNodeList(v, node.Comment)
}

func (node *JSDocImportTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocImportTag(node, v.visitNode(node.TagName), v.visitNode(node.ImportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes), v.visitNodes(node.Comment))
}

func (node *JSDocImportTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocImportTag(node.TagName, node.ImportClause, node.ModuleSpecifier, node.Attributes, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocImportTag(node *Node) bool {
	return node.Kind == KindJSDocImportTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocCallbackTag
// ──────────────────────────────────────────────────────────────────────

type JSDocCallbackTag struct {
	JSDocTagBase
	TypeExpression *TypeNode
	name           *JSDocFullName // Optional
}

func (f *NodeFactory) NewJSDocCallbackTag(tagName *IdentifierNode, typeExpression *TypeNode, name *JSDocFullName, comment *NodeList) *Node {
	data := &JSDocCallbackTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.name = name
	data.Comment = comment
	return f.newNode(KindJSDocCallbackTag, data)
}

func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *IdentifierNode, typeExpression *TypeNode, name *JSDocFullName, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || name != node.name || comment != node.Comment {
		return updateNode(f.NewJSDocCallbackTag(tagName, typeExpression, name, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocCallbackTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) ||
		visit(v, node.TypeExpression) ||
		visit(v, node.name) ||
		visitNodeList(v, node.Comment)
}

func (node *JSDocCallbackTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocCallbackTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.name), v.visitNodes(node.Comment))
}

func (node *JSDocCallbackTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocCallbackTag(node.TagName, node.TypeExpression, node.name, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocCallbackTag) Name() *DeclarationName {
	return node.name
}

func IsJSDocCallbackTag(node *Node) bool {
	return node.Kind == KindJSDocCallbackTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocOverloadTag
// ──────────────────────────────────────────────────────────────────────

type JSDocOverloadTag struct {
	JSDocTagBase
	TypeExpression *TypeNode
}

func (f *NodeFactory) NewJSDocOverloadTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	data := &JSDocOverloadTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.Comment = comment
	return f.newNode(KindJSDocOverloadTag, data)
}

func (f *NodeFactory) UpdateJSDocOverloadTag(node *JSDocOverloadTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment {
		return updateNode(f.NewJSDocOverloadTag(tagName, typeExpression, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocOverloadTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment)
}

func (node *JSDocOverloadTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocOverloadTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment))
}

func (node *JSDocOverloadTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocOverloadTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocOverloadTag(node *Node) bool {
	return node.Kind == KindJSDocOverloadTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocTypedefTag
// ──────────────────────────────────────────────────────────────────────

type JSDocTypedefTag struct {
	JSDocTagBase
	TypeExpression *Node          // Optional
	name           *JSDocFullName // Optional
}

func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression *Node, name *JSDocFullName, comment *NodeList) *Node {
	data := &JSDocTypedefTag{}
	data.TagName = tagName
	data.TypeExpression = typeExpression
	data.name = name
	data.Comment = comment
	return f.newNode(KindJSDocTypedefTag, data)
}

func (f *NodeFactory) UpdateJSDocTypedefTag(node *JSDocTypedefTag, tagName *IdentifierNode, typeExpression *Node, name *JSDocFullName, comment *NodeList) *Node {
	if tagName != node.TagName || typeExpression != node.TypeExpression || name != node.name || comment != node.Comment {
		return updateNode(f.NewJSDocTypedefTag(tagName, typeExpression, name, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocTypedefTag) ForEachChild(v Visitor) bool {
	return visit(v, node.TagName) ||
		visit(v, node.TypeExpression) ||
		visit(v, node.name) ||
		visitNodeList(v, node.Comment)
}

func (node *JSDocTypedefTag) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocTypedefTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.name), v.visitNodes(node.Comment))
}

func (node *JSDocTypedefTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocTypedefTag(node.TagName, node.TypeExpression, node.name, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocTypedefTag) Name() *DeclarationName {
	return node.name
}

func IsJSDocTypedefTag(node *Node) bool {
	return node.Kind == KindJSDocTypedefTag
}

// ──────────────────────────────────────────────────────────────────────
// JSDocSignature
// ──────────────────────────────────────────────────────────────────────

type JSDocSignature struct {
	JSDocTypeBase
	FunctionLikeBase
}

func (f *NodeFactory) NewJSDocSignature(typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	data := &JSDocSignature{}
	data.TypeParameters = typeParameters
	data.Parameters = parameters
	data.Type = typeNode
	return f.newNode(KindJSDocSignature, data)
}

func (f *NodeFactory) UpdateJSDocSignature(node *JSDocSignature, typeParameters *TypeParameterList, parameters *ParameterList, typeNode *TypeNode) *Node {
	if typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type {
		return updateNode(f.NewJSDocSignature(typeParameters, parameters, typeNode), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocSignature) ForEachChild(v Visitor) bool {
	return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type)
}

func (node *JSDocSignature) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocSignature(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type))
}

func (node *JSDocSignature) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocSignature(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocSignature(node *Node) bool {
	return node.Kind == KindJSDocSignature
}

// ──────────────────────────────────────────────────────────────────────
// JSDocNameReference
// ──────────────────────────────────────────────────────────────────────

type JSDocNameReference struct {
	TypeNodeBase
	name *EntityName
}

func (f *NodeFactory) NewJSDocNameReference(name *EntityName) *Node {
	data := &JSDocNameReference{}
	data.name = name
	return f.newNode(KindJSDocNameReference, data)
}

func (f *NodeFactory) UpdateJSDocNameReference(node *JSDocNameReference, name *EntityName) *Node {
	if name != node.name {
		return updateNode(f.NewJSDocNameReference(name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocNameReference) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *JSDocNameReference) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocNameReference(node, v.visitNode(node.name))
}

func (node *JSDocNameReference) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocNameReference(node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocNameReference) Name() *DeclarationName {
	return node.name
}

func IsJSDocNameReference(node *Node) bool {
	return node.Kind == KindJSDocNameReference
}

// ──────────────────────────────────────────────────────────────────────
// SourceFile
// ──────────────────────────────────────────────────────────────────────

func IsSourceFile(node *Node) bool {
	return node.Kind == KindSourceFile
}

// Struct and factory methods hand-written in ./ast.go
// ──────────────────────────────────────────────────────────────────────
// ModuleDeclaration
// ──────────────────────────────────────────────────────────────────────

type ModuleDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	LocalsContainerBase
	BodyBase
	CompositeBase
	Keyword Kind
	name    *ModuleName
}

func (f *NodeFactory) NewModuleDeclaration(modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node {
	data := &ModuleDeclaration{}
	data.modifiers = modifiers
	data.Keyword = keyword
	data.name = name
	data.Body = body
	return f.newNode(KindModuleDeclaration, data)
}

func (f *NodeFactory) UpdateModuleDeclaration(node *ModuleDeclaration, modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node {
	if modifiers != node.modifiers || keyword != node.Keyword || name != node.name || body != node.Body {
		return updateNode(f.NewModuleDeclaration(modifiers, keyword, name, body), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ModuleDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Body)
}

func (node *ModuleDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateModuleDeclaration(node, v.visitModifiers(node.modifiers), node.Keyword, v.visitNode(node.name), v.visitNode(node.Body))
}

func (node *ModuleDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewModuleDeclaration(node.Modifiers(), node.Keyword, node.name, node.Body), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ModuleDeclaration) Name() *DeclarationName {
	return node.name
}

func IsModuleDeclaration(node *Node) bool {
	return node.Kind == KindModuleDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ImportEqualsDeclaration
// ──────────────────────────────────────────────────────────────────────

type ImportEqualsDeclaration struct {
	DeclarationBase
	StatementBase
	ExportableBase
	ModifiersBase
	CompositeBase
	IsTypeOnly      bool
	name            *IdentifierNode
	ModuleReference *ModuleReference
}

func (f *NodeFactory) NewImportEqualsDeclaration(modifiers *ModifierList, isTypeOnly bool, name *IdentifierNode, moduleReference *ModuleReference) *Node {
	data := &ImportEqualsDeclaration{}
	data.modifiers = modifiers
	data.IsTypeOnly = isTypeOnly
	data.name = name
	data.ModuleReference = moduleReference
	return f.newNode(KindImportEqualsDeclaration, data)
}

func (f *NodeFactory) UpdateImportEqualsDeclaration(node *ImportEqualsDeclaration, modifiers *ModifierList, isTypeOnly bool, name *IdentifierNode, moduleReference *ModuleReference) *Node {
	if modifiers != node.modifiers || isTypeOnly != node.IsTypeOnly || name != node.name || moduleReference != node.ModuleReference {
		return updateNode(f.NewImportEqualsDeclaration(modifiers, isTypeOnly, name, moduleReference), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportEqualsDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.ModuleReference)
}

func (node *ImportEqualsDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportEqualsDeclaration(node, v.visitModifiers(node.modifiers), node.IsTypeOnly, v.visitNode(node.name), v.visitNode(node.ModuleReference))
}

func (node *ImportEqualsDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportEqualsDeclaration(node.Modifiers(), node.IsTypeOnly, node.name, node.ModuleReference), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportEqualsDeclaration) Name() *DeclarationName {
	return node.name
}

func IsImportEqualsDeclaration(node *Node) bool {
	return node.Kind == KindImportEqualsDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ExportDeclaration
// ──────────────────────────────────────────────────────────────────────

type ExportDeclaration struct {
	DeclarationBase
	StatementBase
	ModifiersBase
	CompositeBase
	IsTypeOnly      bool
	ExportClause    *NamedExportBindings  // Optional
	ModuleSpecifier *Expression           // Optional
	Attributes      *ImportAttributesNode // Optional
}

func (f *NodeFactory) NewExportDeclaration(modifiers *ModifierList, isTypeOnly bool, exportClause *NamedExportBindings, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
	data := &ExportDeclaration{}
	data.modifiers = modifiers
	data.IsTypeOnly = isTypeOnly
	data.ExportClause = exportClause
	data.ModuleSpecifier = moduleSpecifier
	data.Attributes = attributes
	return f.newNode(KindExportDeclaration, data)
}

func (f *NodeFactory) UpdateExportDeclaration(node *ExportDeclaration, modifiers *ModifierList, isTypeOnly bool, exportClause *NamedExportBindings, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node {
	if modifiers != node.modifiers || isTypeOnly != node.IsTypeOnly || exportClause != node.ExportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes {
		return updateNode(f.NewExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, attributes), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ExportDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.ExportClause) ||
		visit(v, node.ModuleSpecifier) ||
		visit(v, node.Attributes)
}

func (node *ExportDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateExportDeclaration(node, v.visitModifiers(node.modifiers), node.IsTypeOnly, v.visitNode(node.ExportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes))
}

func (node *ExportDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewExportDeclaration(node.Modifiers(), node.IsTypeOnly, node.ExportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsExportDeclaration(node *Node) bool {
	return node.Kind == KindExportDeclaration
}

// ──────────────────────────────────────────────────────────────────────
// ImportTypeNode
// ──────────────────────────────────────────────────────────────────────

type ImportTypeNode struct {
	NodeWithTypeArgumentsBase
	IsTypeOf   bool
	Argument   *TypeNode
	Attributes *ImportAttributesNode // Optional
	Qualifier  *EntityName           // Optional
}

func (f *NodeFactory) NewImportTypeNode(isTypeOf bool, argument *TypeNode, attributes *ImportAttributesNode, qualifier *EntityName, typeArguments *TypeList) *Node {
	data := &ImportTypeNode{}
	data.IsTypeOf = isTypeOf
	data.Argument = argument
	data.Attributes = attributes
	data.Qualifier = qualifier
	data.TypeArguments = typeArguments
	return f.newNode(KindImportType, data)
}

func (f *NodeFactory) UpdateImportTypeNode(node *ImportTypeNode, isTypeOf bool, argument *TypeNode, attributes *ImportAttributesNode, qualifier *EntityName, typeArguments *TypeList) *Node {
	if isTypeOf != node.IsTypeOf || argument != node.Argument || attributes != node.Attributes || qualifier != node.Qualifier || typeArguments != node.TypeArguments {
		return updateNode(f.NewImportTypeNode(isTypeOf, argument, attributes, qualifier, typeArguments), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportTypeNode) ForEachChild(v Visitor) bool {
	return visit(v, node.Argument) ||
		visit(v, node.Attributes) ||
		visit(v, node.Qualifier) ||
		visitNodeList(v, node.TypeArguments)
}

func (node *ImportTypeNode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportTypeNode(node, node.IsTypeOf, v.visitNode(node.Argument), v.visitNode(node.Attributes), v.visitNode(node.Qualifier), v.visitNodes(node.TypeArguments))
}

func (node *ImportTypeNode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportTypeNode(node.IsTypeOf, node.Argument, node.Attributes, node.Qualifier, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsImportTypeNode(node *Node) bool {
	return node.Kind == KindImportType
}

// ──────────────────────────────────────────────────────────────────────
// ImportClause
// ──────────────────────────────────────────────────────────────────────

type ImportClause struct {
	NodeBase
	DeclarationBase
	ExportableBase
	CompositeBase
	PhaseModifier ImportPhaseModifierSyntaxKind // Optional
	name          *IdentifierNode               // Optional
	NamedBindings *NamedImportBindings          // Optional
}

func (f *NodeFactory) NewImportClause(phaseModifier ImportPhaseModifierSyntaxKind, name *IdentifierNode, namedBindings *NamedImportBindings) *Node {
	data := &ImportClause{}
	data.PhaseModifier = phaseModifier
	data.name = name
	data.NamedBindings = namedBindings
	return f.newNode(KindImportClause, data)
}

func (f *NodeFactory) UpdateImportClause(node *ImportClause, phaseModifier ImportPhaseModifierSyntaxKind, name *IdentifierNode, namedBindings *NamedImportBindings) *Node {
	if phaseModifier != node.PhaseModifier || name != node.name || namedBindings != node.NamedBindings {
		return updateNode(f.NewImportClause(phaseModifier, name, namedBindings), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportClause) ForEachChild(v Visitor) bool {
	return visit(v, node.name) || visit(v, node.NamedBindings)
}

func (node *ImportClause) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportClause(node, node.PhaseModifier, v.visitNode(node.name), v.visitNode(node.NamedBindings))
}

func (node *ImportClause) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportClause(node.PhaseModifier, node.name, node.NamedBindings), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportClause) Name() *DeclarationName {
	return node.name
}

func IsImportClause(node *Node) bool {
	return node.Kind == KindImportClause
}

// ──────────────────────────────────────────────────────────────────────
// ImportSpecifier
// ──────────────────────────────────────────────────────────────────────

type ImportSpecifier struct {
	NodeBase
	DeclarationBase
	ExportableBase
	CompositeBase
	IsTypeOnly   bool
	PropertyName *ModuleExportName // Optional
	name         *IdentifierNode
}

func (f *NodeFactory) NewImportSpecifier(isTypeOnly bool, propertyName *ModuleExportName, name *IdentifierNode) *Node {
	data := f.importSpecifierArena.New()
	data.IsTypeOnly = isTypeOnly
	data.PropertyName = propertyName
	data.name = name
	return f.newNode(KindImportSpecifier, data)
}

func (f *NodeFactory) UpdateImportSpecifier(node *ImportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *IdentifierNode) *Node {
	if isTypeOnly != node.IsTypeOnly || propertyName != node.PropertyName || name != node.name {
		return updateNode(f.NewImportSpecifier(isTypeOnly, propertyName, name), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *ImportSpecifier) ForEachChild(v Visitor) bool {
	return visit(v, node.PropertyName) || visit(v, node.name)
}

func (node *ImportSpecifier) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateImportSpecifier(node, node.IsTypeOnly, v.visitNode(node.PropertyName), v.visitNode(node.name))
}

func (node *ImportSpecifier) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewImportSpecifier(node.IsTypeOnly, node.PropertyName, node.name), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *ImportSpecifier) Name() *DeclarationName {
	return node.name
}

func IsImportSpecifier(node *Node) bool {
	return node.Kind == KindImportSpecifier
}

// ──────────────────────────────────────────────────────────────────────
// JSDocText
// ──────────────────────────────────────────────────────────────────────

type JSDocText struct {
	JSDocCommentBase
}

func (f *NodeFactory) NewJSDocText(text []string) *Node {
	data := f.jsdocTextArena.New()
	data.text = text
	f.textCount++
	return f.newNode(KindJSDocText, data)
}

func (node *JSDocText) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocText(node.text), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocText(node *Node) bool {
	return node.Kind == KindJSDocText
}

// ──────────────────────────────────────────────────────────────────────
// JSDocLink
// ──────────────────────────────────────────────────────────────────────

type JSDocLink struct {
	JSDocCommentBase
	name *EntityName // Optional
}

func (f *NodeFactory) NewJSDocLink(name *EntityName, text []string) *Node {
	data := &JSDocLink{}
	data.name = name
	data.text = text
	f.textCount++
	return f.newNode(KindJSDocLink, data)
}

func (f *NodeFactory) UpdateJSDocLink(node *JSDocLink, name *EntityName, text []string) *Node {
	if name != node.name || !core.Same(text, node.text) {
		return updateNode(f.NewJSDocLink(name, text), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocLink) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *JSDocLink) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocLink(node, v.visitNode(node.name), node.text)
}

func (node *JSDocLink) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocLink(node.name, node.text), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocLink) Name() *DeclarationName {
	return node.name
}

func IsJSDocLink(node *Node) bool {
	return node.Kind == KindJSDocLink
}

// ──────────────────────────────────────────────────────────────────────
// JSDocLinkPlain
// ──────────────────────────────────────────────────────────────────────

type JSDocLinkPlain struct {
	JSDocCommentBase
	name *EntityName // Optional
}

func (f *NodeFactory) NewJSDocLinkPlain(name *EntityName, text []string) *Node {
	data := &JSDocLinkPlain{}
	data.name = name
	data.text = text
	f.textCount++
	return f.newNode(KindJSDocLinkPlain, data)
}

func (f *NodeFactory) UpdateJSDocLinkPlain(node *JSDocLinkPlain, name *EntityName, text []string) *Node {
	if name != node.name || !core.Same(text, node.text) {
		return updateNode(f.NewJSDocLinkPlain(name, text), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocLinkPlain) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *JSDocLinkPlain) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocLinkPlain(node, v.visitNode(node.name), node.text)
}

func (node *JSDocLinkPlain) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocLinkPlain(node.name, node.text), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocLinkPlain) Name() *DeclarationName {
	return node.name
}

func IsJSDocLinkPlain(node *Node) bool {
	return node.Kind == KindJSDocLinkPlain
}

// ──────────────────────────────────────────────────────────────────────
// JSDocLinkCode
// ──────────────────────────────────────────────────────────────────────

type JSDocLinkCode struct {
	JSDocCommentBase
	name *EntityName // Optional
}

func (f *NodeFactory) NewJSDocLinkCode(name *EntityName, text []string) *Node {
	data := &JSDocLinkCode{}
	data.name = name
	data.text = text
	f.textCount++
	return f.newNode(KindJSDocLinkCode, data)
}

func (f *NodeFactory) UpdateJSDocLinkCode(node *JSDocLinkCode, name *EntityName, text []string) *Node {
	if name != node.name || !core.Same(text, node.text) {
		return updateNode(f.NewJSDocLinkCode(name, text), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocLinkCode) ForEachChild(v Visitor) bool {
	return visit(v, node.name)
}

func (node *JSDocLinkCode) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateJSDocLinkCode(node, v.visitNode(node.name), node.text)
}

func (node *JSDocLinkCode) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocLinkCode(node.name, node.text), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocLinkCode) Name() *DeclarationName {
	return node.name
}

func IsJSDocLinkCode(node *Node) bool {
	return node.Kind == KindJSDocLinkCode
}

// ──────────────────────────────────────────────────────────────────────
// TypeParameterDeclaration
// ──────────────────────────────────────────────────────────────────────

type TypeParameterDeclaration struct {
	NodeBase
	DeclarationBase
	ModifiersBase
	TypeSyntaxBase
	name        *IdentifierNode
	Constraint  *TypeNode   // Optional
	Expression  *Expression // Optional
	DefaultType *TypeNode   // Optional
}

func (f *NodeFactory) NewTypeParameterDeclaration(modifiers *ModifierList, name *IdentifierNode, constraint *TypeNode, expression *Expression, defaultType *TypeNode) *Node {
	data := f.typeParameterDeclarationArena.New()
	data.modifiers = modifiers
	data.name = name
	data.Constraint = constraint
	data.Expression = expression
	data.DefaultType = defaultType
	return f.newNode(KindTypeParameter, data)
}

func (f *NodeFactory) UpdateTypeParameterDeclaration(node *TypeParameterDeclaration, modifiers *ModifierList, name *IdentifierNode, constraint *TypeNode, expression *Expression, defaultType *TypeNode) *Node {
	if modifiers != node.modifiers || name != node.name || constraint != node.Constraint || expression != node.Expression || defaultType != node.DefaultType {
		return updateNode(f.NewTypeParameterDeclaration(modifiers, name, constraint, expression, defaultType), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *TypeParameterDeclaration) ForEachChild(v Visitor) bool {
	return visitModifiers(v, node.modifiers) ||
		visit(v, node.name) ||
		visit(v, node.Constraint) ||
		visit(v, node.Expression) ||
		visit(v, node.DefaultType)
}

func (node *TypeParameterDeclaration) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateTypeParameterDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.Constraint), v.visitNode(node.Expression), v.visitNode(node.DefaultType))
}

func (node *TypeParameterDeclaration) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewTypeParameterDeclaration(node.Modifiers(), node.name, node.Constraint, node.Expression, node.DefaultType), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *TypeParameterDeclaration) Name() *DeclarationName {
	return node.name
}

func IsTypeParameterDeclaration(node *Node) bool {
	return node.Kind == KindTypeParameter
}

// ──────────────────────────────────────────────────────────────────────
// SyntheticReferenceExpression
// ──────────────────────────────────────────────────────────────────────

type SyntheticReferenceExpression struct {
	ExpressionBase
	Expression *Expression
	ThisArg    *Expression
}

func (f *NodeFactory) NewSyntheticReferenceExpression(expression *Expression, thisArg *Expression) *Node {
	data := &SyntheticReferenceExpression{}
	data.Expression = expression
	data.ThisArg = thisArg
	return f.newNode(KindSyntheticReferenceExpression, data)
}

func (f *NodeFactory) UpdateSyntheticReferenceExpression(node *SyntheticReferenceExpression, expression *Expression, thisArg *Expression) *Node {
	if expression != node.Expression || thisArg != node.ThisArg {
		return updateNode(f.NewSyntheticReferenceExpression(expression, thisArg), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *SyntheticReferenceExpression) ForEachChild(v Visitor) bool {
	return visit(v, node.Expression) || visit(v, node.ThisArg)
}

func (node *SyntheticReferenceExpression) VisitEachChild(v *NodeVisitor) *Node {
	return v.Factory.UpdateSyntheticReferenceExpression(node, v.visitNode(node.Expression), v.visitNode(node.ThisArg))
}

func (node *SyntheticReferenceExpression) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewSyntheticReferenceExpression(node.Expression, node.ThisArg), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *SyntheticReferenceExpression) computeSubtreeFacts() SubtreeFacts {
	return propagateSubtreeFacts(node.Expression) |
		propagateSubtreeFacts(node.ThisArg)
}

func IsSyntheticReferenceExpression(node *Node) bool {
	return node.Kind == KindSyntheticReferenceExpression
}

// ──────────────────────────────────────────────────────────────────────
// JSDocTypeLiteral
// ──────────────────────────────────────────────────────────────────────

type JSDocTypeLiteral struct {
	JSDocTypeBase
	DeclarationBase
	JSDocPropertyTags []*Node // Optional
	IsArrayType       bool
}

func (f *NodeFactory) NewJSDocTypeLiteral(jsdocPropertyTags []*Node, isArrayType bool) *Node {
	data := &JSDocTypeLiteral{}
	data.JSDocPropertyTags = jsdocPropertyTags
	data.IsArrayType = isArrayType
	return f.newNode(KindJSDocTypeLiteral, data)
}

func (f *NodeFactory) UpdateJSDocTypeLiteral(node *JSDocTypeLiteral, jsdocPropertyTags []*Node, isArrayType bool) *Node {
	if !core.Same(jsdocPropertyTags, node.JSDocPropertyTags) || isArrayType != node.IsArrayType {
		return updateNode(f.NewJSDocTypeLiteral(jsdocPropertyTags, isArrayType), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocTypeLiteral) ForEachChild(v Visitor) bool {
	return visitNodes(v, node.JSDocPropertyTags)
}

func (node *JSDocTypeLiteral) VisitEachChild(v *NodeVisitor) *Node {
	jsdocPropertyTags := core.SameMap(node.JSDocPropertyTags, func(n *Node) *Node { return v.visitNode(n) })
	return v.Factory.UpdateJSDocTypeLiteral(node, jsdocPropertyTags, node.IsArrayType)
}

func (node *JSDocTypeLiteral) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocTypeLiteral(node.JSDocPropertyTags, node.IsArrayType), node.AsNode(), f.AsNodeFactory().hooks)
}

func IsJSDocTypeLiteral(node *Node) bool {
	return node.Kind == KindJSDocTypeLiteral
}

// ──────────────────────────────────────────────────────────────────────
// JSDocParameterOrPropertyTag
// ──────────────────────────────────────────────────────────────────────

type JSDocParameterOrPropertyTag struct {
	JSDocTagBase
	name           *EntityName
	IsBracketed    bool
	TypeExpression *TypeNode // Optional
	IsNameFirst    bool
}

func (f *NodeFactory) NewJSDocParameterOrPropertyTag(kind Kind, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node {
	data := &JSDocParameterOrPropertyTag{}
	data.TagName = tagName
	data.name = name
	data.IsBracketed = isBracketed
	data.TypeExpression = typeExpression
	data.IsNameFirst = isNameFirst
	data.Comment = comment
	return f.newNode(kind, data)
}

func (f *NodeFactory) UpdateJSDocParameterOrPropertyTag(node *JSDocParameterOrPropertyTag, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node {
	if tagName != node.TagName || name != node.name || isBracketed != node.IsBracketed || typeExpression != node.TypeExpression || isNameFirst != node.IsNameFirst || comment != node.Comment {
		return updateNode(f.NewJSDocParameterOrPropertyTag(node.Kind, tagName, name, isBracketed, typeExpression, isNameFirst, comment), node.AsNode(), f.hooks)
	}
	return node.AsNode()
}

func (node *JSDocParameterOrPropertyTag) ForEachChild(v Visitor) bool {
	return forEachChild_JSDocParameterOrPropertyTag(node, v)
}

func (node *JSDocParameterOrPropertyTag) VisitEachChild(v *NodeVisitor) *Node {
	return visitEachChild_JSDocParameterOrPropertyTag(node, v)
}

func (node *JSDocParameterOrPropertyTag) Clone(f NodeFactoryCoercible) *Node {
	return cloneNode(f.AsNodeFactory().NewJSDocParameterOrPropertyTag(node.Kind, node.TagName, node.name, node.IsBracketed, node.TypeExpression, node.IsNameFirst, node.Comment), node.AsNode(), f.AsNodeFactory().hooks)
}

func (node *JSDocParameterOrPropertyTag) Name() *DeclarationName {
	return node.name
}

func IsJSDocParameterTag(node *Node) bool {
	return node.Kind == KindJSDocParameterTag
}

func IsJSDocPropertyTag(node *Node) bool {
	return node.Kind == KindJSDocPropertyTag
}

// ──────────────────────────────────────────────────────────────────────
// ForEachChild dispatch
// ──────────────────────────────────────────────────────────────────────

func (n *Node) ForEachChild(v Visitor) bool {
	switch n.Kind {
	case KindQualifiedName:
		return n.data.(*QualifiedName).ForEachChild(v)
	case KindComputedPropertyName:
		return n.data.(*ComputedPropertyName).ForEachChild(v)
	case KindDecorator:
		return n.data.(*Decorator).ForEachChild(v)
	case KindIfStatement:
		return n.data.(*IfStatement).ForEachChild(v)
	case KindDoStatement:
		return n.data.(*DoStatement).ForEachChild(v)
	case KindWhileStatement:
		return n.data.(*WhileStatement).ForEachChild(v)
	case KindForStatement:
		return n.data.(*ForStatement).ForEachChild(v)
	case KindForInStatement, KindForOfStatement:
		return n.data.(*ForInOrOfStatement).ForEachChild(v)
	case KindBreakStatement:
		return n.data.(*BreakStatement).ForEachChild(v)
	case KindContinueStatement:
		return n.data.(*ContinueStatement).ForEachChild(v)
	case KindReturnStatement:
		return n.data.(*ReturnStatement).ForEachChild(v)
	case KindWithStatement:
		return n.data.(*WithStatement).ForEachChild(v)
	case KindSwitchStatement:
		return n.data.(*SwitchStatement).ForEachChild(v)
	case KindCaseBlock:
		return n.data.(*CaseBlock).ForEachChild(v)
	case KindCaseClause, KindDefaultClause:
		return n.data.(*CaseOrDefaultClause).ForEachChild(v)
	case KindThrowStatement:
		return n.data.(*ThrowStatement).ForEachChild(v)
	case KindTryStatement:
		return n.data.(*TryStatement).ForEachChild(v)
	case KindCatchClause:
		return n.data.(*CatchClause).ForEachChild(v)
	case KindLabeledStatement:
		return n.data.(*LabeledStatement).ForEachChild(v)
	case KindExpressionStatement:
		return n.data.(*ExpressionStatement).ForEachChild(v)
	case KindBlock:
		return n.data.(*Block).ForEachChild(v)
	case KindVariableStatement:
		return n.data.(*VariableStatement).ForEachChild(v)
	case KindVariableDeclaration:
		return n.data.(*VariableDeclaration).ForEachChild(v)
	case KindVariableDeclarationList:
		return n.data.(*VariableDeclarationList).ForEachChild(v)
	case KindObjectBindingPattern, KindArrayBindingPattern:
		return n.data.(*BindingPattern).ForEachChild(v)
	case KindParameter:
		return n.data.(*ParameterDeclaration).ForEachChild(v)
	case KindBindingElement:
		return n.data.(*BindingElement).ForEachChild(v)
	case KindMissingDeclaration:
		return n.data.(*MissingDeclaration).ForEachChild(v)
	case KindFunctionDeclaration:
		return n.data.(*FunctionDeclaration).ForEachChild(v)
	case KindClassDeclaration:
		return n.data.(*ClassDeclaration).ForEachChild(v)
	case KindClassExpression:
		return n.data.(*ClassExpression).ForEachChild(v)
	case KindHeritageClause:
		return n.data.(*HeritageClause).ForEachChild(v)
	case KindInterfaceDeclaration:
		return n.data.(*InterfaceDeclaration).ForEachChild(v)
	case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration:
		return n.data.(*TypeAliasDeclaration).ForEachChild(v)
	case KindEnumMember:
		return n.data.(*EnumMember).ForEachChild(v)
	case KindEnumDeclaration:
		return n.data.(*EnumDeclaration).ForEachChild(v)
	case KindModuleBlock:
		return n.data.(*ModuleBlock).ForEachChild(v)
	case KindImportDeclaration, KindJSImportDeclaration:
		return n.data.(*ImportDeclaration).ForEachChild(v)
	case KindExternalModuleReference:
		return n.data.(*ExternalModuleReference).ForEachChild(v)
	case KindNamespaceImport:
		return n.data.(*NamespaceImport).ForEachChild(v)
	case KindNamedImports:
		return n.data.(*NamedImports).ForEachChild(v)
	case KindExportAssignment:
		return n.data.(*ExportAssignment).ForEachChild(v)
	case KindNamespaceExportDeclaration:
		return n.data.(*NamespaceExportDeclaration).ForEachChild(v)
	case KindNamespaceExport:
		return n.data.(*NamespaceExport).ForEachChild(v)
	case KindNamedExports:
		return n.data.(*NamedExports).ForEachChild(v)
	case KindExportSpecifier:
		return n.data.(*ExportSpecifier).ForEachChild(v)
	case KindCallSignature:
		return n.data.(*CallSignatureDeclaration).ForEachChild(v)
	case KindConstructSignature:
		return n.data.(*ConstructSignatureDeclaration).ForEachChild(v)
	case KindConstructor:
		return n.data.(*ConstructorDeclaration).ForEachChild(v)
	case KindGetAccessor:
		return n.data.(*GetAccessorDeclaration).ForEachChild(v)
	case KindSetAccessor:
		return n.data.(*SetAccessorDeclaration).ForEachChild(v)
	case KindIndexSignature:
		return n.data.(*IndexSignatureDeclaration).ForEachChild(v)
	case KindMethodSignature:
		return n.data.(*MethodSignatureDeclaration).ForEachChild(v)
	case KindMethodDeclaration:
		return n.data.(*MethodDeclaration).ForEachChild(v)
	case KindPropertySignature:
		return n.data.(*PropertySignatureDeclaration).ForEachChild(v)
	case KindPropertyDeclaration:
		return n.data.(*PropertyDeclaration).ForEachChild(v)
	case KindClassStaticBlockDeclaration:
		return n.data.(*ClassStaticBlockDeclaration).ForEachChild(v)
	case KindBinaryExpression:
		return n.data.(*BinaryExpression).ForEachChild(v)
	case KindPrefixUnaryExpression:
		return n.data.(*PrefixUnaryExpression).ForEachChild(v)
	case KindPostfixUnaryExpression:
		return n.data.(*PostfixUnaryExpression).ForEachChild(v)
	case KindYieldExpression:
		return n.data.(*YieldExpression).ForEachChild(v)
	case KindArrowFunction:
		return n.data.(*ArrowFunction).ForEachChild(v)
	case KindFunctionExpression:
		return n.data.(*FunctionExpression).ForEachChild(v)
	case KindAsExpression:
		return n.data.(*AsExpression).ForEachChild(v)
	case KindSatisfiesExpression:
		return n.data.(*SatisfiesExpression).ForEachChild(v)
	case KindConditionalExpression:
		return n.data.(*ConditionalExpression).ForEachChild(v)
	case KindPropertyAccessExpression:
		return n.data.(*PropertyAccessExpression).ForEachChild(v)
	case KindElementAccessExpression:
		return n.data.(*ElementAccessExpression).ForEachChild(v)
	case KindCallExpression:
		return n.data.(*CallExpression).ForEachChild(v)
	case KindNewExpression:
		return n.data.(*NewExpression).ForEachChild(v)
	case KindMetaProperty:
		return n.data.(*MetaProperty).ForEachChild(v)
	case KindNonNullExpression:
		return n.data.(*NonNullExpression).ForEachChild(v)
	case KindSpreadElement:
		return n.data.(*SpreadElement).ForEachChild(v)
	case KindTemplateExpression:
		return n.data.(*TemplateExpression).ForEachChild(v)
	case KindTemplateSpan:
		return n.data.(*TemplateSpan).ForEachChild(v)
	case KindTaggedTemplateExpression:
		return n.data.(*TaggedTemplateExpression).ForEachChild(v)
	case KindParenthesizedExpression:
		return n.data.(*ParenthesizedExpression).ForEachChild(v)
	case KindArrayLiteralExpression:
		return n.data.(*ArrayLiteralExpression).ForEachChild(v)
	case KindObjectLiteralExpression:
		return n.data.(*ObjectLiteralExpression).ForEachChild(v)
	case KindSpreadAssignment:
		return n.data.(*SpreadAssignment).ForEachChild(v)
	case KindPropertyAssignment:
		return n.data.(*PropertyAssignment).ForEachChild(v)
	case KindShorthandPropertyAssignment:
		return n.data.(*ShorthandPropertyAssignment).ForEachChild(v)
	case KindDeleteExpression:
		return n.data.(*DeleteExpression).ForEachChild(v)
	case KindTypeOfExpression:
		return n.data.(*TypeOfExpression).ForEachChild(v)
	case KindVoidExpression:
		return n.data.(*VoidExpression).ForEachChild(v)
	case KindAwaitExpression:
		return n.data.(*AwaitExpression).ForEachChild(v)
	case KindTypeAssertionExpression:
		return n.data.(*TypeAssertion).ForEachChild(v)
	case KindUnionType:
		return n.data.(*UnionTypeNode).ForEachChild(v)
	case KindIntersectionType:
		return n.data.(*IntersectionTypeNode).ForEachChild(v)
	case KindConditionalType:
		return n.data.(*ConditionalTypeNode).ForEachChild(v)
	case KindTypeOperator:
		return n.data.(*TypeOperatorNode).ForEachChild(v)
	case KindInferType:
		return n.data.(*InferTypeNode).ForEachChild(v)
	case KindArrayType:
		return n.data.(*ArrayTypeNode).ForEachChild(v)
	case KindIndexedAccessType:
		return n.data.(*IndexedAccessTypeNode).ForEachChild(v)
	case KindTypeReference:
		return n.data.(*TypeReferenceNode).ForEachChild(v)
	case KindExpressionWithTypeArguments:
		return n.data.(*ExpressionWithTypeArguments).ForEachChild(v)
	case KindLiteralType:
		return n.data.(*LiteralTypeNode).ForEachChild(v)
	case KindTypePredicate:
		return n.data.(*TypePredicateNode).ForEachChild(v)
	case KindImportAttribute:
		return n.data.(*ImportAttribute).ForEachChild(v)
	case KindImportAttributes:
		return n.data.(*ImportAttributes).ForEachChild(v)
	case KindTypeQuery:
		return n.data.(*TypeQueryNode).ForEachChild(v)
	case KindMappedType:
		return n.data.(*MappedTypeNode).ForEachChild(v)
	case KindTypeLiteral:
		return n.data.(*TypeLiteralNode).ForEachChild(v)
	case KindTupleType:
		return n.data.(*TupleTypeNode).ForEachChild(v)
	case KindNamedTupleMember:
		return n.data.(*NamedTupleMember).ForEachChild(v)
	case KindOptionalType:
		return n.data.(*OptionalTypeNode).ForEachChild(v)
	case KindRestType:
		return n.data.(*RestTypeNode).ForEachChild(v)
	case KindParenthesizedType:
		return n.data.(*ParenthesizedTypeNode).ForEachChild(v)
	case KindFunctionType:
		return n.data.(*FunctionTypeNode).ForEachChild(v)
	case KindConstructorType:
		return n.data.(*ConstructorTypeNode).ForEachChild(v)
	case KindTemplateLiteralType:
		return n.data.(*TemplateLiteralTypeNode).ForEachChild(v)
	case KindTemplateLiteralTypeSpan:
		return n.data.(*TemplateLiteralTypeSpan).ForEachChild(v)
	case KindSyntheticExpression:
		return n.data.(*SyntheticExpression).ForEachChild(v)
	case KindPartiallyEmittedExpression:
		return n.data.(*PartiallyEmittedExpression).ForEachChild(v)
	case KindJsxElement:
		return n.data.(*JsxElement).ForEachChild(v)
	case KindJsxAttributes:
		return n.data.(*JsxAttributes).ForEachChild(v)
	case KindJsxNamespacedName:
		return n.data.(*JsxNamespacedName).ForEachChild(v)
	case KindJsxOpeningElement:
		return n.data.(*JsxOpeningElement).ForEachChild(v)
	case KindJsxSelfClosingElement:
		return n.data.(*JsxSelfClosingElement).ForEachChild(v)
	case KindJsxFragment:
		return n.data.(*JsxFragment).ForEachChild(v)
	case KindJsxAttribute:
		return n.data.(*JsxAttribute).ForEachChild(v)
	case KindJsxSpreadAttribute:
		return n.data.(*JsxSpreadAttribute).ForEachChild(v)
	case KindJsxClosingElement:
		return n.data.(*JsxClosingElement).ForEachChild(v)
	case KindJsxExpression:
		return n.data.(*JsxExpression).ForEachChild(v)
	case KindSyntaxList:
		return n.data.(*SyntaxList).ForEachChild(v)
	case KindJSDoc:
		return n.data.(*JSDoc).ForEachChild(v)
	case KindJSDocTypeExpression:
		return n.data.(*JSDocTypeExpression).ForEachChild(v)
	case KindJSDocNonNullableType:
		return n.data.(*JSDocNonNullableType).ForEachChild(v)
	case KindJSDocNullableType:
		return n.data.(*JSDocNullableType).ForEachChild(v)
	case KindJSDocVariadicType:
		return n.data.(*JSDocVariadicType).ForEachChild(v)
	case KindJSDocOptionalType:
		return n.data.(*JSDocOptionalType).ForEachChild(v)
	case KindJSDocTypeTag:
		return n.data.(*JSDocTypeTag).ForEachChild(v)
	case KindJSDocUnknownTag:
		return n.data.(*JSDocUnknownTag).ForEachChild(v)
	case KindJSDocTemplateTag:
		return n.data.(*JSDocTemplateTag).ForEachChild(v)
	case KindJSDocReturnTag:
		return n.data.(*JSDocReturnTag).ForEachChild(v)
	case KindJSDocPublicTag:
		return n.data.(*JSDocPublicTag).ForEachChild(v)
	case KindJSDocPrivateTag:
		return n.data.(*JSDocPrivateTag).ForEachChild(v)
	case KindJSDocProtectedTag:
		return n.data.(*JSDocProtectedTag).ForEachChild(v)
	case KindJSDocReadonlyTag:
		return n.data.(*JSDocReadonlyTag).ForEachChild(v)
	case KindJSDocOverrideTag:
		return n.data.(*JSDocOverrideTag).ForEachChild(v)
	case KindJSDocDeprecatedTag:
		return n.data.(*JSDocDeprecatedTag).ForEachChild(v)
	case KindJSDocSeeTag:
		return n.data.(*JSDocSeeTag).ForEachChild(v)
	case KindJSDocImplementsTag:
		return n.data.(*JSDocImplementsTag).ForEachChild(v)
	case KindJSDocAugmentsTag:
		return n.data.(*JSDocAugmentsTag).ForEachChild(v)
	case KindJSDocSatisfiesTag:
		return n.data.(*JSDocSatisfiesTag).ForEachChild(v)
	case KindJSDocThrowsTag:
		return n.data.(*JSDocThrowsTag).ForEachChild(v)
	case KindJSDocThisTag:
		return n.data.(*JSDocThisTag).ForEachChild(v)
	case KindJSDocImportTag:
		return n.data.(*JSDocImportTag).ForEachChild(v)
	case KindJSDocCallbackTag:
		return n.data.(*JSDocCallbackTag).ForEachChild(v)
	case KindJSDocOverloadTag:
		return n.data.(*JSDocOverloadTag).ForEachChild(v)
	case KindJSDocTypedefTag:
		return n.data.(*JSDocTypedefTag).ForEachChild(v)
	case KindJSDocSignature:
		return n.data.(*JSDocSignature).ForEachChild(v)
	case KindJSDocNameReference:
		return n.data.(*JSDocNameReference).ForEachChild(v)
	case KindSourceFile:
		return n.data.(*SourceFile).ForEachChild(v)
	case KindModuleDeclaration:
		return n.data.(*ModuleDeclaration).ForEachChild(v)
	case KindImportEqualsDeclaration:
		return n.data.(*ImportEqualsDeclaration).ForEachChild(v)
	case KindExportDeclaration:
		return n.data.(*ExportDeclaration).ForEachChild(v)
	case KindImportType:
		return n.data.(*ImportTypeNode).ForEachChild(v)
	case KindImportClause:
		return n.data.(*ImportClause).ForEachChild(v)
	case KindImportSpecifier:
		return n.data.(*ImportSpecifier).ForEachChild(v)
	case KindJSDocLink:
		return n.data.(*JSDocLink).ForEachChild(v)
	case KindJSDocLinkPlain:
		return n.data.(*JSDocLinkPlain).ForEachChild(v)
	case KindJSDocLinkCode:
		return n.data.(*JSDocLinkCode).ForEachChild(v)
	case KindTypeParameter:
		return n.data.(*TypeParameterDeclaration).ForEachChild(v)
	case KindSyntheticReferenceExpression:
		return n.data.(*SyntheticReferenceExpression).ForEachChild(v)
	case KindJSDocTypeLiteral:
		return n.data.(*JSDocTypeLiteral).ForEachChild(v)
	case KindJSDocParameterTag, KindJSDocPropertyTag:
		return n.data.(*JSDocParameterOrPropertyTag).ForEachChild(v)
	default:
		return false
	}
}

// ──────────────────────────────────────────────────────────────────────
// As*() cast methods
// ──────────────────────────────────────────────────────────────────────

func (n *Node) AsToken() *Token {
	return n.data.(*Token)
}

func (n *Node) AsIdentifier() *Identifier {
	return n.data.(*Identifier)
}

func (n *Node) AsPrivateIdentifier() *PrivateIdentifier {
	return n.data.(*PrivateIdentifier)
}

func (n *Node) AsQualifiedName() *QualifiedName {
	return n.data.(*QualifiedName)
}

func (n *Node) AsComputedPropertyName() *ComputedPropertyName {
	return n.data.(*ComputedPropertyName)
}

func (n *Node) AsDecorator() *Decorator {
	return n.data.(*Decorator)
}

func (n *Node) AsEmptyStatement() *EmptyStatement {
	return n.data.(*EmptyStatement)
}

func (n *Node) AsIfStatement() *IfStatement {
	return n.data.(*IfStatement)
}

func (n *Node) AsDoStatement() *DoStatement {
	return n.data.(*DoStatement)
}

func (n *Node) AsWhileStatement() *WhileStatement {
	return n.data.(*WhileStatement)
}

func (n *Node) AsForStatement() *ForStatement {
	return n.data.(*ForStatement)
}

func (n *Node) AsForInOrOfStatement() *ForInOrOfStatement {
	return n.data.(*ForInOrOfStatement)
}

func (n *Node) AsBreakStatement() *BreakStatement {
	return n.data.(*BreakStatement)
}

func (n *Node) AsContinueStatement() *ContinueStatement {
	return n.data.(*ContinueStatement)
}

func (n *Node) AsReturnStatement() *ReturnStatement {
	return n.data.(*ReturnStatement)
}

func (n *Node) AsWithStatement() *WithStatement {
	return n.data.(*WithStatement)
}

func (n *Node) AsSwitchStatement() *SwitchStatement {
	return n.data.(*SwitchStatement)
}

func (n *Node) AsCaseBlock() *CaseBlock {
	return n.data.(*CaseBlock)
}

func (n *Node) AsCaseOrDefaultClause() *CaseOrDefaultClause {
	return n.data.(*CaseOrDefaultClause)
}

func (n *Node) AsThrowStatement() *ThrowStatement {
	return n.data.(*ThrowStatement)
}

func (n *Node) AsTryStatement() *TryStatement {
	return n.data.(*TryStatement)
}

func (n *Node) AsCatchClause() *CatchClause {
	return n.data.(*CatchClause)
}

func (n *Node) AsDebuggerStatement() *DebuggerStatement {
	return n.data.(*DebuggerStatement)
}

func (n *Node) AsLabeledStatement() *LabeledStatement {
	return n.data.(*LabeledStatement)
}

func (n *Node) AsExpressionStatement() *ExpressionStatement {
	return n.data.(*ExpressionStatement)
}

func (n *Node) AsBlock() *Block {
	return n.data.(*Block)
}

func (n *Node) AsVariableStatement() *VariableStatement {
	return n.data.(*VariableStatement)
}

func (n *Node) AsVariableDeclaration() *VariableDeclaration {
	return n.data.(*VariableDeclaration)
}

func (n *Node) AsVariableDeclarationList() *VariableDeclarationList {
	return n.data.(*VariableDeclarationList)
}

func (n *Node) AsBindingPattern() *BindingPattern {
	return n.data.(*BindingPattern)
}

func (n *Node) AsParameterDeclaration() *ParameterDeclaration {
	return n.data.(*ParameterDeclaration)
}

func (n *Node) AsBindingElement() *BindingElement {
	return n.data.(*BindingElement)
}

func (n *Node) AsMissingDeclaration() *MissingDeclaration {
	return n.data.(*MissingDeclaration)
}

func (n *Node) AsFunctionDeclaration() *FunctionDeclaration {
	return n.data.(*FunctionDeclaration)
}

func (n *Node) AsClassDeclaration() *ClassDeclaration {
	return n.data.(*ClassDeclaration)
}

func (n *Node) AsClassExpression() *ClassExpression {
	return n.data.(*ClassExpression)
}

func (n *Node) AsHeritageClause() *HeritageClause {
	return n.data.(*HeritageClause)
}

func (n *Node) AsInterfaceDeclaration() *InterfaceDeclaration {
	return n.data.(*InterfaceDeclaration)
}

func (n *Node) AsTypeAliasDeclaration() *TypeAliasDeclaration {
	return n.data.(*TypeAliasDeclaration)
}

func (n *Node) AsEnumMember() *EnumMember {
	return n.data.(*EnumMember)
}

func (n *Node) AsEnumDeclaration() *EnumDeclaration {
	return n.data.(*EnumDeclaration)
}

func (n *Node) AsModuleBlock() *ModuleBlock {
	return n.data.(*ModuleBlock)
}

func (n *Node) AsNotEmittedStatement() *NotEmittedStatement {
	return n.data.(*NotEmittedStatement)
}

func (n *Node) AsNotEmittedTypeElement() *NotEmittedTypeElement {
	return n.data.(*NotEmittedTypeElement)
}

func (n *Node) AsImportDeclaration() *ImportDeclaration {
	return n.data.(*ImportDeclaration)
}

func (n *Node) AsExternalModuleReference() *ExternalModuleReference {
	return n.data.(*ExternalModuleReference)
}

func (n *Node) AsNamespaceImport() *NamespaceImport {
	return n.data.(*NamespaceImport)
}

func (n *Node) AsNamedImports() *NamedImports {
	return n.data.(*NamedImports)
}

func (n *Node) AsExportAssignment() *ExportAssignment {
	return n.data.(*ExportAssignment)
}

func (n *Node) AsNamespaceExportDeclaration() *NamespaceExportDeclaration {
	return n.data.(*NamespaceExportDeclaration)
}

func (n *Node) AsNamespaceExport() *NamespaceExport {
	return n.data.(*NamespaceExport)
}

func (n *Node) AsNamedExports() *NamedExports {
	return n.data.(*NamedExports)
}

func (n *Node) AsExportSpecifier() *ExportSpecifier {
	return n.data.(*ExportSpecifier)
}

func (n *Node) AsCallSignatureDeclaration() *CallSignatureDeclaration {
	return n.data.(*CallSignatureDeclaration)
}

func (n *Node) AsConstructSignatureDeclaration() *ConstructSignatureDeclaration {
	return n.data.(*ConstructSignatureDeclaration)
}

func (n *Node) AsConstructorDeclaration() *ConstructorDeclaration {
	return n.data.(*ConstructorDeclaration)
}

func (n *Node) AsGetAccessorDeclaration() *GetAccessorDeclaration {
	return n.data.(*GetAccessorDeclaration)
}

func (n *Node) AsSetAccessorDeclaration() *SetAccessorDeclaration {
	return n.data.(*SetAccessorDeclaration)
}

func (n *Node) AsIndexSignatureDeclaration() *IndexSignatureDeclaration {
	return n.data.(*IndexSignatureDeclaration)
}

func (n *Node) AsMethodSignatureDeclaration() *MethodSignatureDeclaration {
	return n.data.(*MethodSignatureDeclaration)
}

func (n *Node) AsMethodDeclaration() *MethodDeclaration {
	return n.data.(*MethodDeclaration)
}

func (n *Node) AsPropertySignatureDeclaration() *PropertySignatureDeclaration {
	return n.data.(*PropertySignatureDeclaration)
}

func (n *Node) AsPropertyDeclaration() *PropertyDeclaration {
	return n.data.(*PropertyDeclaration)
}

func (n *Node) AsSemicolonClassElement() *SemicolonClassElement {
	return n.data.(*SemicolonClassElement)
}

func (n *Node) AsClassStaticBlockDeclaration() *ClassStaticBlockDeclaration {
	return n.data.(*ClassStaticBlockDeclaration)
}

func (n *Node) AsOmittedExpression() *OmittedExpression {
	return n.data.(*OmittedExpression)
}

func (n *Node) AsKeywordExpression() *KeywordExpression {
	return n.data.(*KeywordExpression)
}

func (n *Node) AsStringLiteral() *StringLiteral {
	return n.data.(*StringLiteral)
}

func (n *Node) AsNumericLiteral() *NumericLiteral {
	return n.data.(*NumericLiteral)
}

func (n *Node) AsBigIntLiteral() *BigIntLiteral {
	return n.data.(*BigIntLiteral)
}

func (n *Node) AsRegularExpressionLiteral() *RegularExpressionLiteral {
	return n.data.(*RegularExpressionLiteral)
}

func (n *Node) AsNoSubstitutionTemplateLiteral() *NoSubstitutionTemplateLiteral {
	return n.data.(*NoSubstitutionTemplateLiteral)
}

func (n *Node) AsBinaryExpression() *BinaryExpression {
	return n.data.(*BinaryExpression)
}

func (n *Node) AsPrefixUnaryExpression() *PrefixUnaryExpression {
	return n.data.(*PrefixUnaryExpression)
}

func (n *Node) AsPostfixUnaryExpression() *PostfixUnaryExpression {
	return n.data.(*PostfixUnaryExpression)
}

func (n *Node) AsYieldExpression() *YieldExpression {
	return n.data.(*YieldExpression)
}

func (n *Node) AsArrowFunction() *ArrowFunction {
	return n.data.(*ArrowFunction)
}

func (n *Node) AsFunctionExpression() *FunctionExpression {
	return n.data.(*FunctionExpression)
}

func (n *Node) AsAsExpression() *AsExpression {
	return n.data.(*AsExpression)
}

func (n *Node) AsSatisfiesExpression() *SatisfiesExpression {
	return n.data.(*SatisfiesExpression)
}

func (n *Node) AsConditionalExpression() *ConditionalExpression {
	return n.data.(*ConditionalExpression)
}

func (n *Node) AsPropertyAccessExpression() *PropertyAccessExpression {
	return n.data.(*PropertyAccessExpression)
}

func (n *Node) AsElementAccessExpression() *ElementAccessExpression {
	return n.data.(*ElementAccessExpression)
}

func (n *Node) AsCallExpression() *CallExpression {
	return n.data.(*CallExpression)
}

func (n *Node) AsNewExpression() *NewExpression {
	return n.data.(*NewExpression)
}

func (n *Node) AsMetaProperty() *MetaProperty {
	return n.data.(*MetaProperty)
}

func (n *Node) AsNonNullExpression() *NonNullExpression {
	return n.data.(*NonNullExpression)
}

func (n *Node) AsSpreadElement() *SpreadElement {
	return n.data.(*SpreadElement)
}

func (n *Node) AsTemplateExpression() *TemplateExpression {
	return n.data.(*TemplateExpression)
}

func (n *Node) AsTemplateSpan() *TemplateSpan {
	return n.data.(*TemplateSpan)
}

func (n *Node) AsTaggedTemplateExpression() *TaggedTemplateExpression {
	return n.data.(*TaggedTemplateExpression)
}

func (n *Node) AsParenthesizedExpression() *ParenthesizedExpression {
	return n.data.(*ParenthesizedExpression)
}

func (n *Node) AsArrayLiteralExpression() *ArrayLiteralExpression {
	return n.data.(*ArrayLiteralExpression)
}

func (n *Node) AsObjectLiteralExpression() *ObjectLiteralExpression {
	return n.data.(*ObjectLiteralExpression)
}

func (n *Node) AsSpreadAssignment() *SpreadAssignment {
	return n.data.(*SpreadAssignment)
}

func (n *Node) AsPropertyAssignment() *PropertyAssignment {
	return n.data.(*PropertyAssignment)
}

func (n *Node) AsShorthandPropertyAssignment() *ShorthandPropertyAssignment {
	return n.data.(*ShorthandPropertyAssignment)
}

func (n *Node) AsDeleteExpression() *DeleteExpression {
	return n.data.(*DeleteExpression)
}

func (n *Node) AsTypeOfExpression() *TypeOfExpression {
	return n.data.(*TypeOfExpression)
}

func (n *Node) AsVoidExpression() *VoidExpression {
	return n.data.(*VoidExpression)
}

func (n *Node) AsAwaitExpression() *AwaitExpression {
	return n.data.(*AwaitExpression)
}

func (n *Node) AsTypeAssertion() *TypeAssertion {
	return n.data.(*TypeAssertion)
}

func (n *Node) AsKeywordTypeNode() *KeywordTypeNode {
	return n.data.(*KeywordTypeNode)
}

func (n *Node) AsUnionTypeNode() *UnionTypeNode {
	return n.data.(*UnionTypeNode)
}

func (n *Node) AsIntersectionTypeNode() *IntersectionTypeNode {
	return n.data.(*IntersectionTypeNode)
}

func (n *Node) AsConditionalTypeNode() *ConditionalTypeNode {
	return n.data.(*ConditionalTypeNode)
}

func (n *Node) AsTypeOperatorNode() *TypeOperatorNode {
	return n.data.(*TypeOperatorNode)
}

func (n *Node) AsInferTypeNode() *InferTypeNode {
	return n.data.(*InferTypeNode)
}

func (n *Node) AsArrayTypeNode() *ArrayTypeNode {
	return n.data.(*ArrayTypeNode)
}

func (n *Node) AsIndexedAccessTypeNode() *IndexedAccessTypeNode {
	return n.data.(*IndexedAccessTypeNode)
}

func (n *Node) AsTypeReferenceNode() *TypeReferenceNode {
	return n.data.(*TypeReferenceNode)
}

func (n *Node) AsExpressionWithTypeArguments() *ExpressionWithTypeArguments {
	return n.data.(*ExpressionWithTypeArguments)
}

func (n *Node) AsLiteralTypeNode() *LiteralTypeNode {
	return n.data.(*LiteralTypeNode)
}

func (n *Node) AsThisTypeNode() *ThisTypeNode {
	return n.data.(*ThisTypeNode)
}

func (n *Node) AsTypePredicateNode() *TypePredicateNode {
	return n.data.(*TypePredicateNode)
}

func (n *Node) AsImportAttribute() *ImportAttribute {
	return n.data.(*ImportAttribute)
}

func (n *Node) AsImportAttributes() *ImportAttributes {
	return n.data.(*ImportAttributes)
}

func (n *Node) AsTypeQueryNode() *TypeQueryNode {
	return n.data.(*TypeQueryNode)
}

func (n *Node) AsMappedTypeNode() *MappedTypeNode {
	return n.data.(*MappedTypeNode)
}

func (n *Node) AsTypeLiteralNode() *TypeLiteralNode {
	return n.data.(*TypeLiteralNode)
}

func (n *Node) AsTupleTypeNode() *TupleTypeNode {
	return n.data.(*TupleTypeNode)
}

func (n *Node) AsNamedTupleMember() *NamedTupleMember {
	return n.data.(*NamedTupleMember)
}

func (n *Node) AsOptionalTypeNode() *OptionalTypeNode {
	return n.data.(*OptionalTypeNode)
}

func (n *Node) AsRestTypeNode() *RestTypeNode {
	return n.data.(*RestTypeNode)
}

func (n *Node) AsParenthesizedTypeNode() *ParenthesizedTypeNode {
	return n.data.(*ParenthesizedTypeNode)
}

func (n *Node) AsFunctionTypeNode() *FunctionTypeNode {
	return n.data.(*FunctionTypeNode)
}

func (n *Node) AsConstructorTypeNode() *ConstructorTypeNode {
	return n.data.(*ConstructorTypeNode)
}

func (n *Node) AsTemplateHead() *TemplateHead {
	return n.data.(*TemplateHead)
}

func (n *Node) AsTemplateMiddle() *TemplateMiddle {
	return n.data.(*TemplateMiddle)
}

func (n *Node) AsTemplateTail() *TemplateTail {
	return n.data.(*TemplateTail)
}

func (n *Node) AsTemplateLiteralTypeNode() *TemplateLiteralTypeNode {
	return n.data.(*TemplateLiteralTypeNode)
}

func (n *Node) AsTemplateLiteralTypeSpan() *TemplateLiteralTypeSpan {
	return n.data.(*TemplateLiteralTypeSpan)
}

func (n *Node) AsSyntheticExpression() *SyntheticExpression {
	return n.data.(*SyntheticExpression)
}

func (n *Node) AsPartiallyEmittedExpression() *PartiallyEmittedExpression {
	return n.data.(*PartiallyEmittedExpression)
}

func (n *Node) AsJsxElement() *JsxElement {
	return n.data.(*JsxElement)
}

func (n *Node) AsJsxAttributes() *JsxAttributes {
	return n.data.(*JsxAttributes)
}

func (n *Node) AsJsxNamespacedName() *JsxNamespacedName {
	return n.data.(*JsxNamespacedName)
}

func (n *Node) AsJsxOpeningElement() *JsxOpeningElement {
	return n.data.(*JsxOpeningElement)
}

func (n *Node) AsJsxSelfClosingElement() *JsxSelfClosingElement {
	return n.data.(*JsxSelfClosingElement)
}

func (n *Node) AsJsxFragment() *JsxFragment {
	return n.data.(*JsxFragment)
}

func (n *Node) AsJsxOpeningFragment() *JsxOpeningFragment {
	return n.data.(*JsxOpeningFragment)
}

func (n *Node) AsJsxClosingFragment() *JsxClosingFragment {
	return n.data.(*JsxClosingFragment)
}

func (n *Node) AsJsxAttribute() *JsxAttribute {
	return n.data.(*JsxAttribute)
}

func (n *Node) AsJsxSpreadAttribute() *JsxSpreadAttribute {
	return n.data.(*JsxSpreadAttribute)
}

func (n *Node) AsJsxClosingElement() *JsxClosingElement {
	return n.data.(*JsxClosingElement)
}

func (n *Node) AsJsxExpression() *JsxExpression {
	return n.data.(*JsxExpression)
}

func (n *Node) AsJsxText() *JsxText {
	return n.data.(*JsxText)
}

func (n *Node) AsSyntaxList() *SyntaxList {
	return n.data.(*SyntaxList)
}

func (n *Node) AsJSDoc() *JSDoc {
	return n.data.(*JSDoc)
}

func (n *Node) AsJSDocTypeExpression() *JSDocTypeExpression {
	return n.data.(*JSDocTypeExpression)
}

func (n *Node) AsJSDocNonNullableType() *JSDocNonNullableType {
	return n.data.(*JSDocNonNullableType)
}

func (n *Node) AsJSDocNullableType() *JSDocNullableType {
	return n.data.(*JSDocNullableType)
}

func (n *Node) AsJSDocAllType() *JSDocAllType {
	return n.data.(*JSDocAllType)
}

func (n *Node) AsJSDocVariadicType() *JSDocVariadicType {
	return n.data.(*JSDocVariadicType)
}

func (n *Node) AsJSDocOptionalType() *JSDocOptionalType {
	return n.data.(*JSDocOptionalType)
}

func (n *Node) AsJSDocTypeTag() *JSDocTypeTag {
	return n.data.(*JSDocTypeTag)
}

func (n *Node) AsJSDocUnknownTag() *JSDocUnknownTag {
	return n.data.(*JSDocUnknownTag)
}

func (n *Node) AsJSDocTemplateTag() *JSDocTemplateTag {
	return n.data.(*JSDocTemplateTag)
}

func (n *Node) AsJSDocReturnTag() *JSDocReturnTag {
	return n.data.(*JSDocReturnTag)
}

func (n *Node) AsJSDocPublicTag() *JSDocPublicTag {
	return n.data.(*JSDocPublicTag)
}

func (n *Node) AsJSDocPrivateTag() *JSDocPrivateTag {
	return n.data.(*JSDocPrivateTag)
}

func (n *Node) AsJSDocProtectedTag() *JSDocProtectedTag {
	return n.data.(*JSDocProtectedTag)
}

func (n *Node) AsJSDocReadonlyTag() *JSDocReadonlyTag {
	return n.data.(*JSDocReadonlyTag)
}

func (n *Node) AsJSDocOverrideTag() *JSDocOverrideTag {
	return n.data.(*JSDocOverrideTag)
}

func (n *Node) AsJSDocDeprecatedTag() *JSDocDeprecatedTag {
	return n.data.(*JSDocDeprecatedTag)
}

func (n *Node) AsJSDocSeeTag() *JSDocSeeTag {
	return n.data.(*JSDocSeeTag)
}

func (n *Node) AsJSDocImplementsTag() *JSDocImplementsTag {
	return n.data.(*JSDocImplementsTag)
}

func (n *Node) AsJSDocAugmentsTag() *JSDocAugmentsTag {
	return n.data.(*JSDocAugmentsTag)
}

func (n *Node) AsJSDocSatisfiesTag() *JSDocSatisfiesTag {
	return n.data.(*JSDocSatisfiesTag)
}

func (n *Node) AsJSDocThrowsTag() *JSDocThrowsTag {
	return n.data.(*JSDocThrowsTag)
}

func (n *Node) AsJSDocThisTag() *JSDocThisTag {
	return n.data.(*JSDocThisTag)
}

func (n *Node) AsJSDocImportTag() *JSDocImportTag {
	return n.data.(*JSDocImportTag)
}

func (n *Node) AsJSDocCallbackTag() *JSDocCallbackTag {
	return n.data.(*JSDocCallbackTag)
}

func (n *Node) AsJSDocOverloadTag() *JSDocOverloadTag {
	return n.data.(*JSDocOverloadTag)
}

func (n *Node) AsJSDocTypedefTag() *JSDocTypedefTag {
	return n.data.(*JSDocTypedefTag)
}

func (n *Node) AsJSDocSignature() *JSDocSignature {
	return n.data.(*JSDocSignature)
}

func (n *Node) AsJSDocNameReference() *JSDocNameReference {
	return n.data.(*JSDocNameReference)
}

func (n *Node) AsSourceFile() *SourceFile {
	return n.data.(*SourceFile)
}

func (n *Node) AsModuleDeclaration() *ModuleDeclaration {
	return n.data.(*ModuleDeclaration)
}

func (n *Node) AsImportEqualsDeclaration() *ImportEqualsDeclaration {
	return n.data.(*ImportEqualsDeclaration)
}

func (n *Node) AsExportDeclaration() *ExportDeclaration {
	return n.data.(*ExportDeclaration)
}

func (n *Node) AsImportTypeNode() *ImportTypeNode {
	return n.data.(*ImportTypeNode)
}

func (n *Node) AsImportClause() *ImportClause {
	return n.data.(*ImportClause)
}

func (n *Node) AsImportSpecifier() *ImportSpecifier {
	return n.data.(*ImportSpecifier)
}

func (n *Node) AsJSDocText() *JSDocText {
	return n.data.(*JSDocText)
}

func (n *Node) AsJSDocLink() *JSDocLink {
	return n.data.(*JSDocLink)
}

func (n *Node) AsJSDocLinkPlain() *JSDocLinkPlain {
	return n.data.(*JSDocLinkPlain)
}

func (n *Node) AsJSDocLinkCode() *JSDocLinkCode {
	return n.data.(*JSDocLinkCode)
}

func (n *Node) AsTypeParameterDeclaration() *TypeParameterDeclaration {
	return n.data.(*TypeParameterDeclaration)
}

func (n *Node) AsSyntheticReferenceExpression() *SyntheticReferenceExpression {
	return n.data.(*SyntheticReferenceExpression)
}

func (n *Node) AsJSDocTypeLiteral() *JSDocTypeLiteral {
	return n.data.(*JSDocTypeLiteral)
}

func (n *Node) AsJSDocParameterOrPropertyTag() *JSDocParameterOrPropertyTag {
	return n.data.(*JSDocParameterOrPropertyTag)
}

// ──────────────────────────────────────────────────────────────────────
// Kind alias guards
// ──────────────────────────────────────────────────────────────────────

func IsTriviaKind(kind Kind) bool {
	switch kind {
	case KindSingleLineCommentTrivia, KindMultiLineCommentTrivia, KindNewLineTrivia, KindWhitespaceTrivia, KindConflictMarkerTrivia:
		return true
	}
	return false
}

func IsLiteralKind(kind Kind) bool {
	return kind >= KindFirstLiteralToken && kind <= KindLastLiteralToken
}

func IsPseudoLiteralKind(kind Kind) bool {
	switch kind {
	case KindTemplateHead, KindTemplateMiddle, KindTemplateTail:
		return true
	}
	return false
}

func IsPunctuationKind(kind Kind) bool {
	return kind >= KindFirstPunctuation && kind <= KindLastPunctuation
}

func IsKeywordKind(kind Kind) bool {
	return kind >= KindFirstKeyword && kind <= KindLastKeyword
}

func IsModifierKind(kind Kind) bool {
	switch kind {
	case KindAbstractKeyword, KindAccessorKeyword, KindAsyncKeyword, KindConstKeyword, KindDeclareKeyword, KindDefaultKeyword, KindExportKeyword, KindInKeyword, KindPrivateKeyword, KindProtectedKeyword, KindPublicKeyword, KindReadonlyKeyword, KindOutKeyword, KindOverrideKeyword, KindStaticKeyword:
		return true
	}
	return false
}

func IsKeywordTypeKind(kind Kind) bool {
	switch kind {
	case KindAnyKeyword, KindBigIntKeyword, KindBooleanKeyword, KindIntrinsicKeyword, KindNeverKeyword, KindNumberKeyword, KindObjectKeyword, KindStringKeyword, KindSymbolKeyword, KindUndefinedKeyword, KindUnknownKeyword, KindVoidKeyword:
		return true
	}
	return false
}

func IsKeywordExpressionKind(kind Kind) bool {
	switch kind {
	case KindNullKeyword, KindTrueKeyword, KindFalseKeyword, KindThisKeyword, KindSuperKeyword, KindImportKeyword:
		return true
	}
	return false
}

func IsTokenKind(kind Kind) bool {
	return kind >= KindFirstToken && kind <= KindLastToken
}

func IsJsxTokenKind(kind Kind) bool {
	switch kind {
	case KindLessThanSlashToken, KindEndOfFile, KindConflictMarkerTrivia, KindJsxText, KindJsxTextAllWhiteSpaces, KindOpenBraceToken, KindLessThanToken:
		return true
	}
	return false
}

func IsJSDocNodeKind(kind Kind) bool {
	return kind >= KindFirstJSDocNode && kind <= KindLastJSDocNode
}

func IsImportPhaseModifierKind(kind Kind) bool {
	switch kind {
	case KindTypeKeyword, KindDeferKeyword:
		return true
	}
	return false
}

func IsPostfixUnaryOperator(kind Kind) bool {
	switch kind {
	case KindPlusPlusToken, KindMinusMinusToken:
		return true
	}
	return false
}

func IsPrefixUnaryOperator(kind Kind) bool {
	switch kind {
	case KindPlusToken, KindMinusToken, KindTildeToken, KindExclamationToken, KindPlusPlusToken, KindMinusMinusToken:
		return true
	}
	return false
}

func IsAssignmentOperator(kind Kind) bool {
	switch kind {
	case KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskAsteriskEqualsToken, KindAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindCaretEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken:
		return true
	}
	return false
}

func IsBinaryOperator(kind Kind) bool {
	switch kind {
	case KindQuestionQuestionToken, KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword, KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindAmpersandAmpersandToken, KindBarBarToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskAsteriskEqualsToken, KindAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindCaretEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken, KindCommaToken:
		return true
	}
	return false
}

func IsExponentiationOperator(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken:
		return true
	}
	return false
}

func IsMultiplicativeOperator(kind Kind) bool {
	switch kind {
	case KindAsteriskToken, KindSlashToken, KindPercentToken:
		return true
	}
	return false
}

func IsMultiplicativeOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken:
		return true
	}
	return false
}

func IsAdditiveOperator(kind Kind) bool {
	switch kind {
	case KindPlusToken, KindMinusToken:
		return true
	}
	return false
}

func IsAdditiveOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken:
		return true
	}
	return false
}

func IsShiftOperator(kind Kind) bool {
	switch kind {
	case KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken:
		return true
	}
	return false
}

func IsShiftOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken:
		return true
	}
	return false
}

func IsRelationalOperator(kind Kind) bool {
	switch kind {
	case KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword:
		return true
	}
	return false
}

func IsRelationalOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword:
		return true
	}
	return false
}

func IsEqualityOperator(kind Kind) bool {
	switch kind {
	case KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken:
		return true
	}
	return false
}

func IsEqualityOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword, KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken:
		return true
	}
	return false
}

func IsBitwiseOperator(kind Kind) bool {
	switch kind {
	case KindAmpersandToken, KindBarToken, KindCaretToken:
		return true
	}
	return false
}

func IsBitwiseOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword, KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken, KindAmpersandToken, KindBarToken, KindCaretToken:
		return true
	}
	return false
}

func IsLogicalOperator(kind Kind) bool {
	switch kind {
	case KindAmpersandAmpersandToken, KindBarBarToken:
		return true
	}
	return false
}

func IsLogicalOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword, KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindAmpersandAmpersandToken, KindBarBarToken:
		return true
	}
	return false
}

func IsCompoundAssignmentOperator(kind Kind) bool {
	switch kind {
	case KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskAsteriskEqualsToken, KindAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindCaretEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken:
		return true
	}
	return false
}

func IsAssignmentOperatorOrHigher(kind Kind) bool {
	switch kind {
	case KindQuestionQuestionToken, KindAsteriskAsteriskToken, KindAsteriskToken, KindSlashToken, KindPercentToken, KindPlusToken, KindMinusToken, KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken, KindLessThanToken, KindLessThanEqualsToken, KindGreaterThanToken, KindGreaterThanEqualsToken, KindInstanceOfKeyword, KindInKeyword, KindEqualsEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken, KindExclamationEqualsToken, KindAmpersandToken, KindBarToken, KindCaretToken, KindAmpersandAmpersandToken, KindBarBarToken, KindEqualsToken, KindPlusEqualsToken, KindMinusEqualsToken, KindAsteriskAsteriskEqualsToken, KindAsteriskEqualsToken, KindSlashEqualsToken, KindPercentEqualsToken, KindAmpersandEqualsToken, KindBarEqualsToken, KindCaretEqualsToken, KindLessThanLessThanEqualsToken, KindGreaterThanGreaterThanGreaterThanEqualsToken, KindGreaterThanGreaterThanEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken, KindQuestionQuestionEqualsToken:
		return true
	}
	return false
}

func IsLogicalOrCoalescingAssignmentOperator(kind Kind) bool {
	switch kind {
	case KindAmpersandAmpersandEqualsToken, KindBarBarEqualsToken, KindQuestionQuestionEqualsToken:
		return true
	}
	return false
}
