@openrewrite/rewrite 8.67.0-20251114-112006 → 8.67.0-20251114-141647

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openrewrite/rewrite",
3
- "version": "8.67.0-20251114-112006",
3
+ "version": "8.67.0-20251114-141647",
4
4
  "license": "Moderne Source Available License",
5
5
  "description": "OpenRewrite JavaScript.",
6
6
  "homepage": "https://github.com/openrewrite/rewrite",
@@ -232,7 +232,7 @@ export class TypeVisitor<P> {
232
232
  recipe?: (draft: Draft<T>) =>
233
233
  ValidImmerRecipeReturnType<Draft<T>> |
234
234
  PromiseLike<ValidImmerRecipeReturnType<Draft<T>>>
235
- ): Promise<T> {
235
+ ): Promise<T | undefined> {
236
236
  if (recipe) {
237
237
  return produceAsync<T>(before, recipe);
238
238
  }
@@ -17,7 +17,7 @@ import {Cursor, isTree, SourceFile} from "../tree";
17
17
  import {mapAsync, updateIfChanged} from "../util";
18
18
  import {produceAsync, TreeVisitor, ValidImmerRecipeReturnType} from "../visitor";
19
19
  import {Expression, isSpace, J, NameTree, Statement, TypedTree, TypeTree} from "./tree";
20
- import {createDraft, Draft, finishDraft} from "immer";
20
+ import {createDraft, Draft, finishDraft, nothing} from "immer";
21
21
  import {Type} from "./type";
22
22
 
23
23
  const javaKindValues = new Set(Object.values(J.Kind));
@@ -1214,7 +1214,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
1214
1214
  return right ? this.visitRightPadded(right, p) : undefined;
1215
1215
  }
1216
1216
 
1217
- public async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: P): Promise<J.RightPadded<T>> {
1217
+ public async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: P): Promise<J.RightPadded<T> | undefined> {
1218
1218
  return produceAsync<J.RightPadded<T>>(right, async draft => {
1219
1219
  this.cursor = new Cursor(right, this.cursor);
1220
1220
  if (isTree(right.element)) {
@@ -1223,6 +1223,9 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
1223
1223
  draft.after = await this.visitSpace(right.after, p);
1224
1224
  draft.markers = await this.visitMarkers(right.markers, p);
1225
1225
  this.cursor = this.cursor.parent!;
1226
+ if (draft.element === undefined) {
1227
+ return nothing;
1228
+ }
1226
1229
  });
1227
1230
  }
1228
1231
 
@@ -1230,7 +1233,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
1230
1233
  return left ? this.visitLeftPadded(left, p) : undefined;
1231
1234
  }
1232
1235
 
1233
- public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T>> {
1236
+ public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T> | undefined> {
1234
1237
  return produceAsync<J.LeftPadded<T>>(left, async draft => {
1235
1238
  this.cursor = new Cursor(left, this.cursor);
1236
1239
  draft.before = await this.visitSpace(left.before, p);
@@ -1241,6 +1244,9 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
1241
1244
  }
1242
1245
  draft.markers = await this.visitMarkers(left.markers, p);
1243
1246
  this.cursor = this.cursor.parent!;
1247
+ if (draft.element === undefined) {
1248
+ return nothing;
1249
+ }
1244
1250
  });
1245
1251
  }
1246
1252
 
@@ -1249,13 +1255,13 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
1249
1255
  }
1250
1256
 
1251
1257
  public async visitContainer<T extends J>(container: J.Container<T>, p: P): Promise<J.Container<T>> {
1252
- return produceAsync<J.Container<T>>(container, async draft => {
1258
+ return (await produceAsync<J.Container<T>>(container, async draft => {
1253
1259
  this.cursor = new Cursor(container, this.cursor);
1254
1260
  draft.before = await this.visitSpace(container.before, p);
1255
1261
  (draft.elements as J.RightPadded<J>[]) = await mapAsync(container.elements, e => this.visitRightPadded(e, p));
1256
1262
  draft.markers = await this.visitMarkers(container.markers, p);
1257
1263
  this.cursor = this.cursor.parent!;
1258
- });
1264
+ }))!;
1259
1265
  }
1260
1266
 
1261
1267
  protected async produceJava<J2 extends J>(
@@ -470,18 +470,18 @@ export class SpacesVisitor<P> extends JavaScriptVisitor<P> {
470
470
  }
471
471
 
472
472
  private async spaceBeforeLeftPaddedElement<T extends J>(left: J.LeftPadded<T>, spaceBeforePadding: boolean, spaceBeforeElement: boolean): Promise<J.LeftPadded<T>> {
473
- return produceAsync(left, async draft => {
473
+ return (await produceAsync(left, async draft => {
474
474
  if (draft.before.comments.length == 0) {
475
475
  draft.before.whitespace = spaceBeforePadding ? " " : "";
476
476
  }
477
477
  draft.element = await this.spaceBefore(left.element, spaceBeforeElement) as Draft<T>;
478
- });
478
+ }))!;
479
479
  }
480
480
 
481
481
  private async spaceBeforeRightPaddedElement<T extends J>(right: J.RightPadded<T>, spaceBefore: boolean): Promise<J.RightPadded<T>> {
482
- return produceAsync(right, async draft => {
482
+ return (await produceAsync(right, async draft => {
483
483
  draft.element = await this.spaceBefore(right.element, spaceBefore) as Draft<T>;
484
- });
484
+ }))!;
485
485
  }
486
486
 
487
487
  private async spaceBefore<T extends J>(j: T, spaceBefore: boolean): Promise<T> {
@@ -1209,7 +1209,7 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
1209
1209
  return await super.visit(tree, p) as R;
1210
1210
  }
1211
1211
 
1212
- public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T>> {
1212
+ public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T> | undefined> {
1213
1213
  const ret = await super.visitLeftPadded(left, p);
1214
1214
  if (ret == undefined) {
1215
1215
  return ret;
@@ -557,14 +557,14 @@ class MarkerAttachmentVisitor extends JavaScriptVisitor<undefined> {
557
557
  /**
558
558
  * Propagates markers from element to RightPadded wrapper.
559
559
  */
560
- public override async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: undefined): Promise<J.RightPadded<T>> {
560
+ public override async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: undefined): Promise<J.RightPadded<T> | undefined> {
561
561
  if (!isTree(right.element)) {
562
562
  return right;
563
563
  }
564
564
 
565
565
  const visitedElement = await this.visit(right.element as J, p);
566
566
  if (visitedElement && visitedElement !== right.element as Tree) {
567
- return produceAsync<J.RightPadded<T>>(right, async (draft: any) => {
567
+ const result = await produceAsync<J.RightPadded<T>>(right, async (draft: any) => {
568
568
  // Visit element first
569
569
  if (right.element && (right.element as any).kind) {
570
570
  // Check if element has a CaptureMarker
@@ -576,6 +576,7 @@ class MarkerAttachmentVisitor extends JavaScriptVisitor<undefined> {
576
576
  }
577
577
  }
578
578
  });
579
+ return result!;
579
580
  }
580
581
 
581
582
  return right;
@@ -93,7 +93,7 @@ export class PlaceholderReplacementVisitor extends JavaScriptVisitor<any> {
93
93
  * The base implementation will visit the element, which triggers our visit() override
94
94
  * for placeholder detection and replacement.
95
95
  */
96
- override async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: any): Promise<J.RightPadded<T>> {
96
+ override async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: any): Promise<J.RightPadded<T> | undefined> {
97
97
  return super.visitRightPadded(right, p);
98
98
  }
99
99
 
package/src/json/rpc.ts CHANGED
@@ -158,7 +158,7 @@ class JsonReceiver extends JsonVisitor<RpcReceiveQueue> {
158
158
  }
159
159
 
160
160
  public async visitSpace(space: Json.Space, q: RpcReceiveQueue): Promise<Json.Space> {
161
- return produceAsync<Json.Space>(space, async draft => {
161
+ return (await produceAsync<Json.Space>(space, async draft => {
162
162
  draft.comments = await q.receiveListDefined(space.comments, async c => {
163
163
  return await produceAsync(c, async draft => {
164
164
  draft.multiline = await q.receive(c.multiline);
@@ -168,7 +168,7 @@ class JsonReceiver extends JsonVisitor<RpcReceiveQueue> {
168
168
  })
169
169
  });
170
170
  draft.whitespace = await q.receive(space.whitespace);
171
- });
171
+ }))!;
172
172
  }
173
173
 
174
174
  public async visitRightPadded<T extends Json>(right: Json.RightPadded<T>, p: RpcReceiveQueue): Promise<Json.RightPadded<T> | undefined> {
@@ -63,7 +63,7 @@ export class OrderImports extends Recipe {
63
63
  const cuWithImportsSorted = await produceAsync(cu, async draft => {
64
64
  draft.statements = [...sortedImports, ...restStatements];
65
65
  });
66
- return produce(cuWithImportsSorted, draft => {
66
+ return produce(cuWithImportsSorted!, draft => {
67
67
  for (let i = 0; i < importCount; i++) {
68
68
  draft.statements[i].element.prefix.whitespace = i > 0 ? "\n" : "";
69
69
  }
package/src/visitor.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import {emptyMarkers, Marker, Markers} from "./markers";
17
17
  import {Cursor, isSourceFile, rootCursor, SourceFile, Tree} from "./tree";
18
- import {createDraft, Draft, finishDraft, Objectish} from "immer";
18
+ import {createDraft, Draft, finishDraft, nothing, Objectish} from "immer";
19
19
  import {mapAsync} from "./util";
20
20
 
21
21
  /* Not exported beyond the internal immer module */
@@ -23,15 +23,23 @@ export type ValidImmerRecipeReturnType<State> =
23
23
  | State
24
24
  | void
25
25
  | undefined
26
+ | typeof nothing
26
27
 
27
28
  export async function produceAsync<Base extends Objectish>(
28
29
  before: Promise<Base> | Base,
29
30
  recipe: (draft: Draft<Base>) => ValidImmerRecipeReturnType<Draft<Base>> |
30
31
  PromiseLike<ValidImmerRecipeReturnType<Draft<Base>>>
31
- ): Promise<Base> {
32
+ ): Promise<Base | undefined> {
32
33
  const b: Base = await before;
33
34
  const draft = createDraft(b);
34
- await recipe(draft);
35
+ const result = await recipe(draft);
36
+
37
+ // If recipe explicitly returned Immer's nothing, return undefined
38
+ if (result === nothing) {
39
+ return undefined;
40
+ }
41
+
42
+ // Otherwise, return the finished draft (void/undefined means use draft)
35
43
  return finishDraft(draft) as Base;
36
44
  }
37
45
 
@@ -128,9 +136,9 @@ export abstract class TreeVisitor<T extends Tree, P> {
128
136
  } else if ((markers.markers?.length || 0) === 0) {
129
137
  return markers;
130
138
  }
131
- return produceAsync<Markers>(markers, async (draft) => {
139
+ return (await produceAsync<Markers>(markers, async (draft) => {
132
140
  draft.markers = await mapAsync(markers.markers, m => this.visitMarker(m, p))
133
- });
141
+ }))!;
134
142
  }
135
143
 
136
144
  protected async visitMarker<M extends Marker>(marker: M, p: P): Promise<M> {
@@ -143,7 +151,7 @@ export abstract class TreeVisitor<T extends Tree, P> {
143
151
  recipe?:
144
152
  ((draft: Draft<T>) => ValidImmerRecipeReturnType<Draft<T>>) |
145
153
  ((draft: Draft<T>) => Promise<ValidImmerRecipeReturnType<Draft<T>>>)
146
- ): Promise<T> {
154
+ ): Promise<T | undefined> {
147
155
  return produceAsync(before, async draft => {
148
156
  draft.markers = await this.visitMarkers(before.markers, p);
149
157
  if (recipe) {