@openrewrite/rewrite 8.92.17 → 8.92.18
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/README.md +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/java/formatting-utils.d.ts +2 -1
- package/dist/java/formatting-utils.d.ts.map +1 -1
- package/dist/java/formatting-utils.js +4 -3
- package/dist/java/formatting-utils.js.map +1 -1
- package/dist/java/rpc.d.ts.map +1 -1
- package/dist/java/rpc.js +2 -0
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/tree.d.ts +8 -0
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/tree.js +11 -1
- package/dist/java/tree.js.map +1 -1
- package/dist/java/type.d.ts +7 -1
- package/dist/java/type.d.ts.map +1 -1
- package/dist/java/type.js +16 -1
- package/dist/java/type.js.map +1 -1
- package/dist/javascript/add-import.d.ts +27 -21
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +303 -143
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +25 -10
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/autodetect.js +36 -45
- package/dist/javascript/autodetect.js.map +1 -1
- package/dist/javascript/binding.d.ts +6 -4
- package/dist/javascript/binding.d.ts.map +1 -1
- package/dist/javascript/binding.js +54 -18
- package/dist/javascript/binding.js.map +1 -1
- package/dist/javascript/comparator.d.ts +22 -5
- package/dist/javascript/comparator.d.ts.map +1 -1
- package/dist/javascript/comparator.js +116 -38
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/format/format.d.ts +2 -0
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +11 -1
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/index.d.ts +4 -2
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +10 -1
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/markers.d.ts.map +1 -1
- package/dist/javascript/markers.js +64 -0
- package/dist/javascript/markers.js.map +1 -1
- package/dist/javascript/method-matcher.d.ts +13 -2
- package/dist/javascript/method-matcher.d.ts.map +1 -1
- package/dist/javascript/method-matcher.js +32 -19
- package/dist/javascript/method-matcher.js.map +1 -1
- package/dist/javascript/package-name.d.ts +6 -0
- package/dist/javascript/package-name.d.ts.map +1 -0
- package/dist/javascript/package-name.js +47 -0
- package/dist/javascript/package-name.js.map +1 -0
- package/dist/javascript/preconditions.d.ts +4 -1
- package/dist/javascript/preconditions.d.ts.map +1 -1
- package/dist/javascript/preconditions.js +7 -4
- package/dist/javascript/preconditions.js.map +1 -1
- package/dist/javascript/recipes/change-method-target-to-import.d.ts +29 -0
- package/dist/javascript/recipes/change-method-target-to-import.d.ts.map +1 -0
- package/dist/javascript/recipes/change-method-target-to-import.js +164 -0
- package/dist/javascript/recipes/change-method-target-to-import.js.map +1 -0
- package/dist/javascript/recipes/index.d.ts +1 -0
- package/dist/javascript/recipes/index.d.ts.map +1 -1
- package/dist/javascript/recipes/index.js +1 -0
- package/dist/javascript/recipes/index.js.map +1 -1
- package/dist/javascript/scope.d.ts +60 -16
- package/dist/javascript/scope.d.ts.map +1 -1
- package/dist/javascript/scope.js +596 -131
- package/dist/javascript/scope.js.map +1 -1
- package/dist/javascript/search/uses-method.d.ts +1 -1
- package/dist/javascript/search/uses-method.d.ts.map +1 -1
- package/dist/javascript/search/uses-method.js +2 -2
- package/dist/javascript/search/uses-method.js.map +1 -1
- package/dist/javascript/search/uses-type.d.ts +14 -1
- package/dist/javascript/search/uses-type.d.ts.map +1 -1
- package/dist/javascript/search/uses-type.js +24 -9
- package/dist/javascript/search/uses-type.js.map +1 -1
- package/dist/javascript/templating/bindings.d.ts +1 -1
- package/dist/javascript/templating/bindings.d.ts.map +1 -1
- package/dist/javascript/templating/bindings.js +10 -50
- package/dist/javascript/templating/bindings.js.map +1 -1
- package/dist/javascript/templating/comparator.d.ts +8 -11
- package/dist/javascript/templating/comparator.d.ts.map +1 -1
- package/dist/javascript/templating/comparator.js +12 -110
- package/dist/javascript/templating/comparator.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts +34 -24
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +200 -112
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts +11 -5
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +86 -20
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts +34 -3
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +126 -60
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/precedence.d.ts +3 -1
- package/dist/javascript/templating/precedence.d.ts.map +1 -1
- package/dist/javascript/templating/precedence.js +28 -8
- package/dist/javascript/templating/precedence.js.map +1 -1
- package/dist/javascript/templating/template.d.ts +7 -6
- package/dist/javascript/templating/template.d.ts.map +1 -1
- package/dist/javascript/templating/template.js +31 -28
- package/dist/javascript/templating/template.js.map +1 -1
- package/dist/javascript/templating/types.d.ts +6 -3
- package/dist/javascript/templating/types.d.ts.map +1 -1
- package/dist/javascript/templating/utils.d.ts +10 -1
- package/dist/javascript/templating/utils.d.ts.map +1 -1
- package/dist/javascript/templating/utils.js +22 -3
- package/dist/javascript/templating/utils.js.map +1 -1
- package/dist/javascript/tree-debug.d.ts +2 -0
- package/dist/javascript/tree-debug.d.ts.map +1 -1
- package/dist/javascript/tree-debug.js +6 -0
- package/dist/javascript/tree-debug.js.map +1 -1
- package/dist/javascript/tsconfig.d.ts.map +1 -1
- package/dist/javascript/tsconfig.js +7 -17
- package/dist/javascript/tsconfig.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +34 -16
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +253 -249
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/type-report-cli.d.ts +7 -0
- package/dist/javascript/type-report-cli.d.ts.map +1 -0
- package/dist/javascript/type-report-cli.js +129 -0
- package/dist/javascript/type-report-cli.js.map +1 -0
- package/dist/javascript/type-report.d.ts +61 -0
- package/dist/javascript/type-report.d.ts.map +1 -0
- package/dist/javascript/type-report.js +488 -0
- package/dist/javascript/type-report.js.map +1 -0
- package/dist/markers.d.ts +4 -0
- package/dist/markers.d.ts.map +1 -1
- package/dist/markers.js +8 -0
- package/dist/markers.js.map +1 -1
- package/dist/recipe.d.ts +5 -0
- package/dist/recipe.d.ts.map +1 -1
- package/dist/recipe.js +5 -0
- package/dist/recipe.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/rpc/queue.d.ts +16 -0
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +27 -9
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/prepare-recipe.d.ts +3 -1
- package/dist/rpc/request/prepare-recipe.d.ts.map +1 -1
- package/dist/rpc/request/prepare-recipe.js +13 -6
- package/dist/rpc/request/prepare-recipe.js.map +1 -1
- package/dist/search/is-source-file.d.ts +1 -0
- package/dist/search/is-source-file.d.ts.map +1 -1
- package/dist/search/is-source-file.js +7 -2
- package/dist/search/is-source-file.js.map +1 -1
- package/dist/test/rewrite-test.d.ts +5 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +14 -3
- package/dist/test/rewrite-test.js.map +1 -1
- package/package.json +4 -3
- package/src/index.ts +3 -1
- package/src/java/formatting-utils.ts +5 -4
- package/src/java/rpc.ts +2 -0
- package/src/java/tree.ts +15 -0
- package/src/java/type.ts +19 -2
- package/src/javascript/add-import.ts +338 -152
- package/src/javascript/amd.ts +28 -12
- package/src/javascript/autodetect.ts +32 -41
- package/src/javascript/binding.ts +64 -22
- package/src/javascript/comparator.ts +119 -43
- package/src/javascript/format/format.ts +9 -0
- package/src/javascript/index.ts +6 -3
- package/src/javascript/markers.ts +43 -1
- package/src/javascript/method-matcher.ts +34 -22
- package/src/javascript/package-name.ts +45 -0
- package/src/javascript/preconditions.ts +7 -4
- package/src/javascript/recipes/change-method-target-to-import.ts +178 -0
- package/src/javascript/recipes/index.ts +1 -0
- package/src/javascript/scope.ts +705 -169
- package/src/javascript/search/uses-method.ts +2 -2
- package/src/javascript/search/uses-type.ts +30 -9
- package/src/javascript/templating/bindings.ts +13 -38
- package/src/javascript/templating/comparator.ts +16 -127
- package/src/javascript/templating/engine.ts +229 -127
- package/src/javascript/templating/pattern.ts +107 -28
- package/src/javascript/templating/placeholder-replacement.ts +154 -62
- package/src/javascript/templating/precedence.ts +33 -11
- package/src/javascript/templating/template.ts +35 -30
- package/src/javascript/templating/types.ts +6 -3
- package/src/javascript/templating/utils.ts +24 -2
- package/src/javascript/tree-debug.ts +9 -0
- package/src/javascript/tsconfig.ts +7 -17
- package/src/javascript/type-mapping.ts +258 -252
- package/src/javascript/type-report-cli.ts +96 -0
- package/src/javascript/type-report.ts +575 -0
- package/src/markers.ts +8 -0
- package/src/recipe.ts +6 -0
- package/src/rpc/queue.ts +44 -5
- package/src/rpc/request/prepare-recipe.ts +16 -6
- package/src/search/is-source-file.ts +8 -3
- package/src/test/rewrite-test.ts +14 -3
package/src/rpc/queue.ts
CHANGED
|
@@ -52,12 +52,27 @@ export interface RpcCodec<T> {
|
|
|
52
52
|
rpcReceive(before: T, q: RpcReceiveQueue): Promise<T>;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Converts a type that has no {@link RpcCodec} on either side, and so travels as one inline value,
|
|
57
|
+
* between its shape here and the one the peer's serializer gives it.
|
|
58
|
+
*/
|
|
59
|
+
export interface RpcValueCodec<T> {
|
|
60
|
+
/**
|
|
61
|
+
* @param value The value as the peer serialized it, with its `kind` and without its top-level serializer keys.
|
|
62
|
+
*/
|
|
63
|
+
fromValue(value: any): T;
|
|
64
|
+
|
|
65
|
+
toValue(after: T): any;
|
|
66
|
+
}
|
|
67
|
+
|
|
55
68
|
/**
|
|
56
69
|
* A registry for managing RPC codecs based on object types.
|
|
57
70
|
*/
|
|
58
71
|
export class RpcCodecs {
|
|
59
72
|
private static nonTreeCodecs = new Map<string, RpcCodec<any>>();
|
|
60
73
|
|
|
74
|
+
private static valueCodecs = new Map<string, RpcValueCodec<any>>();
|
|
75
|
+
|
|
61
76
|
/**
|
|
62
77
|
* The first key is on sourceFileType and the second on object type
|
|
63
78
|
*/
|
|
@@ -98,6 +113,14 @@ export class RpcCodecs {
|
|
|
98
113
|
return this.nonTreeCodecs.get(type);
|
|
99
114
|
}
|
|
100
115
|
|
|
116
|
+
static registerValueCodec(type: string, codec: RpcValueCodec<any>): void {
|
|
117
|
+
this.valueCodecs.set(type, codec);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static valueCodecForType(type: string): RpcValueCodec<any> | undefined {
|
|
121
|
+
return this.valueCodecs.get(type);
|
|
122
|
+
}
|
|
123
|
+
|
|
101
124
|
/**
|
|
102
125
|
* Determines the appropriate codec for an instance based on its `kind` property.
|
|
103
126
|
*
|
|
@@ -204,7 +227,7 @@ export class RpcSendQueue {
|
|
|
204
227
|
await this.add(after, onChange);
|
|
205
228
|
} else {
|
|
206
229
|
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
207
|
-
this.put(
|
|
230
|
+
this.put(this.valueMessage(RpcObjectState.CHANGE, after, !onChange && !afterCodec));
|
|
208
231
|
await this.doChange(after, before, onChange, afterCodec);
|
|
209
232
|
}
|
|
210
233
|
});
|
|
@@ -239,7 +262,7 @@ export class RpcSendQueue {
|
|
|
239
262
|
const afterCodec = onChangeRun ? undefined : RpcCodecs.forInstance(anAfter, this.sourceFileType);
|
|
240
263
|
// Without an onChange callback or codec, no property messages follow, so the
|
|
241
264
|
// value must travel inline (as in send()) or the receiver keeps the stale element
|
|
242
|
-
this.put(
|
|
265
|
+
this.put(this.valueMessage(RpcObjectState.CHANGE, anAfter, !onChangeRun && !afterCodec));
|
|
243
266
|
await this.doChange(anAfter, aBefore, onChangeRun, afterCodec);
|
|
244
267
|
}
|
|
245
268
|
}
|
|
@@ -288,14 +311,23 @@ export class RpcSendQueue {
|
|
|
288
311
|
}
|
|
289
312
|
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
290
313
|
this.put({
|
|
291
|
-
|
|
314
|
+
...this.valueMessage(RpcObjectState.ADD, after, !onChange && !afterCodec),
|
|
292
315
|
valueType: this.getValueType(after),
|
|
293
|
-
value: onChange || afterCodec ? undefined : after,
|
|
294
316
|
ref: ref
|
|
295
317
|
});
|
|
296
318
|
await this.doChange(after, undefined, onChange, afterCodec);
|
|
297
319
|
}
|
|
298
320
|
|
|
321
|
+
// An inline value carries its type even in a CHANGE, as the peer needs it to decode the value
|
|
322
|
+
private valueMessage(state: RpcObjectState, after: any, inline: boolean): RpcObjectData {
|
|
323
|
+
if (!inline) {
|
|
324
|
+
return {state};
|
|
325
|
+
}
|
|
326
|
+
const valueType = this.getValueType(after);
|
|
327
|
+
const valueCodec = valueType === undefined ? undefined : RpcCodecs.valueCodecForType(valueType);
|
|
328
|
+
return {state, valueType, value: valueCodec ? valueCodec.toValue(after) : after};
|
|
329
|
+
}
|
|
330
|
+
|
|
299
331
|
private async doChange(after: any, before: any, onChange?: () => Promise<void>, afterCodec?: RpcCodec<any>): Promise<void> {
|
|
300
332
|
const lastBefore = this.before;
|
|
301
333
|
this.before = before;
|
|
@@ -526,7 +558,7 @@ export class RpcReceiveQueue {
|
|
|
526
558
|
after = await codec.rpcReceive(before, this);
|
|
527
559
|
} else if (message.value !== undefined) {
|
|
528
560
|
after = message.valueType ?
|
|
529
|
-
|
|
561
|
+
this.inlineValue(message.valueType, message.value) :
|
|
530
562
|
typeof message.value === "string" ? this.internedStrings.internValue(message.value) : message.value;
|
|
531
563
|
} else if (message.state === RpcObjectState.ADD && message.valueType) {
|
|
532
564
|
throw new Error(
|
|
@@ -608,6 +640,13 @@ export class RpcReceiveQueue {
|
|
|
608
640
|
}
|
|
609
641
|
}
|
|
610
642
|
|
|
643
|
+
private inlineValue(valueType: string, value: any): any {
|
|
644
|
+
const kind = this.internedStrings.internType(valueType);
|
|
645
|
+
const valueCodec = RpcCodecs.valueCodecForType(kind);
|
|
646
|
+
const typed = {kind, ...withoutSerializerKeys(value)};
|
|
647
|
+
return valueCodec ? valueCodec.fromValue(typed) : typed;
|
|
648
|
+
}
|
|
649
|
+
|
|
611
650
|
private newObj<T>(type: string): T {
|
|
612
651
|
const codec = RpcCodecs.forType(type, this.sourceFileType);
|
|
613
652
|
if (codec?.rpcNew) {
|
|
@@ -26,7 +26,10 @@ import {withMetrics} from "./metrics";
|
|
|
26
26
|
import {RecipeMarketplace} from "../../marketplace";
|
|
27
27
|
|
|
28
28
|
export class PrepareRecipe {
|
|
29
|
-
constructor(private readonly id: string,
|
|
29
|
+
constructor(private readonly id: string,
|
|
30
|
+
private readonly options?: any,
|
|
31
|
+
// Older Java hosts reject unknown response fields, so causesAnotherCycle is only sent when asked.
|
|
32
|
+
private readonly acceptsCausesAnotherCycle?: boolean) {
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
static handle(connection: MessageConnection,
|
|
@@ -41,18 +44,19 @@ export class PrepareRecipe {
|
|
|
41
44
|
metricsCsv,
|
|
42
45
|
(context) => async (request) => {
|
|
43
46
|
context.target = request.id;
|
|
47
|
+
const accepts = request.acceptsCausesAnotherCycle === true;
|
|
44
48
|
const recipeCtor = marketplace.findRecipe(request.id);
|
|
45
49
|
if (!recipeCtor) {
|
|
46
50
|
// A miss means the host owns this recipe (e.g. a Java-delegate child a host
|
|
47
51
|
// re-prepares by name), so answer with a delegatesTo stand-in for it to resolve.
|
|
48
52
|
return await PrepareRecipe.prepareInstance(new DelegatingRecipe(request.id, request.options ?? {}),
|
|
49
|
-
snowflake, preparedRecipes, marketplace);
|
|
53
|
+
snowflake, preparedRecipes, marketplace, accepts);
|
|
50
54
|
}
|
|
51
55
|
if (!recipeCtor[1]) {
|
|
52
56
|
throw new Error(`Recipe ${request.id} was installed without a constructor`);
|
|
53
57
|
}
|
|
54
58
|
return await PrepareRecipe.prepareInstance(new recipeCtor[1](request.options),
|
|
55
|
-
snowflake, preparedRecipes, marketplace);
|
|
59
|
+
snowflake, preparedRecipes, marketplace, accepts);
|
|
56
60
|
}
|
|
57
61
|
)
|
|
58
62
|
);
|
|
@@ -68,7 +72,8 @@ export class PrepareRecipe {
|
|
|
68
72
|
private static async prepareInstance(recipe: Recipe,
|
|
69
73
|
snowflake: ReturnType<typeof SnowflakeId>,
|
|
70
74
|
preparedRecipes: Map<String, Recipe>,
|
|
71
|
-
marketplace: RecipeMarketplace
|
|
75
|
+
marketplace: RecipeMarketplace,
|
|
76
|
+
acceptsCausesAnotherCycle: boolean): Promise<PrepareRecipeResponse> {
|
|
72
77
|
const id = snowflake.generate();
|
|
73
78
|
const delegatesTo = PrepareRecipe.delegatesTo(recipe);
|
|
74
79
|
if (delegatesTo) {
|
|
@@ -106,6 +111,9 @@ export class PrepareRecipe {
|
|
|
106
111
|
scanVisitor: recipe instanceof ScanningRecipe ? `scan:${id}` : undefined,
|
|
107
112
|
scanPreconditions: scanPreconditions
|
|
108
113
|
};
|
|
114
|
+
if (acceptsCausesAnotherCycle && recipe.causesAnotherCycle === true) {
|
|
115
|
+
response.causesAnotherCycle = true;
|
|
116
|
+
}
|
|
109
117
|
|
|
110
118
|
const childResponses: PrepareRecipeResponse[] = [];
|
|
111
119
|
for (const child of await recipe.recipeList()) {
|
|
@@ -118,7 +126,7 @@ export class PrepareRecipe {
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
childResponses.push(await PrepareRecipe.prepareInstance(new DelegatingRecipe(child.name, options),
|
|
121
|
-
snowflake, preparedRecipes, marketplace));
|
|
129
|
+
snowflake, preparedRecipes, marketplace, acceptsCausesAnotherCycle));
|
|
122
130
|
continue;
|
|
123
131
|
}
|
|
124
132
|
// Register a child that was instantiated in recipeList() but never installed, so a peer
|
|
@@ -126,7 +134,8 @@ export class PrepareRecipe {
|
|
|
126
134
|
if (!PrepareRecipe.delegatesTo(child) && !marketplace.findRecipe(child.name)) {
|
|
127
135
|
await marketplace.install(child.constructor as any, []);
|
|
128
136
|
}
|
|
129
|
-
childResponses.push(await PrepareRecipe.prepareInstance(child, snowflake, preparedRecipes, marketplace
|
|
137
|
+
childResponses.push(await PrepareRecipe.prepareInstance(child, snowflake, preparedRecipes, marketplace,
|
|
138
|
+
acceptsCausesAnotherCycle));
|
|
130
139
|
}
|
|
131
140
|
response.recipeList = childResponses;
|
|
132
141
|
|
|
@@ -276,6 +285,7 @@ export interface PrepareRecipeResponse {
|
|
|
276
285
|
* locally from these instead of re-preparing each child by name (the whole-tree optimization).
|
|
277
286
|
*/
|
|
278
287
|
recipeList?: PrepareRecipeResponse[]
|
|
288
|
+
causesAnotherCycle?: boolean
|
|
279
289
|
}
|
|
280
290
|
|
|
281
291
|
/**
|
|
@@ -5,12 +5,17 @@ import {foundSearchResult} from "../markers";
|
|
|
5
5
|
import * as picomatch from "picomatch";
|
|
6
6
|
|
|
7
7
|
export class IsSourceFile extends TreeVisitor<any, ExecutionContext> {
|
|
8
|
-
private readonly matcher:
|
|
8
|
+
private readonly matcher: (path: string) => boolean;
|
|
9
9
|
|
|
10
|
+
/** Reads and matches `filePattern` the way Java's FindSourceFiles does, so the precondition agrees on both hosts. */
|
|
10
11
|
constructor(filePattern: string) {
|
|
11
12
|
super();
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const patterns = filePattern.split(";")
|
|
14
|
+
.map(p => p.trim().replace(/^\.?[/\\]/, ""))
|
|
15
|
+
.filter(p => p.length > 0);
|
|
16
|
+
const options = {dot: true};
|
|
17
|
+
this.matcher = patterns.length === 0 ? () => true :
|
|
18
|
+
picomatch.default ? picomatch.default(patterns, options) : (picomatch as any)(patterns, options);
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
protected async preVisit(tree: any, _: ExecutionContext): Promise<any> {
|
package/src/test/rewrite-test.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {mapAsync, trimIndent} from "../util";
|
|
|
24
24
|
import {ParseErrorKind} from "../parse-error";
|
|
25
25
|
import {MarkersKind, ParseExceptionResult} from "../markers";
|
|
26
26
|
import {JavaScriptVisitor} from "../javascript";
|
|
27
|
+
import {attributionHint, dumpTypesIfRequested} from "../javascript/type-report";
|
|
27
28
|
import {J} from "../java";
|
|
28
29
|
|
|
29
30
|
export interface SourceSpec<T extends SourceFile> {
|
|
@@ -117,6 +118,11 @@ export class RecipeSpec {
|
|
|
117
118
|
RecipeSpec.live &&= [];
|
|
118
119
|
}
|
|
119
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Setting `REWRITE_JAVASCRIPT_DUMP_TYPES` prints each parsed file's type attribution, and a
|
|
123
|
+
* recipe that produces no change names the nodes that carry none. See the README section
|
|
124
|
+
* "Inspecting type attribution".
|
|
125
|
+
*/
|
|
120
126
|
async rewriteRun(...sourceSpecs: (SourceSpec<any> | Generator<SourceSpec<any>, void, unknown> | AsyncGenerator<SourceSpec<any>, void, unknown>)[]): Promise<void> {
|
|
121
127
|
// Flatten generators into a list of sourceSpecs
|
|
122
128
|
const flattenedSpecs: SourceSpec<any>[] = [];
|
|
@@ -152,6 +158,9 @@ export class RecipeSpec {
|
|
|
152
158
|
const specs = specsByKind[kind];
|
|
153
159
|
const parsed = await this.parse(specs);
|
|
154
160
|
await this.expectNoParseFailures(parsed);
|
|
161
|
+
for (const [_, sourceFile] of parsed) {
|
|
162
|
+
await dumpTypesIfRequested(sourceFile);
|
|
163
|
+
}
|
|
155
164
|
await this.expectWhitespaceNotToContainNonwhitespaceCharacters(parsed);
|
|
156
165
|
this.checkParsePrintIdempotence && await this.expectParsePrintIdempotence(parsed);
|
|
157
166
|
allParsed.push(...parsed);
|
|
@@ -245,7 +254,7 @@ export class RecipeSpec {
|
|
|
245
254
|
await spec.afterRecipe(matchingSpec![1]);
|
|
246
255
|
}
|
|
247
256
|
} else {
|
|
248
|
-
await this.expectAfter(spec, after);
|
|
257
|
+
await this.expectAfter(spec, after, matchingSpec?.[1]);
|
|
249
258
|
}
|
|
250
259
|
}
|
|
251
260
|
}
|
|
@@ -263,7 +272,7 @@ export class RecipeSpec {
|
|
|
263
272
|
}
|
|
264
273
|
}
|
|
265
274
|
|
|
266
|
-
private async expectAfter(spec: SourceSpec<any>, after?: SourceFile) {
|
|
275
|
+
private async expectAfter(spec: SourceSpec<any>, after?: SourceFile, before?: SourceFile) {
|
|
267
276
|
if (!after) {
|
|
268
277
|
throw new Error('Expected for recipe to have produced a change for file:\n' + trimIndent(spec.before))
|
|
269
278
|
}
|
|
@@ -272,9 +281,11 @@ export class RecipeSpec {
|
|
|
272
281
|
const afterSource = typeof spec.after === "function" ?
|
|
273
282
|
(spec.after as (actual: string) => string)(actualAfter) : spec.after as string;
|
|
274
283
|
if (actualAfter !== afterSource) {
|
|
284
|
+
// A tree the recipe returned unchanged usually means it never fired.
|
|
285
|
+
const hint = after === before ? await attributionHint(after) : "";
|
|
275
286
|
throw new Error(
|
|
276
287
|
`Recipe output does not match expected.\n` +
|
|
277
|
-
`Expected:\n${afterSource}\n\nActual:\n${actualAfter}`
|
|
288
|
+
`Expected:\n${afterSource}\n\nActual:\n${actualAfter}${hint}`
|
|
278
289
|
);
|
|
279
290
|
}
|
|
280
291
|
if (spec.afterRecipe) {
|