@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.
Files changed (95) hide show
  1. package/dist/execution.d.ts.map +1 -1
  2. package/dist/execution.js.map +1 -1
  3. package/dist/java/rpc.d.ts +1 -0
  4. package/dist/java/rpc.d.ts.map +1 -1
  5. package/dist/java/rpc.js +81 -0
  6. package/dist/java/rpc.js.map +1 -1
  7. package/dist/java/tree.d.ts.map +1 -1
  8. package/dist/java/tree.js +0 -87
  9. package/dist/java/tree.js.map +1 -1
  10. package/dist/java/visitor.d.ts +4 -4
  11. package/dist/java/visitor.d.ts.map +1 -1
  12. package/dist/java/visitor.js.map +1 -1
  13. package/dist/javascript/format.d.ts +2 -2
  14. package/dist/javascript/format.d.ts.map +1 -1
  15. package/dist/javascript/format.js.map +1 -1
  16. package/dist/javascript/parser.d.ts +1 -1
  17. package/dist/javascript/parser.d.ts.map +1 -1
  18. package/dist/javascript/parser.js +26 -4
  19. package/dist/javascript/parser.js.map +1 -1
  20. package/dist/javascript/print.d.ts +2 -2
  21. package/dist/javascript/print.d.ts.map +1 -1
  22. package/dist/javascript/print.js.map +1 -1
  23. package/dist/javascript/rpc.js +1 -16
  24. package/dist/javascript/rpc.js.map +1 -1
  25. package/dist/javascript/type-mapping.d.ts +4 -19
  26. package/dist/javascript/type-mapping.d.ts.map +1 -1
  27. package/dist/javascript/type-mapping.js +228 -163
  28. package/dist/javascript/type-mapping.js.map +1 -1
  29. package/dist/javascript/visitor.d.ts +1 -1
  30. package/dist/javascript/visitor.d.ts.map +1 -1
  31. package/dist/javascript/visitor.js.map +1 -1
  32. package/dist/json/print.js.map +1 -1
  33. package/dist/json/rpc.js +46 -17
  34. package/dist/json/rpc.js.map +1 -1
  35. package/dist/json/visitor.d.ts +2 -2
  36. package/dist/json/visitor.d.ts.map +1 -1
  37. package/dist/json/visitor.js.map +1 -1
  38. package/dist/print.d.ts +2 -2
  39. package/dist/print.d.ts.map +1 -1
  40. package/dist/print.js +4 -2
  41. package/dist/print.js.map +1 -1
  42. package/dist/rpc/queue.d.ts +15 -6
  43. package/dist/rpc/queue.d.ts.map +1 -1
  44. package/dist/rpc/queue.js +37 -13
  45. package/dist/rpc/queue.js.map +1 -1
  46. package/dist/rpc/request/generate.d.ts +4 -0
  47. package/dist/rpc/request/generate.d.ts.map +1 -1
  48. package/dist/rpc/request/generate.js +9 -4
  49. package/dist/rpc/request/generate.js.map +1 -1
  50. package/dist/rpc/request/get-object.d.ts +2 -2
  51. package/dist/rpc/request/get-object.d.ts.map +1 -1
  52. package/dist/rpc/request/get-object.js +4 -12
  53. package/dist/rpc/request/get-object.js.map +1 -1
  54. package/dist/rpc/request/parse.d.ts.map +1 -1
  55. package/dist/rpc/request/parse.js.map +1 -1
  56. package/dist/rpc/request/print.d.ts +3 -4
  57. package/dist/rpc/request/print.d.ts.map +1 -1
  58. package/dist/rpc/request/print.js +5 -6
  59. package/dist/rpc/request/print.js.map +1 -1
  60. package/dist/rpc/request/visit.d.ts +3 -2
  61. package/dist/rpc/request/visit.d.ts.map +1 -1
  62. package/dist/rpc/request/visit.js +5 -4
  63. package/dist/rpc/request/visit.js.map +1 -1
  64. package/dist/rpc/rewrite-rpc.d.ts +3 -3
  65. package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
  66. package/dist/rpc/rewrite-rpc.js +19 -16
  67. package/dist/rpc/rewrite-rpc.js.map +1 -1
  68. package/dist/test/rewrite-test.js.map +1 -1
  69. package/dist/text/rpc.js +37 -40
  70. package/dist/text/rpc.js.map +1 -1
  71. package/dist/version.txt +1 -1
  72. package/package.json +1 -1
  73. package/src/execution.ts +0 -2
  74. package/src/java/rpc.ts +68 -0
  75. package/src/java/tree.ts +1 -65
  76. package/src/java/visitor.ts +4 -4
  77. package/src/javascript/format.ts +2 -2
  78. package/src/javascript/parser.ts +19 -5
  79. package/src/javascript/print.ts +3 -3
  80. package/src/javascript/rpc.ts +4 -17
  81. package/src/javascript/type-mapping.ts +235 -170
  82. package/src/javascript/visitor.ts +1 -1
  83. package/src/json/print.ts +1 -1
  84. package/src/json/rpc.ts +40 -19
  85. package/src/json/visitor.ts +2 -2
  86. package/src/print.ts +6 -4
  87. package/src/rpc/queue.ts +36 -12
  88. package/src/rpc/request/generate.ts +18 -6
  89. package/src/rpc/request/get-object.ts +6 -13
  90. package/src/rpc/request/parse.ts +1 -1
  91. package/src/rpc/request/print.ts +5 -7
  92. package/src/rpc/request/visit.ts +6 -5
  93. package/src/rpc/rewrite-rpc.ts +24 -19
  94. package/src/test/rewrite-test.ts +1 -1
  95. 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 codecs = new Map<string, RpcCodec<any>>();
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>): void {
58
- this.codecs.set(type, codec);
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
- return this.codecs.get(type);
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, private readonly trace: boolean) {
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
- import {UUID} from "node:crypto";
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, UUID[], Error>("Generate"), async (request) => {
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
- return generated.map(g => {
51
+
52
+ for (const g of generated) {
43
53
  localObjects.set(g.id.toString(), g);
44
- return g.id;
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, private readonly lastKnownId?: 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
+ }
@@ -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 {Parser, ParserInput, Parsers} from "../../parser";
19
+ import {ParserInput, Parsers} from "../../parser";
20
20
  import {randomId} from "../../uuid";
21
21
  import {produce} from "immer";
22
22
  import {SourceFile} from "../../tree";
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import * as rpc from "vscode-jsonrpc/node";
17
- import {Cursor, isSourceFile, Tree} from "../../tree";
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 cursor?: string[], readonly markerPrinter: MarkerPrinter = MarkerPrinter.DEFAULT) {
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
- const cursor = await getCursor(request.cursor);
41
- return await printer(cursor).print(tree, out);
39
+ return await printer(request.sourceFileType).print(tree, out);
42
40
  }
43
41
  });
44
42
  }
@@ -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) {
@@ -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, getCursor);
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, lastKnownId)
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, this.getCursorIds(cursor))
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
- for (const g of await this.connection.sendRequest(
206
- new rpc.RequestType<Generate, string[], Error>("Generate"),
209
+ const response = await this.connection.sendRequest(
210
+ new rpc.RequestType<Generate, GenerateResponse, Error>("Generate"),
207
211
  new Generate(remoteRecipeId, ctxId)
208
- )) {
209
- generated.push(await this.getObject(g));
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
  }
@@ -212,7 +212,7 @@ export class RecipeSpec {
212
212
  }
213
213
 
214
214
  class ValidateWhitespaceVisitor extends JavaScriptVisitor<ExecutionContext> {
215
- protected override async visitSpace(space: J.Space, p: ExecutionContext): Promise<J.Space> {
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 {RpcCodec, RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "../rpc";
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
- const textCodec: RpcCodec<PlainText> = {
30
- async rpcReceive(before: PlainText, q: RpcReceiveQueue): Promise<PlainText> {
31
- const draft: Draft<PlainText> = createDraft(before);
32
- draft.id = await q.receive(before.id);
33
- draft.markers = await q.receive(before.markers);
34
- draft.sourcePath = await q.receive(before.sourcePath);
35
- draft.charsetName = await q.receive(before.charsetName);
36
- draft.charsetBomMarked = await q.receive(before.charsetBomMarked);
37
- draft.checksum = await q.receive(before.checksum);
38
- draft.fileAttributes = await q.receive(before.fileAttributes);
39
- draft.text = await q.receive(before.text);
40
- draft.snippets = (await q.receiveList(before.snippets, snippet => receiveSnippet(snippet, q)))!;
41
- return finishDraft(draft);
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
- async rpcSend(after: PlainText, q: RpcSendQueue): Promise<void> {
45
- await q.getAndSend(after, p => p.id);
46
- await q.getAndSend(after, p => p.markers);
47
- await q.getAndSend(after, p => p.sourcePath);
48
- await q.getAndSend(after, p => p.charsetName);
49
- await q.getAndSend(after, p => p.charsetBomMarked);
50
- await q.getAndSend(after, p => p.checksum);
51
- await q.getAndSend(after, p => p.fileAttributes);
52
- await q.getAndSend(after, p => p.text);
53
- await q.getAndSendList(after, a => a.snippets, s => s.id, async (snippet) => {
54
- await q.getAndSend(snippet, p => p.id);
55
- await q.getAndSend(snippet, p => p.markers);
56
- await q.getAndSend(snippet, p => p.text);
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
- });