or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--helper-member-expression-to-functions

Helper function to replace certain member expressions with function calls

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/helper-member-expression-to-functions@7.27.x

To install, run

npx @tessl/cli install tessl/npm-babel--helper-member-expression-to-functions@7.27.0

index.mddocs/

@babel/helper-member-expression-to-functions

@babel/helper-member-expression-to-functions is a specialized Babel helper that transforms member expressions into function calls for complex scenarios. It handles optional chaining, private properties, computed property access, and provides essential infrastructure for Babel plugins that need to replace property access patterns with more complex runtime behavior.

Package Information

  • Package Name: @babel/helper-member-expression-to-functions
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @babel/helper-member-expression-to-functions

Core Imports

import memberExpressionToFunctions, { Handler, HandlerState, willPathCastToBoolean } from "@babel/helper-member-expression-to-functions";

For CommonJS:

const memberExpressionToFunctions = require("@babel/helper-member-expression-to-functions").default;
const { Handler, HandlerState, willPathCastToBoolean } = require("@babel/helper-member-expression-to-functions");

Basic Usage

import traverse from "@babel/traverse";
import memberExpressionToFunctions, { Handler, willPathCastToBoolean } from "@babel/helper-member-expression-to-functions";
import * as t from "@babel/types";

// Example handler implementation
const handler: Handler<{}> = {
  get(member) {
    return t.callExpression(t.identifier("_get"), [member.node]);
  },
  set(member, value) {
    return t.callExpression(t.identifier("_set"), [member.node, value]);
  },
  call(member, args) {
    return t.callExpression(t.identifier("_call"), [member.node, ...args]);
  },
  optionalCall(member, args) {
    return t.callExpression(t.identifier("_optionalCall"), [member.node, ...args]);
  },
  delete(member) {
    return t.callExpression(t.identifier("_delete"), [member.node]);
  },
  destructureSet(member) {
    return t.callExpression(t.identifier("_destructureSet"), [member.node]);
  },
  boundGet(member) {
    return t.callExpression(
      t.memberExpression(this.get(member), t.identifier("bind")),
      [t.thisExpression()]
    );
  }
};

// Transform member expressions in AST
memberExpressionToFunctions(path, {
  MemberExpression(path) {
    this.handle(path);
  },
  OptionalMemberExpression(path) {
    this.handle(path);
  }
}, handler);

// Alternative: Handle all member expressions with single visitor
memberExpressionToFunctions(path, {
  "MemberExpression|OptionalMemberExpression"(path) {
    this.handle(path);
  }
}, handler);

// Conditional transformation based on context
memberExpressionToFunctions(path, {
  MemberExpression(path) {
    // Only transform private property access
    if (path.get("property").isPrivateName()) {
      this.handle(path);
    }
  }
}, handler);

Architecture

@babel/helper-member-expression-to-functions is built around a visitor-based transformation system with several key components:

  • Main Transformation Function: Traverses AST nodes using a visitor pattern and applies handler functions
  • Handler Interface: Defines how different member expression operations (get, set, call, etc.) are transformed
  • HandlerState: Extended handler interface that includes transformation utilities and memoization
  • AssignmentMemoiser: Optimizes repeated member access by memoizing expressions to avoid reevaluation
  • Utility Functions: Helper functions like willPathCastToBoolean for analyzing AST context

The system handles complex scenarios including optional chaining, private properties, computed access, and ensures proper context preservation for method calls.

Capabilities

Member Expression Transformation

Core transformation function that converts member expressions into function calls with custom handlers.

/**
 * Transform member expressions into function calls using custom handler functions
 * @param path - Babel AST node path to traverse  
 * @param visitor - Babel visitor object defining which node types to transform and their handlers
 * @param state - Combined object containing Handler interface methods and optional custom state
 */
export default function memberExpressionToFunctions<State extends object>(
  path: NodePath,
  visitor: Visitor<HandlerState<State>>,
  state: Handler<State> & State
): void;

interface Visitor<State> {
  [key: string]: (path: NodePath, state: State) => void;
}

Handler Interface

The transformation system requires implementing the Handler interface to define how member expressions are converted.

interface Handler<State> {
  /** Optional memoization method called when member is self-referential */
  memoise?(
    this: HandlerState<State> & State,
    member: Member,
    count: number
  ): void;
  
  /** Handle destructuring assignments like { prop } = obj or [elem] = arr */
  destructureSet(
    this: HandlerState<State> & State,
    member: Member
  ): t.Expression;
  
  /** Handle bound member access for tagged templates */
  boundGet(
    this: HandlerState<State> & State, 
    member: Member
  ): t.Expression;
  
  /** Optional simple set operation for update expressions */
  simpleSet?(
    this: HandlerState<State> & State,
    member: Member
  ): t.Expression;
  
  /** Handle member get operations like obj.prop */
  get(
    this: HandlerState<State> & State,
    member: Member
  ): t.Expression;
  
  /** Handle member set operations like obj.prop = value */
  set(
    this: HandlerState<State> & State,
    member: Member,
    value: t.Expression
  ): t.Expression;
  
  /** Handle method calls like obj.method(args) */
  call(
    this: HandlerState<State> & State,
    member: Member,
    args: t.CallExpression["arguments"]
  ): t.Expression;
  
  /** Handle optional method calls like obj?.method?.(args) */
  optionalCall(
    this: HandlerState<State> & State,
    member: Member,
    args: t.OptionalCallExpression["arguments"]
  ): t.Expression;
  
  /** Handle member deletion like delete obj.prop */
  delete(
    this: HandlerState<State> & State,
    member: Member
  ): t.Expression;
}

HandlerState Interface

Extended handler interface provided by the transformation system.

interface HandlerState<State = object> extends Handler<State> {
  /** Core transformation handler method */
  handle(
    this: HandlerState<State> & State,
    member: Member,
    noDocumentAll?: boolean
  ): void;
  
  /** Assignment memoization utility */
  memoiser: AssignmentMemoiser;
}

Path Boolean Casting Utility

Utility function to determine if a path will be cast to boolean in its evaluation context.

/**
 * Test if a NodePath will be cast to boolean when evaluated
 * @param path - The AST node path to analyze
 * @returns true if the path will be cast to boolean, false otherwise
 */
export function willPathCastToBoolean(path: NodePath): boolean;

Usage Examples:

import { willPathCastToBoolean } from "@babel/helper-member-expression-to-functions";

// Returns true - used in if condition
const testPath = getNodePath("if (a?.#b) {}").get("test");
willPathCastToBoolean(testPath); // true

// Returns false - standalone expression
const standalonePath = getNodePath("a?.#b");
willPathCastToBoolean(standalonePath); // false

// Returns true - used in logical expression
const logicalPath = getNodePath("a?.#b && c").get("left");
willPathCastToBoolean(logicalPath); // true

Types

/** Type alias for member expression node paths */
type Member = NodePath<t.OptionalMemberExpression | t.MemberExpression>;

/** Assignment memoization utility class that optimizes repeated member expression access */
class AssignmentMemoiser {
  /** Check if expression has been memoized for reuse */
  has(key: t.Expression): boolean;
  
  /** 
   * Get memoized value and decrement usage count
   * Returns assignment expression on final usage to perform the memoization
   */
  get(key: t.Expression): t.Expression | undefined;
  
  /** 
   * Set memoized value with expected usage count
   * @param key - Expression to memoize
   * @param value - Identifier to store the memoized value
   * @param count - Number of times this expression will be accessed
   */
  set(key: t.Expression, value: t.Identifier, count: number): void;
}

Supported Transformations

The helper automatically handles the following member expression patterns:

  • Simple access: obj.prop_get(obj.prop)
  • Optional chaining: obj?.prop → conditional with null checks
  • Computed access: obj[key]_get(obj[key])
  • Method calls: obj.method(args)_call(obj.method, args)
  • Optional calls: obj?.method?.(args)_optionalCall(obj.method, args)
  • Assignment operations: obj.prop = value_set(obj.prop, value)
  • Compound assignments: obj.prop += value_set(obj.prop, _get(obj.prop) + value)
  • Update expressions: ++obj.prop_set(obj.prop, ++_get(obj.prop))
  • Destructuring: {prop} = obj{prop: _destructureSet(obj.prop)} = obj
  • Delete operations: delete obj.prop_delete(obj.prop)
  • Tagged templates: obj.method\template`_get(obj.method).bind(obj)`

Error Handling

The transformation system throws specific errors for unsupported operations:

  • Update expressions: Throws "can't handle update expression" for complex update scenarios
  • Private property deletion: Throws "can't delete a private class element" for delete obj?.#prop
  • Invalid AST: Throws "Internal error: unexpected [node type]" for malformed AST structures

Advanced Features

Memoization

The helper implements sophisticated memoization to avoid repeated evaluation of complex expressions:

// Handler can implement memoise method
memoise(member, count) {
  // Called when member needs to be referenced multiple times
  // count indicates how many times the member will be accessed
}

Optional Chaining Semantics

Proper handling of optional chaining with null/undefined checks:

  • Converts obj?.prop to conditional expressions with appropriate null checks
  • Maintains correct short-circuiting behavior
  • Handles nested optional chains like obj?.a?.b?.c

Context Preservation

Ensures proper this binding for method calls:

  • Bound method access for tagged template literals
  • Correct context handling in optional call chains
  • Proper this binding preservation in transformations