@openrewrite/rewrite 8.67.0-20251104-111121 → 8.67.0-20251104-114312
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.
- package/dist/javascript/comparator.d.ts +67 -4
- package/dist/javascript/comparator.d.ts.map +1 -1
- package/dist/javascript/comparator.js +523 -2794
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/index.d.ts +1 -1
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +1 -1
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/templating/capture.d.ts +226 -0
- package/dist/javascript/templating/capture.d.ts.map +1 -0
- package/dist/javascript/templating/capture.js +371 -0
- package/dist/javascript/templating/capture.js.map +1 -0
- package/dist/javascript/templating/comparator.d.ts +61 -0
- package/dist/javascript/templating/comparator.d.ts.map +1 -0
- package/dist/javascript/templating/comparator.js +393 -0
- package/dist/javascript/templating/comparator.js.map +1 -0
- package/dist/javascript/templating/engine.d.ts +75 -0
- package/dist/javascript/templating/engine.d.ts.map +1 -0
- package/dist/javascript/templating/engine.js +228 -0
- package/dist/javascript/templating/engine.js.map +1 -0
- package/dist/javascript/templating/index.d.ts +6 -0
- package/dist/javascript/templating/index.d.ts.map +1 -0
- package/dist/javascript/templating/index.js +42 -0
- package/dist/javascript/templating/index.js.map +1 -0
- package/dist/javascript/templating/pattern.d.ts +171 -0
- package/dist/javascript/templating/pattern.d.ts.map +1 -0
- package/dist/javascript/templating/pattern.js +681 -0
- package/dist/javascript/templating/pattern.js.map +1 -0
- package/dist/javascript/templating/placeholder-replacement.d.ts +58 -0
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -0
- package/dist/javascript/templating/placeholder-replacement.js +365 -0
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -0
- package/dist/javascript/templating/rewrite.d.ts +39 -0
- package/dist/javascript/templating/rewrite.d.ts.map +1 -0
- package/dist/javascript/templating/rewrite.js +81 -0
- package/dist/javascript/templating/rewrite.js.map +1 -0
- package/dist/javascript/templating/template.d.ts +204 -0
- package/dist/javascript/templating/template.d.ts.map +1 -0
- package/dist/javascript/templating/template.js +293 -0
- package/dist/javascript/templating/template.js.map +1 -0
- package/dist/javascript/templating/types.d.ts +263 -0
- package/dist/javascript/templating/types.d.ts.map +1 -0
- package/dist/javascript/templating/types.js +3 -0
- package/dist/javascript/templating/types.js.map +1 -0
- package/dist/javascript/templating/utils.d.ts +118 -0
- package/dist/javascript/templating/utils.d.ts.map +1 -0
- package/dist/javascript/templating/utils.js +253 -0
- package/dist/javascript/templating/utils.js.map +1 -0
- package/dist/version.txt +1 -1
- package/package.json +2 -1
- package/src/javascript/comparator.ts +554 -3323
- package/src/javascript/index.ts +1 -1
- package/src/javascript/templating/capture.ts +503 -0
- package/src/javascript/templating/comparator.ts +430 -0
- package/src/javascript/templating/engine.ts +252 -0
- package/src/javascript/templating/index.ts +60 -0
- package/src/javascript/templating/pattern.ts +727 -0
- package/src/javascript/templating/placeholder-replacement.ts +372 -0
- package/src/javascript/templating/rewrite.ts +95 -0
- package/src/javascript/templating/template.ts +326 -0
- package/src/javascript/templating/types.ts +300 -0
- package/src/javascript/templating/utils.ts +284 -0
- package/dist/javascript/templating.d.ts +0 -265
- package/dist/javascript/templating.d.ts.map +0 -1
- package/dist/javascript/templating.js +0 -1027
- package/dist/javascript/templating.js.map +0 -1
- package/src/javascript/templating.ts +0 -1226
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TemplateApplier = exports.TemplateEngine = void 0;
|
|
13
|
+
/*
|
|
14
|
+
* Copyright 2025 the original author or authors.
|
|
15
|
+
* <p>
|
|
16
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
17
|
+
* you may not use this file except in compliance with the License.
|
|
18
|
+
* You may obtain a copy of the License at
|
|
19
|
+
* <p>
|
|
20
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
21
|
+
* <p>
|
|
22
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
23
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
24
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
25
|
+
* See the License for the specific language governing permissions and
|
|
26
|
+
* limitations under the License.
|
|
27
|
+
*/
|
|
28
|
+
const __1 = require("../..");
|
|
29
|
+
const java_1 = require("../../java");
|
|
30
|
+
const __2 = require("..");
|
|
31
|
+
const immer_1 = require("immer");
|
|
32
|
+
const utils_1 = require("./utils");
|
|
33
|
+
const capture_1 = require("./capture");
|
|
34
|
+
const placeholder_replacement_1 = require("./placeholder-replacement");
|
|
35
|
+
/**
|
|
36
|
+
* Cache for compiled templates.
|
|
37
|
+
*/
|
|
38
|
+
const templateCache = new utils_1.TemplateCache();
|
|
39
|
+
/**
|
|
40
|
+
* Internal template engine - handles the core templating logic.
|
|
41
|
+
* Not exported from index, so only visible within the templating module.
|
|
42
|
+
*/
|
|
43
|
+
class TemplateEngine {
|
|
44
|
+
/**
|
|
45
|
+
* Applies a template with optional match results from pattern matching.
|
|
46
|
+
*
|
|
47
|
+
* @param templateParts The string parts of the template
|
|
48
|
+
* @param parameters The parameters between the string parts
|
|
49
|
+
* @param cursor The cursor pointing to the current location in the AST
|
|
50
|
+
* @param coordinates The coordinates specifying where and how to insert the generated AST
|
|
51
|
+
* @param values Map of capture names to values to replace the parameters with
|
|
52
|
+
* @param wrappersMap Map of capture names to J.RightPadded wrappers (for preserving markers)
|
|
53
|
+
* @param contextStatements Context declarations (imports, types, etc.) to prepend for type attribution
|
|
54
|
+
* @param dependencies NPM dependencies for type attribution
|
|
55
|
+
* @returns A Promise resolving to the generated AST node
|
|
56
|
+
*/
|
|
57
|
+
static applyTemplate(templateParts_1, parameters_1, cursor_1, coordinates_1) {
|
|
58
|
+
return __awaiter(this, arguments, void 0, function* (templateParts, parameters, cursor, coordinates, values = new Map(), wrappersMap = new Map(), contextStatements = [], dependencies = {}) {
|
|
59
|
+
// Build the template string with parameter placeholders
|
|
60
|
+
const templateString = TemplateEngine.buildTemplateString(templateParts, parameters);
|
|
61
|
+
// If the template string is empty, return undefined
|
|
62
|
+
if (!templateString.trim()) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
// Use cache to get or parse the compilation unit
|
|
66
|
+
// For templates, we don't have captures, so use empty array
|
|
67
|
+
const cu = yield templateCache.getOrParse(templateString, [], // templates don't have captures in the cache key
|
|
68
|
+
contextStatements, dependencies);
|
|
69
|
+
// Check if there are any statements
|
|
70
|
+
if (!cu.statements || cu.statements.length === 0) {
|
|
71
|
+
throw new Error(`Failed to parse template code (no statements):\n${templateString}`);
|
|
72
|
+
}
|
|
73
|
+
// Skip context statements to get to the actual template code
|
|
74
|
+
const templateStatementIndex = contextStatements.length;
|
|
75
|
+
if (templateStatementIndex >= cu.statements.length) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
// Extract the relevant part of the AST
|
|
79
|
+
const firstStatement = cu.statements[templateStatementIndex].element;
|
|
80
|
+
let extracted;
|
|
81
|
+
// Check if this is a wrapped template (function __TEMPLATE__() { ... })
|
|
82
|
+
if (firstStatement.kind === java_1.J.Kind.MethodDeclaration) {
|
|
83
|
+
const func = firstStatement;
|
|
84
|
+
if (func.name.simpleName === '__TEMPLATE__' && func.body) {
|
|
85
|
+
// __TEMPLATE__ wrapper indicates the original template was a block.
|
|
86
|
+
// Always return the block to preserve the block structure.
|
|
87
|
+
extracted = func.body;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Not a __TEMPLATE__ wrapper
|
|
91
|
+
extracted = firstStatement;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (firstStatement.kind === __2.JS.Kind.ExpressionStatement) {
|
|
95
|
+
extracted = firstStatement.expression;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
extracted = firstStatement;
|
|
99
|
+
}
|
|
100
|
+
// Create a copy to avoid sharing cached AST instances
|
|
101
|
+
const ast = (0, immer_1.produce)(extracted, _ => { });
|
|
102
|
+
// Create substitutions map for placeholders
|
|
103
|
+
const substitutions = new Map();
|
|
104
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
105
|
+
const placeholder = `${utils_1.PlaceholderUtils.PLACEHOLDER_PREFIX}${i}__`;
|
|
106
|
+
substitutions.set(placeholder, parameters[i]);
|
|
107
|
+
}
|
|
108
|
+
// Unsubstitute placeholders with actual parameter values and match results
|
|
109
|
+
const visitor = new placeholder_replacement_1.PlaceholderReplacementVisitor(substitutions, values, wrappersMap);
|
|
110
|
+
const unsubstitutedAst = (yield visitor.visit(ast, null));
|
|
111
|
+
// Apply the template to the current AST
|
|
112
|
+
return new TemplateApplier(cursor, coordinates, unsubstitutedAst).apply();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Builds a template string with parameter placeholders.
|
|
117
|
+
*
|
|
118
|
+
* @param templateParts The string parts of the template
|
|
119
|
+
* @param parameters The parameters between the string parts
|
|
120
|
+
* @returns The template string
|
|
121
|
+
*/
|
|
122
|
+
static buildTemplateString(templateParts, parameters) {
|
|
123
|
+
let result = '';
|
|
124
|
+
for (let i = 0; i < templateParts.length; i++) {
|
|
125
|
+
result += templateParts[i];
|
|
126
|
+
if (i < parameters.length) {
|
|
127
|
+
const param = parameters[i].value;
|
|
128
|
+
// Use a placeholder for Captures, TemplateParams, CaptureValues, Tree nodes, and Tree arrays
|
|
129
|
+
// Inline everything else (strings, numbers, booleans) directly
|
|
130
|
+
// Check for Capture (could be a Proxy, so check for symbol property)
|
|
131
|
+
const isCapture = param instanceof capture_1.CaptureImpl ||
|
|
132
|
+
(param && typeof param === 'object' && param[capture_1.CAPTURE_NAME_SYMBOL]);
|
|
133
|
+
const isTemplateParam = param instanceof capture_1.TemplateParamImpl;
|
|
134
|
+
const isCaptureValue = param instanceof capture_1.CaptureValue;
|
|
135
|
+
const isTreeArray = Array.isArray(param) && param.length > 0 && (0, __1.isTree)(param[0]);
|
|
136
|
+
if (isCapture || isTemplateParam || isCaptureValue || (0, __1.isTree)(param) || isTreeArray) {
|
|
137
|
+
const placeholder = `${utils_1.PlaceholderUtils.PLACEHOLDER_PREFIX}${i}__`;
|
|
138
|
+
result += placeholder;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
result += param;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Detect if this is a block template that needs wrapping
|
|
146
|
+
const trimmed = result.trim();
|
|
147
|
+
if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
|
|
148
|
+
result = `function __TEMPLATE__() ${result}`;
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.TemplateEngine = TemplateEngine;
|
|
154
|
+
/**
|
|
155
|
+
* Helper class for applying a template to an AST.
|
|
156
|
+
*/
|
|
157
|
+
class TemplateApplier {
|
|
158
|
+
constructor(cursor, coordinates, ast) {
|
|
159
|
+
this.cursor = cursor;
|
|
160
|
+
this.coordinates = coordinates;
|
|
161
|
+
this.ast = ast;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Applies the template to the current AST.
|
|
165
|
+
*
|
|
166
|
+
* @returns A Promise resolving to the modified AST
|
|
167
|
+
*/
|
|
168
|
+
apply() {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
const { loc } = this.coordinates;
|
|
171
|
+
// Apply the template based on the location and mode
|
|
172
|
+
switch (loc || 'EXPRESSION_PREFIX') {
|
|
173
|
+
case 'EXPRESSION_PREFIX':
|
|
174
|
+
return this.applyToExpression();
|
|
175
|
+
case 'STATEMENT_PREFIX':
|
|
176
|
+
return this.applyToStatement();
|
|
177
|
+
case 'BLOCK_END':
|
|
178
|
+
return this.applyToBlock();
|
|
179
|
+
default:
|
|
180
|
+
throw new Error(`Unsupported location: ${loc}`);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Applies the template to an expression.
|
|
186
|
+
*
|
|
187
|
+
* @returns A Promise resolving to the modified AST
|
|
188
|
+
*/
|
|
189
|
+
applyToExpression() {
|
|
190
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
191
|
+
const { tree } = this.coordinates;
|
|
192
|
+
// Create a copy of the AST with the prefix from the target
|
|
193
|
+
return tree ? (0, immer_1.produce)(this.ast, draft => {
|
|
194
|
+
draft.prefix = tree.prefix;
|
|
195
|
+
}) : this.ast;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Applies the template to a statement.
|
|
200
|
+
*
|
|
201
|
+
* @returns A Promise resolving to the modified AST
|
|
202
|
+
*/
|
|
203
|
+
applyToStatement() {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
205
|
+
const { tree } = this.coordinates;
|
|
206
|
+
// Create a copy of the AST with the prefix from the target
|
|
207
|
+
return (0, immer_1.produce)(this.ast, draft => {
|
|
208
|
+
draft.prefix = tree.prefix;
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Applies the template to a block.
|
|
214
|
+
*
|
|
215
|
+
* @returns A Promise resolving to the modified AST
|
|
216
|
+
*/
|
|
217
|
+
applyToBlock() {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
const { tree } = this.coordinates;
|
|
220
|
+
// Create a copy of the AST with the prefix from the target
|
|
221
|
+
return (0, immer_1.produce)(this.ast, draft => {
|
|
222
|
+
draft.prefix = tree.prefix;
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.TemplateApplier = TemplateApplier;
|
|
228
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/javascript/templating/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { VariadicOptions, CaptureOptions, Capture, Any, TemplateParam, PatternOptions, TemplateParameter, TemplateOptions, RewriteRule, RewriteConfig } from './types';
|
|
2
|
+
export { and, or, not, capture, any, param, _ } from './capture';
|
|
3
|
+
export { Pattern, PatternBuilder, MatchResult, pattern } from './pattern';
|
|
4
|
+
export { rewrite } from './rewrite';
|
|
5
|
+
export { Template, TemplateBuilder, template } from './template';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/javascript/templating/index.ts"],"names":[],"mappings":"AAiBA,YAAY,EACR,eAAe,EACf,cAAc,EACd,OAAO,EACP,GAAG,EACH,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,aAAa,EAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACH,GAAG,EACH,EAAE,EACF,GAAG,EACH,OAAO,EACP,GAAG,EACH,KAAK,EACL,CAAC,EACJ,MAAM,WAAW,CAAC;AAGnB,OAAO,EACH,OAAO,EACP,cAAc,EACd,WAAW,EACX,OAAO,EACV,MAAM,WAAW,CAAC;AAGnB,OAAO,EACH,OAAO,EACV,MAAM,WAAW,CAAC;AAGnB,OAAO,EACH,QAAQ,EACR,eAAe,EACf,QAAQ,EACX,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025 the original author or authors.
|
|
4
|
+
* <p>
|
|
5
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
* <p>
|
|
9
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
10
|
+
* <p>
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.template = exports.TemplateBuilder = exports.Template = exports.rewrite = exports.pattern = exports.MatchResult = exports.PatternBuilder = exports.Pattern = exports._ = exports.param = exports.any = exports.capture = exports.not = exports.or = exports.and = void 0;
|
|
19
|
+
// Export capture functionality
|
|
20
|
+
var capture_1 = require("./capture");
|
|
21
|
+
Object.defineProperty(exports, "and", { enumerable: true, get: function () { return capture_1.and; } });
|
|
22
|
+
Object.defineProperty(exports, "or", { enumerable: true, get: function () { return capture_1.or; } });
|
|
23
|
+
Object.defineProperty(exports, "not", { enumerable: true, get: function () { return capture_1.not; } });
|
|
24
|
+
Object.defineProperty(exports, "capture", { enumerable: true, get: function () { return capture_1.capture; } });
|
|
25
|
+
Object.defineProperty(exports, "any", { enumerable: true, get: function () { return capture_1.any; } });
|
|
26
|
+
Object.defineProperty(exports, "param", { enumerable: true, get: function () { return capture_1.param; } });
|
|
27
|
+
Object.defineProperty(exports, "_", { enumerable: true, get: function () { return capture_1._; } });
|
|
28
|
+
// Export pattern functionality
|
|
29
|
+
var pattern_1 = require("./pattern");
|
|
30
|
+
Object.defineProperty(exports, "Pattern", { enumerable: true, get: function () { return pattern_1.Pattern; } });
|
|
31
|
+
Object.defineProperty(exports, "PatternBuilder", { enumerable: true, get: function () { return pattern_1.PatternBuilder; } });
|
|
32
|
+
Object.defineProperty(exports, "MatchResult", { enumerable: true, get: function () { return pattern_1.MatchResult; } });
|
|
33
|
+
Object.defineProperty(exports, "pattern", { enumerable: true, get: function () { return pattern_1.pattern; } });
|
|
34
|
+
// Export rewrite functionality
|
|
35
|
+
var rewrite_1 = require("./rewrite");
|
|
36
|
+
Object.defineProperty(exports, "rewrite", { enumerable: true, get: function () { return rewrite_1.rewrite; } });
|
|
37
|
+
// Export template functionality
|
|
38
|
+
var template_1 = require("./template");
|
|
39
|
+
Object.defineProperty(exports, "Template", { enumerable: true, get: function () { return template_1.Template; } });
|
|
40
|
+
Object.defineProperty(exports, "TemplateBuilder", { enumerable: true, get: function () { return template_1.TemplateBuilder; } });
|
|
41
|
+
Object.defineProperty(exports, "template", { enumerable: true, get: function () { return template_1.template; } });
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/javascript/templating/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAgBH,+BAA+B;AAC/B,qCAQmB;AAPf,8FAAA,GAAG,OAAA;AACH,6FAAA,EAAE,OAAA;AACF,8FAAA,GAAG,OAAA;AACH,kGAAA,OAAO,OAAA;AACP,8FAAA,GAAG,OAAA;AACH,gGAAA,KAAK,OAAA;AACL,4FAAA,CAAC,OAAA;AAGL,+BAA+B;AAC/B,qCAKmB;AAJf,kGAAA,OAAO,OAAA;AACP,yGAAA,cAAc,OAAA;AACd,sGAAA,WAAW,OAAA;AACX,kGAAA,OAAO,OAAA;AAGX,+BAA+B;AAC/B,qCAEmB;AADf,kGAAA,OAAO,OAAA;AAGX,gCAAgC;AAChC,uCAIoB;AAHhB,oGAAA,QAAQ,OAAA;AACR,2GAAA,eAAe,OAAA;AACf,oGAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { J } from '../../java';
|
|
2
|
+
import { Capture, Any, PatternOptions } from './types';
|
|
3
|
+
import { CaptureStorageValue, WRAPPERS_MAP_SYMBOL } from './utils';
|
|
4
|
+
/**
|
|
5
|
+
* Builder for creating patterns programmatically.
|
|
6
|
+
* Use when pattern structure is not known at compile time.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Loop-based pattern generation
|
|
10
|
+
* const builder = Pattern.builder().code('myFunction(');
|
|
11
|
+
* for (let i = 0; i < argCount; i++) {
|
|
12
|
+
* if (i > 0) builder.code(', ');
|
|
13
|
+
* builder.capture(capture(`arg${i}`));
|
|
14
|
+
* }
|
|
15
|
+
* builder.code(')');
|
|
16
|
+
* const pat = builder.build();
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Conditional pattern construction
|
|
20
|
+
* const builder = Pattern.builder().code('foo(');
|
|
21
|
+
* builder.capture(capture('first'));
|
|
22
|
+
* if (needsSecondArg) {
|
|
23
|
+
* builder.code(', ').capture(capture('second'));
|
|
24
|
+
* }
|
|
25
|
+
* builder.code(')');
|
|
26
|
+
* const pat = builder.build();
|
|
27
|
+
*/
|
|
28
|
+
export declare class PatternBuilder {
|
|
29
|
+
private parts;
|
|
30
|
+
private captures;
|
|
31
|
+
/**
|
|
32
|
+
* Adds a static string part to the pattern.
|
|
33
|
+
*
|
|
34
|
+
* @param str The string to add
|
|
35
|
+
* @returns This builder for chaining
|
|
36
|
+
*/
|
|
37
|
+
code(str: string): this;
|
|
38
|
+
/**
|
|
39
|
+
* Adds a capture to the pattern.
|
|
40
|
+
*
|
|
41
|
+
* @param value The capture object (Capture or Any) or string name
|
|
42
|
+
* @returns This builder for chaining
|
|
43
|
+
*/
|
|
44
|
+
capture(value: Capture | Any<any> | string): this;
|
|
45
|
+
/**
|
|
46
|
+
* Builds the pattern from accumulated parts and captures.
|
|
47
|
+
*
|
|
48
|
+
* @returns A Pattern instance
|
|
49
|
+
*/
|
|
50
|
+
build(): Pattern;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Represents a pattern that can be matched against AST nodes.
|
|
54
|
+
*/
|
|
55
|
+
export declare class Pattern {
|
|
56
|
+
readonly templateParts: TemplateStringsArray;
|
|
57
|
+
readonly captures: (Capture | Any<any>)[];
|
|
58
|
+
private _options;
|
|
59
|
+
/**
|
|
60
|
+
* Gets the configuration options for this pattern.
|
|
61
|
+
* @readonly
|
|
62
|
+
*/
|
|
63
|
+
get options(): Readonly<PatternOptions>;
|
|
64
|
+
/**
|
|
65
|
+
* Creates a new builder for constructing patterns programmatically.
|
|
66
|
+
*
|
|
67
|
+
* @returns A new PatternBuilder instance
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* const pat = Pattern.builder()
|
|
71
|
+
* .code('function ')
|
|
72
|
+
* .capture(capture('name'))
|
|
73
|
+
* .code('() { return ')
|
|
74
|
+
* .capture(capture('value'))
|
|
75
|
+
* .code('; }')
|
|
76
|
+
* .build();
|
|
77
|
+
*/
|
|
78
|
+
static builder(): PatternBuilder;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new pattern from template parts and captures.
|
|
81
|
+
*
|
|
82
|
+
* @param templateParts The string parts of the template
|
|
83
|
+
* @param captures The captures between the string parts (can be Capture or Any)
|
|
84
|
+
*/
|
|
85
|
+
constructor(templateParts: TemplateStringsArray, captures: (Capture | Any<any>)[]);
|
|
86
|
+
/**
|
|
87
|
+
* Configures this pattern with additional options.
|
|
88
|
+
*
|
|
89
|
+
* @param options Configuration options
|
|
90
|
+
* @returns This pattern for method chaining
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* pattern`isDate(${capture('date')})`
|
|
94
|
+
* .configure({
|
|
95
|
+
* imports: ['import { isDate } from \"util\"'],
|
|
96
|
+
* dependencies: { 'util': '^1.0.0' }
|
|
97
|
+
* })
|
|
98
|
+
*/
|
|
99
|
+
configure(options: PatternOptions): Pattern;
|
|
100
|
+
/**
|
|
101
|
+
* Creates a matcher for this pattern against a specific AST node.
|
|
102
|
+
*
|
|
103
|
+
* @param ast The AST node to match against
|
|
104
|
+
* @returns A Matcher object
|
|
105
|
+
*/
|
|
106
|
+
match(ast: J): Promise<MatchResult | undefined>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Result of a successful pattern match containing captured values.
|
|
110
|
+
*
|
|
111
|
+
* Provides access to captured AST nodes from pattern matching operations.
|
|
112
|
+
* Use the `get()` method to retrieve captured values by name or by Capture object.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* const x = capture('x');
|
|
116
|
+
* const pat = pattern`foo(${x})`;
|
|
117
|
+
* const match = await pat.match(someNode);
|
|
118
|
+
* if (match) {
|
|
119
|
+
* const captured = match.get('x'); // Get by name
|
|
120
|
+
* // or
|
|
121
|
+
* const captured = match.get(x); // Get by Capture object
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Variadic captures return arrays
|
|
126
|
+
* const args = capture({ variadic: true });
|
|
127
|
+
* const pat = pattern`foo(${args})`;
|
|
128
|
+
* const match = await pat.match(methodInvocation);
|
|
129
|
+
* if (match) {
|
|
130
|
+
* const capturedArgs = match.get(args); // Returns J[] for variadic captures
|
|
131
|
+
* }
|
|
132
|
+
*/
|
|
133
|
+
export declare class MatchResult implements Pick<Map<string, J>, "get"> {
|
|
134
|
+
private readonly storage;
|
|
135
|
+
constructor(storage?: Map<string, CaptureStorageValue>);
|
|
136
|
+
get<T>(capture: Capture<T[]>): T[] | undefined;
|
|
137
|
+
get<T>(capture: Capture<T>): T | undefined;
|
|
138
|
+
get(capture: string): J | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Extracts semantic elements from storage value.
|
|
141
|
+
* For wrappers, extracts the .element; for arrays, returns array of elements.
|
|
142
|
+
*
|
|
143
|
+
* @param value The storage value
|
|
144
|
+
* @returns The semantic element(s)
|
|
145
|
+
*/
|
|
146
|
+
private extractElements;
|
|
147
|
+
/**
|
|
148
|
+
* Internal method to get wrappers (used by template expansion).
|
|
149
|
+
* Returns both scalar and variadic wrappers.
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
[WRAPPERS_MAP_SYMBOL](): Map<string, J.RightPadded<J> | J.RightPadded<J>[]>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Tagged template function for creating patterns.
|
|
156
|
+
*
|
|
157
|
+
* @param strings The string parts of the template
|
|
158
|
+
* @param captures The captures between the string parts (Capture, Any, or string names)
|
|
159
|
+
* @returns A Pattern object
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* // Using the same capture multiple times for repeated patterns
|
|
163
|
+
* const expr = capture('expr');
|
|
164
|
+
* const redundantOr = pattern`${expr} || ${expr}`;
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* // Using any() for non-capturing matches
|
|
168
|
+
* const pat = pattern`foo(${any()})`;
|
|
169
|
+
*/
|
|
170
|
+
export declare function pattern(strings: TemplateStringsArray, ...captures: (Capture | Any<any> | string)[]): Pattern;
|
|
171
|
+
//# sourceMappingURL=pattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../../src/javascript/templating/pattern.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,CAAC,EAAC,MAAM,YAAY,CAAC;AAG7B,OAAO,EAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAC,MAAM,SAAS,CAAC;AAGrD,OAAO,EAAiD,mBAAmB,EAAE,mBAAmB,EAAC,MAAM,SAAS,CAAC;AAEjH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAA8B;IAE9C;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAcvB;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI;IAajD;;;;OAIG;IACH,KAAK,IAAI,OAAO;CAiBnB;AAED;;GAEG;AACH,qBAAa,OAAO;aAoCI,aAAa,EAAE,oBAAoB;aACnC,QAAQ,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;IApCpD,OAAO,CAAC,QAAQ,CAAsB;IAEtC;;;OAGG;IACH,IAAI,OAAO,IAAI,QAAQ,CAAC,cAAc,CAAC,CAEtC;IAED;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,OAAO,IAAI,cAAc;IAIhC;;;;;OAKG;gBAEiB,aAAa,EAAE,oBAAoB,EACnC,QAAQ,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;IAIpD;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO;IAK3C;;;;;OAKG;IACG,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAUxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,WAAY,YAAW,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC;IAEvD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAa;IAK1E,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS;IAE9C,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS;IAE1C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAYnC;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAkBvB;;;;OAIG;IACH,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;CAa9E;AA4ZD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,QAAQ,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,OAAO,CAY5G"}
|