@openrewrite/rewrite 8.92.16 → 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 +120 -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/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +31 -4
- package/dist/javascript/format/tabs-and-indents-visitor.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 +12 -0
- package/dist/javascript/markers.d.ts.map +1 -1
- package/dist/javascript/markers.js +81 -2
- 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/node-resolution-result.js +3 -2
- package/dist/javascript/node-resolution-result.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/parser.d.ts +9 -0
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +185 -88
- package/dist/javascript/parser.js.map +1 -1
- 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/print.d.ts +10 -1
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js +120 -77
- package/dist/javascript/print.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 +208 -115
- 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 +35 -16
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +271 -252
- 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/print.d.ts +6 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +21 -7
- package/dist/print.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/java-rpc-client.d.ts +2 -0
- package/dist/rpc/java-rpc-client.d.ts.map +1 -1
- package/dist/rpc/java-rpc-client.js +1 -0
- package/dist/rpc/java-rpc-client.js.map +1 -1
- package/dist/rpc/queue.d.ts +24 -0
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +71 -11
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/get-object.d.ts +4 -0
- package/dist/rpc/request/get-object.d.ts.map +1 -1
- package/dist/rpc/request/get-object.js +23 -1
- package/dist/rpc/request/get-object.js.map +1 -1
- package/dist/rpc/request/parse.d.ts.map +1 -1
- package/dist/rpc/request/parse.js +3 -1
- package/dist/rpc/request/parse.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/rpc/request/print.d.ts +8 -2
- package/dist/rpc/request/print.d.ts.map +1 -1
- package/dist/rpc/request/print.js +12 -9
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts +3 -2
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +9 -3
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +19 -5
- package/dist/rpc/server.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/java-rpc.d.ts.map +1 -1
- package/dist/test/java-rpc.js +3 -0
- package/dist/test/java-rpc.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 +129 -43
- package/src/javascript/format/format.ts +9 -0
- package/src/javascript/format/tabs-and-indents-visitor.ts +30 -3
- package/src/javascript/index.ts +6 -3
- package/src/javascript/markers.ts +77 -5
- package/src/javascript/method-matcher.ts +34 -22
- package/src/javascript/node-resolution-result.ts +3 -2
- package/src/javascript/package-name.ts +45 -0
- package/src/javascript/parser.ts +200 -91
- package/src/javascript/preconditions.ts +7 -4
- package/src/javascript/print.ts +123 -76
- 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 +236 -129
- 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 +277 -255
- 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/print.ts +23 -8
- package/src/recipe.ts +6 -0
- package/src/rpc/java-rpc-client.ts +3 -0
- package/src/rpc/queue.ts +80 -7
- package/src/rpc/request/get-object.ts +24 -0
- package/src/rpc/request/parse.ts +4 -1
- package/src/rpc/request/prepare-recipe.ts +16 -6
- package/src/rpc/request/print.ts +12 -8
- package/src/rpc/rewrite-rpc.ts +16 -5
- package/src/rpc/server.ts +18 -6
- package/src/search/is-source-file.ts +8 -3
- package/src/test/java-rpc.ts +3 -0
- package/src/test/rewrite-test.ts +14 -3
package/src/print.ts
CHANGED
|
@@ -35,11 +35,7 @@ export namespace MarkerPrinter {
|
|
|
35
35
|
let searchResult = marker as SearchResult;
|
|
36
36
|
return commentWrapper(searchResult.description == null ? "" : "(" + searchResult.description + ")");
|
|
37
37
|
} else if (marker.kind.startsWith("org.openrewrite.marker.Markup$")) {
|
|
38
|
-
|
|
39
|
-
const content = markup.detail
|
|
40
|
-
? `(${markup.message}: ${markup.detail})`
|
|
41
|
-
: `(${markup.message})`;
|
|
42
|
-
return commentWrapper(content);
|
|
38
|
+
return commentWrapper(`(${(marker as Markup).message})`);
|
|
43
39
|
}
|
|
44
40
|
return "";
|
|
45
41
|
},
|
|
@@ -51,6 +47,24 @@ export namespace MarkerPrinter {
|
|
|
51
47
|
},
|
|
52
48
|
}
|
|
53
49
|
|
|
50
|
+
/**
|
|
51
|
+
* As {@link DEFAULT}, but a {@link Markup} that has a detail prints it rather than its message.
|
|
52
|
+
*/
|
|
53
|
+
export const VERBOSE: MarkerPrinter = {
|
|
54
|
+
beforeSyntax(marker: Marker, cursor: Cursor, commentWrapper: CommentWrapper): string {
|
|
55
|
+
if (marker.kind.startsWith("org.openrewrite.marker.Markup$")) {
|
|
56
|
+
return commentWrapper(`(${(marker as Markup).detail ?? (marker as Markup).message})`);
|
|
57
|
+
}
|
|
58
|
+
return DEFAULT.beforeSyntax(marker, cursor, commentWrapper);
|
|
59
|
+
},
|
|
60
|
+
beforePrefix(): string {
|
|
61
|
+
return "";
|
|
62
|
+
},
|
|
63
|
+
afterSyntax(): string {
|
|
64
|
+
return "";
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
|
|
54
68
|
export const SEARCH_MARKERS_ONLY: MarkerPrinter = {
|
|
55
69
|
beforeSyntax(marker: Marker, _cursor: Cursor, commentWrapper: CommentWrapper): string {
|
|
56
70
|
if (marker.kind == MarkersKind.SearchResult) {
|
|
@@ -124,8 +138,9 @@ interface TreePrinter {
|
|
|
124
138
|
* @param tree Helps to determine what kind of language we are dealing with when
|
|
125
139
|
* printing a subtree whose LST type is shared between multiple languages in a language family.
|
|
126
140
|
* @param out Accumulates printing output.
|
|
141
|
+
* @param cursor What encloses `tree`, when it is not a source file.
|
|
127
142
|
*/
|
|
128
|
-
print(tree: Tree, out?: PrintOutputCapture): Promise<string>;
|
|
143
|
+
print(tree: Tree, out?: PrintOutputCapture, cursor?: Cursor): Promise<string>;
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
export class TreePrinters {
|
|
@@ -134,9 +149,9 @@ export class TreePrinters {
|
|
|
134
149
|
|
|
135
150
|
static register(kind: string, printer: () => TreeVisitor<any, PrintOutputCapture>): void {
|
|
136
151
|
this._registry.set(kind, {
|
|
137
|
-
async print(tree: Tree, out?: PrintOutputCapture): Promise<string> {
|
|
152
|
+
async print(tree: Tree, out?: PrintOutputCapture, cursor?: Cursor): Promise<string> {
|
|
138
153
|
const p = out || new PrintOutputCapture();
|
|
139
|
-
await printer().visit(tree, p);
|
|
154
|
+
await printer().visit(tree, p, cursor);
|
|
140
155
|
return p.out;
|
|
141
156
|
}
|
|
142
157
|
})
|
package/src/recipe.ts
CHANGED
|
@@ -71,6 +71,12 @@ export abstract class Recipe {
|
|
|
71
71
|
|
|
72
72
|
readonly estimatedEffortPerOccurrence: Minutes = 5
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Set to true when changes made by this recipe should trigger another recipe cycle,
|
|
76
|
+
* mirroring Java's `Recipe.causesAnotherCycle()`.
|
|
77
|
+
*/
|
|
78
|
+
readonly causesAnotherCycle: boolean = false
|
|
79
|
+
|
|
74
80
|
readonly dataTables: DataTableDescriptor[] = []
|
|
75
81
|
|
|
76
82
|
async recipeList(): Promise<Recipe[]> {
|
|
@@ -38,6 +38,8 @@ export interface JavaRpcOptions {
|
|
|
38
38
|
* only. Does NOT configure the Java side — for that, use {@link marketplaceCsv}.
|
|
39
39
|
*/
|
|
40
40
|
marketplace?: RecipeMarketplace;
|
|
41
|
+
/** How many messages the TS-side {@link RewriteRpc} sends per page of an object. */
|
|
42
|
+
batchSize?: number;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/**
|
|
@@ -116,6 +118,7 @@ export class JavaRpcTestServer {
|
|
|
116
118
|
const rewriteRpc = new RewriteRpc(connection, {
|
|
117
119
|
marketplace: opts.marketplace,
|
|
118
120
|
logger: opts.logger,
|
|
121
|
+
batchSize: opts.batchSize,
|
|
119
122
|
});
|
|
120
123
|
|
|
121
124
|
// Hand back control once we know either (a) the JVM is up and the connection is
|
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
|
*
|
|
@@ -182,6 +205,13 @@ export class RpcSendQueue {
|
|
|
182
205
|
|
|
183
206
|
send<T>(after: T | undefined, before: T | undefined, onChange?: (() => Promise<any>)): Promise<void> {
|
|
184
207
|
return saveTrace(this.trace, async () => {
|
|
208
|
+
// The peer has a single absent value, and an ADD that carries nothing is not one it can decode.
|
|
209
|
+
if (after === null) {
|
|
210
|
+
after = undefined;
|
|
211
|
+
}
|
|
212
|
+
if (before === null) {
|
|
213
|
+
before = undefined;
|
|
214
|
+
}
|
|
185
215
|
if (before === after) {
|
|
186
216
|
this.put({state: RpcObjectState.NO_CHANGE});
|
|
187
217
|
} else if (before === undefined || (after !== undefined && this.typesAreDifferent(after, before))) {
|
|
@@ -197,7 +227,7 @@ export class RpcSendQueue {
|
|
|
197
227
|
await this.add(after, onChange);
|
|
198
228
|
} else {
|
|
199
229
|
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
200
|
-
this.put(
|
|
230
|
+
this.put(this.valueMessage(RpcObjectState.CHANGE, after, !onChange && !afterCodec));
|
|
201
231
|
await this.doChange(after, before, onChange, afterCodec);
|
|
202
232
|
}
|
|
203
233
|
});
|
|
@@ -232,7 +262,7 @@ export class RpcSendQueue {
|
|
|
232
262
|
const afterCodec = onChangeRun ? undefined : RpcCodecs.forInstance(anAfter, this.sourceFileType);
|
|
233
263
|
// Without an onChange callback or codec, no property messages follow, so the
|
|
234
264
|
// value must travel inline (as in send()) or the receiver keeps the stale element
|
|
235
|
-
this.put(
|
|
265
|
+
this.put(this.valueMessage(RpcObjectState.CHANGE, anAfter, !onChangeRun && !afterCodec));
|
|
236
266
|
await this.doChange(anAfter, aBefore, onChangeRun, afterCodec);
|
|
237
267
|
}
|
|
238
268
|
}
|
|
@@ -281,14 +311,23 @@ export class RpcSendQueue {
|
|
|
281
311
|
}
|
|
282
312
|
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
283
313
|
this.put({
|
|
284
|
-
|
|
314
|
+
...this.valueMessage(RpcObjectState.ADD, after, !onChange && !afterCodec),
|
|
285
315
|
valueType: this.getValueType(after),
|
|
286
|
-
value: onChange || afterCodec ? undefined : after,
|
|
287
316
|
ref: ref
|
|
288
317
|
});
|
|
289
318
|
await this.doChange(after, undefined, onChange, afterCodec);
|
|
290
319
|
}
|
|
291
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
|
+
|
|
292
331
|
private async doChange(after: any, before: any, onChange?: () => Promise<void>, afterCodec?: RpcCodec<any>): Promise<void> {
|
|
293
332
|
const lastBefore = this.before;
|
|
294
333
|
this.before = before;
|
|
@@ -372,10 +411,20 @@ export class StringInternTable {
|
|
|
372
411
|
}
|
|
373
412
|
}
|
|
374
413
|
|
|
414
|
+
// Java's serializer names the class and numbers the object inside the value; the kind already says the first.
|
|
415
|
+
function withoutSerializerKeys(value: any): any {
|
|
416
|
+
if (value === null || typeof value !== "object") {
|
|
417
|
+
return value;
|
|
418
|
+
}
|
|
419
|
+
const {"@c": _class, "@ref": _ref, ...fields} = value;
|
|
420
|
+
return fields;
|
|
421
|
+
}
|
|
422
|
+
|
|
375
423
|
export class RpcReceiveQueue {
|
|
376
424
|
private batch: RpcObjectData[] = [];
|
|
377
425
|
private batchIndex = 0;
|
|
378
426
|
private sinceYield = 0;
|
|
427
|
+
private recorded: number[] = [];
|
|
379
428
|
|
|
380
429
|
constructor(private readonly refs: Map<number, any>,
|
|
381
430
|
private readonly sourceFileType: string | undefined,
|
|
@@ -385,6 +434,23 @@ export class RpcReceiveQueue {
|
|
|
385
434
|
private readonly internedStrings: StringInternTable = new StringInternTable()) {
|
|
386
435
|
}
|
|
387
436
|
|
|
437
|
+
private record(ref: number, value: any): void {
|
|
438
|
+
this.refs.set(ref, value);
|
|
439
|
+
this.recorded.push(ref);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Drops the refs this transfer defined, for when it could not be read to its end and the
|
|
444
|
+
* sender is about to forget them too.
|
|
445
|
+
* @internal
|
|
446
|
+
*/
|
|
447
|
+
forgetRefs(): void {
|
|
448
|
+
for (const ref of this.recorded) {
|
|
449
|
+
this.refs.delete(ref);
|
|
450
|
+
}
|
|
451
|
+
this.recorded = [];
|
|
452
|
+
}
|
|
453
|
+
|
|
388
454
|
/**
|
|
389
455
|
* Returns a value rather than a promise for all but the message that refills the
|
|
390
456
|
* batch or yields, so the common path costs neither a promise nor an async frame.
|
|
@@ -479,7 +545,7 @@ export class RpcReceiveQueue {
|
|
|
479
545
|
// For an object like JavaType that we will mutate in place rather than using
|
|
480
546
|
// immutable updates because of its cyclic nature, the before instance will ultimately
|
|
481
547
|
// be the same as the after instance below.
|
|
482
|
-
this.
|
|
548
|
+
this.record(ref, before);
|
|
483
549
|
}
|
|
484
550
|
}
|
|
485
551
|
// Intentional fall-through...
|
|
@@ -492,7 +558,7 @@ export class RpcReceiveQueue {
|
|
|
492
558
|
after = await codec.rpcReceive(before, this);
|
|
493
559
|
} else if (message.value !== undefined) {
|
|
494
560
|
after = message.valueType ?
|
|
495
|
-
|
|
561
|
+
this.inlineValue(message.valueType, message.value) :
|
|
496
562
|
typeof message.value === "string" ? this.internedStrings.internValue(message.value) : message.value;
|
|
497
563
|
} else if (message.state === RpcObjectState.ADD && message.valueType) {
|
|
498
564
|
throw new Error(
|
|
@@ -504,7 +570,7 @@ export class RpcReceiveQueue {
|
|
|
504
570
|
after = before;
|
|
505
571
|
}
|
|
506
572
|
if (ref !== undefined) {
|
|
507
|
-
this.
|
|
573
|
+
this.record(ref, after);
|
|
508
574
|
}
|
|
509
575
|
return after;
|
|
510
576
|
default:
|
|
@@ -574,6 +640,13 @@ export class RpcReceiveQueue {
|
|
|
574
640
|
}
|
|
575
641
|
}
|
|
576
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
|
+
|
|
577
650
|
private newObj<T>(type: string): T {
|
|
578
651
|
const codec = RpcCodecs.forType(type, this.sourceFileType);
|
|
579
652
|
if (codec?.rpcNew) {
|
|
@@ -18,6 +18,11 @@ import {RpcObjectData, RpcObjectState, RpcSendQueue} from "../queue";
|
|
|
18
18
|
import {ReferenceMap} from "../../reference";
|
|
19
19
|
import {extractSourcePath, withMetrics} from "./metrics";
|
|
20
20
|
|
|
21
|
+
export class AbortGetObject {
|
|
22
|
+
constructor(readonly id: string) {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
export class GetObject {
|
|
22
27
|
constructor(private readonly id: string,
|
|
23
28
|
private readonly sourceFileType?: string) {
|
|
@@ -33,6 +38,24 @@ export class GetObject {
|
|
|
33
38
|
metricsCsv?: string,
|
|
34
39
|
): void {
|
|
35
40
|
const pendingData = new Map<string, { data: (RpcObjectData | undefined)[], offset: number }>();
|
|
41
|
+
let latestTransfer: { id: string, refCount: number } | undefined;
|
|
42
|
+
|
|
43
|
+
// The receiver could not read a transfer to its end and has dropped what it took from it.
|
|
44
|
+
connection.onRequest(
|
|
45
|
+
new rpc.RequestType<AbortGetObject, boolean, Error>("AbortGetObject"),
|
|
46
|
+
request => {
|
|
47
|
+
pendingData.delete(request.id);
|
|
48
|
+
remoteObjects.delete(request.id);
|
|
49
|
+
if (latestTransfer?.id === request.id) {
|
|
50
|
+
localRefs.rollbackTo(latestTransfer.refCount);
|
|
51
|
+
} else {
|
|
52
|
+
// which refs that transfer assigned is no longer known; everything goes out whole again
|
|
53
|
+
localRefs.clear();
|
|
54
|
+
}
|
|
55
|
+
latestTransfer = undefined;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
);
|
|
36
59
|
|
|
37
60
|
connection.onRequest(
|
|
38
61
|
new rpc.RequestType<GetObject, any, Error>("GetObject"),
|
|
@@ -75,6 +98,7 @@ export class GetObject {
|
|
|
75
98
|
};
|
|
76
99
|
pendingData.set(objId, pending);
|
|
77
100
|
remoteObjects.set(objId, after);
|
|
101
|
+
latestTransfer = {id: objId, refCount: savedRefCount};
|
|
78
102
|
} catch (e) {
|
|
79
103
|
remoteObjects.delete(objId);
|
|
80
104
|
localRefs.rollbackTo(savedRefCount);
|
package/src/rpc/request/parse.ts
CHANGED
|
@@ -67,7 +67,10 @@ export class Parse {
|
|
|
67
67
|
relativeTo: request.relativeTo
|
|
68
68
|
})!;
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
// an input without its text names a file for the parser to read
|
|
71
|
+
const inputs = request.inputs.map(input =>
|
|
72
|
+
typeof input === 'object' && input.text == null ? input.sourcePath : input);
|
|
73
|
+
const generator = parser.parse(...inputs);
|
|
71
74
|
const resultIds: UUID[] = [];
|
|
72
75
|
|
|
73
76
|
for (let i = 0; i < request.inputs.length; i++) {
|
|
@@ -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
|
/**
|
package/src/rpc/request/print.ts
CHANGED
|
@@ -14,25 +14,31 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import * as rpc from "vscode-jsonrpc/node";
|
|
17
|
-
import {isSourceFile, Tree} from "../../tree";
|
|
17
|
+
import {Cursor, isSourceFile, Tree} from "../../tree";
|
|
18
18
|
import {MarkerPrinter as PrintMarkerPrinter, printer, PrintOutputCapture} from "../../print";
|
|
19
19
|
import {UUID} from "../../uuid";
|
|
20
20
|
import {extractSourcePath, withMetrics} from "./metrics";
|
|
21
21
|
|
|
22
22
|
export const enum MarkerPrinter {
|
|
23
23
|
DEFAULT = "DEFAULT",
|
|
24
|
+
SEARCH_MARKERS_ONLY = "SEARCH_MARKERS_ONLY",
|
|
24
25
|
FENCED = "FENCED",
|
|
25
26
|
SANITIZED = "SANITIZED"
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export class Print {
|
|
30
|
+
/**
|
|
31
|
+
* @param cursor The ids of what encloses a tree that is not a source file, from its parent outward.
|
|
32
|
+
*/
|
|
29
33
|
constructor(private readonly treeId: UUID,
|
|
30
34
|
private readonly sourceFileType: string,
|
|
31
|
-
readonly markerPrinter: MarkerPrinter = MarkerPrinter.DEFAULT
|
|
35
|
+
readonly markerPrinter: MarkerPrinter = MarkerPrinter.DEFAULT,
|
|
36
|
+
readonly cursor?: string[]) {
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
static handle(connection: rpc.MessageConnection,
|
|
35
40
|
getObject: (id: string, sourceFileType: string) => any,
|
|
41
|
+
getCursor: (cursorIds: string[] | undefined, sourceFileType?: string) => Promise<Cursor>,
|
|
36
42
|
logger?: rpc.Logger,
|
|
37
43
|
metricsCsv?: string): void {
|
|
38
44
|
connection.onRequest(
|
|
@@ -46,14 +52,12 @@ export class Print {
|
|
|
46
52
|
if (logger) {
|
|
47
53
|
logger.log("Printing " + (isSourceFile(tree) ? tree.sourcePath : `tree of type ${tree.kind} in ${context.target}`));
|
|
48
54
|
}
|
|
49
|
-
const out = new PrintOutputCapture(PrintMarkerPrinter[request.markerPrinter]);
|
|
50
|
-
let result: string;
|
|
55
|
+
const out = new PrintOutputCapture(PrintMarkerPrinter[request.markerPrinter ?? MarkerPrinter.DEFAULT]);
|
|
51
56
|
if (isSourceFile(tree)) {
|
|
52
|
-
|
|
53
|
-
} else {
|
|
54
|
-
result = await printer(request.sourceFileType).print(tree, out);
|
|
57
|
+
return printer(tree).print(tree, out);
|
|
55
58
|
}
|
|
56
|
-
|
|
59
|
+
const cursor = request.cursor ? await getCursor(request.cursor, request.sourceFileType) : undefined;
|
|
60
|
+
return printer(request.sourceFileType).print(tree, out, cursor);
|
|
57
61
|
}
|
|
58
62
|
)
|
|
59
63
|
);
|
package/src/rpc/rewrite-rpc.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
DependencyTypes,
|
|
23
23
|
Generate,
|
|
24
24
|
GenerateResponse,
|
|
25
|
+
AbortGetObject,
|
|
25
26
|
GetObject,
|
|
26
27
|
GetMarketplace,
|
|
27
28
|
GetMarketplaceResponseRow,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
ParseProject,
|
|
31
32
|
PrepareRecipe,
|
|
32
33
|
PrepareRecipeResponse,
|
|
34
|
+
MarkerPrinter,
|
|
33
35
|
Print,
|
|
34
36
|
TraceGetObject,
|
|
35
37
|
Visit,
|
|
@@ -142,7 +144,7 @@ export class RewriteRpc {
|
|
|
142
144
|
Parse.handle(this.connection, this.localObjects, options.metricsCsv);
|
|
143
145
|
ParseProject.handle(this.connection, this.localObjects, options.metricsCsv);
|
|
144
146
|
DependencyTypes.handle(this.connection, options?.batchSize || 1000, options.metricsCsv);
|
|
145
|
-
Print.handle(this.connection, getObject, options.logger, options.metricsCsv);
|
|
147
|
+
Print.handle(this.connection, getObject, getCursor, options.logger, options.metricsCsv);
|
|
146
148
|
InstallRecipes.handle(this.connection, options.recipeInstallDir ?? ".rewrite", marketplace, recipeOrigin, options.logger, options.metricsCsv);
|
|
147
149
|
|
|
148
150
|
this.connection.onRequest(
|
|
@@ -289,6 +291,15 @@ export class RewriteRpc {
|
|
|
289
291
|
await nextPage.catch(() => {
|
|
290
292
|
});
|
|
291
293
|
}
|
|
294
|
+
// The sender still counts the object and its refs as delivered until it is told otherwise.
|
|
295
|
+
const rolledBack = await this.connection.sendRequest(
|
|
296
|
+
new rpc.RequestType<AbortGetObject, boolean, Error>("AbortGetObject"),
|
|
297
|
+
new AbortGetObject(id)
|
|
298
|
+
).catch(() => false);
|
|
299
|
+
if (rolledBack) {
|
|
300
|
+
// a peer that could not roll back goes on sending these refs bare, so they are kept for it
|
|
301
|
+
q.forgetRefs();
|
|
302
|
+
}
|
|
292
303
|
throw e;
|
|
293
304
|
}
|
|
294
305
|
|
|
@@ -321,9 +332,9 @@ export class RewriteRpc {
|
|
|
321
332
|
return parsed;
|
|
322
333
|
}
|
|
323
334
|
|
|
324
|
-
async print(tree: SourceFile): Promise<string>;
|
|
325
|
-
async print(tree: Tree, cursor: Cursor): Promise<string>;
|
|
326
|
-
async print(tree: Tree, cursor?: Cursor): Promise<string> {
|
|
335
|
+
async print(tree: SourceFile, cursor?: undefined, markerPrinter?: MarkerPrinter): Promise<string>;
|
|
336
|
+
async print(tree: Tree, cursor: Cursor, markerPrinter?: MarkerPrinter): Promise<string>;
|
|
337
|
+
async print(tree: Tree, cursor?: Cursor, markerPrinter?: MarkerPrinter): Promise<string> {
|
|
327
338
|
if (!cursor && !isSourceFile(tree)) {
|
|
328
339
|
throw new Error("Cursor is required for non-SourceFile trees");
|
|
329
340
|
}
|
|
@@ -331,7 +342,7 @@ export class RewriteRpc {
|
|
|
331
342
|
const sourceFile = isSourceFile(tree) ? tree : cursor!.firstEnclosing(t => isSourceFile(t))!;
|
|
332
343
|
return await this.connection.sendRequest(
|
|
333
344
|
new rpc.RequestType<Print, string, Error>("Print"),
|
|
334
|
-
new Print(tree.id, sourceFile.kind)
|
|
345
|
+
new Print(tree.id, sourceFile.kind, markerPrinter, isSourceFile(tree) ? undefined : this.getCursorIds(cursor))
|
|
335
346
|
);
|
|
336
347
|
}
|
|
337
348
|
|
package/src/rpc/server.ts
CHANGED
|
@@ -22,6 +22,7 @@ import * as fs from "fs";
|
|
|
22
22
|
import {Command} from 'commander';
|
|
23
23
|
import {dir} from 'tmp-promise';
|
|
24
24
|
import {DependencyWorkspace} from "../javascript/dependency-workspace";
|
|
25
|
+
import {isMainThread, parentPort, Worker} from "worker_threads";
|
|
25
26
|
|
|
26
27
|
// Include all languages you want this server to support.
|
|
27
28
|
import "../text";
|
|
@@ -30,9 +31,6 @@ import "../yaml";
|
|
|
30
31
|
import "../java";
|
|
31
32
|
import "../javascript";
|
|
32
33
|
|
|
33
|
-
// Not possible to set the stack size when executing from npx for security reasons
|
|
34
|
-
require('v8').setFlagsFromString('--stack-size=8000');
|
|
35
|
-
|
|
36
34
|
function initPyroscope(logger: rpc.Logger): any {
|
|
37
35
|
// Strip trailing slashes: the SDK builds the ingest URL as `${serverAddress}/ingest`,
|
|
38
36
|
// so a trailing slash produces `//ingest`, which the server normalizes via redirect —
|
|
@@ -126,8 +124,8 @@ async function main() {
|
|
|
126
124
|
}
|
|
127
125
|
};
|
|
128
126
|
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
// signals are delivered to the main thread, which passes them on
|
|
128
|
+
parentPort!.on('message', shutdown);
|
|
131
129
|
|
|
132
130
|
const log = options.logFile ? fs.createWriteStream(options.logFile, {flags: 'a'}) : undefined;
|
|
133
131
|
const logger: rpc.Logger = {
|
|
@@ -191,4 +189,18 @@ async function main() {
|
|
|
191
189
|
});
|
|
192
190
|
}
|
|
193
191
|
|
|
194
|
-
|
|
192
|
+
if (isMainThread) {
|
|
193
|
+
// A thread's stack is sized when it starts, and the default is too shallow for the type checker
|
|
194
|
+
// on long chains of inferred return types, so the server runs on a thread started with more.
|
|
195
|
+
const server = new Worker(__filename, {
|
|
196
|
+
argv: process.argv.slice(2),
|
|
197
|
+
stdin: true,
|
|
198
|
+
resourceLimits: {stackSizeMb: 8}
|
|
199
|
+
});
|
|
200
|
+
process.stdin.pipe(server.stdin!);
|
|
201
|
+
process.on('SIGINT', () => server.postMessage('SIGINT'));
|
|
202
|
+
process.on('SIGTERM', () => server.postMessage('SIGTERM'));
|
|
203
|
+
server.on('exit', code => process.exit(code));
|
|
204
|
+
} else {
|
|
205
|
+
main().catch(console.error);
|
|
206
|
+
}
|
|
@@ -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/java-rpc.ts
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
*/
|
|
40
40
|
import {describe, type SuiteAPI, test as base} from "vitest";
|
|
41
41
|
import {findTestClasspath, JavaRpcTestServer} from "../rpc/java-rpc-client";
|
|
42
|
+
import {RewriteRpc} from "../rpc/rewrite-rpc";
|
|
42
43
|
|
|
43
44
|
export {findTestClasspath, JavaRpcTestServer} from "../rpc/java-rpc-client";
|
|
44
45
|
export type {JavaRpcOptions} from "../rpc/java-rpc-client";
|
|
@@ -76,6 +77,8 @@ export const testJavaRpc = base.extend<JavaRpcFixtures>({
|
|
|
76
77
|
{scope: "worker"},
|
|
77
78
|
],
|
|
78
79
|
javaRpc: async ({_javaRpcServer}, use) => {
|
|
80
|
+
// any RewriteRpc constructed in this worker since has replaced it as the active connection
|
|
81
|
+
RewriteRpc.set(_javaRpcServer.rpc);
|
|
79
82
|
await _javaRpcServer.reset();
|
|
80
83
|
await use(_javaRpcServer);
|
|
81
84
|
},
|