import { Cursor, Tree } from '../..'; import { J } from '../../java'; import { ApplyOptions, Parameter, TemplateOptions, TemplateParameter } from './types'; /** * Coordinates for template application. */ type JavaCoordinates = { tree?: Tree; loc?: JavaCoordinates.Location; mode?: JavaCoordinates.Mode; }; declare namespace JavaCoordinates { type Location = 'EXPRESSION_PREFIX' | 'STATEMENT_PREFIX' | 'BLOCK_END'; enum Mode { Before = 0, After = 1, Replace = 2 } } /** * Builder for creating templates programmatically. * Use when template structure is not known at compile time. * * @example * // Conditional construction * const builder = Template.builder().code('function foo(x) {'); * if (needsValidation) { * builder.code('if (typeof x !== "number") throw new Error("Invalid");'); * } * builder.code('return x * 2; }'); * const tmpl = builder.build(); * * @example * // Composition from fragments * function createWrapper(innerBody: Capture): Template { * return Template.builder() * .code('function wrapper() { try { ') * .param(innerBody) * .code(' } catch(e) { console.error(e); } }') * .build(); * } */ export declare class TemplateBuilder { private parts; private params; /** * Adds a static string part to the template. * * @param str The string to add * @returns This builder for chaining */ code(str: string): this; /** * Adds a parameter to the template. * * @param value The parameter value (Capture, Tree, or primitive); may be added more than once * (see {@link template}) * @returns This builder for chaining */ param(value: TemplateParameter): this; /** * Builds the template from accumulated parts and parameters. * * @returns A Template instance */ build(): Template; } /** * Template for creating AST nodes. * * This class provides the public API for template generation. * The actual templating logic is handled by the internal TemplateEngine. * * Templates can reference captures from patterns, and you can access properties * of captured nodes using dot notation. This allows you to extract and insert * specific subtrees from matched AST nodes. * * @example * // Generate a literal AST node * const result = await template`2`.apply(node, cursor); * * @example * // Generate an AST node with a parameter * const result = await template`${capture()}`.apply(node, cursor); * * @example * // Access properties of captured nodes in templates * const method = capture('method'); * const pat = pattern`foo(${method})`; * const tmpl = template`bar(${method.name})`; // Access the 'name' property * * const match = await pat.match(someNode, cursor); * if (match) { * // The template will insert just the 'name' subtree from the captured method * const result = await tmpl.apply(someNode, cursor, { values: match }); * } * * @example * // Deep property access chains * const method = capture('method'); * template`console.log(${method.name.simpleName})` // Navigate multiple properties * * @example * // Array element access * const invocation = capture('invocation'); * template`bar(${invocation.arguments.elements[0].element})` // Access array elements */ export declare class Template { private readonly templateParts; private readonly parameters; private options; private _cachedTemplate?; /** * Creates a new template. * * @param templateParts The string parts of the template * @param parameters The parameters between the string parts */ constructor(templateParts: TemplateStringsArray, parameters: Parameter[]); /** * Creates a new builder for constructing templates programmatically. * * @returns A new TemplateBuilder instance * * @example * const tmpl = Template.builder() * .code('function foo() {') * .code('return ') * .param(capture('value')) * .code('; }') * .build(); */ static builder(): TemplateBuilder; /** * Configures this template with additional options. * * @param options Configuration options * @returns This template for method chaining * * @example * template`isDate(${capture('date')})` * .configure({ * context: ['import { isDate } from "util"'], * dependencies: { 'util': '^1.0.0' } * }) */ configure(options: TemplateOptions): Template; /** * Gets the template tree for this template, using two-level caching: * - Level 1: Instance cache (this._cachedTemplate) - fastest, no lookup needed * - Level 2: Global cache (globalAstCache) - fast, shared across all templates * - Level 3: TemplateEngine - slow, parses and processes the template * * Most parameters use placeholders that are replaced during application, so templates * with the same structure share cached ASTs. However, raw() parameters are spliced at * construction time, so their values must be included in the cache key. * * @returns The cached or newly computed template tree * @internal */ private getTemplateTree; /** * Applies this template and returns the resulting tree. * * @param tree Input tree to transform * @param cursor The cursor pointing to the current location in the AST * @param options Optional configuration including values for parameters * @returns A Promise resolving to the generated AST node * * @example * ```typescript * // Simple application without values * const result = await tmpl.apply(node, cursor); * * // With values from pattern match * const match = await pat.match(node, cursor); * const result = await tmpl.apply(node, cursor, { values: match }); * * // With explicit values * const result = await tmpl.apply(node, cursor, { * values: { x: someNode, y: anotherNode } * }); * ``` */ apply(tree: J, cursor: Cursor, options?: ApplyOptions): Promise; } /** * Tagged template function for creating templates that generate AST nodes. * * Templates support property access on captures from patterns, allowing you to * extract and insert specific subtrees from matched AST nodes. Use dot notation * to navigate properties (e.g., `method.name`) or array bracket notation to * access array elements (e.g., `args.elements[0].element`). * * Templates can also accept AST wrapper types directly: * - J.RightPadded: The element will be extracted and inserted * - J.RightPadded[]: Elements will be expanded in place * - J.Container: Elements will be expanded in place * * @param strings The string parts of the template * @param parameters The parameters between the string parts (Capture, CaptureValue, TemplateParam, Tree, Tree[], J.RightPadded, J.RightPadded[], or J.Container). * A parameter may appear more than once — `(${arr} ? f(${arr}) : -1)`. A node * keeps its id only at its first occurrence, and only if it belongs to the * subtree being replaced; anything else is spliced under fresh ids. * @returns A Template object that can be applied to generate AST nodes * * @example * // Simple template with literal * const tmpl = template`console.log("hello")`; * const result = await tmpl.apply(node, cursor); * * @example * // Template with capture - matches captured value from pattern * const expr = capture('expr'); * const pat = pattern`foo(${expr})`; * const tmpl = template`bar(${expr})`; * * const match = await pat.match(node, cursor); * if (match) { * const result = await tmpl.apply(node, cursor, { values: match }); * } * * @example * // Property access on captures - extract subtrees * const method = capture('method'); * const pat = pattern`foo(${method})`; * // Access the 'name' property of the captured method invocation * const tmpl = template`bar(${method.name})`; * * @example * // Deep property chains * const method = capture('method'); * template`console.log(${method.name.simpleName})` * * @example * // Array element access * const invocation = capture('invocation'); * template`bar(${invocation.arguments.elements[0].element})` * * @example * // Using J.RightPadded and J.Container directly * const selectExpr = method.select; // J.RightPadded * const args = method.arguments; // J.Container * template`${selectExpr}.newMethod(${args})` */ export declare function template(strings: TemplateStringsArray, ...parameters: TemplateParameter[]): Template; export type { JavaCoordinates }; //# sourceMappingURL=template.d.ts.map