import { Cursor } from '../..'; import { J } from '../../java'; import { Any, Capture, DebugOptions, MatchAttemptResult, MatchOptions, MatchResult as IMatchResult, PatternOptions } from './types'; import { RawCode } from './capture'; import { CaptureStorageValue, WRAPPERS_MAP_SYMBOL } from './utils'; /** * Builder for creating patterns programmatically. * Use when pattern structure is not known at compile time. * * @example * // Loop-based pattern generation * const builder = Pattern.builder().code('myFunction('); * for (let i = 0; i < argCount; i++) { * if (i > 0) builder.code(', '); * builder.capture(capture(`arg${i}`)); * } * builder.code(')'); * const pat = builder.build(); * * @example * // Conditional pattern construction * const builder = Pattern.builder().code('foo('); * builder.capture(capture('first')); * if (needsSecondArg) { * builder.code(', ').capture(capture('second')); * } * builder.code(')'); * const pat = builder.build(); */ export declare class PatternBuilder { private parts; private captures; /** * Adds a static string part to the pattern. * * @param str The string to add * @returns This builder for chaining */ code(str: string): this; /** * Adds a capture to the pattern. * * @param value The capture object (Capture, Any, or RawCode) or string name * @returns This builder for chaining */ capture(value: Capture | Any | RawCode | string): this; /** * Builds the pattern from accumulated parts and captures. * * @returns A Pattern instance */ build(): Pattern; } /** * Represents a pattern that can be matched against AST nodes. */ export declare class Pattern { readonly templateParts: TemplateStringsArray; readonly captures: (Capture | Any | RawCode)[]; private _options; private _cachedAstPattern?; private static nextPatternId; private readonly patternId; private readonly unnamedCaptureMapping; /** * Gets the configuration options for this pattern. * @readonly */ get options(): Readonly; /** * Creates a new builder for constructing patterns programmatically. * * @returns A new PatternBuilder instance * * @example * const pat = Pattern.builder() * .code('function ') * .capture(capture('name')) * .code('() { return ') * .capture(capture('value')) * .code('; }') * .build(); */ static builder(): PatternBuilder; /** * Creates a new pattern from template parts and captures. * * @param templateParts The string parts of the template * @param captures The captures between the string parts (can be Capture, Any, or RawCode) */ constructor(templateParts: TemplateStringsArray, captures: (Capture | Any | RawCode)[]); /** * Configures this pattern with additional options. * * @param options Configuration options * @returns This pattern for method chaining * * @example * pattern`forwardRef((${props}, ${ref}) => ${body})` * .configure({ * context: ['import { forwardRef } from "react"'], * dependencies: {'@types/react': '^18.0.0'} * }) */ configure(options: PatternOptions): Pattern; /** * Gets the AST pattern for this pattern, using two-level caching: * 1. Instance-level cache (fastest - this pattern instance) * 2. Global LRU cache (fast - shared across pattern instances with same code) * 3. Compute via TemplateProcessor (slow - parse and process) * * @returns The cached or newly computed pattern AST * @internal */ getAstPattern(): Promise; /** * Creates a matcher for this pattern against a specific AST node. * * @param tree The AST node to match against * @param cursor Cursor at the node's position in a larger tree. Used for context-aware * capture constraints to navigate to parent nodes. * @param options Optional match options (e.g., debug flag) * @returns A MatchResult if the pattern matches, undefined otherwise * * @example * ```typescript * // Normal match * const match = await pattern.match(node, cursor); * * // Debug this specific call * const match = await pattern.match(node, cursor, { debug: true }); * ``` */ match(tree: J, cursor: Cursor, options?: MatchOptions): Promise; /** * Formats and logs the match result to stderr. * @private */ private logMatchResult; /** * Compacts array index navigations into the previous path element. * For example: ['J$VariableDeclarations#variables', '0'] → ['J$VariableDeclarations#variables[0]'] * @private */ private compactPath; /** * Gets the source code representation of this pattern for logging. * @private */ private getPatternSource; /** * Formats a captured value for logging. * @private */ private formatCapturedValue; /** * Formats a single AST node for logging. * @private */ private formatSingleValue; /** * Matches a pattern against an AST node with detailed debug information. * Part of Layer 2 (Public API). * * This method always enables debug logging and returns detailed information about * the match attempt, including: * - Whether the pattern matched * - Captured nodes (if matched) * - Explanation of failure (if not matched) * - Debug log entries showing the matching process * * @param tree The AST node to match against * @param cursor Cursor at the node's position in a larger tree * @param debugOptions Optional debug options (defaults to all logging enabled) * @returns Detailed result with debug information * * @example * const x = capture('x'); * const pat = pattern`console.log(${x})`; * const attempt = await pat.matchWithExplanation(node, cursor); * if (attempt.matched) { * console.log('Matched!'); * console.log('Captured x:', attempt.result.get('x')); * } else { * console.log('Failed:', attempt.explanation); * console.log('Debug log:', attempt.debugLog); * } */ matchWithExplanation(tree: J, cursor: Cursor, debugOptions?: DebugOptions): Promise; } /** * Result of a successful pattern match containing captured values. * * Provides access to captured AST nodes from pattern matching operations. * Use the `get()` method to retrieve captured values by name or by Capture object. * * @example * const x = capture('x'); * const pat = pattern`foo(${x})`; * const match = await pat.match(someNode, cursor); * if (match) { * const captured = match.get('x'); // Get by name * // or * const captured = match.get(x); // Get by Capture object * } * * @example * // Variadic captures return arrays * const args = capture({ variadic: true }); * const pat = pattern`foo(${args})`; * const match = await pat.match(methodInvocation, cursor); * if (match) { * const capturedArgs = match.get(args); // Returns J[] for variadic captures * } */ export declare class MatchResult implements IMatchResult { private readonly storage; constructor(storage?: Map); get(capture: Capture): T | undefined; get(capture: string): any; /** * Checks if a capture has been matched. * * @param capture The capture name (string) or Capture object * @returns true if the capture exists in the match result */ has(capture: Capture | string): boolean; /** * Extracts semantic elements from storage value. * For wrappers, extracts the .element; for arrays, returns array of elements. * * @param value The storage value * @returns The semantic element(s) */ private extractElements; /** * Internal method to get wrappers (used by template expansion). * Returns both scalar and variadic wrappers. * @internal */ [WRAPPERS_MAP_SYMBOL](): Map | J.RightPadded[]>; } /** * Tagged template function for creating patterns. * * @param strings The string parts of the template * @param captures The captures between the string parts (Capture, Any, RawCode, or string names) * @returns A Pattern object * * @example * // Using the same capture multiple times for repeated patterns * const expr = capture('expr'); * const redundantOr = pattern`${expr} || ${expr}`; * * @example * // Using any() for non-capturing matches * const pat = pattern`foo(${any()})`; * * @example * // Using raw() for dynamic pattern construction * const operator = '==='; * const pat = pattern`x ${raw(operator)} y`; */ /** * Creates a pattern from a template literal (direct usage). * * @example * ```typescript * const pat = pattern`console.log(${x})`; * ``` */ export declare function pattern(strings: TemplateStringsArray, ...captures: (Capture | Any | RawCode | string)[]): Pattern; /** * Creates a pattern factory with options that returns a tagged template function. * * @example * ```typescript * const pat = pattern({ debug: true })`console.log(${x})`; * ``` */ export declare function pattern(options: PatternOptions): (strings: TemplateStringsArray, ...captures: (Capture | Any | RawCode | string)[]) => Pattern; //# sourceMappingURL=pattern.d.ts.map