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

retrievers.mddocs/

Identifier and Binding Retrieval

Utilities for extracting binding identifiers and function names from AST nodes. These functions help analyze variable declarations, assignments, and function definitions in JavaScript code.

Capabilities

Binding Identifiers

Get Binding Identifiers

Extract all binding identifiers from a node and its children.

/**
 * Extract binding identifiers from a node
 * @param node - Node to extract bindings from
 * @param duplicates - Whether to collect duplicate bindings in arrays (default: false)
 * @param outerOnly - Whether to only collect outer-level bindings (default: false)
 * @param newBindingsOnly - Whether to only collect new bindings, excluding assignments (default: false)
 * @returns Object mapping identifier names to identifiers or arrays of identifiers
 */
function getBindingIdentifiers(
  node: t.Node,
  duplicates: true,
  outerOnly?: boolean,
  newBindingsOnly?: boolean
): Record<string, Array<t.Identifier>>;

function getBindingIdentifiers(
  node: t.Node,
  duplicates?: false,
  outerOnly?: boolean,
  newBindingsOnly?: boolean
): Record<string, t.Identifier>;

Get Outer Binding Identifiers

Extract only outer-level binding identifiers, excluding nested bindings.

/**
 * Extract only outer-level binding identifiers
 * @param node - Node to extract bindings from
 * @param duplicates - Whether to collect duplicate bindings in arrays (default: false)
 * @returns Object mapping identifier names to identifiers or arrays of identifiers
 */
function getOuterBindingIdentifiers(
  node: t.Node,
  duplicates: true
): Record<string, Array<t.Identifier>>;

function getOuterBindingIdentifiers(
  node: t.Node,
  duplicates?: false
): Record<string, t.Identifier>;

Assignment Identifiers

Get Assignment Identifiers

Extract identifiers that are being assigned to in assignment expressions.

/**
 * Extract identifiers from assignment expressions
 * @param node - Node to extract assignment identifiers from
 * @returns Object mapping identifier names to arrays of identifiers
 */
function getAssignmentIdentifiers(node: t.Node): Record<string, Array<t.Identifier>>;

Function Names

Get Function Name

Extract the name of a function from various function node types.

/**
 * Get the name identifier of a function
 * @param node - Function node (FunctionDeclaration, FunctionExpression, etc.)
 * @returns Function name identifier or null if anonymous
 */
function getFunctionName(node: t.Function): t.Identifier | null;

Usage Examples

Basic Binding Extraction

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

// Variable declaration: const { a, b } = obj;
const destructuringDecl = t.variableDeclaration("const", [
  t.variableDeclarator(
    t.objectPattern([
      t.objectProperty(t.identifier("a"), t.identifier("a"), false, true),
      t.objectProperty(t.identifier("b"), t.identifier("b"), false, true)
    ]),
    t.identifier("obj")
  )
]);

const bindings = t.getBindingIdentifiers(destructuringDecl);
console.log(Object.keys(bindings)); // ["a", "b"]
console.log(bindings.a.name); // "a"
console.log(bindings.b.name); // "b"

Function Parameter Binding

// Function with parameters: function test(x, y, {z}) { }
const funcDecl = t.functionDeclaration(
  t.identifier("test"),
  [
    t.identifier("x"),
    t.identifier("y"),
    t.objectPattern([
      t.objectProperty(t.identifier("z"), t.identifier("z"), false, true)
    ])
  ],
  t.blockStatement([])
);

const paramBindings = t.getBindingIdentifiers(funcDecl);
console.log(Object.keys(paramBindings)); // ["test", "x", "y", "z"]

Handling Duplicates

// Multiple declarations with same name
const multipleDecls = t.program([
  t.variableDeclaration("var", [
    t.variableDeclarator(t.identifier("x"), t.numericLiteral(1))
  ]),
  t.variableDeclaration("var", [
    t.variableDeclarator(t.identifier("x"), t.numericLiteral(2))
  ])
]);

// Without duplicates - returns last occurrence
const singleBindings = t.getBindingIdentifiers(multipleDecls);
console.log(singleBindings.x); // Second 'x' identifier

// With duplicates - returns array
const duplicateBindings = t.getBindingIdentifiers(multipleDecls, true);
console.log(duplicateBindings.x.length); // 2
console.log(duplicateBindings.x[0]); // First 'x' identifier
console.log(duplicateBindings.x[1]); // Second 'x' identifier

Outer-Only Bindings

// Function with nested function
const outerFunc = t.functionDeclaration(
  t.identifier("outer"),
  [t.identifier("param")],
  t.blockStatement([
    t.functionDeclaration(
      t.identifier("inner"),
      [t.identifier("innerParam")],
      t.blockStatement([])
    )
  ])
);

// All bindings (including nested)
const allBindings = t.getBindingIdentifiers(outerFunc);
console.log(Object.keys(allBindings)); // ["outer", "param", "inner", "innerParam"]

// Only outer-level bindings
const outerBindings = t.getOuterBindingIdentifiers(outerFunc);
console.log(Object.keys(outerBindings)); // ["outer", "param"]

Assignment Identifier Extraction

// Assignment expressions: a = b, obj.prop = value
const assignments = [
  t.assignmentExpression("=", t.identifier("a"), t.identifier("b")),
  t.assignmentExpression("=", 
    t.memberExpression(t.identifier("obj"), t.identifier("prop")),
    t.identifier("value")
  ),
  t.assignmentExpression("=",
    t.objectPattern([
      t.objectProperty(t.identifier("x"), t.identifier("x"))
    ]),
    t.identifier("source")
  )
];

assignments.forEach(assignment => {
  const assignmentIds = t.getAssignmentIdentifiers(assignment);
  console.log(Object.keys(assignmentIds));
});
// ["a"]
// [] (member expressions don't create bindings)
// ["x"] (destructuring creates bindings)

Function Name Extraction

// Named function declaration
const namedFunc = t.functionDeclaration(
  t.identifier("myFunction"),
  [],
  t.blockStatement([])
);
console.log(t.getFunctionName(namedFunc)?.name); // "myFunction"

// Anonymous function expression
const anonFunc = t.functionExpression(
  null,
  [],
  t.blockStatement([])
);
console.log(t.getFunctionName(anonFunc)); // null

// Arrow function (anonymous)
const arrowFunc = t.arrowFunctionExpression(
  [],
  t.identifier("result")
);
console.log(t.getFunctionName(arrowFunc)); // null

// Method definition
const method = t.objectMethod(
  "method",
  t.identifier("methodName"),
  [],
  t.blockStatement([])
);
console.log(t.getFunctionName(method)?.name); // "methodName"

Complex Destructuring Patterns

// Complex destructuring: const [a, {b, c: d}, ...rest] = array;
const complexPattern = t.variableDeclaration("const", [
  t.variableDeclarator(
    t.arrayPattern([
      t.identifier("a"),
      t.objectPattern([
        t.objectProperty(t.identifier("b"), t.identifier("b"), false, true),
        t.objectProperty(t.identifier("c"), t.identifier("d"))
      ]),
      t.restElement(t.identifier("rest"))
    ]),
    t.identifier("array")
  )
]);

const destructuredBindings = t.getBindingIdentifiers(complexPattern);
console.log(Object.keys(destructuredBindings)); // ["a", "b", "d", "rest"]

Class and Function Analysis

// Class with methods
const classDecl = t.classDeclaration(
  t.identifier("MyClass"),
  null,
  t.classBody([
    t.classMethod(
      "constructor",
      t.identifier("constructor"),
      [t.identifier("param")],
      t.blockStatement([])
    ),
    t.classMethod(
      "method",
      t.identifier("doSomething"),
      [],
      t.blockStatement([])
    )
  ])
);

const classBindings = t.getBindingIdentifiers(classDecl);
console.log(Object.keys(classBindings)); // ["MyClass", "param"]

// Get function names from class methods
const methods = classDecl.body.body.filter(t.isMethod);
methods.forEach(method => {
  const name = t.getFunctionName(method);
  console.log(name?.name); // "constructor", "doSomething"
});

Import/Export Binding Analysis

// Import declaration: import {a, b as c} from "module";
const importDecl = t.importDeclaration([
  t.importSpecifier(t.identifier("a"), t.identifier("a")),
  t.importSpecifier(t.identifier("c"), t.identifier("b"))
], t.stringLiteral("module"));

const importBindings = t.getBindingIdentifiers(importDecl);
console.log(Object.keys(importBindings)); // ["a", "c"]

// Export declaration: export const {x, y} = obj;
const exportDecl = t.exportNamedDeclaration(
  t.variableDeclaration("const", [
    t.variableDeclarator(
      t.objectPattern([
        t.objectProperty(t.identifier("x"), t.identifier("x"), false, true),
        t.objectProperty(t.identifier("y"), t.identifier("y"), false, true)
      ]),
      t.identifier("obj")
    )
  ])
);

const exportBindings = t.getBindingIdentifiers(exportDecl);
console.log(Object.keys(exportBindings)); // ["x", "y"]

Scope Analysis Preparation

// Prepare binding information for scope analysis
function analyzeBindings(node: t.Node) {
  const allBindings = t.getBindingIdentifiers(node, true);
  const assignments = t.getAssignmentIdentifiers(node);
  
  return {
    declared: Object.keys(allBindings),
    assigned: Object.keys(assignments),
    duplicates: Object.entries(allBindings)
      .filter(([_, ids]) => Array.isArray(ids) && ids.length > 1)
      .map(([name]) => name)
  };
}

// Usage with a program
const program = t.program([
  t.variableDeclaration("var", [
    t.variableDeclarator(t.identifier("x"), t.numericLiteral(1))
  ]),
  t.expressionStatement(
    t.assignmentExpression("=", t.identifier("y"), t.identifier("x"))
  )
]);

const analysis = analyzeBindings(program);
console.log(analysis);
// {
//   declared: ["x"],
//   assigned: ["y"], 
//   duplicates: []
// }