// NOTE: This file is generated by the templates/template.rb script and should not // be modified manually. See /home/runner/work/herb/herb/templates/javascript/packages/core/src/node-type-guards.ts.erb import type { Node, NodeType, ERBNode } from "./nodes.js" import { Token } from "./token.js" import { ParseResult } from "./parse-result.js" import { DocumentNode, LiteralNode, HTMLOpenTagNode, HTMLConditionalOpenTagNode, HTMLCloseTagNode, HTMLOmittedCloseTagNode, HTMLVirtualCloseTagNode, HTMLElementNode, HTMLConditionalElementNode, HTMLAttributeValueNode, HTMLAttributeNameNode, HTMLAttributeNode, RubyLiteralNode, RubyHTMLAttributesSplatNode, ERBOpenTagNode, HTMLTextNode, HTMLCommentNode, HTMLDoctypeNode, XMLDeclarationNode, CDATANode, WhitespaceNode, ERBContentNode, ERBEndNode, ERBElseNode, ERBIfNode, ERBBlockNode, ERBWhenNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBUntilNode, ERBForNode, ERBRescueNode, ERBEnsureNode, ERBBeginNode, ERBUnlessNode, RubyRenderLocalNode, RubyRenderKeywordsNode, ERBRenderNode, RubyParameterNode, ERBStrictLocalsNode, ERBYieldNode, ERBInNode, } from "./nodes.js" /** * Type guard functions for AST nodes. * These functions provide type checking by combining both instanceof * checks and type string comparisons for maximum reliability across different * runtime scenarios (e.g., serialized/deserialized nodes). */ /** * Checks if a node is a DocumentNode */ export function isDocumentNode(node: Node | null | undefined): node is DocumentNode { if (!node) return false return node instanceof DocumentNode || node.type === "AST_DOCUMENT_NODE" || (node.constructor as any).type === "AST_DOCUMENT_NODE" } /** * Checks if a node is a LiteralNode */ export function isLiteralNode(node: Node | null | undefined): node is LiteralNode { if (!node) return false return node instanceof LiteralNode || node.type === "AST_LITERAL_NODE" || (node.constructor as any).type === "AST_LITERAL_NODE" } /** * Checks if a node is a HTMLOpenTagNode */ export function isHTMLOpenTagNode(node: Node | null | undefined): node is HTMLOpenTagNode { if (!node) return false return node instanceof HTMLOpenTagNode || node.type === "AST_HTML_OPEN_TAG_NODE" || (node.constructor as any).type === "AST_HTML_OPEN_TAG_NODE" } /** * Checks if a node is a HTMLConditionalOpenTagNode */ export function isHTMLConditionalOpenTagNode(node: Node | null | undefined): node is HTMLConditionalOpenTagNode { if (!node) return false return node instanceof HTMLConditionalOpenTagNode || node.type === "AST_HTML_CONDITIONAL_OPEN_TAG_NODE" || (node.constructor as any).type === "AST_HTML_CONDITIONAL_OPEN_TAG_NODE" } /** * Checks if a node is a HTMLCloseTagNode */ export function isHTMLCloseTagNode(node: Node | null | undefined): node is HTMLCloseTagNode { if (!node) return false return node instanceof HTMLCloseTagNode || node.type === "AST_HTML_CLOSE_TAG_NODE" || (node.constructor as any).type === "AST_HTML_CLOSE_TAG_NODE" } /** * Checks if a node is a HTMLOmittedCloseTagNode */ export function isHTMLOmittedCloseTagNode(node: Node | null | undefined): node is HTMLOmittedCloseTagNode { if (!node) return false return node instanceof HTMLOmittedCloseTagNode || node.type === "AST_HTML_OMITTED_CLOSE_TAG_NODE" || (node.constructor as any).type === "AST_HTML_OMITTED_CLOSE_TAG_NODE" } /** * Checks if a node is a HTMLVirtualCloseTagNode */ export function isHTMLVirtualCloseTagNode(node: Node | null | undefined): node is HTMLVirtualCloseTagNode { if (!node) return false return node instanceof HTMLVirtualCloseTagNode || node.type === "AST_HTML_VIRTUAL_CLOSE_TAG_NODE" || (node.constructor as any).type === "AST_HTML_VIRTUAL_CLOSE_TAG_NODE" } /** * Checks if a node is a HTMLElementNode */ export function isHTMLElementNode(node: Node | null | undefined): node is HTMLElementNode { if (!node) return false return node instanceof HTMLElementNode || node.type === "AST_HTML_ELEMENT_NODE" || (node.constructor as any).type === "AST_HTML_ELEMENT_NODE" } /** * Checks if a node is a HTMLConditionalElementNode */ export function isHTMLConditionalElementNode(node: Node | null | undefined): node is HTMLConditionalElementNode { if (!node) return false return node instanceof HTMLConditionalElementNode || node.type === "AST_HTML_CONDITIONAL_ELEMENT_NODE" || (node.constructor as any).type === "AST_HTML_CONDITIONAL_ELEMENT_NODE" } /** * Checks if a node is a HTMLAttributeValueNode */ export function isHTMLAttributeValueNode(node: Node | null | undefined): node is HTMLAttributeValueNode { if (!node) return false return node instanceof HTMLAttributeValueNode || node.type === "AST_HTML_ATTRIBUTE_VALUE_NODE" || (node.constructor as any).type === "AST_HTML_ATTRIBUTE_VALUE_NODE" } /** * Checks if a node is a HTMLAttributeNameNode */ export function isHTMLAttributeNameNode(node: Node | null | undefined): node is HTMLAttributeNameNode { if (!node) return false return node instanceof HTMLAttributeNameNode || node.type === "AST_HTML_ATTRIBUTE_NAME_NODE" || (node.constructor as any).type === "AST_HTML_ATTRIBUTE_NAME_NODE" } /** * Checks if a node is a HTMLAttributeNode */ export function isHTMLAttributeNode(node: Node | null | undefined): node is HTMLAttributeNode { if (!node) return false return node instanceof HTMLAttributeNode || node.type === "AST_HTML_ATTRIBUTE_NODE" || (node.constructor as any).type === "AST_HTML_ATTRIBUTE_NODE" } /** * Checks if a node is a RubyLiteralNode */ export function isRubyLiteralNode(node: Node | null | undefined): node is RubyLiteralNode { if (!node) return false return node instanceof RubyLiteralNode || node.type === "AST_RUBY_LITERAL_NODE" || (node.constructor as any).type === "AST_RUBY_LITERAL_NODE" } /** * Checks if a node is a RubyHTMLAttributesSplatNode */ export function isRubyHTMLAttributesSplatNode(node: Node | null | undefined): node is RubyHTMLAttributesSplatNode { if (!node) return false return node instanceof RubyHTMLAttributesSplatNode || node.type === "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE" || (node.constructor as any).type === "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE" } /** * Checks if a node is a ERBOpenTagNode */ export function isERBOpenTagNode(node: Node | null | undefined): node is ERBOpenTagNode { if (!node) return false return node instanceof ERBOpenTagNode || node.type === "AST_ERB_OPEN_TAG_NODE" || (node.constructor as any).type === "AST_ERB_OPEN_TAG_NODE" } /** * Checks if a node is a HTMLTextNode */ export function isHTMLTextNode(node: Node | null | undefined): node is HTMLTextNode { if (!node) return false return node instanceof HTMLTextNode || node.type === "AST_HTML_TEXT_NODE" || (node.constructor as any).type === "AST_HTML_TEXT_NODE" } /** * Checks if a node is a HTMLCommentNode */ export function isHTMLCommentNode(node: Node | null | undefined): node is HTMLCommentNode { if (!node) return false return node instanceof HTMLCommentNode || node.type === "AST_HTML_COMMENT_NODE" || (node.constructor as any).type === "AST_HTML_COMMENT_NODE" } /** * Checks if a node is a HTMLDoctypeNode */ export function isHTMLDoctypeNode(node: Node | null | undefined): node is HTMLDoctypeNode { if (!node) return false return node instanceof HTMLDoctypeNode || node.type === "AST_HTML_DOCTYPE_NODE" || (node.constructor as any).type === "AST_HTML_DOCTYPE_NODE" } /** * Checks if a node is a XMLDeclarationNode */ export function isXMLDeclarationNode(node: Node | null | undefined): node is XMLDeclarationNode { if (!node) return false return node instanceof XMLDeclarationNode || node.type === "AST_XML_DECLARATION_NODE" || (node.constructor as any).type === "AST_XML_DECLARATION_NODE" } /** * Checks if a node is a CDATANode */ export function isCDATANode(node: Node | null | undefined): node is CDATANode { if (!node) return false return node instanceof CDATANode || node.type === "AST_CDATA_NODE" || (node.constructor as any).type === "AST_CDATA_NODE" } /** * Checks if a node is a WhitespaceNode */ export function isWhitespaceNode(node: Node | null | undefined): node is WhitespaceNode { if (!node) return false return node instanceof WhitespaceNode || node.type === "AST_WHITESPACE_NODE" || (node.constructor as any).type === "AST_WHITESPACE_NODE" } /** * Checks if a node is a ERBContentNode */ export function isERBContentNode(node: Node | null | undefined): node is ERBContentNode { if (!node) return false return node instanceof ERBContentNode || node.type === "AST_ERB_CONTENT_NODE" || (node.constructor as any).type === "AST_ERB_CONTENT_NODE" } /** * Checks if a node is a ERBEndNode */ export function isERBEndNode(node: Node | null | undefined): node is ERBEndNode { if (!node) return false return node instanceof ERBEndNode || node.type === "AST_ERB_END_NODE" || (node.constructor as any).type === "AST_ERB_END_NODE" } /** * Checks if a node is a ERBElseNode */ export function isERBElseNode(node: Node | null | undefined): node is ERBElseNode { if (!node) return false return node instanceof ERBElseNode || node.type === "AST_ERB_ELSE_NODE" || (node.constructor as any).type === "AST_ERB_ELSE_NODE" } /** * Checks if a node is a ERBIfNode */ export function isERBIfNode(node: Node | null | undefined): node is ERBIfNode { if (!node) return false return node instanceof ERBIfNode || node.type === "AST_ERB_IF_NODE" || (node.constructor as any).type === "AST_ERB_IF_NODE" } /** * Checks if a node is a ERBBlockNode */ export function isERBBlockNode(node: Node | null | undefined): node is ERBBlockNode { if (!node) return false return node instanceof ERBBlockNode || node.type === "AST_ERB_BLOCK_NODE" || (node.constructor as any).type === "AST_ERB_BLOCK_NODE" } /** * Checks if a node is a ERBWhenNode */ export function isERBWhenNode(node: Node | null | undefined): node is ERBWhenNode { if (!node) return false return node instanceof ERBWhenNode || node.type === "AST_ERB_WHEN_NODE" || (node.constructor as any).type === "AST_ERB_WHEN_NODE" } /** * Checks if a node is a ERBCaseNode */ export function isERBCaseNode(node: Node | null | undefined): node is ERBCaseNode { if (!node) return false return node instanceof ERBCaseNode || node.type === "AST_ERB_CASE_NODE" || (node.constructor as any).type === "AST_ERB_CASE_NODE" } /** * Checks if a node is a ERBCaseMatchNode */ export function isERBCaseMatchNode(node: Node | null | undefined): node is ERBCaseMatchNode { if (!node) return false return node instanceof ERBCaseMatchNode || node.type === "AST_ERB_CASE_MATCH_NODE" || (node.constructor as any).type === "AST_ERB_CASE_MATCH_NODE" } /** * Checks if a node is a ERBWhileNode */ export function isERBWhileNode(node: Node | null | undefined): node is ERBWhileNode { if (!node) return false return node instanceof ERBWhileNode || node.type === "AST_ERB_WHILE_NODE" || (node.constructor as any).type === "AST_ERB_WHILE_NODE" } /** * Checks if a node is a ERBUntilNode */ export function isERBUntilNode(node: Node | null | undefined): node is ERBUntilNode { if (!node) return false return node instanceof ERBUntilNode || node.type === "AST_ERB_UNTIL_NODE" || (node.constructor as any).type === "AST_ERB_UNTIL_NODE" } /** * Checks if a node is a ERBForNode */ export function isERBForNode(node: Node | null | undefined): node is ERBForNode { if (!node) return false return node instanceof ERBForNode || node.type === "AST_ERB_FOR_NODE" || (node.constructor as any).type === "AST_ERB_FOR_NODE" } /** * Checks if a node is a ERBRescueNode */ export function isERBRescueNode(node: Node | null | undefined): node is ERBRescueNode { if (!node) return false return node instanceof ERBRescueNode || node.type === "AST_ERB_RESCUE_NODE" || (node.constructor as any).type === "AST_ERB_RESCUE_NODE" } /** * Checks if a node is a ERBEnsureNode */ export function isERBEnsureNode(node: Node | null | undefined): node is ERBEnsureNode { if (!node) return false return node instanceof ERBEnsureNode || node.type === "AST_ERB_ENSURE_NODE" || (node.constructor as any).type === "AST_ERB_ENSURE_NODE" } /** * Checks if a node is a ERBBeginNode */ export function isERBBeginNode(node: Node | null | undefined): node is ERBBeginNode { if (!node) return false return node instanceof ERBBeginNode || node.type === "AST_ERB_BEGIN_NODE" || (node.constructor as any).type === "AST_ERB_BEGIN_NODE" } /** * Checks if a node is a ERBUnlessNode */ export function isERBUnlessNode(node: Node | null | undefined): node is ERBUnlessNode { if (!node) return false return node instanceof ERBUnlessNode || node.type === "AST_ERB_UNLESS_NODE" || (node.constructor as any).type === "AST_ERB_UNLESS_NODE" } /** * Checks if a node is a RubyRenderLocalNode */ export function isRubyRenderLocalNode(node: Node | null | undefined): node is RubyRenderLocalNode { if (!node) return false return node instanceof RubyRenderLocalNode || node.type === "AST_RUBY_RENDER_LOCAL_NODE" || (node.constructor as any).type === "AST_RUBY_RENDER_LOCAL_NODE" } /** * Checks if a node is a RubyRenderKeywordsNode */ export function isRubyRenderKeywordsNode(node: Node | null | undefined): node is RubyRenderKeywordsNode { if (!node) return false return node instanceof RubyRenderKeywordsNode || node.type === "AST_RUBY_RENDER_KEYWORDS_NODE" || (node.constructor as any).type === "AST_RUBY_RENDER_KEYWORDS_NODE" } /** * Checks if a node is a ERBRenderNode */ export function isERBRenderNode(node: Node | null | undefined): node is ERBRenderNode { if (!node) return false return node instanceof ERBRenderNode || node.type === "AST_ERB_RENDER_NODE" || (node.constructor as any).type === "AST_ERB_RENDER_NODE" } /** * Checks if a node is a RubyParameterNode */ export function isRubyParameterNode(node: Node | null | undefined): node is RubyParameterNode { if (!node) return false return node instanceof RubyParameterNode || node.type === "AST_RUBY_PARAMETER_NODE" || (node.constructor as any).type === "AST_RUBY_PARAMETER_NODE" } /** * Checks if a node is a ERBStrictLocalsNode */ export function isERBStrictLocalsNode(node: Node | null | undefined): node is ERBStrictLocalsNode { if (!node) return false return node instanceof ERBStrictLocalsNode || node.type === "AST_ERB_STRICT_LOCALS_NODE" || (node.constructor as any).type === "AST_ERB_STRICT_LOCALS_NODE" } /** * Checks if a node is a ERBYieldNode */ export function isERBYieldNode(node: Node | null | undefined): node is ERBYieldNode { if (!node) return false return node instanceof ERBYieldNode || node.type === "AST_ERB_YIELD_NODE" || (node.constructor as any).type === "AST_ERB_YIELD_NODE" } /** * Checks if a node is a ERBInNode */ export function isERBInNode(node: Node | null | undefined): node is ERBInNode { if (!node) return false return node instanceof ERBInNode || node.type === "AST_ERB_IN_NODE" || (node.constructor as any).type === "AST_ERB_IN_NODE" } /** * Convenience type guards for common node categories */ /** * Checks if a node is any HTML node type */ export function isHTMLNode(node: Node): boolean { return isHTMLOpenTagNode(node) || isHTMLConditionalOpenTagNode(node) || isHTMLCloseTagNode(node) || isHTMLOmittedCloseTagNode(node) || isHTMLVirtualCloseTagNode(node) || isHTMLElementNode(node) || isHTMLConditionalElementNode(node) || isHTMLAttributeValueNode(node) || isHTMLAttributeNameNode(node) || isHTMLAttributeNode(node) || isHTMLTextNode(node) || isHTMLCommentNode(node) || isHTMLDoctypeNode(node) } /** * Checks if a node is any ERB node type */ export function isERBNode(node: Node): node is ERBNode { return isERBOpenTagNode(node) || isERBContentNode(node) || isERBEndNode(node) || isERBElseNode(node) || isERBIfNode(node) || isERBBlockNode(node) || isERBWhenNode(node) || isERBCaseNode(node) || isERBCaseMatchNode(node) || isERBWhileNode(node) || isERBUntilNode(node) || isERBForNode(node) || isERBRescueNode(node) || isERBEnsureNode(node) || isERBBeginNode(node) || isERBUnlessNode(node) || isERBRenderNode(node) || isERBStrictLocalsNode(node) || isERBYieldNode(node) || isERBInNode(node) } /** * Map of node classes to their corresponding type guard functions * * @example * const guard = NODE_TYPE_GUARDS[HTMLTextNode] * * if (guard(node)) { * // node is HTMLTextNode * } */ export const NODE_TYPE_GUARDS = new Map Node, (node: Node) => boolean>([ [DocumentNode, isDocumentNode], [LiteralNode, isLiteralNode], [HTMLOpenTagNode, isHTMLOpenTagNode], [HTMLConditionalOpenTagNode, isHTMLConditionalOpenTagNode], [HTMLCloseTagNode, isHTMLCloseTagNode], [HTMLOmittedCloseTagNode, isHTMLOmittedCloseTagNode], [HTMLVirtualCloseTagNode, isHTMLVirtualCloseTagNode], [HTMLElementNode, isHTMLElementNode], [HTMLConditionalElementNode, isHTMLConditionalElementNode], [HTMLAttributeValueNode, isHTMLAttributeValueNode], [HTMLAttributeNameNode, isHTMLAttributeNameNode], [HTMLAttributeNode, isHTMLAttributeNode], [RubyLiteralNode, isRubyLiteralNode], [RubyHTMLAttributesSplatNode, isRubyHTMLAttributesSplatNode], [ERBOpenTagNode, isERBOpenTagNode], [HTMLTextNode, isHTMLTextNode], [HTMLCommentNode, isHTMLCommentNode], [HTMLDoctypeNode, isHTMLDoctypeNode], [XMLDeclarationNode, isXMLDeclarationNode], [CDATANode, isCDATANode], [WhitespaceNode, isWhitespaceNode], [ERBContentNode, isERBContentNode], [ERBEndNode, isERBEndNode], [ERBElseNode, isERBElseNode], [ERBIfNode, isERBIfNode], [ERBBlockNode, isERBBlockNode], [ERBWhenNode, isERBWhenNode], [ERBCaseNode, isERBCaseNode], [ERBCaseMatchNode, isERBCaseMatchNode], [ERBWhileNode, isERBWhileNode], [ERBUntilNode, isERBUntilNode], [ERBForNode, isERBForNode], [ERBRescueNode, isERBRescueNode], [ERBEnsureNode, isERBEnsureNode], [ERBBeginNode, isERBBeginNode], [ERBUnlessNode, isERBUnlessNode], [RubyRenderLocalNode, isRubyRenderLocalNode], [RubyRenderKeywordsNode, isRubyRenderKeywordsNode], [ERBRenderNode, isERBRenderNode], [RubyParameterNode, isRubyParameterNode], [ERBStrictLocalsNode, isERBStrictLocalsNode], [ERBYieldNode, isERBYieldNode], [ERBInNode, isERBInNode], ]) /** * Map of AST node type strings to their corresponding type guard functions * * @example * const guard = AST_TYPE_GUARDS["AST_HTML_TEXT_NODE"] * * if (guard(node)) { * // node is HTMLTextNode * } */ export const AST_TYPE_GUARDS = new Map boolean>([ ["AST_DOCUMENT_NODE", isDocumentNode], ["AST_LITERAL_NODE", isLiteralNode], ["AST_HTML_OPEN_TAG_NODE", isHTMLOpenTagNode], ["AST_HTML_CONDITIONAL_OPEN_TAG_NODE", isHTMLConditionalOpenTagNode], ["AST_HTML_CLOSE_TAG_NODE", isHTMLCloseTagNode], ["AST_HTML_OMITTED_CLOSE_TAG_NODE", isHTMLOmittedCloseTagNode], ["AST_HTML_VIRTUAL_CLOSE_TAG_NODE", isHTMLVirtualCloseTagNode], ["AST_HTML_ELEMENT_NODE", isHTMLElementNode], ["AST_HTML_CONDITIONAL_ELEMENT_NODE", isHTMLConditionalElementNode], ["AST_HTML_ATTRIBUTE_VALUE_NODE", isHTMLAttributeValueNode], ["AST_HTML_ATTRIBUTE_NAME_NODE", isHTMLAttributeNameNode], ["AST_HTML_ATTRIBUTE_NODE", isHTMLAttributeNode], ["AST_RUBY_LITERAL_NODE", isRubyLiteralNode], ["AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE", isRubyHTMLAttributesSplatNode], ["AST_ERB_OPEN_TAG_NODE", isERBOpenTagNode], ["AST_HTML_TEXT_NODE", isHTMLTextNode], ["AST_HTML_COMMENT_NODE", isHTMLCommentNode], ["AST_HTML_DOCTYPE_NODE", isHTMLDoctypeNode], ["AST_XML_DECLARATION_NODE", isXMLDeclarationNode], ["AST_CDATA_NODE", isCDATANode], ["AST_WHITESPACE_NODE", isWhitespaceNode], ["AST_ERB_CONTENT_NODE", isERBContentNode], ["AST_ERB_END_NODE", isERBEndNode], ["AST_ERB_ELSE_NODE", isERBElseNode], ["AST_ERB_IF_NODE", isERBIfNode], ["AST_ERB_BLOCK_NODE", isERBBlockNode], ["AST_ERB_WHEN_NODE", isERBWhenNode], ["AST_ERB_CASE_NODE", isERBCaseNode], ["AST_ERB_CASE_MATCH_NODE", isERBCaseMatchNode], ["AST_ERB_WHILE_NODE", isERBWhileNode], ["AST_ERB_UNTIL_NODE", isERBUntilNode], ["AST_ERB_FOR_NODE", isERBForNode], ["AST_ERB_RESCUE_NODE", isERBRescueNode], ["AST_ERB_ENSURE_NODE", isERBEnsureNode], ["AST_ERB_BEGIN_NODE", isERBBeginNode], ["AST_ERB_UNLESS_NODE", isERBUnlessNode], ["AST_RUBY_RENDER_LOCAL_NODE", isRubyRenderLocalNode], ["AST_RUBY_RENDER_KEYWORDS_NODE", isRubyRenderKeywordsNode], ["AST_ERB_RENDER_NODE", isERBRenderNode], ["AST_RUBY_PARAMETER_NODE", isRubyParameterNode], ["AST_ERB_STRICT_LOCALS_NODE", isERBStrictLocalsNode], ["AST_ERB_YIELD_NODE", isERBYieldNode], ["AST_ERB_IN_NODE", isERBInNode], ]) type NodeTypeToClass = { "AST_DOCUMENT_NODE": DocumentNode; "AST_LITERAL_NODE": LiteralNode; "AST_HTML_OPEN_TAG_NODE": HTMLOpenTagNode; "AST_HTML_CONDITIONAL_OPEN_TAG_NODE": HTMLConditionalOpenTagNode; "AST_HTML_CLOSE_TAG_NODE": HTMLCloseTagNode; "AST_HTML_OMITTED_CLOSE_TAG_NODE": HTMLOmittedCloseTagNode; "AST_HTML_VIRTUAL_CLOSE_TAG_NODE": HTMLVirtualCloseTagNode; "AST_HTML_ELEMENT_NODE": HTMLElementNode; "AST_HTML_CONDITIONAL_ELEMENT_NODE": HTMLConditionalElementNode; "AST_HTML_ATTRIBUTE_VALUE_NODE": HTMLAttributeValueNode; "AST_HTML_ATTRIBUTE_NAME_NODE": HTMLAttributeNameNode; "AST_HTML_ATTRIBUTE_NODE": HTMLAttributeNode; "AST_RUBY_LITERAL_NODE": RubyLiteralNode; "AST_RUBY_HTML_ATTRIBUTES_SPLAT_NODE": RubyHTMLAttributesSplatNode; "AST_ERB_OPEN_TAG_NODE": ERBOpenTagNode; "AST_HTML_TEXT_NODE": HTMLTextNode; "AST_HTML_COMMENT_NODE": HTMLCommentNode; "AST_HTML_DOCTYPE_NODE": HTMLDoctypeNode; "AST_XML_DECLARATION_NODE": XMLDeclarationNode; "AST_CDATA_NODE": CDATANode; "AST_WHITESPACE_NODE": WhitespaceNode; "AST_ERB_CONTENT_NODE": ERBContentNode; "AST_ERB_END_NODE": ERBEndNode; "AST_ERB_ELSE_NODE": ERBElseNode; "AST_ERB_IF_NODE": ERBIfNode; "AST_ERB_BLOCK_NODE": ERBBlockNode; "AST_ERB_WHEN_NODE": ERBWhenNode; "AST_ERB_CASE_NODE": ERBCaseNode; "AST_ERB_CASE_MATCH_NODE": ERBCaseMatchNode; "AST_ERB_WHILE_NODE": ERBWhileNode; "AST_ERB_UNTIL_NODE": ERBUntilNode; "AST_ERB_FOR_NODE": ERBForNode; "AST_ERB_RESCUE_NODE": ERBRescueNode; "AST_ERB_ENSURE_NODE": ERBEnsureNode; "AST_ERB_BEGIN_NODE": ERBBeginNode; "AST_ERB_UNLESS_NODE": ERBUnlessNode; "AST_RUBY_RENDER_LOCAL_NODE": RubyRenderLocalNode; "AST_RUBY_RENDER_KEYWORDS_NODE": RubyRenderKeywordsNode; "AST_ERB_RENDER_NODE": ERBRenderNode; "AST_RUBY_PARAMETER_NODE": RubyParameterNode; "AST_ERB_STRICT_LOCALS_NODE": ERBStrictLocalsNode; "AST_ERB_YIELD_NODE": ERBYieldNode; "AST_ERB_IN_NODE": ERBInNode; } type ClassToInstance = T extends new (...args: any[]) => infer R ? R : never /** * Checks if a node matches any of the provided type identifiers with proper type narrowing * Supports AST type strings, node classes, or type guard functions * * @example * if (isAnyOf(node, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE")) { * // node is narrowed to HTMLTextNode | LiteralNode * } * * @example * if (isAnyOf(node, HTMLTextNode, LiteralNode)) { * // node is narrowed to HTMLTextNode | LiteralNode * } */ export function isAnyOf(node: Node, ...types: Array Node) | ((node: Node) => boolean)>): boolean { return types.some(type => { if (typeof type === 'string') { return isNode(node, type) } else if (typeof type === 'function' && type.prototype && type.prototype.constructor === type && NODE_TYPE_GUARDS.has(type as new (...args: any[]) => Node)) { return isNode(node, type as new (...args: any[]) => Node) } else if (typeof type === 'function') { return (type as (node: Node) => boolean)(node) } else { return false } }) } /** * Checks if a node does NOT match any of the provided type identifiers * Supports AST type strings, node classes, or type guard functions * This is the logical inverse of isAnyOf * * @example * if (isNoneOf(node, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE")) { * // node is neither HTMLTextNode nor LiteralNode * } * * @example * if (isNoneOf(node, HTMLTextNode, LiteralNode)) { * // node is neither HTMLTextNode nor LiteralNode * } * * @example * if (isNoneOf(node, isHTMLTextNode, isLiteralNode)) { * // node is neither HTMLTextNode nor LiteralNode * } */ export function isNoneOf( node: Node, ...types: Array Node) | ((node: Node) => boolean)> ): boolean { return !isAnyOf(node, ...types) } /** * Checks if ALL nodes in an array match any of the provided type identifiers * Supports AST type strings, node classes, or type guard functions * Provides type narrowing for the array when true * * @example * if (areAllOfType(nodes, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE")) { * // nodes is narrowed to (HTMLTextNode | LiteralNode)[] * } * * @example * if (areAllOfType(nodes, HTMLTextNode, LiteralNode)) { * // nodes is narrowed to (HTMLTextNode | LiteralNode)[] * } * * @example * if (areAllOfType(nodes, isHTMLTextNode, isLiteralNode)) { * // all nodes are either HTMLTextNode or LiteralNode * } */ export function areAllOfType( nodes: Node[], ...types: T ): nodes is NodeTypeToClass[T[number]][] export function areAllOfType Node)[]>( nodes: Node[], ...types: T ): nodes is ClassToInstance[] export function areAllOfType( nodes: Node[], ...types: Array<(node: Node) => boolean> ): boolean export function areAllOfType( nodes: Node[], ...types: Array Node) | ((node: Node) => boolean)> ): boolean { return nodes.every(node => isAnyOf(node, ...types)) } /** * Filters an array of nodes to only include nodes matching any of the provided type identifiers * Supports AST type strings, node classes, or type guard functions * Returns a properly typed array of the filtered nodes * * @example * const filtered = filterNodes(nodes, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE") * // filtered is typed as (HTMLTextNode | LiteralNode)[] * * @example * const filtered = filterNodes(nodes, HTMLTextNode, LiteralNode) * // filtered is typed as (HTMLTextNode | LiteralNode)[] * * @example * const filtered = filterNodes(nodes, isHTMLTextNode, isLiteralNode) * // filtered contains only HTMLTextNode or LiteralNode instances * * @example * const filtered = filterNodes(nodes, "AST_LITERAL_NODE", HTMLTextNode, isERBContentNode) * // filtered contains only LiteralNode, HTMLTextNode, or ERBContentNode instances */ export function filterNodes( nodes: Node[] | undefined | null, ...types: T ): NodeTypeToClass[T[number]][] export function filterNodes Node)[]>( nodes: Node[] | undefined | null, ...types: T ): ClassToInstance[] export function filterNodes( nodes: Node[] | undefined | null, ...types: Array<(node: Node) => boolean> ): Node[] export function filterNodes( nodes: Node[] | undefined | null, ...types: Array Node) | ((node: Node) => boolean)> ): Node[] { if (!nodes) return [] return nodes.filter(node => isAnyOf(node, ...types)) } /** * Checks if a node matches a specific type identifier with proper type narrowing * Supports AST type strings or node classes * * @example * if (isNode(node, "AST_HTML_TEXT_NODE")) { * // node is narrowed to HTMLTextNode * } * * @example * if (isNode(node, HTMLTextNode)) { * // node is narrowed to HTMLTextNode * } */ export function isNode( node: Node | null | undefined, type: T ): node is NodeTypeToClass[T] export function isNode Node>( node: Node | null | undefined, type: T ): node is ClassToInstance export function isNode( node: Node | null | undefined, type: NodeType | (new (...args: any[]) => Node) ): boolean { if (!node) return false if (typeof type === 'string') { const guard = AST_TYPE_GUARDS.get(type) return guard ? guard(node) : false } else if (typeof type === 'function') { const guard = NODE_TYPE_GUARDS.get(type as new (...args: any[]) => Node) return guard ? guard(node) : false } else { return false } } export function isToken(object: any): object is Token { return (object instanceof Token) || (object?.constructor?.name === "Token" && "value" in object) || (object as any).type?.startsWith('TOKEN_') } export function isParseResult(object: any): object is ParseResult { return (object instanceof ParseResult) || (object?.constructor?.name === "ParseResult" && "value" in object) } /** * Checks if a node has children (contains other nodes) */ export function hasChildren(node: Node): boolean { return isDocumentNode(node) || isHTMLOpenTagNode(node) || isHTMLCloseTagNode(node) || isHTMLElementNode(node) || isHTMLAttributeValueNode(node) || isHTMLAttributeNameNode(node) || isHTMLCommentNode(node) || isHTMLDoctypeNode(node) || isERBElseNode(node) || isERBIfNode(node) || isERBBlockNode(node) || isERBWhenNode(node) || isERBCaseNode(node) || isERBCaseMatchNode(node) || isERBWhileNode(node) || isERBUntilNode(node) || isERBForNode(node) || isERBRescueNode(node) || isERBEnsureNode(node) || isERBBeginNode(node) || isERBUnlessNode(node) || isERBInNode(node) } /** * Filter functions for extracting specific node types from arrays */ /** * Filters an array of nodes to only include DocumentNode nodes */ export function filterDocumentNodes(nodes: Node[]): DocumentNode[] { return nodes.filter(isDocumentNode) as DocumentNode[] } /** * Filters an array of nodes to only include LiteralNode nodes */ export function filterLiteralNodes(nodes: Node[]): LiteralNode[] { return nodes.filter(isLiteralNode) as LiteralNode[] } /** * Filters an array of nodes to only include HTMLOpenTagNode nodes */ export function filterHTMLOpenTagNodes(nodes: Node[]): HTMLOpenTagNode[] { return nodes.filter(isHTMLOpenTagNode) as HTMLOpenTagNode[] } /** * Filters an array of nodes to only include HTMLConditionalOpenTagNode nodes */ export function filterHTMLConditionalOpenTagNodes(nodes: Node[]): HTMLConditionalOpenTagNode[] { return nodes.filter(isHTMLConditionalOpenTagNode) as HTMLConditionalOpenTagNode[] } /** * Filters an array of nodes to only include HTMLCloseTagNode nodes */ export function filterHTMLCloseTagNodes(nodes: Node[]): HTMLCloseTagNode[] { return nodes.filter(isHTMLCloseTagNode) as HTMLCloseTagNode[] } /** * Filters an array of nodes to only include HTMLOmittedCloseTagNode nodes */ export function filterHTMLOmittedCloseTagNodes(nodes: Node[]): HTMLOmittedCloseTagNode[] { return nodes.filter(isHTMLOmittedCloseTagNode) as HTMLOmittedCloseTagNode[] } /** * Filters an array of nodes to only include HTMLVirtualCloseTagNode nodes */ export function filterHTMLVirtualCloseTagNodes(nodes: Node[]): HTMLVirtualCloseTagNode[] { return nodes.filter(isHTMLVirtualCloseTagNode) as HTMLVirtualCloseTagNode[] } /** * Filters an array of nodes to only include HTMLElementNode nodes */ export function filterHTMLElementNodes(nodes: Node[]): HTMLElementNode[] { return nodes.filter(isHTMLElementNode) as HTMLElementNode[] } /** * Filters an array of nodes to only include HTMLConditionalElementNode nodes */ export function filterHTMLConditionalElementNodes(nodes: Node[]): HTMLConditionalElementNode[] { return nodes.filter(isHTMLConditionalElementNode) as HTMLConditionalElementNode[] } /** * Filters an array of nodes to only include HTMLAttributeValueNode nodes */ export function filterHTMLAttributeValueNodes(nodes: Node[]): HTMLAttributeValueNode[] { return nodes.filter(isHTMLAttributeValueNode) as HTMLAttributeValueNode[] } /** * Filters an array of nodes to only include HTMLAttributeNameNode nodes */ export function filterHTMLAttributeNameNodes(nodes: Node[]): HTMLAttributeNameNode[] { return nodes.filter(isHTMLAttributeNameNode) as HTMLAttributeNameNode[] } /** * Filters an array of nodes to only include HTMLAttributeNode nodes */ export function filterHTMLAttributeNodes(nodes: Node[]): HTMLAttributeNode[] { return nodes.filter(isHTMLAttributeNode) as HTMLAttributeNode[] } /** * Filters an array of nodes to only include RubyLiteralNode nodes */ export function filterRubyLiteralNodes(nodes: Node[]): RubyLiteralNode[] { return nodes.filter(isRubyLiteralNode) as RubyLiteralNode[] } /** * Filters an array of nodes to only include RubyHTMLAttributesSplatNode nodes */ export function filterRubyHTMLAttributesSplatNodes(nodes: Node[]): RubyHTMLAttributesSplatNode[] { return nodes.filter(isRubyHTMLAttributesSplatNode) as RubyHTMLAttributesSplatNode[] } /** * Filters an array of nodes to only include ERBOpenTagNode nodes */ export function filterERBOpenTagNodes(nodes: Node[]): ERBOpenTagNode[] { return nodes.filter(isERBOpenTagNode) as ERBOpenTagNode[] } /** * Filters an array of nodes to only include HTMLTextNode nodes */ export function filterHTMLTextNodes(nodes: Node[]): HTMLTextNode[] { return nodes.filter(isHTMLTextNode) as HTMLTextNode[] } /** * Filters an array of nodes to only include HTMLCommentNode nodes */ export function filterHTMLCommentNodes(nodes: Node[]): HTMLCommentNode[] { return nodes.filter(isHTMLCommentNode) as HTMLCommentNode[] } /** * Filters an array of nodes to only include HTMLDoctypeNode nodes */ export function filterHTMLDoctypeNodes(nodes: Node[]): HTMLDoctypeNode[] { return nodes.filter(isHTMLDoctypeNode) as HTMLDoctypeNode[] } /** * Filters an array of nodes to only include XMLDeclarationNode nodes */ export function filterXMLDeclarationNodes(nodes: Node[]): XMLDeclarationNode[] { return nodes.filter(isXMLDeclarationNode) as XMLDeclarationNode[] } /** * Filters an array of nodes to only include CDATANode nodes */ export function filterCDATANodes(nodes: Node[]): CDATANode[] { return nodes.filter(isCDATANode) as CDATANode[] } /** * Filters an array of nodes to only include WhitespaceNode nodes */ export function filterWhitespaceNodes(nodes: Node[]): WhitespaceNode[] { return nodes.filter(isWhitespaceNode) as WhitespaceNode[] } /** * Filters an array of nodes to only include ERBContentNode nodes */ export function filterERBContentNodes(nodes: Node[]): ERBContentNode[] { return nodes.filter(isERBContentNode) as ERBContentNode[] } /** * Filters an array of nodes to only include ERBEndNode nodes */ export function filterERBEndNodes(nodes: Node[]): ERBEndNode[] { return nodes.filter(isERBEndNode) as ERBEndNode[] } /** * Filters an array of nodes to only include ERBElseNode nodes */ export function filterERBElseNodes(nodes: Node[]): ERBElseNode[] { return nodes.filter(isERBElseNode) as ERBElseNode[] } /** * Filters an array of nodes to only include ERBIfNode nodes */ export function filterERBIfNodes(nodes: Node[]): ERBIfNode[] { return nodes.filter(isERBIfNode) as ERBIfNode[] } /** * Filters an array of nodes to only include ERBBlockNode nodes */ export function filterERBBlockNodes(nodes: Node[]): ERBBlockNode[] { return nodes.filter(isERBBlockNode) as ERBBlockNode[] } /** * Filters an array of nodes to only include ERBWhenNode nodes */ export function filterERBWhenNodes(nodes: Node[]): ERBWhenNode[] { return nodes.filter(isERBWhenNode) as ERBWhenNode[] } /** * Filters an array of nodes to only include ERBCaseNode nodes */ export function filterERBCaseNodes(nodes: Node[]): ERBCaseNode[] { return nodes.filter(isERBCaseNode) as ERBCaseNode[] } /** * Filters an array of nodes to only include ERBCaseMatchNode nodes */ export function filterERBCaseMatchNodes(nodes: Node[]): ERBCaseMatchNode[] { return nodes.filter(isERBCaseMatchNode) as ERBCaseMatchNode[] } /** * Filters an array of nodes to only include ERBWhileNode nodes */ export function filterERBWhileNodes(nodes: Node[]): ERBWhileNode[] { return nodes.filter(isERBWhileNode) as ERBWhileNode[] } /** * Filters an array of nodes to only include ERBUntilNode nodes */ export function filterERBUntilNodes(nodes: Node[]): ERBUntilNode[] { return nodes.filter(isERBUntilNode) as ERBUntilNode[] } /** * Filters an array of nodes to only include ERBForNode nodes */ export function filterERBForNodes(nodes: Node[]): ERBForNode[] { return nodes.filter(isERBForNode) as ERBForNode[] } /** * Filters an array of nodes to only include ERBRescueNode nodes */ export function filterERBRescueNodes(nodes: Node[]): ERBRescueNode[] { return nodes.filter(isERBRescueNode) as ERBRescueNode[] } /** * Filters an array of nodes to only include ERBEnsureNode nodes */ export function filterERBEnsureNodes(nodes: Node[]): ERBEnsureNode[] { return nodes.filter(isERBEnsureNode) as ERBEnsureNode[] } /** * Filters an array of nodes to only include ERBBeginNode nodes */ export function filterERBBeginNodes(nodes: Node[]): ERBBeginNode[] { return nodes.filter(isERBBeginNode) as ERBBeginNode[] } /** * Filters an array of nodes to only include ERBUnlessNode nodes */ export function filterERBUnlessNodes(nodes: Node[]): ERBUnlessNode[] { return nodes.filter(isERBUnlessNode) as ERBUnlessNode[] } /** * Filters an array of nodes to only include RubyRenderLocalNode nodes */ export function filterRubyRenderLocalNodes(nodes: Node[]): RubyRenderLocalNode[] { return nodes.filter(isRubyRenderLocalNode) as RubyRenderLocalNode[] } /** * Filters an array of nodes to only include RubyRenderKeywordsNode nodes */ export function filterRubyRenderKeywordsNodes(nodes: Node[]): RubyRenderKeywordsNode[] { return nodes.filter(isRubyRenderKeywordsNode) as RubyRenderKeywordsNode[] } /** * Filters an array of nodes to only include ERBRenderNode nodes */ export function filterERBRenderNodes(nodes: Node[]): ERBRenderNode[] { return nodes.filter(isERBRenderNode) as ERBRenderNode[] } /** * Filters an array of nodes to only include RubyParameterNode nodes */ export function filterRubyParameterNodes(nodes: Node[]): RubyParameterNode[] { return nodes.filter(isRubyParameterNode) as RubyParameterNode[] } /** * Filters an array of nodes to only include ERBStrictLocalsNode nodes */ export function filterERBStrictLocalsNodes(nodes: Node[]): ERBStrictLocalsNode[] { return nodes.filter(isERBStrictLocalsNode) as ERBStrictLocalsNode[] } /** * Filters an array of nodes to only include ERBYieldNode nodes */ export function filterERBYieldNodes(nodes: Node[]): ERBYieldNode[] { return nodes.filter(isERBYieldNode) as ERBYieldNode[] } /** * Filters an array of nodes to only include ERBInNode nodes */ export function filterERBInNodes(nodes: Node[]): ERBInNode[] { return nodes.filter(isERBInNode) as ERBInNode[] }