@openrewrite/rewrite 8.62.3 → 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 (90) 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 +208 -167
  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/rpc/queue.d.ts +15 -6
  39. package/dist/rpc/queue.d.ts.map +1 -1
  40. package/dist/rpc/queue.js +37 -13
  41. package/dist/rpc/queue.js.map +1 -1
  42. package/dist/rpc/request/generate.d.ts +4 -0
  43. package/dist/rpc/request/generate.d.ts.map +1 -1
  44. package/dist/rpc/request/generate.js +9 -4
  45. package/dist/rpc/request/generate.js.map +1 -1
  46. package/dist/rpc/request/get-object.d.ts +2 -2
  47. package/dist/rpc/request/get-object.d.ts.map +1 -1
  48. package/dist/rpc/request/get-object.js +4 -12
  49. package/dist/rpc/request/get-object.js.map +1 -1
  50. package/dist/rpc/request/parse.d.ts.map +1 -1
  51. package/dist/rpc/request/parse.js.map +1 -1
  52. package/dist/rpc/request/print.d.ts +1 -1
  53. package/dist/rpc/request/print.d.ts.map +1 -1
  54. package/dist/rpc/request/print.js +1 -1
  55. package/dist/rpc/request/print.js.map +1 -1
  56. package/dist/rpc/request/visit.d.ts +3 -2
  57. package/dist/rpc/request/visit.d.ts.map +1 -1
  58. package/dist/rpc/request/visit.js +5 -4
  59. package/dist/rpc/request/visit.js.map +1 -1
  60. package/dist/rpc/rewrite-rpc.d.ts +3 -3
  61. package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
  62. package/dist/rpc/rewrite-rpc.js +16 -14
  63. package/dist/rpc/rewrite-rpc.js.map +1 -1
  64. package/dist/test/rewrite-test.js.map +1 -1
  65. package/dist/text/rpc.js +37 -40
  66. package/dist/text/rpc.js.map +1 -1
  67. package/dist/version.txt +1 -1
  68. package/package.json +1 -1
  69. package/src/execution.ts +0 -2
  70. package/src/java/rpc.ts +68 -0
  71. package/src/java/tree.ts +1 -65
  72. package/src/java/visitor.ts +4 -4
  73. package/src/javascript/format.ts +2 -2
  74. package/src/javascript/parser.ts +19 -5
  75. package/src/javascript/print.ts +3 -3
  76. package/src/javascript/rpc.ts +4 -17
  77. package/src/javascript/type-mapping.ts +216 -173
  78. package/src/javascript/visitor.ts +1 -1
  79. package/src/json/print.ts +1 -1
  80. package/src/json/rpc.ts +40 -19
  81. package/src/json/visitor.ts +2 -2
  82. package/src/rpc/queue.ts +36 -12
  83. package/src/rpc/request/generate.ts +18 -6
  84. package/src/rpc/request/get-object.ts +6 -13
  85. package/src/rpc/request/parse.ts +1 -1
  86. package/src/rpc/request/print.ts +2 -2
  87. package/src/rpc/request/visit.ts +6 -5
  88. package/src/rpc/rewrite-rpc.ts +21 -17
  89. package/src/test/rewrite-test.ts +1 -1
  90. 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";
@@ -29,9 +29,9 @@ export class Print {
29
29
  }
30
30
 
31
31
  static handle(connection: rpc.MessageConnection,
32
- getObject: (id: string) => any): void {
32
+ getObject: (id: string, sourceFileType?: string) => any): void {
33
33
  connection.onRequest(new rpc.RequestType<Print, string, Error>("Print"), async request => {
34
- const tree: Tree = await getObject(request.treeId.toString());
34
+ const tree: Tree = await getObject(request.treeId.toString(), request.sourceFileType);
35
35
  const out = new PrintOutputCapture(PrintMarkerPrinter[request.markerPrinter]);
36
36
  if (isSourceFile(tree)) {
37
37
  return await printer(tree).print(tree, out);
@@ -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
 
@@ -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
  }
@@ -193,21 +192,26 @@ export class RewriteRpc {
193
192
  this.localObjects.set(tree.id.toString(), tree);
194
193
  const pId = this.localObject(p);
195
194
  const cursorIds = this.getCursorIds(cursor);
195
+
196
+ const sourceFileType = isSourceFile(tree) ? tree.kind :
197
+ cursor!.firstEnclosing(t => isSourceFile(t))!.kind;
198
+
196
199
  const response = await this.connection.sendRequest(
197
200
  new rpc.RequestType<Visit, VisitResponse, Error>("Visit"),
198
- new Visit(visitorName, undefined, tree.id.toString(), pId, cursorIds)
201
+ new Visit(visitorName, sourceFileType, undefined, tree.id.toString(), pId, cursorIds)
199
202
  );
200
- return response.modified ? this.getObject(tree.id.toString()) : tree;
203
+ return response.modified ? this.getObject(tree.id.toString(), sourceFileType) : tree;
201
204
  }
202
205
 
203
206
  async generate(remoteRecipeId: string, ctx: ExecutionContext): Promise<SourceFile[]> {
204
207
  const ctxId = this.localObject(ctx);
205
208
  const generated: SourceFile[] = [];
206
- for (const g of await this.connection.sendRequest(
207
- new rpc.RequestType<Generate, string[], Error>("Generate"),
209
+ const response = await this.connection.sendRequest(
210
+ new rpc.RequestType<Generate, GenerateResponse, Error>("Generate"),
208
211
  new Generate(remoteRecipeId, ctxId)
209
- )) {
210
- 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]));
211
215
  }
212
216
  return generated;
213
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
- });