@openrewrite/rewrite 8.62.2 → 8.62.4
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/execution.d.ts.map +1 -1
- package/dist/execution.js.map +1 -1
- package/dist/java/rpc.d.ts +1 -0
- package/dist/java/rpc.d.ts.map +1 -1
- package/dist/java/rpc.js +81 -0
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/tree.js +0 -87
- package/dist/java/tree.js.map +1 -1
- package/dist/java/visitor.d.ts +4 -4
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/format.d.ts +2 -2
- package/dist/javascript/format.d.ts.map +1 -1
- package/dist/javascript/format.js.map +1 -1
- package/dist/javascript/parser.d.ts +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +26 -4
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/print.d.ts +2 -2
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/rpc.js +1 -16
- package/dist/javascript/rpc.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +4 -19
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +228 -163
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/visitor.d.ts +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/json/print.js.map +1 -1
- package/dist/json/rpc.js +46 -17
- package/dist/json/rpc.js.map +1 -1
- package/dist/json/visitor.d.ts +2 -2
- package/dist/json/visitor.d.ts.map +1 -1
- package/dist/json/visitor.js.map +1 -1
- package/dist/print.d.ts +2 -2
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +4 -2
- package/dist/print.js.map +1 -1
- package/dist/rpc/queue.d.ts +15 -6
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +37 -13
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/generate.d.ts +4 -0
- package/dist/rpc/request/generate.d.ts.map +1 -1
- package/dist/rpc/request/generate.js +9 -4
- package/dist/rpc/request/generate.js.map +1 -1
- package/dist/rpc/request/get-object.d.ts +2 -2
- package/dist/rpc/request/get-object.d.ts.map +1 -1
- package/dist/rpc/request/get-object.js +4 -12
- 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.map +1 -1
- package/dist/rpc/request/print.d.ts +3 -4
- package/dist/rpc/request/print.d.ts.map +1 -1
- package/dist/rpc/request/print.js +5 -6
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/request/visit.d.ts +3 -2
- package/dist/rpc/request/visit.d.ts.map +1 -1
- package/dist/rpc/request/visit.js +5 -4
- package/dist/rpc/request/visit.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts +3 -3
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +19 -16
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/text/rpc.js +37 -40
- package/dist/text/rpc.js.map +1 -1
- package/dist/version.txt +1 -1
- package/package.json +1 -1
- package/src/execution.ts +0 -2
- package/src/java/rpc.ts +68 -0
- package/src/java/tree.ts +1 -65
- package/src/java/visitor.ts +4 -4
- package/src/javascript/format.ts +2 -2
- package/src/javascript/parser.ts +19 -5
- package/src/javascript/print.ts +3 -3
- package/src/javascript/rpc.ts +4 -17
- package/src/javascript/type-mapping.ts +235 -170
- package/src/javascript/visitor.ts +1 -1
- package/src/json/print.ts +1 -1
- package/src/json/rpc.ts +40 -19
- package/src/json/visitor.ts +2 -2
- package/src/print.ts +6 -4
- package/src/rpc/queue.ts +36 -12
- package/src/rpc/request/generate.ts +18 -6
- package/src/rpc/request/get-object.ts +6 -13
- package/src/rpc/request/parse.ts +1 -1
- package/src/rpc/request/print.ts +5 -7
- package/src/rpc/request/visit.ts +6 -5
- package/src/rpc/rewrite-rpc.ts +24 -19
- package/src/test/rewrite-test.ts +1 -1
- package/src/text/rpc.ts +33 -37
package/src/rpc/queue.ts
CHANGED
|
@@ -46,37 +46,58 @@ export interface RpcCodec<T> {
|
|
|
46
46
|
* A registry for managing RPC codecs based on object types.
|
|
47
47
|
*/
|
|
48
48
|
export class RpcCodecs {
|
|
49
|
-
private static
|
|
49
|
+
private static nonTreeCodecs = new Map<string, RpcCodec<any>>();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The first key is on sourceFileType and the second on object type
|
|
53
|
+
*/
|
|
54
|
+
private static treeCodecs = new Map<string, Map<string, RpcCodec<any>>>();
|
|
50
55
|
|
|
51
56
|
/**
|
|
52
57
|
* Registers an RPC codec for a given type.
|
|
53
58
|
*
|
|
54
59
|
* @param type - The string identifier of the object type.
|
|
55
60
|
* @param codec - The codec implementation to be registered.
|
|
61
|
+
* @param sourceFileType The source file type of the source file containing (or will contain) this element.
|
|
56
62
|
*/
|
|
57
|
-
static registerCodec(type: string, codec: RpcCodec<any
|
|
58
|
-
|
|
63
|
+
static registerCodec(type: string, codec: RpcCodec<any>, sourceFileType?: string): void {
|
|
64
|
+
if (sourceFileType) {
|
|
65
|
+
let codecsForSourceFile = this.treeCodecs.get(sourceFileType);
|
|
66
|
+
if (!codecsForSourceFile) {
|
|
67
|
+
codecsForSourceFile = new Map<string, RpcCodec<any>>();
|
|
68
|
+
this.treeCodecs.set(sourceFileType, codecsForSourceFile);
|
|
69
|
+
}
|
|
70
|
+
codecsForSourceFile.set(type, codec);
|
|
71
|
+
} else {
|
|
72
|
+
this.nonTreeCodecs.set(type, codec);
|
|
73
|
+
}
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
/**
|
|
62
77
|
* Retrieves the registered codec for a given type.
|
|
63
78
|
*
|
|
64
79
|
* @param type - The string identifier of the object type.
|
|
80
|
+
* @param sourceFileType The source file type of the source file containing (or will contain) this element.
|
|
65
81
|
* @returns The corresponding `RpcCodec`, or `undefined` if not found.
|
|
66
82
|
*/
|
|
67
|
-
static forType(type: string): RpcCodec<any> | undefined {
|
|
68
|
-
|
|
83
|
+
static forType(type: string, sourceFileType?: string): RpcCodec<any> | undefined {
|
|
84
|
+
if (sourceFileType) {
|
|
85
|
+
const treeCodec = this.treeCodecs.get(sourceFileType)?.get(type);
|
|
86
|
+
return treeCodec || this.nonTreeCodecs.get(type);
|
|
87
|
+
}
|
|
88
|
+
return this.nonTreeCodecs.get(type);
|
|
69
89
|
}
|
|
70
90
|
|
|
71
91
|
/**
|
|
72
92
|
* Determines the appropriate codec for an instance based on its `kind` property.
|
|
73
93
|
*
|
|
74
94
|
* @param before - The object instance to find a codec for.
|
|
95
|
+
* @param sourceFileType The source file type of the source file containing (or will contain) this element.
|
|
75
96
|
* @returns The corresponding `RpcCodec`, or `undefined` if no matching codec is found.
|
|
76
97
|
*/
|
|
77
|
-
static forInstance(before: any): RpcCodec<any> | undefined {
|
|
98
|
+
static forInstance(before: any, sourceFileType?: string): RpcCodec<any> | undefined {
|
|
78
99
|
if (before !== undefined && before !== null && typeof before === "object" && "kind" in before) {
|
|
79
|
-
return RpcCodecs.forType(before["kind"] as string);
|
|
100
|
+
return RpcCodecs.forType(before["kind"] as string, sourceFileType);
|
|
80
101
|
}
|
|
81
102
|
}
|
|
82
103
|
}
|
|
@@ -86,7 +107,9 @@ export class RpcSendQueue {
|
|
|
86
107
|
|
|
87
108
|
private before?: any;
|
|
88
109
|
|
|
89
|
-
constructor(private readonly refs: ReferenceMap,
|
|
110
|
+
constructor(private readonly refs: ReferenceMap,
|
|
111
|
+
private readonly sourceFileType: string | undefined,
|
|
112
|
+
private readonly trace: boolean) {
|
|
90
113
|
}
|
|
91
114
|
|
|
92
115
|
async generate(after: any, before: any): Promise<RpcObjectData[]> {
|
|
@@ -132,7 +155,7 @@ export class RpcSendQueue {
|
|
|
132
155
|
} else if (after === undefined) {
|
|
133
156
|
this.put({state: RpcObjectState.DELETE});
|
|
134
157
|
} else {
|
|
135
|
-
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after);
|
|
158
|
+
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
136
159
|
this.put({state: RpcObjectState.CHANGE, value: onChange || afterCodec ? undefined : after});
|
|
137
160
|
await this.doChange(after, before, onChange, afterCodec);
|
|
138
161
|
}
|
|
@@ -161,7 +184,7 @@ export class RpcSendQueue {
|
|
|
161
184
|
this.put({state: RpcObjectState.NO_CHANGE});
|
|
162
185
|
} else {
|
|
163
186
|
this.put({state: RpcObjectState.CHANGE});
|
|
164
|
-
await this.doChange(anAfter, aBefore, onChangeRun, RpcCodecs.forInstance(anAfter));
|
|
187
|
+
await this.doChange(anAfter, aBefore, onChangeRun, RpcCodecs.forInstance(anAfter, this.sourceFileType));
|
|
165
188
|
}
|
|
166
189
|
}
|
|
167
190
|
}
|
|
@@ -199,7 +222,7 @@ export class RpcSendQueue {
|
|
|
199
222
|
}
|
|
200
223
|
ref = this.refs.create(after);
|
|
201
224
|
}
|
|
202
|
-
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after);
|
|
225
|
+
let afterCodec = onChange ? undefined : RpcCodecs.forInstance(after, this.sourceFileType);
|
|
203
226
|
this.put({
|
|
204
227
|
state: RpcObjectState.ADD,
|
|
205
228
|
valueType: this.getValueType(after),
|
|
@@ -236,6 +259,7 @@ export class RpcReceiveQueue {
|
|
|
236
259
|
private batch: RpcObjectData[] = [];
|
|
237
260
|
|
|
238
261
|
constructor(private readonly refs: Map<number, any>,
|
|
262
|
+
private readonly sourceFileType: string | undefined,
|
|
239
263
|
private readonly pull: () => Promise<RpcObjectData[]>,
|
|
240
264
|
private readonly logFile?: Writable) {
|
|
241
265
|
}
|
|
@@ -301,7 +325,7 @@ export class RpcReceiveQueue {
|
|
|
301
325
|
let codec;
|
|
302
326
|
if (onChange) {
|
|
303
327
|
after = await onChange(before!);
|
|
304
|
-
} else if ((codec = RpcCodecs.forInstance(before))) {
|
|
328
|
+
} else if ((codec = RpcCodecs.forInstance(before, this.sourceFileType))) {
|
|
305
329
|
after = await codec.rpcReceive(before, this);
|
|
306
330
|
} else if (message.value !== undefined) {
|
|
307
331
|
after = message.valueType ? {kind: message.valueType, ...message.value} : message.value;
|
|
@@ -17,7 +17,11 @@ import * as rpc from "vscode-jsonrpc/node";
|
|
|
17
17
|
import {Recipe, ScanningRecipe} from "../../recipe";
|
|
18
18
|
import {Cursor, rootCursor} from "../../tree";
|
|
19
19
|
import {ExecutionContext} from "../../execution";
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
export interface GenerateResponse {
|
|
22
|
+
ids: string[]
|
|
23
|
+
sourceFileTypes: string[]
|
|
24
|
+
}
|
|
21
25
|
|
|
22
26
|
export class Generate {
|
|
23
27
|
constructor(private readonly id: string, private readonly p: string) {
|
|
@@ -28,8 +32,13 @@ export class Generate {
|
|
|
28
32
|
preparedRecipes: Map<String, Recipe>,
|
|
29
33
|
recipeCursors: WeakMap<Recipe, Cursor>,
|
|
30
34
|
getObject: (id: string) => any): void {
|
|
31
|
-
connection.onRequest(new rpc.RequestType<Generate,
|
|
35
|
+
connection.onRequest(new rpc.RequestType<Generate, GenerateResponse, Error>("Generate"), async (request) => {
|
|
32
36
|
const recipe = preparedRecipes.get(request.id);
|
|
37
|
+
const response = {
|
|
38
|
+
ids: [],
|
|
39
|
+
sourceFileTypes: []
|
|
40
|
+
} as GenerateResponse;
|
|
41
|
+
|
|
33
42
|
if (recipe && recipe instanceof ScanningRecipe) {
|
|
34
43
|
let cursor = recipeCursors.get(recipe);
|
|
35
44
|
if (!cursor) {
|
|
@@ -39,12 +48,15 @@ export class Generate {
|
|
|
39
48
|
const ctx = getObject(request.p) as ExecutionContext;
|
|
40
49
|
const acc = recipe.accumulator(cursor, ctx);
|
|
41
50
|
const generated = await recipe.generate(acc, ctx)
|
|
42
|
-
|
|
51
|
+
|
|
52
|
+
for (const g of generated) {
|
|
43
53
|
localObjects.set(g.id.toString(), g);
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
response.ids.push(g.id.toString());
|
|
55
|
+
response.sourceFileTypes.push(g.kind);
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
}
|
|
47
|
-
return
|
|
59
|
+
return response;
|
|
48
60
|
});
|
|
49
61
|
}
|
|
50
62
|
}
|
|
@@ -18,7 +18,8 @@ import {RpcObjectData, RpcObjectState, RpcSendQueue} from "../queue";
|
|
|
18
18
|
import {ReferenceMap} from "../../reference";
|
|
19
19
|
|
|
20
20
|
export class GetObject {
|
|
21
|
-
constructor(private readonly id: string,
|
|
21
|
+
constructor(private readonly id: string,
|
|
22
|
+
private readonly sourceFileType?: string) {
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
static handle(
|
|
@@ -49,18 +50,9 @@ export class GetObject {
|
|
|
49
50
|
let allData = pendingData.get(objId);
|
|
50
51
|
if (!allData) {
|
|
51
52
|
const after = localObjects.get(objId);
|
|
52
|
-
|
|
53
|
-
// Determine what the remote has cached
|
|
54
|
-
let before = undefined;
|
|
55
|
-
if (request.lastKnownId) {
|
|
56
|
-
before = remoteObjects.get(request.lastKnownId);
|
|
57
|
-
if (before === undefined) {
|
|
58
|
-
// Remote had something cached, but we've evicted it - must send full object
|
|
59
|
-
remoteObjects.delete(request.lastKnownId);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
53
|
+
const before = remoteObjects.get(objId);
|
|
62
54
|
|
|
63
|
-
allData = await new RpcSendQueue(localRefs, trace).generate(after, before);
|
|
55
|
+
allData = await new RpcSendQueue(localRefs, request.sourceFileType, trace).generate(after, before);
|
|
64
56
|
pendingData.set(objId, allData);
|
|
65
57
|
|
|
66
58
|
remoteObjects.set(objId, after);
|
|
@@ -75,4 +67,5 @@ export class GetObject {
|
|
|
75
67
|
|
|
76
68
|
return batch;
|
|
77
69
|
});
|
|
78
|
-
}
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/rpc/request/parse.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import * as rpc from "vscode-jsonrpc/node";
|
|
17
17
|
import {ExecutionContext} from "../../execution";
|
|
18
18
|
import {UUID} from "node:crypto";
|
|
19
|
-
import {
|
|
19
|
+
import {ParserInput, Parsers} from "../../parser";
|
|
20
20
|
import {randomId} from "../../uuid";
|
|
21
21
|
import {produce} from "immer";
|
|
22
22
|
import {SourceFile} from "../../tree";
|
package/src/rpc/request/print.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import * as rpc from "vscode-jsonrpc/node";
|
|
17
|
-
import {
|
|
17
|
+
import {isSourceFile, Tree} from "../../tree";
|
|
18
18
|
import {MarkerPrinter as PrintMarkerPrinter, printer, PrintOutputCapture} from "../../print";
|
|
19
19
|
import {UUID} from "../../uuid";
|
|
20
20
|
|
|
@@ -25,20 +25,18 @@ export const enum MarkerPrinter {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export class Print {
|
|
28
|
-
constructor(private readonly treeId: UUID, private readonly
|
|
28
|
+
constructor(private readonly treeId: UUID, private readonly sourceFileType: string, readonly markerPrinter: MarkerPrinter = MarkerPrinter.DEFAULT) {
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
static handle(connection: rpc.MessageConnection,
|
|
32
|
-
getObject: (id: string) => any
|
|
33
|
-
getCursor: (cursorIds: string[] | undefined) => Promise<Cursor>): void {
|
|
32
|
+
getObject: (id: string, sourceFileType?: string) => any): void {
|
|
34
33
|
connection.onRequest(new rpc.RequestType<Print, string, Error>("Print"), async request => {
|
|
35
|
-
const tree: Tree = await getObject(request.treeId.toString());
|
|
34
|
+
const tree: Tree = await getObject(request.treeId.toString(), request.sourceFileType);
|
|
36
35
|
const out = new PrintOutputCapture(PrintMarkerPrinter[request.markerPrinter]);
|
|
37
36
|
if (isSourceFile(tree)) {
|
|
38
37
|
return await printer(tree).print(tree, out);
|
|
39
38
|
} else {
|
|
40
|
-
|
|
41
|
-
return await printer(cursor).print(tree, out);
|
|
39
|
+
return await printer(request.sourceFileType).print(tree, out);
|
|
42
40
|
}
|
|
43
41
|
});
|
|
44
42
|
}
|
package/src/rpc/request/visit.ts
CHANGED
|
@@ -25,6 +25,7 @@ export interface VisitResponse {
|
|
|
25
25
|
|
|
26
26
|
export class Visit {
|
|
27
27
|
constructor(private readonly visitor: string,
|
|
28
|
+
private readonly sourceFileType: string,
|
|
28
29
|
private readonly visitorOptions: Map<string, any> | undefined,
|
|
29
30
|
private readonly treeId: string,
|
|
30
31
|
private readonly p: string,
|
|
@@ -35,15 +36,15 @@ export class Visit {
|
|
|
35
36
|
localObjects: Map<string, any>,
|
|
36
37
|
preparedRecipes: Map<String, Recipe>,
|
|
37
38
|
recipeCursors: WeakMap<Recipe, Cursor>,
|
|
38
|
-
getObject: (id: string) => any,
|
|
39
|
-
getCursor: (cursorIds: string[] | undefined) => Promise<Cursor>): void {
|
|
39
|
+
getObject: (id: string, sourceFileType?: string) => any,
|
|
40
|
+
getCursor: (cursorIds: string[] | undefined, sourceFileType?: string) => Promise<Cursor>): void {
|
|
40
41
|
connection.onRequest(new rpc.RequestType<Visit, VisitResponse, Error>("Visit"), async (request) => {
|
|
41
|
-
const p = await getObject(request.p);
|
|
42
|
-
const before: Tree = await getObject(request.treeId);
|
|
42
|
+
const p = await getObject(request.p, undefined);
|
|
43
|
+
const before: Tree = await getObject(request.treeId, request.sourceFileType);
|
|
43
44
|
localObjects.set(before.id.toString(), before);
|
|
44
45
|
|
|
45
46
|
const visitor = await Visit.instantiateVisitor(request, preparedRecipes, recipeCursors, p);
|
|
46
|
-
const after = await visitor.visit(before, p, await getCursor(request.cursor));
|
|
47
|
+
const after = await visitor.visit(before, p, await getCursor(request.cursor, request.sourceFileType));
|
|
47
48
|
if (!after) {
|
|
48
49
|
localObjects.delete(before.id.toString());
|
|
49
50
|
} else if (after !== before) {
|
package/src/rpc/rewrite-rpc.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {Cursor, isSourceFile, isTree, rootCursor, SourceFile, Tree} from "../tre
|
|
|
19
19
|
import {Recipe, RecipeDescriptor, RecipeRegistry} from "../recipe";
|
|
20
20
|
import {SnowflakeId} from "@akashrajpurohit/snowflake-id";
|
|
21
21
|
import {
|
|
22
|
-
Generate,
|
|
22
|
+
Generate, GenerateResponse,
|
|
23
23
|
GetObject,
|
|
24
24
|
GetRecipes,
|
|
25
25
|
Parse,
|
|
@@ -69,8 +69,8 @@ export class RewriteRpc {
|
|
|
69
69
|
const recipeCursors: WeakMap<Recipe, Cursor> = new WeakMap()
|
|
70
70
|
|
|
71
71
|
// Need this indirection, otherwise `this` will be undefined when executed in the handlers.
|
|
72
|
-
const getObject = (id: string) => this.getObject(id);
|
|
73
|
-
const getCursor = (cursorIds: string[] | undefined) => this.getCursor(cursorIds);
|
|
72
|
+
const getObject = (id: string, sourceFileType?: string) => this.getObject(id, sourceFileType);
|
|
73
|
+
const getCursor = (cursorIds: string[] | undefined, sourceFileType?: string) => this.getCursor(cursorIds, sourceFileType);
|
|
74
74
|
|
|
75
75
|
const registry = options.registry || new RecipeRegistry();
|
|
76
76
|
|
|
@@ -82,7 +82,7 @@ export class RewriteRpc {
|
|
|
82
82
|
GetLanguages.handle(this.connection);
|
|
83
83
|
PrepareRecipe.handle(this.connection, registry, preparedRecipes);
|
|
84
84
|
Parse.handle(this.connection, this.localObjects);
|
|
85
|
-
Print.handle(this.connection, getObject
|
|
85
|
+
Print.handle(this.connection, getObject);
|
|
86
86
|
InstallRecipes.handle(this.connection, options.recipeInstallDir ?? ".rewrite", registry, options.logger);
|
|
87
87
|
|
|
88
88
|
this.connection.listen();
|
|
@@ -104,14 +104,13 @@ export class RewriteRpc {
|
|
|
104
104
|
return this;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
async getObject<P>(id: string): Promise<P> {
|
|
107
|
+
async getObject<P>(id: string, sourceFileType?: string): Promise<P> {
|
|
108
108
|
const localObject = this.localObjects.get(id);
|
|
109
|
-
const lastKnownId = localObject ? id : undefined;
|
|
110
109
|
|
|
111
|
-
const q = new RpcReceiveQueue(this.remoteRefs, () => {
|
|
110
|
+
const q = new RpcReceiveQueue(this.remoteRefs, sourceFileType, () => {
|
|
112
111
|
return this.connection.sendRequest(
|
|
113
112
|
new rpc.RequestType<GetObject, RpcObjectData[], Error>("GetObject"),
|
|
114
|
-
new GetObject(id,
|
|
113
|
+
new GetObject(id, sourceFileType)
|
|
115
114
|
);
|
|
116
115
|
}, this.options.traceGetObjectInput);
|
|
117
116
|
|
|
@@ -128,11 +127,11 @@ export class RewriteRpc {
|
|
|
128
127
|
return remoteObject;
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
async getCursor(cursorIds: string[] | undefined): Promise<Cursor> {
|
|
130
|
+
async getCursor(cursorIds: string[] | undefined, sourceFileType?: string): Promise<Cursor> {
|
|
132
131
|
let cursor = rootCursor();
|
|
133
132
|
if (cursorIds) {
|
|
134
133
|
for (let i = cursorIds.length - 1; i >= 0; i--) {
|
|
135
|
-
const cursorObject = await this.getObject(cursorIds[i]);
|
|
134
|
+
const cursorObject = await this.getObject(cursorIds[i], sourceFileType);
|
|
136
135
|
this.remoteObjects.set(cursorIds[i], cursorObject);
|
|
137
136
|
cursor = new Cursor(cursorObject, cursor);
|
|
138
137
|
}
|
|
@@ -140,13 +139,13 @@ export class RewriteRpc {
|
|
|
140
139
|
return cursor;
|
|
141
140
|
}
|
|
142
141
|
|
|
143
|
-
async parse(inputs: ParserInput[], relativeTo?: string): Promise<SourceFile[]> {
|
|
142
|
+
async parse(inputs: ParserInput[], sourceFileType: string, relativeTo?: string): Promise<SourceFile[]> {
|
|
144
143
|
const parsed: SourceFile[] = [];
|
|
145
144
|
for (const g of await this.connection.sendRequest(
|
|
146
145
|
new rpc.RequestType<Parse, string[], Error>("Parse"),
|
|
147
146
|
new Parse(inputs, relativeTo)
|
|
148
147
|
)) {
|
|
149
|
-
parsed.push(await this.getObject(g));
|
|
148
|
+
parsed.push(await this.getObject(g, sourceFileType));
|
|
150
149
|
}
|
|
151
150
|
return parsed;
|
|
152
151
|
}
|
|
@@ -160,7 +159,8 @@ export class RewriteRpc {
|
|
|
160
159
|
this.localObjects.set(tree.id.toString(), tree);
|
|
161
160
|
return await this.connection.sendRequest(
|
|
162
161
|
new rpc.RequestType<Print, string, Error>("Print"),
|
|
163
|
-
new Print(tree.id,
|
|
162
|
+
new Print(tree.id, isSourceFile(tree) ? tree.kind :
|
|
163
|
+
cursor!.firstEnclosing(t => isSourceFile(t))!.kind)
|
|
164
164
|
);
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -192,21 +192,26 @@ export class RewriteRpc {
|
|
|
192
192
|
this.localObjects.set(tree.id.toString(), tree);
|
|
193
193
|
const pId = this.localObject(p);
|
|
194
194
|
const cursorIds = this.getCursorIds(cursor);
|
|
195
|
+
|
|
196
|
+
const sourceFileType = isSourceFile(tree) ? tree.kind :
|
|
197
|
+
cursor!.firstEnclosing(t => isSourceFile(t))!.kind;
|
|
198
|
+
|
|
195
199
|
const response = await this.connection.sendRequest(
|
|
196
200
|
new rpc.RequestType<Visit, VisitResponse, Error>("Visit"),
|
|
197
|
-
new Visit(visitorName, undefined, tree.id.toString(), pId, cursorIds)
|
|
201
|
+
new Visit(visitorName, sourceFileType, undefined, tree.id.toString(), pId, cursorIds)
|
|
198
202
|
);
|
|
199
|
-
return response.modified ? this.getObject(tree.id.toString()) : tree;
|
|
203
|
+
return response.modified ? this.getObject(tree.id.toString(), sourceFileType) : tree;
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
async generate(remoteRecipeId: string, ctx: ExecutionContext): Promise<SourceFile[]> {
|
|
203
207
|
const ctxId = this.localObject(ctx);
|
|
204
208
|
const generated: SourceFile[] = [];
|
|
205
|
-
|
|
206
|
-
new rpc.RequestType<Generate,
|
|
209
|
+
const response = await this.connection.sendRequest(
|
|
210
|
+
new rpc.RequestType<Generate, GenerateResponse, Error>("Generate"),
|
|
207
211
|
new Generate(remoteRecipeId, ctxId)
|
|
208
|
-
)
|
|
209
|
-
|
|
212
|
+
);
|
|
213
|
+
for (let i = 0; i < response.ids.length; i++) {
|
|
214
|
+
generated.push(await this.getObject(response.ids[i], response.sourceFileTypes[i]));
|
|
210
215
|
}
|
|
211
216
|
return generated;
|
|
212
217
|
}
|
package/src/test/rewrite-test.ts
CHANGED
|
@@ -212,7 +212,7 @@ export class RecipeSpec {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
class ValidateWhitespaceVisitor extends JavaScriptVisitor<ExecutionContext> {
|
|
215
|
-
|
|
215
|
+
public override async visitSpace(space: J.Space, p: ExecutionContext): Promise<J.Space> {
|
|
216
216
|
const ret = super.visitSpace(space, p);
|
|
217
217
|
expect(space.whitespace).toMatch(/^\s*$/);
|
|
218
218
|
return ret;
|
package/src/text/rpc.ts
CHANGED
|
@@ -13,10 +13,9 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import {RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "../rpc";
|
|
17
17
|
import {PlainText} from "./tree";
|
|
18
18
|
import {createDraft, Draft, finishDraft} from "immer";
|
|
19
|
-
import {TreeKind} from "../tree";
|
|
20
19
|
|
|
21
20
|
async function receiveSnippet(before: PlainText.Snippet, q: RpcReceiveQueue): Promise<PlainText.Snippet | undefined> {
|
|
22
21
|
const draft: Draft<PlainText.Snippet> = createDraft(before);
|
|
@@ -26,40 +25,37 @@ async function receiveSnippet(before: PlainText.Snippet, q: RpcReceiveQueue): Pr
|
|
|
26
25
|
return finishDraft(draft);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
// Register codec for all Java AST node types
|
|
29
|
+
for (const kind of Object.values(PlainText.Kind)) {
|
|
30
|
+
RpcCodecs.registerCodec(kind as string, {
|
|
31
|
+
async rpcReceive(before: PlainText, q: RpcReceiveQueue): Promise<PlainText> {
|
|
32
|
+
const draft: Draft<PlainText> = createDraft(before);
|
|
33
|
+
draft.id = await q.receive(before.id);
|
|
34
|
+
draft.markers = await q.receive(before.markers);
|
|
35
|
+
draft.sourcePath = await q.receive(before.sourcePath);
|
|
36
|
+
draft.charsetName = await q.receive(before.charsetName);
|
|
37
|
+
draft.charsetBomMarked = await q.receive(before.charsetBomMarked);
|
|
38
|
+
draft.checksum = await q.receive(before.checksum);
|
|
39
|
+
draft.fileAttributes = await q.receive(before.fileAttributes);
|
|
40
|
+
draft.text = await q.receive(before.text);
|
|
41
|
+
draft.snippets = (await q.receiveList(before.snippets, snippet => receiveSnippet(snippet, q)))!;
|
|
42
|
+
return finishDraft(draft);
|
|
43
|
+
},
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
async rpcSend(after: PlainText, q: RpcSendQueue): Promise<void> {
|
|
46
|
+
await q.getAndSend(after, p => p.id);
|
|
47
|
+
await q.getAndSend(after, p => p.markers);
|
|
48
|
+
await q.getAndSend(after, p => p.sourcePath);
|
|
49
|
+
await q.getAndSend(after, p => p.charsetName);
|
|
50
|
+
await q.getAndSend(after, p => p.charsetBomMarked);
|
|
51
|
+
await q.getAndSend(after, p => p.checksum);
|
|
52
|
+
await q.getAndSend(after, p => p.fileAttributes);
|
|
53
|
+
await q.getAndSend(after, p => p.text);
|
|
54
|
+
await q.getAndSendList(after, a => a.snippets, s => s.id, async (snippet) => {
|
|
55
|
+
await q.getAndSend(snippet, p => p.id);
|
|
56
|
+
await q.getAndSend(snippet, p => p.markers);
|
|
57
|
+
await q.getAndSend(snippet, p => p.text);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}, PlainText.Kind.PlainText);
|
|
59
61
|
}
|
|
60
|
-
|
|
61
|
-
Object.values(PlainText.Kind).forEach(kind => {
|
|
62
|
-
if (!Object.values(TreeKind).includes(kind as any)) {
|
|
63
|
-
RpcCodecs.registerCodec(kind, textCodec);
|
|
64
|
-
}
|
|
65
|
-
});
|