@openrewrite/rewrite 8.66.0 → 8.66.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/java/tree.d.ts +10 -1
  2. package/dist/java/tree.d.ts.map +1 -1
  3. package/dist/java/tree.js +21 -5
  4. package/dist/java/tree.js.map +1 -1
  5. package/dist/java/type-visitor.d.ts +1 -1
  6. package/dist/java/type-visitor.d.ts.map +1 -1
  7. package/dist/java/visitor.d.ts +2 -2
  8. package/dist/java/visitor.d.ts.map +1 -1
  9. package/dist/java/visitor.js +8 -2
  10. package/dist/java/visitor.js.map +1 -1
  11. package/dist/javascript/assertions.d.ts +6 -0
  12. package/dist/javascript/assertions.d.ts.map +1 -1
  13. package/dist/javascript/assertions.js +14 -6
  14. package/dist/javascript/assertions.js.map +1 -1
  15. package/dist/javascript/comparator.d.ts +217 -7
  16. package/dist/javascript/comparator.d.ts.map +1 -1
  17. package/dist/javascript/comparator.js +1020 -2848
  18. package/dist/javascript/comparator.js.map +1 -1
  19. package/dist/javascript/format.d.ts +5 -3
  20. package/dist/javascript/format.d.ts.map +1 -1
  21. package/dist/javascript/format.js +87 -44
  22. package/dist/javascript/format.js.map +1 -1
  23. package/dist/javascript/index.d.ts +2 -1
  24. package/dist/javascript/index.d.ts.map +1 -1
  25. package/dist/javascript/index.js +2 -1
  26. package/dist/javascript/index.js.map +1 -1
  27. package/dist/javascript/parser.d.ts +2 -1
  28. package/dist/javascript/parser.d.ts.map +1 -1
  29. package/dist/javascript/parser.js +54 -43
  30. package/dist/javascript/parser.js.map +1 -1
  31. package/dist/javascript/templating/capture.d.ts +293 -0
  32. package/dist/javascript/templating/capture.d.ts.map +1 -0
  33. package/dist/javascript/templating/capture.js +461 -0
  34. package/dist/javascript/templating/capture.js.map +1 -0
  35. package/dist/javascript/templating/comparator.d.ts +171 -0
  36. package/dist/javascript/templating/comparator.d.ts.map +1 -0
  37. package/dist/javascript/templating/comparator.js +1221 -0
  38. package/dist/javascript/templating/comparator.js.map +1 -0
  39. package/dist/javascript/templating/engine.d.ts +108 -0
  40. package/dist/javascript/templating/engine.d.ts.map +1 -0
  41. package/dist/javascript/templating/engine.js +661 -0
  42. package/dist/javascript/templating/engine.js.map +1 -0
  43. package/dist/javascript/templating/index.d.ts +6 -0
  44. package/dist/javascript/templating/index.d.ts.map +1 -0
  45. package/dist/javascript/templating/index.js +44 -0
  46. package/dist/javascript/templating/index.js.map +1 -0
  47. package/dist/javascript/templating/pattern.d.ts +276 -0
  48. package/dist/javascript/templating/pattern.d.ts.map +1 -0
  49. package/dist/javascript/templating/pattern.js +952 -0
  50. package/dist/javascript/templating/pattern.js.map +1 -0
  51. package/dist/javascript/templating/placeholder-replacement.d.ts +83 -0
  52. package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -0
  53. package/dist/javascript/templating/placeholder-replacement.js +467 -0
  54. package/dist/javascript/templating/placeholder-replacement.js.map +1 -0
  55. package/dist/javascript/templating/rewrite.d.ts +84 -0
  56. package/dist/javascript/templating/rewrite.d.ts.map +1 -0
  57. package/dist/javascript/templating/rewrite.js +208 -0
  58. package/dist/javascript/templating/rewrite.js.map +1 -0
  59. package/dist/javascript/templating/template.d.ts +230 -0
  60. package/dist/javascript/templating/template.d.ts.map +1 -0
  61. package/dist/javascript/templating/template.js +367 -0
  62. package/dist/javascript/templating/template.js.map +1 -0
  63. package/dist/javascript/templating/types.d.ts +610 -0
  64. package/dist/javascript/templating/types.d.ts.map +1 -0
  65. package/dist/javascript/templating/types.js +3 -0
  66. package/dist/javascript/templating/types.js.map +1 -0
  67. package/dist/javascript/templating/utils.d.ts +135 -0
  68. package/dist/javascript/templating/utils.d.ts.map +1 -0
  69. package/dist/javascript/templating/utils.js +251 -0
  70. package/dist/javascript/templating/utils.js.map +1 -0
  71. package/dist/javascript/type-mapping.d.ts.map +1 -1
  72. package/dist/javascript/type-mapping.js +21 -11
  73. package/dist/javascript/type-mapping.js.map +1 -1
  74. package/dist/json/rpc.js +2 -2
  75. package/dist/json/rpc.js.map +1 -1
  76. package/dist/recipe/order-imports.js.map +1 -1
  77. package/dist/test/rewrite-test.d.ts.map +1 -1
  78. package/dist/test/rewrite-test.js +10 -6
  79. package/dist/test/rewrite-test.js.map +1 -1
  80. package/dist/version.txt +1 -1
  81. package/dist/visitor.d.ts +4 -4
  82. package/dist/visitor.d.ts.map +1 -1
  83. package/dist/visitor.js +8 -3
  84. package/dist/visitor.js.map +1 -1
  85. package/package.json +5 -2
  86. package/src/java/tree.ts +10 -3
  87. package/src/java/type-visitor.ts +1 -1
  88. package/src/java/visitor.ts +11 -5
  89. package/src/javascript/assertions.ts +9 -3
  90. package/src/javascript/comparator.ts +1095 -3373
  91. package/src/javascript/format.ts +72 -33
  92. package/src/javascript/index.ts +2 -1
  93. package/src/javascript/parser.ts +67 -45
  94. package/src/javascript/templating/capture.ts +595 -0
  95. package/src/javascript/templating/comparator.ts +1383 -0
  96. package/src/javascript/templating/engine.ts +750 -0
  97. package/src/javascript/templating/index.ts +67 -0
  98. package/src/javascript/templating/pattern.ts +1101 -0
  99. package/src/javascript/templating/placeholder-replacement.ts +475 -0
  100. package/src/javascript/templating/rewrite.ts +229 -0
  101. package/src/javascript/templating/template.ts +414 -0
  102. package/src/javascript/templating/types.ts +674 -0
  103. package/src/javascript/templating/utils.ts +298 -0
  104. package/src/javascript/type-mapping.ts +20 -11
  105. package/src/json/rpc.ts +2 -2
  106. package/src/recipe/order-imports.ts +1 -1
  107. package/src/test/rewrite-test.ts +12 -7
  108. package/src/visitor.ts +14 -6
  109. package/dist/javascript/templating.d.ts +0 -265
  110. package/dist/javascript/templating.d.ts.map +0 -1
  111. package/dist/javascript/templating.js +0 -1027
  112. package/dist/javascript/templating.js.map +0 -1
  113. package/src/javascript/templating.ts +0 -1226
@@ -0,0 +1,610 @@
1
+ import { Cursor, Tree } from '../..';
2
+ import { J, Type } from '../../java';
3
+ import type { Pattern } from "./pattern";
4
+ import type { Template } from "./template";
5
+ import type { CaptureValue, RawCode } from "./capture";
6
+ /**
7
+ * Options for variadic captures that match zero or more nodes in a sequence.
8
+ */
9
+ export interface VariadicOptions {
10
+ /**
11
+ * Minimum number of nodes that must be matched (default: 0).
12
+ */
13
+ min?: number;
14
+ /**
15
+ * Maximum number of nodes that can be matched (default: unlimited).
16
+ */
17
+ max?: number;
18
+ }
19
+ /**
20
+ * Constraint function for captures.
21
+ * The cursor parameter is always provided with a defined value, but functions can
22
+ * choose to accept it or not (TypeScript allows functions with fewer parameters).
23
+ *
24
+ * For non-variadic captures: use ConstraintFunction<T> where T is the node type
25
+ * For variadic captures: use ConstraintFunction<T[]> where T[] is the array type
26
+ *
27
+ * When used with variadic captures, the cursor points to the nearest common parent
28
+ * of the captured elements.
29
+ */
30
+ export type ConstraintFunction<T> = (node: T, cursor: Cursor) => boolean;
31
+ /**
32
+ * Options for the capture function.
33
+ *
34
+ * The constraint function receives different parameter types depending on whether
35
+ * the capture is variadic:
36
+ * - For regular captures: constraint receives a single node of type T
37
+ * - For variadic captures: constraint receives an array of nodes of type T[]
38
+ *
39
+ * The constraint function can optionally receive a cursor parameter to perform
40
+ * context-aware validation during pattern matching.
41
+ */
42
+ export interface CaptureOptions<T = any> {
43
+ name?: string;
44
+ variadic?: boolean | VariadicOptions;
45
+ /**
46
+ * Optional constraint function that validates whether a captured node should be accepted.
47
+ * The function always receives:
48
+ * - node: The captured node (or array of nodes for variadic captures)
49
+ * - cursor: A cursor at the captured node's position (always defined)
50
+ *
51
+ * Functions can choose to accept just the node parameter if they don't need the cursor.
52
+ *
53
+ * @param node The captured node to validate
54
+ * @param cursor Cursor at the captured node's position
55
+ * @returns true if the capture should be accepted, false otherwise
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // Simple node validation (cursor parameter ignored)
60
+ * capture<J.Literal>('size', {
61
+ * constraint: (node) => typeof node.value === 'number' && node.value > 100
62
+ * })
63
+ *
64
+ * // Context-aware validation (using cursor)
65
+ * capture<J.MethodInvocation>('method', {
66
+ * constraint: (node, cursor) => {
67
+ * if (!node.name.simpleName.startsWith('get')) return false;
68
+ * const cls = cursor.firstEnclosing(isClassDeclaration);
69
+ * return cls?.name.simpleName === 'ApiController';
70
+ * }
71
+ * })
72
+ * ```
73
+ */
74
+ constraint?: ConstraintFunction<T>;
75
+ /**
76
+ * Type annotation for this capture. When provided, the template engine will generate
77
+ * a preamble declaring the capture identifier with this type annotation, allowing
78
+ * the TypeScript parser/compiler to produce a properly type-attributed AST.
79
+ *
80
+ * Can be specified as:
81
+ * - A string type annotation (e.g., "boolean", "string", "number")
82
+ * - A Type instance from the AST (the type will be inferred from the Type)
83
+ */
84
+ type?: string | Type;
85
+ }
86
+ /**
87
+ * Capture specification for pattern matching.
88
+ * Represents a placeholder in a template pattern that can capture a part of the AST.
89
+ *
90
+ * @template T The expected type of the captured AST node (for TypeScript autocomplete)
91
+ *
92
+ * @remarks
93
+ * **Important: Type Parameter is for IDE Support Only**
94
+ *
95
+ * The generic type parameter `<T>` provides IDE autocomplete and type checking in your code,
96
+ * but does NOT enforce any runtime constraints on what the capture will match.
97
+ *
98
+ * **Pattern Matching Behavior:**
99
+ * - A bare `pattern`${capture()}`` will structurally match ANY expression
100
+ * - Pattern structure determines matching: `pattern`foo(${capture()})`` only matches `foo()` calls with one arg
101
+ * - Use structural patterns to narrow matching scope before applying semantic validation
102
+ *
103
+ * **Variadic Captures:**
104
+ * Use `{ variadic: true }` to match zero or more nodes in a sequence:
105
+ * ```typescript
106
+ * const args = capture({ variadic: true });
107
+ * pattern`foo(${args})` // Matches: foo(), foo(a), foo(a, b, c)
108
+ * ```
109
+ */
110
+ export interface Capture<T = any> {
111
+ /**
112
+ * Gets the string name of this capture.
113
+ */
114
+ getName(): string;
115
+ /**
116
+ * Returns true if this is a variadic capture (matching zero or more nodes).
117
+ */
118
+ isVariadic(): boolean;
119
+ /**
120
+ * Returns the variadic options if this is a variadic capture, undefined otherwise.
121
+ */
122
+ getVariadicOptions(): VariadicOptions | undefined;
123
+ /**
124
+ * Gets the constraint function if this capture has one.
125
+ * For regular captures (T = Expression), constraint receives a single node.
126
+ * For variadic captures (T = Expression[]), constraint receives an array of nodes.
127
+ * The constraint function can optionally receive a cursor for context-aware validation.
128
+ */
129
+ getConstraint?(): ConstraintFunction<T> | undefined;
130
+ }
131
+ /**
132
+ * Non-capturing pattern match specification.
133
+ * Represents a placeholder in a pattern that matches AST nodes without binding them to a name.
134
+ *
135
+ * Use `any()` when you need to match structure without caring about the specific values.
136
+ * The key difference from `Capture` is that `Any` cannot be used in templates - the TypeScript
137
+ * type system prevents this at compile time.
138
+ *
139
+ * @template T The expected type of the matched AST node (for TypeScript autocomplete and constraints)
140
+ *
141
+ * @remarks
142
+ * **Why Any<T> is Separate from Capture<T>:**
143
+ *
144
+ * Using a separate type provides compile-time safety:
145
+ * - `pattern`foo(${any()})`` - ✅ OK in patterns
146
+ * - `template`bar(${any()})`` - ❌ TypeScript error (Any<T> not assignable to template parameters)
147
+ *
148
+ * This prevents logical errors where you try to use a non-capturing match in a template.
149
+ *
150
+ * **Semantic Parallel with TypeScript's `any`:**
151
+ *
152
+ * Just as TypeScript's `any` type means "be permissive about types here",
153
+ * pattern matching's `any()` means "be permissive about values here":
154
+ * - TypeScript `any`: Accept any type, don't check it
155
+ * - Pattern `any()`: Match any value, don't bind it
156
+ *
157
+ * @example
158
+ * // Match without capturing
159
+ * const pat = pattern`foo(${any()})`
160
+ *
161
+ * @example
162
+ * // Variadic any - match zero or more without capturing
163
+ * const first = any();
164
+ * const rest = any({ variadic: true });
165
+ * const pat = pattern`bar(${first}, ${rest})`
166
+ *
167
+ * @example
168
+ * // With constraints - validate but don't capture
169
+ * const numericArg = any<J.Literal>({
170
+ * constraint: (node) => typeof node.value === 'number'
171
+ * });
172
+ * const pat = pattern`process(${numericArg})`
173
+ */
174
+ export interface Any<T = any> {
175
+ /**
176
+ * Gets the internal identifier for this any pattern.
177
+ */
178
+ getName(): string;
179
+ /**
180
+ * Returns true if this is a variadic any (matching zero or more nodes).
181
+ */
182
+ isVariadic(): boolean;
183
+ /**
184
+ * Returns the variadic options if this is a variadic any, undefined otherwise.
185
+ */
186
+ getVariadicOptions(): VariadicOptions | undefined;
187
+ /**
188
+ * Gets the constraint function if this any pattern has one.
189
+ * For regular any (T = Expression), constraint receives a single node.
190
+ * For variadic any (T = Expression[]), constraint receives an array of nodes.
191
+ */
192
+ getConstraint?(): ConstraintFunction<T> | undefined;
193
+ }
194
+ /**
195
+ * Template parameter specification for template-only parameter substitution.
196
+ * Unlike Capture, TemplateParam does not support property access and is simpler.
197
+ *
198
+ * @template T The expected type of the parameter value (for TypeScript autocomplete only)
199
+ */
200
+ export interface TemplateParam<T = any> {
201
+ /**
202
+ * The name of the parameter, used to look up the value in the values map.
203
+ */
204
+ readonly name: string;
205
+ /**
206
+ * Gets the string name of this parameter.
207
+ */
208
+ getName(): string;
209
+ }
210
+ /**
211
+ * Configuration options for patterns.
212
+ */
213
+ export interface PatternOptions {
214
+ /**
215
+ * Declarations to provide type attribution context for the pattern.
216
+ * These can include import statements, type declarations, function declarations, or any
217
+ * other declarations needed for proper type information. They are prepended to the pattern
218
+ * when parsing to ensure proper type attribution.
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * pattern`forwardRef(${capture('comp')})`
223
+ * .configure({
224
+ * context: [
225
+ * `import { forwardRef } from 'react'`,
226
+ * `type MyType = { value: number }`
227
+ * ]
228
+ * })
229
+ * ```
230
+ */
231
+ context?: string[];
232
+ /**
233
+ * @deprecated Use `context` instead. This alias will be removed in a future version.
234
+ *
235
+ * Import statements to provide type attribution context.
236
+ * These are prepended to the pattern when parsing to ensure proper type information.
237
+ */
238
+ imports?: string[];
239
+ /**
240
+ * NPM dependencies required for import resolution and type attribution.
241
+ * Maps package names to version specifiers (e.g., { 'util': '^1.0.0' }).
242
+ * The template engine will create a package.json with these dependencies.
243
+ */
244
+ dependencies?: Record<string, string>;
245
+ /**
246
+ * When true, allows patterns without type annotations to match code with type annotations.
247
+ * This enables more flexible pattern matching during development or when full type attribution
248
+ * is not needed. When false, enforces strict type matching where both pattern and target must
249
+ * have matching type annotations.
250
+ *
251
+ * @default true (lenient matching enabled for backward compatibility)
252
+ */
253
+ lenientTypeMatching?: boolean;
254
+ /**
255
+ * Enable debug logging for this pattern.
256
+ * When enabled, all match attempts will log detailed information to stderr,
257
+ * including the AST path traversed, mismatches encountered, and captured values.
258
+ *
259
+ * Can be overridden at the match() call level.
260
+ * Global debug can be enabled via PATTERN_DEBUG=true environment variable.
261
+ *
262
+ * Precedence: match() call > pattern configure() > PATTERN_DEBUG env var
263
+ *
264
+ * @default undefined (inherits from environment or match() call)
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * // Pattern-level debug
269
+ * const pat = pattern({ debug: true })`console.log(${value})`;
270
+ *
271
+ * // Disable debug for a noisy pattern when global debug is on
272
+ * const noisyPat = pattern({ debug: false })`import ${x} from ${y}`;
273
+ * ```
274
+ */
275
+ debug?: boolean;
276
+ }
277
+ /**
278
+ * Options for individual match() calls.
279
+ */
280
+ export interface MatchOptions {
281
+ /**
282
+ * Enable debug logging for this specific match() call.
283
+ * Overrides pattern-level debug setting and global PATTERN_DEBUG env var.
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * // Debug just this call
288
+ * const match = await pattern.match(node, cursor, { debug: true });
289
+ *
290
+ * // Disable debug for this call even if pattern or global debug is on
291
+ * const match = await pattern.match(node, cursor, { debug: false });
292
+ * ```
293
+ */
294
+ debug?: boolean;
295
+ }
296
+ /**
297
+ * Valid parameter types for template literals.
298
+ * - Capture: For pattern matching and reuse
299
+ * - CaptureValue: Result of property access or array operations on captures (e.g., capture.prop, capture[0], capture.slice(1))
300
+ * - TemplateParam: For standalone template parameters
301
+ * - RawCode: For inserting literal code strings at construction time
302
+ * - Tree: AST nodes to be inserted directly
303
+ * - Tree[]: Arrays of AST nodes (from variadic capture operations like slice)
304
+ * - J.RightPadded<any>: Wrapper containing an element with markers (element will be extracted)
305
+ * - J.RightPadded<any>[]: Array of wrappers (elements will be expanded)
306
+ * - J.Container<any>: Container with elements (elements will be expanded)
307
+ *
308
+ * Note: Primitive values (string, number, boolean) are NOT supported in template literals.
309
+ * Use raw() for inserting code strings, or Template.builder() API for programmatic construction.
310
+ */
311
+ export type TemplateParameter = Capture | CaptureValue | TemplateParam | RawCode | Tree | Tree[] | J.RightPadded<any> | J.RightPadded<any>[] | J.Container<any>;
312
+ /**
313
+ * Parameter specification for template generation (internal).
314
+ * Represents a placeholder in a template that will be replaced with a parameter value.
315
+ * This is the internal wrapper used by the template engine.
316
+ *
317
+ * Note: The value is typed as `any` rather than `TemplateParameter` to allow flexible
318
+ * internal handling without excessive type guards. The public API (template function)
319
+ * constrains inputs to `TemplateParameter`, providing type safety at the API boundary.
320
+ */
321
+ export interface Parameter {
322
+ /**
323
+ * The value to substitute into the template.
324
+ */
325
+ value: any;
326
+ }
327
+ /**
328
+ * Configuration options for templates.
329
+ */
330
+ export interface TemplateOptions {
331
+ /**
332
+ * Declarations to provide type attribution context for the template.
333
+ * These can include import statements, type declarations, function declarations, or any
334
+ * other declarations needed for proper type information. They are prepended to the template
335
+ * when parsing to ensure proper type attribution.
336
+ *
337
+ * @example
338
+ * ```typescript
339
+ * template`console.log(${capture('value')})`
340
+ * .configure({
341
+ * context: [
342
+ * `type MyType = { value: number }`,
343
+ * `const console = { log: (x: any) => void 0 }`
344
+ * ]
345
+ * })
346
+ * ```
347
+ */
348
+ context?: string[];
349
+ /**
350
+ * @deprecated Use `context` instead. This alias will be removed in a future version.
351
+ *
352
+ * Import statements to provide type attribution context.
353
+ * These are prepended to the template when parsing to ensure proper type information.
354
+ */
355
+ imports?: string[];
356
+ /**
357
+ * NPM dependencies required for import resolution and type attribution.
358
+ * Maps package names to version specifiers (e.g., { 'util': '^1.0.0' }).
359
+ * The template engine will create a package.json with these dependencies.
360
+ */
361
+ dependencies?: Record<string, string>;
362
+ }
363
+ /**
364
+ * Represents a replacement rule that can match a pattern and apply a template.
365
+ */
366
+ export interface RewriteRule {
367
+ /**
368
+ * Attempts to apply this rewrite rule to the given AST node.
369
+ *
370
+ * @param cursor The cursor context at the current position in the AST
371
+ * @param node The AST node to try matching and transforming
372
+ * @returns The transformed node if a pattern matched, or `undefined` if no pattern matched.
373
+ * When using in a visitor, always use the `|| node` pattern to return the original
374
+ * node when there's no match: `return await rule.tryOn(this.cursor, node) || node;`
375
+ */
376
+ tryOn(cursor: Cursor, node: J): Promise<J | undefined>;
377
+ /**
378
+ * Chains this rule with another rule, creating a composite rule that applies both transformations sequentially.
379
+ *
380
+ * The resulting rule:
381
+ * 1. First applies this rule to the input node
382
+ * 2. If this rule matches and transforms the node, applies the next rule to the result
383
+ * 3. If the next rule returns undefined (no match), keeps the result from the first rule
384
+ * 4. If this rule returns undefined (no match), returns undefined without trying the next rule
385
+ *
386
+ * @param next The rule to apply after this rule
387
+ * @returns A new RewriteRule that applies both rules in sequence
388
+ *
389
+ * @example
390
+ * ```typescript
391
+ * const rule1 = rewrite(() => {
392
+ * const { a, b } = { a: capture(), b: capture() };
393
+ * return {
394
+ * before: pattern`${a} + ${b}`,
395
+ * after: template`${b} + ${a}`
396
+ * };
397
+ * });
398
+ *
399
+ * const rule2 = rewrite(() => ({
400
+ * before: pattern`${capture('x')} + 1`,
401
+ * after: template`${capture('x')}++`
402
+ * }));
403
+ *
404
+ * const combined = rule1.andThen(rule2);
405
+ * // Will first swap operands, then if result matches "x + 1", change to "x++"
406
+ * ```
407
+ */
408
+ andThen(next: RewriteRule): RewriteRule;
409
+ /**
410
+ * Creates a composite rule that tries this rule first, and if it doesn't match, tries an alternative rule.
411
+ *
412
+ * The resulting rule:
413
+ * 1. First applies this rule to the input node
414
+ * 2. If this rule matches and transforms the node, returns the result
415
+ * 3. If this rule returns undefined (no match), tries the alternative rule on the original node
416
+ *
417
+ * @param alternative The rule to try if this rule doesn't match
418
+ * @returns A new RewriteRule that tries both rules with fallback behavior
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * // Try specific pattern first, fall back to general pattern
423
+ * const specific = rewrite(() => ({
424
+ * before: pattern`foo(${capture('x')}, 0)`,
425
+ * after: template`bar(${capture('x')})`
426
+ * }));
427
+ *
428
+ * const general = rewrite(() => ({
429
+ * before: pattern`foo(${capture('x')}, ${capture('y')})`,
430
+ * after: template`baz(${capture('x')}, ${capture('y')})`
431
+ * }));
432
+ *
433
+ * const combined = specific.orElse(general);
434
+ * // Will try specific pattern first, if no match, try general pattern
435
+ * ```
436
+ */
437
+ orElse(alternative: RewriteRule): RewriteRule;
438
+ }
439
+ /**
440
+ * Configuration for a replacement rule.
441
+ */
442
+ export interface RewriteConfig {
443
+ before: Pattern | Pattern[];
444
+ after: Template | ((match: MatchResult) => Template);
445
+ /**
446
+ * Optional context predicate that must evaluate to true for the transformation to be applied.
447
+ * Evaluated after the pattern matches structurally but before applying the template.
448
+ * Provides access to both the matched node and the cursor for context inspection.
449
+ *
450
+ * @param node The matched AST node
451
+ * @param cursor The cursor at the matched node, providing access to ancestors and context
452
+ * @returns true if the transformation should be applied, false otherwise
453
+ *
454
+ * @example
455
+ * ```typescript
456
+ * rewrite(() => ({
457
+ * before: pattern`await ${_('promise')}`,
458
+ * after: template`await ${_('promise')}.catch(handleError)`,
459
+ * where: (node, cursor) => {
460
+ * // Only apply inside async functions
461
+ * const method = cursor.firstEnclosing((n: any): n is J.MethodDeclaration =>
462
+ * n.kind === J.Kind.MethodDeclaration
463
+ * );
464
+ * return method?.modifiers.some(m => m.type === 'async') || false;
465
+ * }
466
+ * }));
467
+ * ```
468
+ */
469
+ where?: (node: J, cursor: Cursor) => boolean | Promise<boolean>;
470
+ /**
471
+ * Optional context predicate that must evaluate to false for the transformation to be applied.
472
+ * Evaluated after the pattern matches structurally but before applying the template.
473
+ * Provides access to both the matched node and the cursor for context inspection.
474
+ *
475
+ * @param node The matched AST node
476
+ * @param cursor The cursor at the matched node, providing access to ancestors and context
477
+ * @returns true if the transformation should NOT be applied, false if it should proceed
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * rewrite(() => ({
482
+ * before: pattern`await ${_('promise')}`,
483
+ * after: template`await ${_('promise')}.catch(handleError)`,
484
+ * whereNot: (node, cursor) => {
485
+ * // Don't apply inside try-catch blocks
486
+ * return cursor.firstEnclosing((n: any): n is J.Try =>
487
+ * n.kind === J.Kind.Try
488
+ * ) !== undefined;
489
+ * }
490
+ * }));
491
+ * ```
492
+ */
493
+ whereNot?: (node: J, cursor: Cursor) => boolean | Promise<boolean>;
494
+ }
495
+ /**
496
+ * Options for debugging pattern matching.
497
+ * Used in Layer 1 (Core Instrumentation) to control debug output.
498
+ */
499
+ export interface DebugOptions {
500
+ /**
501
+ * Enable detailed logging during pattern matching.
502
+ */
503
+ enabled?: boolean;
504
+ /**
505
+ * Log structural comparison steps.
506
+ */
507
+ logComparison?: boolean;
508
+ /**
509
+ * Log constraint evaluation.
510
+ */
511
+ logConstraints?: boolean;
512
+ }
513
+ /**
514
+ * A single debug log entry collected during pattern matching.
515
+ * Part of Layer 1 (Core Instrumentation).
516
+ */
517
+ export interface DebugLogEntry {
518
+ /**
519
+ * Severity level of the log entry.
520
+ */
521
+ level: 'trace' | 'debug' | 'info' | 'warn';
522
+ /**
523
+ * The scope/category of the log entry.
524
+ */
525
+ scope: 'matching' | 'comparison' | 'constraint';
526
+ /**
527
+ * Path in the AST where this log entry was generated.
528
+ */
529
+ path: string[];
530
+ /**
531
+ * Human-readable message.
532
+ */
533
+ message: string;
534
+ /**
535
+ * Optional data associated with this log entry.
536
+ */
537
+ data?: any;
538
+ }
539
+ /**
540
+ * Detailed explanation of why a pattern failed to match.
541
+ * Built by Layer 1 (Core Instrumentation) and exposed by Layer 2 (API).
542
+ */
543
+ export interface MatchExplanation {
544
+ /**
545
+ * The reason for the match failure.
546
+ */
547
+ reason: 'structural-mismatch' | 'constraint-failed' | 'type-mismatch' | 'kind-mismatch' | 'value-mismatch' | 'array-length-mismatch';
548
+ /**
549
+ * Path in the AST where the failure occurred (e.g., ['select', 'name']).
550
+ */
551
+ path: string[];
552
+ /**
553
+ * Human-readable description of what was expected.
554
+ */
555
+ expected: string;
556
+ /**
557
+ * Human-readable description of what was actually found.
558
+ */
559
+ actual: string;
560
+ /**
561
+ * For constraint failures, details about which constraints failed.
562
+ */
563
+ constraintFailures?: Array<{
564
+ captureName: string;
565
+ actualValue: any;
566
+ error?: string;
567
+ }>;
568
+ /**
569
+ * Additional context about the failure.
570
+ */
571
+ details?: string;
572
+ }
573
+ /**
574
+ * Interface for accessing captured nodes from a successful pattern match.
575
+ * Part of the public API.
576
+ */
577
+ export interface MatchResult {
578
+ /**
579
+ * Get a captured node by name or by Capture object.
580
+ *
581
+ * @param capture The capture name (string) or Capture object
582
+ * @returns The captured node(s), or undefined if not found
583
+ */
584
+ get(capture: string): any;
585
+ get<T>(capture: Capture<T>): T | undefined;
586
+ }
587
+ /**
588
+ * Result of a pattern match attempt with debug information.
589
+ * Part of Layer 2 (Public API).
590
+ */
591
+ export interface MatchAttemptResult {
592
+ /**
593
+ * Whether the pattern matched successfully.
594
+ */
595
+ matched: boolean;
596
+ /**
597
+ * If matched, the match result with captured nodes. Undefined if not matched.
598
+ * Use `result.get('captureName')` or `result.get(captureObject)` to access captures.
599
+ */
600
+ result?: MatchResult;
601
+ /**
602
+ * If not matched, explanation of why. Undefined if matched.
603
+ */
604
+ explanation?: MatchExplanation;
605
+ /**
606
+ * Debug log entries collected during matching (if debug was enabled).
607
+ */
608
+ debugLog?: DebugLogEntry[];
609
+ }
610
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/javascript/templating/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/javascript/templating/types.ts"],"names":[],"mappings":""}