import { ExecutionContext, Recipe, TreeVisitor } from '../..'; import { J } from '../../java'; import { RewriteConfig, RewriteRule } from './types'; /** * Creates a replacement rule using a capture context and configuration. * * @param builderFn Function that takes a capture context and returns before/after configuration * @returns A replacement rule that can be applied to AST nodes * * @example * // Single pattern * const swapOperands = rewrite(() => { * const { left, right } = { left: capture(), right: capture() }; * return { * before: pattern`${left} + ${right}`, * after: template`${right} + ${left}` * }; * }); * * @example * // Multiple patterns * const normalizeComparisons = rewrite(() => { * const { left, right } = { left: capture(), right: capture() }; * return { * before: [ * pattern`${left} == ${right}`, * pattern`${left} === ${right}` * ], * after: template`${left} === ${right}` * }; * }); * * @example * // Using in a visitor - IMPORTANT: use `|| node` to handle undefined when no match * class MyVisitor extends JavaScriptVisitor { * override async visitBinary(binary: J.Binary, p: any): Promise { * const rule = rewrite(() => ({ * before: pattern`${capture('a')} + ${capture('b')}`, * after: template`${capture('b')} + ${capture('a')}` * })); * // tryOn() returns undefined if no pattern matches, so always use || node * return await rule.tryOn(this.cursor, binary) || binary; * } * } */ export declare function rewrite(builderFn: () => RewriteConfig): RewriteRule; /** * Creates a RewriteRule from a Recipe by using its editor visitor. * * This allows recipes to be used in the same chaining pattern as other rewrite rules, * enabling composition with `andThen()`. * * @param recipe The recipe whose editor will be used to transform nodes * @param ctx The execution context to pass to the recipe's editor * @returns A RewriteRule that applies the recipe's editor to nodes * * @example * ```typescript * class MyRecipe extends Recipe { * name = "my.recipe"; * displayName = "My Recipe"; * description = "Transforms code."; * * async editor(): Promise> { * return new MyVisitor(); * } * } * * // In a visitor: * override async visitBinary(binary: J.Binary, p: ExecutionContext): Promise { * const rule1 = rewrite(() => ({ * before: pattern`${capture('a')} + ${capture('b')}`, * after: template`${capture('b')} + ${capture('a')}` * })); * * const rule2 = fromRecipe(new MyRecipe(), p); * * // Chain the pattern-based rule with the recipe * const combined = rule1.andThen(rule2); * return await combined.tryOn(this.cursor, binary) || binary; * } * ``` */ export declare const fromRecipe: (recipe: Recipe, ctx: ExecutionContext) => RewriteRule; /** * Registers an after-visitor that will flatten a block's statements into its parent block. * * When a rewrite template produces a J.Block containing multiple statements, but you want * those statements to be inserted directly into the parent block (not nested), use this * function to register a follow-up visitor that performs the flattening. * * @param visitor The current visitor instance (to register the after-visitor) * @param block The block whose statements should be flattened into its parent * @returns The block (for chaining in return statements) * * @example * ```typescript * override async visitReturn(ret: J.Return, ctx: ExecutionContext): Promise { * const result = await rewrite(() => ({ * before: pattern`return #{cond} || #{arr}.some(#{cb})`, * after: template`{ * if (#{cond}) return true; * for (const item of #{arr}) { * if (await #{cb}(item)) return true; * } * return false; * }` * })).tryOn(this.cursor, ret); * * if (result && result.kind === J.Kind.Block) { * return flattenBlock(this, result as J.Block); * } * return result ?? ret; * } * ``` */ export declare function flattenBlock

(visitor: TreeVisitor, block: J.Block): J.Block; //# sourceMappingURL=rewrite.d.ts.map