@openrewrite/rewrite 8.88.0 → 8.88.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.
- package/dist/javascript/node-resolution-result.js +18 -16
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/package-exported-types.d.ts +13 -0
- package/dist/javascript/package-exported-types.d.ts.map +1 -0
- package/dist/javascript/package-exported-types.js +374 -0
- package/dist/javascript/package-exported-types.js.map +1 -0
- package/dist/javascript/type-mapping.d.ts +6 -0
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +16 -0
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/rpc/queue.d.ts +12 -0
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +35 -4
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/dependency-types.d.ts +15 -0
- package/dist/rpc/request/dependency-types.d.ts.map +1 -0
- package/dist/rpc/request/dependency-types.js +143 -0
- package/dist/rpc/request/dependency-types.js.map +1 -0
- package/dist/rpc/request/index.d.ts +1 -0
- package/dist/rpc/request/index.d.ts.map +1 -1
- package/dist/rpc/request/index.js +1 -0
- package/dist/rpc/request/index.js.map +1 -1
- package/dist/rpc/request/last-parsed-project.d.ts +3 -0
- package/dist/rpc/request/last-parsed-project.d.ts.map +1 -0
- package/dist/rpc/request/last-parsed-project.js +29 -0
- package/dist/rpc/request/last-parsed-project.js.map +1 -0
- package/dist/rpc/request/parse-project.d.ts.map +1 -1
- package/dist/rpc/request/parse-project.js +2 -0
- package/dist/rpc/request/parse-project.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +1 -0
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +39 -27
- package/dist/run.js.map +1 -1
- package/package.json +1 -1
- package/src/javascript/node-resolution-result.ts +18 -16
- package/src/javascript/package-exported-types.ts +351 -0
- package/src/javascript/type-mapping.ts +16 -0
- package/src/rpc/queue.ts +38 -4
- package/src/rpc/request/dependency-types.ts +128 -0
- package/src/rpc/request/index.ts +1 -0
- package/src/rpc/request/last-parsed-project.ts +27 -0
- package/src/rpc/request/parse-project.ts +2 -0
- package/src/rpc/rewrite-rpc.ts +2 -0
- package/src/run.ts +44 -23
package/src/run.ts
CHANGED
|
@@ -40,28 +40,47 @@ export class Result {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Recipes commonly instantiate their sub-recipes inside `recipeList()`, so calling it more
|
|
45
|
+
* than once yields different instances. A scanning sub-recipe would then hold a different
|
|
46
|
+
* accumulator in every phase and for every source file. Resolving each recipe list once per
|
|
47
|
+
* run keeps sub-recipe identity, and therefore accumulator identity, stable.
|
|
48
|
+
*/
|
|
49
|
+
type RecipeLists = WeakMap<Recipe, Recipe[]>;
|
|
50
|
+
|
|
51
|
+
async function subRecipes(recipe: Recipe, recipeLists: RecipeLists): Promise<Recipe[]> {
|
|
52
|
+
let resolved = recipeLists.get(recipe);
|
|
53
|
+
if (resolved === undefined) {
|
|
54
|
+
resolved = await recipe.recipeList();
|
|
55
|
+
recipeLists.set(recipe, resolved);
|
|
56
|
+
}
|
|
57
|
+
return resolved;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function hasScanningRecipe(recipe: Recipe, recipeLists: RecipeLists): Promise<boolean> {
|
|
44
61
|
if (recipe instanceof ScanningRecipe) return true;
|
|
45
|
-
for (const item of (await recipe
|
|
46
|
-
if (await hasScanningRecipe(item)) return true;
|
|
62
|
+
for (const item of (await subRecipes(recipe, recipeLists))) {
|
|
63
|
+
if (await hasScanningRecipe(item, recipeLists)) return true;
|
|
47
64
|
}
|
|
48
65
|
return false;
|
|
49
66
|
}
|
|
50
67
|
|
|
51
|
-
async function recurseRecipeList<T>(recipe: Recipe, initial: T, fn: (recipe: Recipe, t: T) => Promise<T | undefined>): Promise<T | undefined> {
|
|
68
|
+
async function recurseRecipeList<T>(recipe: Recipe, initial: T, recipeLists: RecipeLists, fn: (recipe: Recipe, t: T) => Promise<T | undefined>): Promise<T | undefined> {
|
|
52
69
|
let t: T | undefined = await fn(recipe, initial);
|
|
53
|
-
for (const subRecipe of await recipe
|
|
70
|
+
for (const subRecipe of await subRecipes(recipe, recipeLists)) {
|
|
54
71
|
if (t === undefined) {
|
|
55
72
|
return undefined;
|
|
56
73
|
}
|
|
57
|
-
t = await recurseRecipeList(subRecipe, t, fn);
|
|
74
|
+
t = await recurseRecipeList(subRecipe, t, recipeLists, fn);
|
|
58
75
|
}
|
|
59
76
|
return t;
|
|
60
77
|
}
|
|
61
78
|
|
|
62
|
-
async function recursiveOnComplete(recipe: Recipe, ctx: ExecutionContext): Promise<void> {
|
|
79
|
+
async function recursiveOnComplete(recipe: Recipe, ctx: ExecutionContext, recipeLists: RecipeLists): Promise<void> {
|
|
63
80
|
await recipe.onComplete(ctx);
|
|
64
|
-
|
|
81
|
+
for (const subRecipe of await subRecipes(recipe, recipeLists)) {
|
|
82
|
+
await recursiveOnComplete(subRecipe, ctx, recipeLists);
|
|
83
|
+
}
|
|
65
84
|
}
|
|
66
85
|
|
|
67
86
|
export async function scheduleRun(recipe: Recipe, before: SourceFile[], ctx: ExecutionContext): Promise<RecipeRun> {
|
|
@@ -94,34 +113,38 @@ export async function* scheduleRunStreaming(
|
|
|
94
113
|
onProgress?: ProgressCallback
|
|
95
114
|
): AsyncGenerator<Result, void, undefined> {
|
|
96
115
|
const cursor = rootCursor();
|
|
97
|
-
const
|
|
116
|
+
const recipeLists: RecipeLists = new WeakMap();
|
|
117
|
+
const isScanning = await hasScanningRecipe(recipe, recipeLists);
|
|
118
|
+
const knownTotal = Array.isArray(before) ? before.length : -1; // -1 = unknown total
|
|
98
119
|
|
|
99
120
|
if (isScanning) {
|
|
100
121
|
// For scanning recipes, pull files from the generator and scan them immediately.
|
|
101
122
|
// Files are stored for the later edit phase.
|
|
102
123
|
const files: SourceFile[] = [];
|
|
103
|
-
const iterable = Array.isArray(before) ? before : before;
|
|
104
|
-
const knownTotal = Array.isArray(before) ? before.length : -1; // -1 = unknown total
|
|
105
124
|
|
|
106
125
|
// Phase 1: Pull files from generator and scan each immediately
|
|
107
126
|
let scanCount = 0;
|
|
108
|
-
for await (const b of
|
|
127
|
+
for await (const b of before) {
|
|
109
128
|
files.push(b);
|
|
110
129
|
scanCount++;
|
|
111
130
|
onProgress?.('scanning', scanCount, knownTotal, b.sourcePath);
|
|
112
131
|
|
|
113
|
-
// Scan this file immediately
|
|
114
|
-
|
|
132
|
+
// Scan this file immediately. Scanning must not modify the tree, so the visit
|
|
133
|
+
// result is discarded and the original file is passed on to the next recipe in
|
|
134
|
+
// the list. Returning `undefined` here would abort traversal of the remainder
|
|
135
|
+
// of the recipe list, leaving nested scanners unrun.
|
|
136
|
+
await recurseRecipeList(recipe, b, recipeLists, async (recipe, b2) => {
|
|
115
137
|
if (recipe instanceof ScanningRecipe) {
|
|
116
|
-
|
|
138
|
+
await (await recipe.scanner(recipe.accumulator(cursor, ctx))).visit(b2, ctx, cursor);
|
|
117
139
|
}
|
|
140
|
+
return b2;
|
|
118
141
|
});
|
|
119
142
|
}
|
|
120
143
|
|
|
121
144
|
const totalFiles = files.length;
|
|
122
145
|
|
|
123
146
|
// Phase 2: Collect generated files
|
|
124
|
-
const generated = (await recurseRecipeList(recipe, [] as SourceFile[], async (recipe, generated) => {
|
|
147
|
+
const generated = (await recurseRecipeList(recipe, [] as SourceFile[], recipeLists, async (recipe, generated) => {
|
|
125
148
|
if (recipe instanceof ScanningRecipe) {
|
|
126
149
|
generated.push(...await recipe.generate(recipe.accumulator(cursor, ctx), ctx));
|
|
127
150
|
}
|
|
@@ -132,7 +155,7 @@ export async function* scheduleRunStreaming(
|
|
|
132
155
|
for (let i = 0; i < files.length; i++) {
|
|
133
156
|
const b = files[i];
|
|
134
157
|
onProgress?.('processing', i + 1, totalFiles, b.sourcePath);
|
|
135
|
-
const editedB = await recurseRecipeList(recipe, b, async (recipe, b2) => (await recipe.editor()).visit(b2, ctx, cursor));
|
|
158
|
+
const editedB = await recurseRecipeList(recipe, b, recipeLists, async (recipe, b2) => (await recipe.editor()).visit(b2, ctx, cursor));
|
|
136
159
|
// Always yield a result so the caller knows when each file is processed
|
|
137
160
|
yield new Result(b, editedB !== b ? editedB : b);
|
|
138
161
|
// Clear array entry to allow GC to free memory for this file
|
|
@@ -141,24 +164,22 @@ export async function* scheduleRunStreaming(
|
|
|
141
164
|
|
|
142
165
|
// Phase 4: Edit generated files and yield results
|
|
143
166
|
for (const g of generated) {
|
|
144
|
-
const editedG = await recurseRecipeList(recipe, g, async (recipe, g2) => (await recipe.editor()).visit(g2, ctx, cursor));
|
|
167
|
+
const editedG = await recurseRecipeList(recipe, g, recipeLists, async (recipe, g2) => (await recipe.editor()).visit(g2, ctx, cursor));
|
|
145
168
|
if (editedG) {
|
|
146
169
|
yield new Result(undefined, editedG);
|
|
147
170
|
}
|
|
148
171
|
}
|
|
149
172
|
} else {
|
|
150
173
|
// For non-scanning recipes, process files immediately as they come in
|
|
151
|
-
const iterable = Array.isArray(before) ? before : before;
|
|
152
|
-
const knownTotal = Array.isArray(before) ? before.length : -1; // -1 = unknown total
|
|
153
174
|
let processCount = 0;
|
|
154
|
-
for await (const b of
|
|
175
|
+
for await (const b of before) {
|
|
155
176
|
processCount++;
|
|
156
177
|
onProgress?.('processing', processCount, knownTotal, b.sourcePath);
|
|
157
|
-
const editedB = await recurseRecipeList(recipe, b, async (recipe, b2) => (await recipe.editor()).visit(b2, ctx, cursor));
|
|
178
|
+
const editedB = await recurseRecipeList(recipe, b, recipeLists, async (recipe, b2) => (await recipe.editor()).visit(b2, ctx, cursor));
|
|
158
179
|
// Always yield a result so the caller knows when each file is processed
|
|
159
180
|
yield new Result(b, editedB !== b ? editedB : b);
|
|
160
181
|
}
|
|
161
182
|
}
|
|
162
183
|
|
|
163
|
-
await recursiveOnComplete(recipe, ctx);
|
|
184
|
+
await recursiveOnComplete(recipe, ctx, recipeLists);
|
|
164
185
|
}
|