or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

builders.mdcloning.mdcomments.mdconstants.mdconverters.mdindex.mdmodifications.mdreact.mdretrievers.mdtraversal.mdvalidators.md
tile.json

constants.mddocs/

Constants and Utilities

Collections of operators, keywords, and utility functions for AST manipulation. These constants provide standardized collections of JavaScript operators and language constructs.

Capabilities

Operator Constants

Binary Operators

Collections of binary operators organized by category.

/**
 * All binary operators supported in expressions
 */
const BINARY_OPERATORS: string[];

/**
 * Arithmetic binary operators
 */
const NUMBER_BINARY_OPERATORS: string[];

/**
 * Boolean-returning binary operators  
 */
const BOOLEAN_BINARY_OPERATORS: string[];

/**
 * Equality comparison operators
 */
const EQUALITY_BINARY_OPERATORS: string[];

/**
 * Relational comparison operators
 */
const COMPARISON_BINARY_OPERATORS: string[];

/**
 * Numeric comparison operators (>, <, >=, <=)
 */
const BOOLEAN_NUMBER_BINARY_OPERATORS: string[];

Unary Operators

Collections of unary operators by result type.

/**
 * All unary operators
 */
const UNARY_OPERATORS: string[];

/**
 * Boolean-returning unary operators
 */
const BOOLEAN_UNARY_OPERATORS: string[];

/**
 * Number-returning unary operators
 */
const NUMBER_UNARY_OPERATORS: string[];

/**
 * String-returning unary operators
 */
const STRING_UNARY_OPERATORS: string[];

Logical Operators

Logical operators for boolean expressions.

/**
 * Logical operators (||, &&, ??)
 */
const LOGICAL_OPERATORS: string[];

Assignment Operators

All assignment operators including compound assignments.

/**
 * All assignment operators (=, +=, -=, etc.)
 */
const ASSIGNMENT_OPERATORS: string[];

Update Operators

Pre/post increment and decrement operators.

/**
 * Update operators (++, --)
 */
const UPDATE_OPERATORS: string[];

AST Structure Constants

Statement and Block Keys

Property names that contain statement or block-like structures.

/**
 * Property keys that can contain statements or blocks
 */
const STATEMENT_OR_BLOCK_KEYS: string[];

/**
 * Property keys that can be flattened (contain arrays of statements)
 */
const FLATTENABLE_KEYS: string[];

/**
 * Property keys used for loop initialization
 */
const FOR_INIT_KEYS: string[];

Comment Keys

Property names for different types of comments.

/**
 * Property keys for comment arrays
 */
const COMMENT_KEYS: readonly string[];

Inheritance Constants

Inherit Keys

Properties that should be inherited during AST transformations.

/**
 * Keys defining inheritance behavior during transformations
 */
const INHERIT_KEYS: {
  readonly optional: readonly string[];
  readonly force: readonly string[];
};

Utility Functions

Shallow Equal

Utility for comparing object properties shallowly.

/**
 * Perform shallow equality comparison between objects
 * @param actual - First object to compare
 * @param expected - Second object to compare
 * @returns Whether objects are shallowly equal
 */
function shallowEqual(actual: object, expected: object): boolean;

Legacy Constants (Conditional)

Block Scoped Symbol

Legacy symbol for block scoping (available in non-breaking builds).

/**
 * Symbol used to mark variables that were block scoped
 * @deprecated Available only in legacy builds
 */
const BLOCK_SCOPED_SYMBOL: symbol;

/**
 * Symbol used to mark bindings that should not be considered local
 * @deprecated Available only in legacy builds
 */
const NOT_LOCAL_BINDING: symbol;

Constant Values

Binary Operators

// Complete list of binary operators
const BINARY_OPERATORS = [
  "+",                    // Addition/concatenation
  "-", "/", "%", "*", "**", "&", "|", ">>", ">>>", "<<", "^", // Arithmetic/bitwise
  "==", "===", "!=", "!==",                                   // Equality
  ">", "<", ">=", "<=",                                       // Comparison
  "in", "instanceof",                                          // Type/property checks
  "|>"                                                         // Pipeline operator
];

// Number-returning binary operators
const NUMBER_BINARY_OPERATORS = [
  "-", "/", "%", "*", "**",           // Arithmetic
  "&", "|", ">>", ">>>", "<<", "^"    // Bitwise
];

// Boolean-returning comparison operators
const BOOLEAN_NUMBER_BINARY_OPERATORS = [">", "<", ">=", "<="];
const EQUALITY_BINARY_OPERATORS = ["==", "===", "!=", "!=="];
const COMPARISON_BINARY_OPERATORS = [
  ...EQUALITY_BINARY_OPERATORS,
  "in", "instanceof"
];
const BOOLEAN_BINARY_OPERATORS = [
  ...COMPARISON_BINARY_OPERATORS,
  ...BOOLEAN_NUMBER_BINARY_OPERATORS
];

Unary Operators

// All unary operators
const UNARY_OPERATORS = [
  "void", "throw",                    // Special operators
  "delete", "!",                      // Boolean-returning
  "+", "-", "~",                      // Number-returning
  "typeof"                            // String-returning
];

const BOOLEAN_UNARY_OPERATORS = ["delete", "!"];
const NUMBER_UNARY_OPERATORS = ["+", "-", "~"];
const STRING_UNARY_OPERATORS = ["typeof"];

Logical and Assignment Operators

const LOGICAL_OPERATORS = ["||", "&&", "??"];
const UPDATE_OPERATORS = ["++", "--"];

// Assignment operators (generated from other operator lists)
const ASSIGNMENT_OPERATORS = [
  "=",                                              // Basic assignment
  "+=",                                            // Addition assignment
  ...NUMBER_BINARY_OPERATORS.map(op => op + "="), // Arithmetic assignments
  ...LOGICAL_OPERATORS.map(op => op + "=")         // Logical assignments
];

Usage Examples

Operator Validation

import * as t from "@babel/types";

// Check if operator is valid for binary expressions
function isValidBinaryOperator(operator: string): boolean {
  return t.BINARY_OPERATORS.includes(operator);
}

// Check if operator returns boolean
function isBooleanBinaryOperator(operator: string): boolean {
  return t.BOOLEAN_BINARY_OPERATORS.includes(operator);
}

// Usage
console.log(isValidBinaryOperator("+")); // true
console.log(isValidBinaryOperator("**")); // true
console.log(isValidBinaryOperator("@")); // false

console.log(isBooleanBinaryOperator(">")); // true
console.log(isBooleanBinaryOperator("+")); // false

Expression Type Inference

// Infer result type of binary expression
function inferBinaryExpressionType(operator: string): "number" | "boolean" | "unknown" {
  if (t.NUMBER_BINARY_OPERATORS.includes(operator)) {
    return "number";
  }
  if (t.BOOLEAN_BINARY_OPERATORS.includes(operator)) {
    return "boolean";
  }
  return "unknown"; // Could be string concatenation, etc.
}

// Usage
console.log(inferBinaryExpressionType("*")); // "number"
console.log(inferBinaryExpressionType(">")); // "boolean"  
console.log(inferBinaryExpressionType("+")); // "unknown" (could be number or string)

Operator Precedence Helpers

// Group operators by precedence (simplified example)
function getOperatorPrecedence(operator: string): number {
  if (t.LOGICAL_OPERATORS.includes(operator)) {
    return operator === "??" ? 3 : operator === "&&" ? 4 : 5;
  }
  if (t.EQUALITY_BINARY_OPERATORS.includes(operator)) {
    return 8;
  }
  if (t.BOOLEAN_NUMBER_BINARY_OPERATORS.includes(operator)) {
    return 9;
  }
  if (["+", "-"].includes(operator)) {
    return 11;
  }
  if (["*", "/", "%"].includes(operator)) {
    return 12;
  }
  return 0; // Unknown/lowest precedence
}

// Check if parentheses needed
function needsParentheses(
  parentOperator: string, 
  childOperator: string, 
  isRightChild: boolean = false
): boolean {
  const parentPrec = getOperatorPrecedence(parentOperator);
  const childPrec = getOperatorPrecedence(childOperator);
  
  if (childPrec < parentPrec) return true;
  if (childPrec === parentPrec && isRightChild) return true;
  return false;
}

Assignment Operator Processing

// Convert compound assignment to binary expression
function expandAssignment(
  left: t.LVal,
  operator: string,
  right: t.Expression
): t.AssignmentExpression | null {
  if (!t.ASSIGNMENT_OPERATORS.includes(operator)) {
    return null;
  }
  
  if (operator === "=") {
    return t.assignmentExpression("=", left, right);
  }
  
  // Compound assignment: a += b becomes a = a + b
  const binaryOp = operator.slice(0, -1); // Remove '='
  if (t.BINARY_OPERATORS.includes(binaryOp)) {
    const binaryExpr = t.binaryExpression(
      binaryOp as any,
      left as t.Expression,
      right
    );
    return t.assignmentExpression("=", left, binaryExpr);
  }
  
  return null;
}

Unary Expression Analysis

// Analyze unary expression effects
function analyzeUnaryExpression(operator: string) {
  return {
    operator,
    returnsBoolean: t.BOOLEAN_UNARY_OPERATORS.includes(operator),
    returnsNumber: t.NUMBER_UNARY_OPERATORS.includes(operator),
    returnsString: t.STRING_UNARY_OPERATORS.includes(operator),
    hasSideEffects: operator === "delete",
    throwsException: operator === "throw"
  };
}

// Usage
console.log(analyzeUnaryExpression("!"));
// { operator: "!", returnsBoolean: true, returnsNumber: false, ... }

console.log(analyzeUnaryExpression("typeof"));
// { operator: "typeof", returnsBoolean: false, returnsString: true, ... }

AST Structure Analysis

// Check if property key can contain statements
function canContainStatements(key: string): boolean {
  return t.STATEMENT_OR_BLOCK_KEYS.includes(key);
}

// Check if property can be flattened
function isFlatteneableProperty(key: string): boolean {
  return t.FLATTENABLE_KEYS.includes(key);
}

// Check if property is used for loop initialization
function isLoopInitProperty(key: string): boolean {
  return t.FOR_INIT_KEYS.includes(key);
}

// Usage with node analysis
function analyzeNodeStructure(node: t.Node) {
  Object.keys(node).forEach(key => {
    if (canContainStatements(key)) {
      console.log(`${key} can contain statements`);
    }
    if (isFlatteneableProperty(key)) {
      console.log(`${key} can be flattened`);
    }
  });
}

Comment Property Detection

// Check if property contains comments
function isCommentProperty(key: string): boolean {
  return t.COMMENT_KEYS.includes(key);
}

// Extract all comments from a node
function extractAllComments(node: t.Node): t.Comment[] {
  const comments: t.Comment[] = [];
  
  t.COMMENT_KEYS.forEach(key => {
    const commentArray = (node as any)[key];
    if (Array.isArray(commentArray)) {
      comments.push(...commentArray);
    }
  });
  
  return comments;
}

Property Inheritance Checking

// Check if property should be inherited
function shouldInheritProperty(key: string, force: boolean = false): boolean {
  if (force) {
    return t.INHERIT_KEYS.force.includes(key);
  }
  return t.INHERIT_KEYS.optional.includes(key) || t.INHERIT_KEYS.force.includes(key);
}

// Custom inheritance with constants
function customInheritance<T extends t.Node>(child: T, parent: t.Node): T {
  // Force inherit certain properties
  t.INHERIT_KEYS.force.forEach(key => {
    if ((parent as any)[key] !== undefined) {
      (child as any)[key] = (parent as any)[key];
    }
  });
  
  // Optionally inherit others
  t.INHERIT_KEYS.optional.forEach(key => {
    if ((parent as any)[key] !== undefined && (child as any)[key] === undefined) {
      (child as any)[key] = (parent as any)[key];
    }
  });
  
  return child;
}

Utility Function Usage

// Object comparison with shallowEqual
function compareNodeProperties(node1: t.Node, node2: t.Node): boolean {
  // Compare only essential properties, ignoring location info
  const props1 = { ...node1 };
  const props2 = { ...node2 };
  
  // Remove location properties
  delete props1.start;
  delete props1.end;
  delete props1.loc;
  delete props2.start;
  delete props2.end;
  delete props2.loc;
  
  return t.shallowEqual(props1, props2);
}

// Property filtering
function filterNodeProperties(node: t.Node, includeComments: boolean = true): object {
  const filtered: any = {};
  
  Object.keys(node).forEach(key => {
    if (!includeComments && isCommentProperty(key)) {
      return; // Skip comment properties
    }
    
    if (!t.INHERIT_KEYS.force.includes(key)) {
      filtered[key] = (node as any)[key];
    }
  });
  
  return filtered;
}

Generated Node Type Constants

Node Type Collections

Babel Types provides 50+ automatically generated arrays containing node types organized by functionality. These are essential for type checking and AST analysis.

// Core node type collections
const EXPRESSION_TYPES: string[];      // All expression node types
const STATEMENT_TYPES: string[];       // All statement node types  
const DECLARATION_TYPES: string[];     // All declaration node types
const LITERAL_TYPES: string[];         // All literal node types
const FUNCTION_TYPES: string[];        // All function-related node types
const CLASS_TYPES: string[];           // All class-related node types
const PATTERN_TYPES: string[];         // All pattern node types
const LVAL_TYPES: string[];            // All left-value node types

// Structural collections
const BLOCK_TYPES: string[];           // All block statement types
const LOOP_TYPES: string[];            // All loop statement types
const CONDITIONAL_TYPES: string[];     // All conditional statement types
const SCOPABLE_TYPES: string[];        // All scope-creating node types
const BLOCKPARENT_TYPES: string[];     // All block parent node types
const TERMINATORLESS_TYPES: string[];  // Statements that don't need semicolons

// Control flow collections
const COMPLETIONSTATEMENT_TYPES: string[];  // Completion statements
const WHILE_TYPES: string[];                // While loop types
const FOR_TYPES: string[];                  // For loop types
const FORXSTATEMENT_TYPES: string[];        // For-in/of statement types

// Expression subcategories
const BINARY_TYPES: string[];          // Binary expression types
const UNARYLIKE_TYPES: string[];       // Unary-like expression types
const EXPRESSIONWRAPPER_TYPES: string[]; // Expression wrapper types
const PUREISH_TYPES: string[];         // Side-effect free expressions
const IMMUTABLE_TYPES: string[];       // Immutable value types

// Member and method collections
const METHOD_TYPES: string[];          // Method definition types
const OBJECTMEMBER_TYPES: string[];    // Object member types
const PROPERTY_TYPES: string[];        // Property-related types
const ACCESSOR_TYPES: string[];        // Accessor (getter/setter) types
const PRIVATE_TYPES: string[];         // Private member types

// Module system collections
const IMPORTOREXPORTDECLARATION_TYPES: string[]; // Import/export declarations
const EXPORTDECLARATION_TYPES: string[];         // Export declaration types
const MODULESPECIFIER_TYPES: string[];           // Module specifier types

// Type system collections (Flow)
const FLOW_TYPES: string[];            // All Flow-related types
const FLOWTYPE_TYPES: string[];        // Flow type annotation types
const FLOWBASEANNOTATION_TYPES: string[]; // Flow base annotation types
const FLOWDECLARATION_TYPES: string[]; // Flow declaration types
const FLOWPREDICATE_TYPES: string[];   // Flow predicate types

// Type system collections (TypeScript)
const TSENTITYNAME_TYPES: string[];    // TypeScript entity name types
const TSTYPE_TYPES: string[];          // TypeScript type types
const TSTYPEELEMENT_TYPES: string[];   // TypeScript type element types
const TS_TYPES: string[];              // All TypeScript-related types

// JSX collections
const JSX_TYPES: string[];             // All JSX-related types
const JSXELEMENT_TYPES: string[];      // JSX element types

// Specialized collections
const STANDARDIZED_TYPES: string[];    // Standardized node types
const FUNCTIONPARENT_TYPES: string[];  // Function parent types
const PATTERNLIKE_TYPES: string[];     // Pattern-like types
const USERWHITESPACABLE_TYPES: string[]; // User-whitespaceable types

Usage Examples

Type Checking with Generated Constants

import * as t from "@babel/types";

function analyzeNode(node: t.Node) {
  if (t.EXPRESSION_TYPES.includes(node.type)) {
    console.log("This is an expression");
  }
  
  if (t.STATEMENT_TYPES.includes(node.type)) {
    console.log("This is a statement");
  }
  
  if (t.FUNCTION_TYPES.includes(node.type)) {
    console.log("This is a function-related node");
  }
}

Finding Nodes by Category

function findNodesByCategory(ast: t.Node, category: string[]): t.Node[] {
  const found: t.Node[] = [];
  
  t.traverse(ast, (node, ancestors, state) => {
    if (category.includes(node.type)) {
      found.push(node);
    }
  });
  
  return found;
}

// Find all expressions in an AST
const expressions = findNodesByCategory(ast, t.EXPRESSION_TYPES);

// Find all loop statements
const loops = findNodesByCategory(ast, t.LOOP_TYPES);

// Find all immutable values
const immutables = findNodesByCategory(ast, t.IMMUTABLE_TYPES);

Conditional Processing

function processNodeByType(node: t.Node) {
  if (t.LITERAL_TYPES.includes(node.type)) {
    console.log("Processing literal value");
    // Handle literals
  } else if (t.BINARY_TYPES.includes(node.type)) {
    console.log("Processing binary operation");
    // Handle binary expressions
  } else if (t.FUNCTION_TYPES.includes(node.type)) {
    console.log("Processing function");
    // Handle functions
  }
}

Validation and Filtering

function filterPureExpressions(nodes: t.Node[]): t.Node[] {
  return nodes.filter(node => 
    t.PUREISH_TYPES.includes(node.type)
  );
}

function isControlFlow(node: t.Node): boolean {
  return t.CONDITIONAL_TYPES.includes(node.type) ||
         t.LOOP_TYPES.includes(node.type) ||
         t.COMPLETIONSTATEMENT_TYPES.includes(node.type);
}

function requiresSemicolon(node: t.Node): boolean {
  return !t.TERMINATORLESS_TYPES.includes(node.type);
}

AST Analysis

function analyzeASTComplexity(ast: t.Node) {
  const stats = {
    expressions: 0,
    statements: 0,
    functions: 0,
    loops: 0,
    conditionals: 0
  };
  
  t.traverse(ast, (node, ancestors, state) => {
    if (t.EXPRESSION_TYPES.includes(node.type)) stats.expressions++;
    if (t.STATEMENT_TYPES.includes(node.type)) stats.statements++;
    if (t.FUNCTION_TYPES.includes(node.type)) stats.functions++;
    if (t.LOOP_TYPES.includes(node.type)) stats.loops++;
    if (t.CONDITIONAL_TYPES.includes(node.type)) stats.conditionals++;
  });
  
  return stats;
}

Note: These generated constants are automatically maintained and updated as Babel adds support for new JavaScript features and proposals. They provide a reliable way to categorize and work with AST nodes without hardcoding node type strings.