@openrewrite/rewrite 8.96.4 → 8.97.0

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 (135) hide show
  1. package/dist/execution.d.ts +2 -0
  2. package/dist/execution.d.ts.map +1 -1
  3. package/dist/execution.js +4 -0
  4. package/dist/execution.js.map +1 -1
  5. package/dist/heavyweight.d.ts +8 -0
  6. package/dist/heavyweight.d.ts.map +1 -0
  7. package/dist/heavyweight.js +45 -0
  8. package/dist/heavyweight.js.map +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/java/tree.d.ts +2 -1
  14. package/dist/java/tree.d.ts.map +1 -1
  15. package/dist/java/tree.js.map +1 -1
  16. package/dist/java/visitor.d.ts +5 -0
  17. package/dist/java/visitor.d.ts.map +1 -1
  18. package/dist/java/visitor.js +264 -217
  19. package/dist/java/visitor.js.map +1 -1
  20. package/dist/javascript/add-import.d.ts +2 -1
  21. package/dist/javascript/add-import.d.ts.map +1 -1
  22. package/dist/javascript/add-import.js +14 -2
  23. package/dist/javascript/add-import.js.map +1 -1
  24. package/dist/javascript/amd.d.ts.map +1 -1
  25. package/dist/javascript/amd.js +2 -1
  26. package/dist/javascript/amd.js.map +1 -1
  27. package/dist/javascript/cleanup/add-parse-int-radix.js +1 -1
  28. package/dist/javascript/cleanup/add-parse-int-radix.js.map +1 -1
  29. package/dist/javascript/dependency-workspace.d.ts +8 -2
  30. package/dist/javascript/dependency-workspace.d.ts.map +1 -1
  31. package/dist/javascript/dependency-workspace.js +36 -4
  32. package/dist/javascript/dependency-workspace.js.map +1 -1
  33. package/dist/javascript/format/format.d.ts +10 -0
  34. package/dist/javascript/format/format.d.ts.map +1 -1
  35. package/dist/javascript/format/format.js +10 -2
  36. package/dist/javascript/format/format.js.map +1 -1
  37. package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
  38. package/dist/javascript/format/tabs-and-indents-visitor.js +4 -0
  39. package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
  40. package/dist/javascript/format/whitespace-reconciler.d.ts.map +1 -1
  41. package/dist/javascript/format/whitespace-reconciler.js +4 -0
  42. package/dist/javascript/format/whitespace-reconciler.js.map +1 -1
  43. package/dist/javascript/node-resolution-result.d.ts.map +1 -1
  44. package/dist/javascript/node-resolution-result.js +2 -0
  45. package/dist/javascript/node-resolution-result.js.map +1 -1
  46. package/dist/javascript/parser-utils.d.ts.map +1 -1
  47. package/dist/javascript/parser-utils.js +9 -6
  48. package/dist/javascript/parser-utils.js.map +1 -1
  49. package/dist/javascript/templating/engine.d.ts +1 -0
  50. package/dist/javascript/templating/engine.d.ts.map +1 -1
  51. package/dist/javascript/templating/engine.js +39 -10
  52. package/dist/javascript/templating/engine.js.map +1 -1
  53. package/dist/javascript/templating/pattern.d.ts.map +1 -1
  54. package/dist/javascript/templating/pattern.js +8 -0
  55. package/dist/javascript/templating/pattern.js.map +1 -1
  56. package/dist/javascript/templating/placeholder-replacement.d.ts +2 -0
  57. package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
  58. package/dist/javascript/templating/placeholder-replacement.js +37 -1
  59. package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
  60. package/dist/javascript/visitor.d.ts.map +1 -1
  61. package/dist/javascript/visitor.js +153 -118
  62. package/dist/javascript/visitor.js.map +1 -1
  63. package/dist/recipe.d.ts +5 -0
  64. package/dist/recipe.d.ts.map +1 -1
  65. package/dist/recipe.js +5 -0
  66. package/dist/recipe.js.map +1 -1
  67. package/dist/rewrite-javascript-version.txt +1 -1
  68. package/dist/run.d.ts +7 -1
  69. package/dist/run.d.ts.map +1 -1
  70. package/dist/run.js +40 -2
  71. package/dist/run.js.map +1 -1
  72. package/dist/test/accumulator-contents.d.ts +15 -0
  73. package/dist/test/accumulator-contents.d.ts.map +1 -0
  74. package/dist/test/accumulator-contents.js +185 -0
  75. package/dist/test/accumulator-contents.js.map +1 -0
  76. package/dist/test/empty-sources.d.ts +14 -0
  77. package/dist/test/empty-sources.d.ts.map +1 -0
  78. package/dist/test/empty-sources.js +98 -0
  79. package/dist/test/empty-sources.js.map +1 -0
  80. package/dist/test/formatting-scope.d.ts +18 -0
  81. package/dist/test/formatting-scope.d.ts.map +1 -0
  82. package/dist/test/formatting-scope.js +244 -0
  83. package/dist/test/formatting-scope.js.map +1 -0
  84. package/dist/test/probes.d.ts +25 -0
  85. package/dist/test/probes.d.ts.map +1 -0
  86. package/dist/test/probes.js +189 -0
  87. package/dist/test/probes.js.map +1 -0
  88. package/dist/test/rewrite-test.d.ts +27 -0
  89. package/dist/test/rewrite-test.d.ts.map +1 -1
  90. package/dist/test/rewrite-test.js +191 -21
  91. package/dist/test/rewrite-test.js.map +1 -1
  92. package/dist/test/tree-shapes.d.ts +15 -0
  93. package/dist/test/tree-shapes.d.ts.map +1 -0
  94. package/dist/test/tree-shapes.js +288 -0
  95. package/dist/test/tree-shapes.js.map +1 -0
  96. package/dist/test/unparsed-sources.d.ts +17 -0
  97. package/dist/test/unparsed-sources.d.ts.map +1 -0
  98. package/dist/test/unparsed-sources.js +113 -0
  99. package/dist/test/unparsed-sources.js.map +1 -0
  100. package/dist/tree.d.ts.map +1 -1
  101. package/dist/tree.js +2 -0
  102. package/dist/tree.js.map +1 -1
  103. package/dist/visitor.d.ts.map +1 -1
  104. package/dist/visitor.js +2 -0
  105. package/dist/visitor.js.map +1 -1
  106. package/package.json +1 -1
  107. package/src/execution.ts +6 -0
  108. package/src/heavyweight.ts +42 -0
  109. package/src/index.ts +1 -0
  110. package/src/java/tree.ts +2 -1
  111. package/src/java/visitor.ts +263 -216
  112. package/src/javascript/add-import.ts +11 -2
  113. package/src/javascript/amd.ts +4 -2
  114. package/src/javascript/cleanup/add-parse-int-radix.ts +2 -2
  115. package/src/javascript/dependency-workspace.ts +35 -3
  116. package/src/javascript/format/format.ts +18 -0
  117. package/src/javascript/format/tabs-and-indents-visitor.ts +4 -0
  118. package/src/javascript/format/whitespace-reconciler.ts +4 -0
  119. package/src/javascript/node-resolution-result.ts +3 -0
  120. package/src/javascript/parser-utils.ts +10 -6
  121. package/src/javascript/templating/engine.ts +41 -9
  122. package/src/javascript/templating/pattern.ts +10 -0
  123. package/src/javascript/templating/placeholder-replacement.ts +38 -1
  124. package/src/javascript/visitor.ts +166 -118
  125. package/src/recipe.ts +5 -0
  126. package/src/run.ts +30 -2
  127. package/src/test/accumulator-contents.ts +194 -0
  128. package/src/test/empty-sources.ts +99 -0
  129. package/src/test/formatting-scope.ts +231 -0
  130. package/src/test/probes.ts +156 -0
  131. package/src/test/rewrite-test.ts +177 -24
  132. package/src/test/tree-shapes.ts +332 -0
  133. package/src/test/unparsed-sources.ts +138 -0
  134. package/src/tree.ts +3 -0
  135. package/src/visitor.ts +3 -0
@@ -16,11 +16,13 @@
16
16
  * limitations under the License.
17
17
  */
18
18
  import {mapAsync, updateIfChanged} from "../util";
19
+ import {Markers} from "../markers";
19
20
  import {SourceFile} from "../tree";
20
21
  import {ValidRecipeReturnType} from "../visitor";
21
22
  import {Expression, J, JavaVisitor, NameTree, Statement, Type, TypedTree} from "../java";
22
23
  import {create, Draft} from "mutative";
23
24
  import {isJavaScript, JS, JSX} from "./tree";
25
+ import {isStatement} from "./parser-utils";
24
26
 
25
27
  export class JavaScriptVisitor<P> extends JavaVisitor<P> {
26
28
 
@@ -76,12 +78,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
76
78
  }
77
79
  alias = expression as JS.Alias;
78
80
 
79
- const updates: any = {
81
+ const updates: any = await this.visitChildrenOf(alias, async () => ({
80
82
  prefix: await this.visitSpace(alias.prefix, p),
81
83
  markers: await this.visitMarkers(alias.markers, p),
82
84
  propertyName: await this.visitRightPadded(alias.propertyName, p),
83
85
  alias: await this.visitDefined<Expression>(alias.alias, p)
84
- };
86
+ }));
85
87
  return updateIfChanged(alias, updates);
86
88
  }
87
89
 
@@ -98,7 +100,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
98
100
  }
99
101
  arrowFunction = statement as JS.ArrowFunction;
100
102
 
101
- const updates: any = {
103
+ const updates: any = await this.visitChildrenOf(arrowFunction, async () => ({
102
104
  prefix: await this.visitSpace(arrowFunction.prefix, p),
103
105
  markers: await this.visitMarkers(arrowFunction.markers, p),
104
106
  leadingAnnotations: await mapAsync(arrowFunction.leadingAnnotations, item => this.visitDefined<J.Annotation>(item, p)),
@@ -106,7 +108,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
106
108
  typeParameters: arrowFunction.typeParameters && await this.visitDefined<J.TypeParameters>(arrowFunction.typeParameters, p),
107
109
  lambda: await this.visitDefined<J.Lambda>(arrowFunction.lambda, p),
108
110
  returnTypeExpression: arrowFunction.returnTypeExpression && await this.visitDefined<TypedTree>(arrowFunction.returnTypeExpression, p)
109
- };
111
+ }));
110
112
  return updateIfChanged(arrowFunction, updates);
111
113
  }
112
114
 
@@ -117,13 +119,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
117
119
  }
118
120
  as_ = expression as JS.As;
119
121
 
120
- const updates: any = {
122
+ const updates: any = await this.visitChildrenOf(as_, async () => ({
121
123
  prefix: await this.visitSpace(as_.prefix, p),
122
124
  markers: await this.visitMarkers(as_.markers, p),
123
125
  left: await this.visitRightPadded<Expression>(as_.left, p),
124
126
  right: await this.visitDefined<Expression>(as_.right, p),
125
127
  type: as_.type && await this.visitType(as_.type, p)
126
- };
128
+ }));
127
129
  return updateIfChanged(as_, updates);
128
130
  }
129
131
 
@@ -134,12 +136,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
134
136
  }
135
137
  await_ = expression as JS.Await;
136
138
 
137
- const updates: any = {
139
+ const updates: any = await this.visitChildrenOf(await_, async () => ({
138
140
  prefix: await this.visitSpace(await_.prefix, p),
139
141
  markers: await this.visitMarkers(await_.markers, p),
140
142
  expression: await this.visitDefined<Expression>(await_.expression, p),
141
143
  type: await_.type && await this.visitType(await_.type, p)
142
- };
144
+ }));
143
145
  return updateIfChanged(await_, updates);
144
146
  }
145
147
 
@@ -150,7 +152,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
150
152
  }
151
153
  element = expression as JSX.Tag;
152
154
 
153
- const updates: any = {
155
+ const updates: any = await this.visitChildrenOf(element, async () => ({
154
156
  prefix: await this.visitSpace(element.prefix, p),
155
157
  markers: await this.visitMarkers(element.markers, p),
156
158
  openName: await this.visitLeftPadded(element.openName, p),
@@ -161,7 +163,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
161
163
  children: element.children && await mapAsync(element.children, child => this.visit(child, p)),
162
164
  closingName: element.closingName && await this.visitLeftPadded(element.closingName, p),
163
165
  afterClosingName: element.afterClosingName && await this.visitSpace(element.afterClosingName, p)
164
- };
166
+ }));
165
167
  return updateIfChanged(element, updates);
166
168
  }
167
169
 
@@ -192,11 +194,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
192
194
  }
193
195
  expr = expression as JSX.EmbeddedExpression;
194
196
 
195
- const updates: any = {
197
+ const updates: any = await this.visitChildrenOf(expr, async () => ({
196
198
  prefix: await this.visitSpace(expr.prefix, p),
197
199
  markers: await this.visitMarkers(expr.markers, p),
198
200
  expression: await this.visitRightPadded(expr.expression, p)
199
- };
201
+ }));
200
202
  return updateIfChanged(expr, updates);
201
203
  }
202
204
 
@@ -227,13 +229,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
227
229
  }
228
230
  conditionalType = expression as JS.ConditionalType;
229
231
 
230
- const updates: any = {
232
+ const updates: any = await this.visitChildrenOf(conditionalType, async () => ({
231
233
  prefix: await this.visitSpace(conditionalType.prefix, p),
232
234
  markers: await this.visitMarkers(conditionalType.markers, p),
233
235
  checkType: await this.visitDefined<Expression>(conditionalType.checkType, p),
234
236
  condition: await this.visitLeftPadded(conditionalType.condition, p),
235
237
  type: conditionalType.type && await this.visitType(conditionalType.type, p)
236
- };
238
+ }));
237
239
  return updateIfChanged(conditionalType, updates);
238
240
  }
239
241
 
@@ -250,11 +252,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
250
252
  }
251
253
  delete_ = statement as JS.Delete;
252
254
 
253
- const updates: any = {
255
+ const updates: any = await this.visitChildrenOf(delete_, async () => ({
254
256
  prefix: await this.visitSpace(delete_.prefix, p),
255
257
  markers: await this.visitMarkers(delete_.markers, p),
256
258
  expression: await this.visitDefined<Expression>(delete_.expression, p)
257
- };
259
+ }));
258
260
  return updateIfChanged(delete_, updates);
259
261
  }
260
262
 
@@ -271,11 +273,28 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
271
273
  }
272
274
  expressionStatement = statement as JS.ExpressionStatement;
273
275
 
274
- const updates: any = {
276
+ const updates: any = await this.visitChildrenOf(expressionStatement, async () => ({
275
277
  prefix: await this.visitSpace(expressionStatement.prefix, p),
276
278
  markers: await this.visitMarkers(expressionStatement.markers, p),
277
279
  expression: await this.visitDefined<Expression>(expressionStatement.expression, p)
278
- };
280
+ }));
281
+ // Outside a `for` head the parser makes a statement the statement itself, so a visit that makes one does too,
282
+ // where the cursor shows what holds the expression statement
283
+ let visited: J | undefined = updates.expression;
284
+ const parent = this.cursor.parentTree()?.value;
285
+ if (visited && visited !== expressionStatement.expression && isStatement(visited) &&
286
+ parent && parent.kind !== J.Kind.ForLoopControl) {
287
+ // and it holds a statement that is no expression in a JS.StatementExpression only when it is a `yield`
288
+ const held = visited.kind === JS.Kind.StatementExpression ? (visited as JS.StatementExpression).statement : undefined;
289
+ if (held && held.kind !== J.Kind.Yield) {
290
+ visited = {...held, prefix: concatenated(visited.prefix, held.prefix), markers: withOuterMarkers(visited.markers, held.markers)};
291
+ }
292
+ return {
293
+ ...visited,
294
+ prefix: concatenated(updates.prefix, visited.prefix),
295
+ markers: withOuterMarkers(updates.markers, visited.markers)
296
+ };
297
+ }
279
298
  return updateIfChanged(expressionStatement, updates);
280
299
  }
281
300
 
@@ -286,13 +305,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
286
305
  }
287
306
  expressionWithTypeArguments = expression as JS.ExpressionWithTypeArguments;
288
307
 
289
- const updates: any = {
308
+ const updates: any = await this.visitChildrenOf(expressionWithTypeArguments, async () => ({
290
309
  prefix: await this.visitSpace(expressionWithTypeArguments.prefix, p),
291
310
  markers: await this.visitMarkers(expressionWithTypeArguments.markers, p),
292
311
  clazz: await this.visitDefined<J>(expressionWithTypeArguments.clazz, p),
293
312
  typeArguments: expressionWithTypeArguments.typeArguments && await this.visitContainer(expressionWithTypeArguments.typeArguments, p),
294
313
  type: expressionWithTypeArguments.type && await this.visitType(expressionWithTypeArguments.type, p)
295
- };
314
+ }));
296
315
  return updateIfChanged(expressionWithTypeArguments, updates);
297
316
  }
298
317
 
@@ -309,14 +328,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
309
328
  }
310
329
  functionCall = statement as JS.FunctionCall;
311
330
 
312
- const updates: any = {
331
+ const updates: any = await this.visitChildrenOf(functionCall, async () => ({
313
332
  prefix: await this.visitSpace(functionCall.prefix, p),
314
333
  markers: await this.visitMarkers(functionCall.markers, p),
315
334
  function: await this.visitOptionalRightPadded(functionCall.function, p),
316
335
  typeParameters: await this.visitOptionalContainer(functionCall.typeParameters, p),
317
336
  arguments: await this.visitContainer(functionCall.arguments, p),
318
337
  methodType: await this.visitType(functionCall.methodType, p) as Type.Method | undefined
319
- };
338
+ }));
320
339
  return updateIfChanged(functionCall, updates);
321
340
  }
322
341
 
@@ -327,7 +346,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
327
346
  }
328
347
  functionType = expression as JS.FunctionType;
329
348
 
330
- const updates: any = {
349
+ const updates: any = await this.visitChildrenOf(functionType, async () => ({
331
350
  prefix: await this.visitSpace(functionType.prefix, p),
332
351
  markers: await this.visitMarkers(functionType.markers, p),
333
352
  modifiers: await mapAsync(functionType.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
@@ -335,7 +354,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
335
354
  typeParameters: functionType.typeParameters && await this.visitDefined<J.TypeParameters>(functionType.typeParameters, p),
336
355
  parameters: await this.visitContainer(functionType.parameters, p),
337
356
  returnType: await this.visitLeftPadded(functionType.returnType, p)
338
- };
357
+ }));
339
358
  return updateIfChanged(functionType, updates);
340
359
  }
341
360
 
@@ -346,12 +365,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
346
365
  }
347
366
  inferType = expression as JS.InferType;
348
367
 
349
- const updates: any = {
368
+ const updates: any = await this.visitChildrenOf(inferType, async () => ({
350
369
  prefix: await this.visitSpace(inferType.prefix, p),
351
370
  markers: await this.visitMarkers(inferType.markers, p),
352
371
  typeParameter: await this.visitLeftPadded(inferType.typeParameter, p),
353
372
  type: inferType.type && await this.visitType(inferType.type, p)
354
- };
373
+ }));
355
374
  return updateIfChanged(inferType, updates);
356
375
  }
357
376
 
@@ -362,7 +381,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
362
381
  }
363
382
  importType = expression as JS.ImportType;
364
383
 
365
- const updates: any = {
384
+ const updates: any = await this.visitChildrenOf(importType, async () => ({
366
385
  prefix: await this.visitSpace(importType.prefix, p),
367
386
  markers: await this.visitMarkers(importType.markers, p),
368
387
  hasTypeof: await this.visitRightPadded(importType.hasTypeof, p),
@@ -370,7 +389,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
370
389
  qualifier: importType.qualifier && await this.visitLeftPadded(importType.qualifier, p),
371
390
  typeArguments: importType.typeArguments && await this.visitContainer(importType.typeArguments, p),
372
391
  type: importType.type && await this.visitType(importType.type, p)
373
- };
392
+ }));
374
393
  return updateIfChanged(importType, updates);
375
394
  }
376
395
 
@@ -381,7 +400,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
381
400
  }
382
401
  jsImport = statement as JS.Import;
383
402
 
384
- const updates: any = {
403
+ const updates: any = await this.visitChildrenOf(jsImport, async () => ({
385
404
  prefix: await this.visitSpace(jsImport.prefix, p),
386
405
  markers: await this.visitMarkers(jsImport.markers, p),
387
406
  modifiers: await mapAsync(jsImport.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
@@ -389,7 +408,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
389
408
  moduleSpecifier: jsImport.moduleSpecifier && await this.visitLeftPadded(jsImport.moduleSpecifier, p),
390
409
  attributes: jsImport.attributes && await this.visitDefined<JS.ImportAttributes>(jsImport.attributes, p),
391
410
  initializer: jsImport.initializer && await this.visitLeftPadded(jsImport.initializer, p)
392
- };
411
+ }));
393
412
  return updateIfChanged(jsImport, updates);
394
413
  }
395
414
 
@@ -410,12 +429,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
410
429
  }
411
430
  namedImports = expression as JS.NamedImports;
412
431
 
413
- const updates: any = {
432
+ const updates: any = await this.visitChildrenOf(namedImports, async () => ({
414
433
  prefix: await this.visitSpace(namedImports.prefix, p),
415
434
  markers: await this.visitMarkers(namedImports.markers, p),
416
435
  elements: await this.visitContainer(namedImports.elements, p),
417
436
  type: namedImports.type && await this.visitType(namedImports.type, p)
418
- };
437
+ }));
419
438
  return updateIfChanged(namedImports, updates);
420
439
  }
421
440
 
@@ -426,13 +445,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
426
445
  }
427
446
  importSpecifier = expression as JS.ImportSpecifier;
428
447
 
429
- const updates: any = {
448
+ const updates: any = await this.visitChildrenOf(importSpecifier, async () => ({
430
449
  prefix: await this.visitSpace(importSpecifier.prefix, p),
431
450
  markers: await this.visitMarkers(importSpecifier.markers, p),
432
451
  importType: await this.visitLeftPadded(importSpecifier.importType, p),
433
452
  specifier: await this.visitDefined<JS.Alias | J.Identifier>(importSpecifier.specifier, p),
434
453
  type: importSpecifier.type && await this.visitType(importSpecifier.type, p)
435
- };
454
+ }));
436
455
  return updateIfChanged(importSpecifier, updates);
437
456
  }
438
457
 
@@ -463,12 +482,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
463
482
  }
464
483
  importAttribute = statement as JS.ImportAttribute;
465
484
 
466
- const updates: any = {
485
+ const updates: any = await this.visitChildrenOf(importAttribute, async () => ({
467
486
  prefix: await this.visitSpace(importAttribute.prefix, p),
468
487
  markers: await this.visitMarkers(importAttribute.markers, p),
469
488
  name: await this.visitDefined<Expression>(importAttribute.name, p),
470
489
  value: await this.visitLeftPadded(importAttribute.value, p)
471
- };
490
+ }));
472
491
  return updateIfChanged(importAttribute, updates);
473
492
  }
474
493
 
@@ -479,14 +498,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
479
498
  }
480
499
  jsBinary = expression as JS.Binary;
481
500
 
482
- const updates: any = {
501
+ const updates: any = await this.visitChildrenOf(jsBinary, async () => ({
483
502
  prefix: await this.visitSpace(jsBinary.prefix, p),
484
503
  markers: await this.visitMarkers(jsBinary.markers, p),
485
504
  left: await this.visitDefined<Expression>(jsBinary.left, p),
486
505
  operator: await this.visitLeftPadded(jsBinary.operator, p),
487
506
  right: await this.visitDefined<Expression>(jsBinary.right, p),
488
507
  type: jsBinary.type && await this.visitType(jsBinary.type, p)
489
- };
508
+ }));
490
509
  return updateIfChanged(jsBinary, updates);
491
510
  }
492
511
 
@@ -497,12 +516,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
497
516
  }
498
517
  literalType = expression as JS.LiteralType;
499
518
 
500
- const updates: any = {
519
+ const updates: any = await this.visitChildrenOf(literalType, async () => ({
501
520
  prefix: await this.visitSpace(literalType.prefix, p),
502
521
  markers: await this.visitMarkers(literalType.markers, p),
503
522
  literal: await this.visitDefined<Expression>(literalType.literal, p),
504
523
  type: (await this.visitType(literalType.type, p))!
505
- };
524
+ }));
506
525
  return updateIfChanged(literalType, updates);
507
526
  }
508
527
 
@@ -513,7 +532,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
513
532
  }
514
533
  mappedType = expression as JS.MappedType;
515
534
 
516
- const updates: any = {
535
+ const updates: any = await this.visitChildrenOf(mappedType, async () => ({
517
536
  prefix: await this.visitSpace(mappedType.prefix, p),
518
537
  markers: await this.visitMarkers(mappedType.markers, p),
519
538
  prefixToken: mappedType.prefixToken && await this.visitLeftPadded(mappedType.prefixToken, p),
@@ -523,7 +542,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
523
542
  hasQuestionToken: await this.visitLeftPadded(mappedType.hasQuestionToken, p),
524
543
  valueType: await this.visitContainer(mappedType.valueType, p),
525
544
  type: mappedType.type && await this.visitType(mappedType.type, p)
526
- };
545
+ }));
527
546
  return updateIfChanged(mappedType, updates);
528
547
  }
529
548
 
@@ -534,12 +553,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
534
553
  }
535
554
  keysRemapping = statement as JS.MappedType.KeysRemapping;
536
555
 
537
- const updates: any = {
556
+ const updates: any = await this.visitChildrenOf(keysRemapping, async () => ({
538
557
  prefix: await this.visitSpace(keysRemapping.prefix, p),
539
558
  markers: await this.visitMarkers(keysRemapping.markers, p),
540
559
  typeParameter: await this.visitRightPadded(keysRemapping.typeParameter, p),
541
560
  nameType: keysRemapping.nameType && await this.visitRightPadded(keysRemapping.nameType, p)
542
- };
561
+ }));
543
562
  return updateIfChanged(keysRemapping, updates);
544
563
  }
545
564
 
@@ -550,12 +569,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
550
569
  }
551
570
  mappedTypeParameter = statement as JS.MappedType.Parameter;
552
571
 
553
- const updates: any = {
572
+ const updates: any = await this.visitChildrenOf(mappedTypeParameter, async () => ({
554
573
  prefix: await this.visitSpace(mappedTypeParameter.prefix, p),
555
574
  markers: await this.visitMarkers(mappedTypeParameter.markers, p),
556
575
  name: await this.visitDefined<Expression>(mappedTypeParameter.name, p),
557
576
  iterateType: await this.visitLeftPadded(mappedTypeParameter.iterateType, p)
558
- };
577
+ }));
559
578
  return updateIfChanged(mappedTypeParameter, updates);
560
579
  }
561
580
 
@@ -566,7 +585,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
566
585
  }
567
586
  objectBindingPattern = expression as JS.ObjectBindingPattern;
568
587
 
569
- const updates: any = {
588
+ const updates: any = await this.visitChildrenOf(objectBindingPattern, async () => ({
570
589
  prefix: await this.visitSpace(objectBindingPattern.prefix, p),
571
590
  markers: await this.visitMarkers(objectBindingPattern.markers, p),
572
591
  leadingAnnotations: await mapAsync(objectBindingPattern.leadingAnnotations, item => this.visitDefined<J.Annotation>(item, p)),
@@ -574,7 +593,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
574
593
  typeExpression: objectBindingPattern.typeExpression && await this.visitDefined<TypedTree>(objectBindingPattern.typeExpression, p),
575
594
  bindings: await this.visitContainer(objectBindingPattern.bindings, p),
576
595
  initializer: objectBindingPattern.initializer && await this.visitLeftPadded(objectBindingPattern.initializer, p)
577
- };
596
+ }));
578
597
  return updateIfChanged(objectBindingPattern, updates);
579
598
  }
580
599
 
@@ -585,13 +604,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
585
604
  }
586
605
  propertyAssignment = statement as JS.PropertyAssignment;
587
606
 
588
- const updates: any = {
607
+ const updates: any = await this.visitChildrenOf(propertyAssignment, async () => ({
589
608
  prefix: await this.visitSpace(propertyAssignment.prefix, p),
590
609
  markers: await this.visitMarkers(propertyAssignment.markers, p),
591
610
  modifiers: await mapAsync(propertyAssignment.modifiers, m => this.visitDefined<J.Modifier>(m, p)),
592
611
  name: await this.visitRightPadded(propertyAssignment.name, p),
593
612
  initializer: propertyAssignment.initializer && await this.visitDefined<Expression>(propertyAssignment.initializer, p)
594
- };
613
+ }));
595
614
  return updateIfChanged(propertyAssignment, updates);
596
615
  }
597
616
 
@@ -602,13 +621,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
602
621
  }
603
622
  satisfiesExpression = expression as JS.SatisfiesExpression;
604
623
 
605
- const updates: any = {
624
+ const updates: any = await this.visitChildrenOf(satisfiesExpression, async () => ({
606
625
  prefix: await this.visitSpace(satisfiesExpression.prefix, p),
607
626
  markers: await this.visitMarkers(satisfiesExpression.markers, p),
608
627
  expression: await this.visitDefined<J>(satisfiesExpression.expression, p),
609
628
  satisfiesType: await this.visitLeftPadded(satisfiesExpression.satisfiesType, p),
610
629
  type: satisfiesExpression.type && await this.visitType(satisfiesExpression.type, p)
611
- };
630
+ }));
612
631
  return updateIfChanged(satisfiesExpression, updates);
613
632
  }
614
633
 
@@ -619,12 +638,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
619
638
  }
620
639
  scopedVariableDeclarations = statement as JS.ScopedVariableDeclarations;
621
640
 
622
- const updates: any = {
641
+ const updates: any = await this.visitChildrenOf(scopedVariableDeclarations, async () => ({
623
642
  prefix: await this.visitSpace(scopedVariableDeclarations.prefix, p),
624
643
  markers: await this.visitMarkers(scopedVariableDeclarations.markers, p),
625
644
  modifiers: await mapAsync(scopedVariableDeclarations.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
626
645
  variables: await mapAsync(scopedVariableDeclarations.variables, item => this.visitRightPadded(item, p))
627
- };
646
+ }));
628
647
  return updateIfChanged(scopedVariableDeclarations, updates);
629
648
  }
630
649
 
@@ -649,12 +668,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
649
668
  }
650
669
  spread = statement as JS.Spread;
651
670
 
652
- const updates: any = {
671
+ const updates: any = await this.visitChildrenOf(spread, async () => ({
653
672
  prefix: await this.visitSpace(spread.prefix, p),
654
673
  markers: await this.visitMarkers(spread.markers, p),
655
674
  expression: await this.visitDefined<Expression>(spread.expression, p),
656
675
  type: await this.visitType(spread.type, p)
657
- };
676
+ }));
658
677
  return updateIfChanged(spread, updates);
659
678
  }
660
679
 
@@ -671,11 +690,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
671
690
  }
672
691
  statementExpression = statement as JS.StatementExpression;
673
692
 
674
- const updates: any = {
693
+ const updates: any = await this.visitChildrenOf(statementExpression, async () => ({
675
694
  prefix: await this.visitSpace(statementExpression.prefix, p),
676
695
  markers: await this.visitMarkers(statementExpression.markers, p),
677
696
  statement: await this.visitDefined<Statement>(statementExpression.statement, p)
678
- };
697
+ }));
679
698
  return updateIfChanged(statementExpression, updates);
680
699
  }
681
700
 
@@ -692,14 +711,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
692
711
  }
693
712
  taggedTemplateExpression = statement as JS.TaggedTemplateExpression;
694
713
 
695
- const updates: any = {
714
+ const updates: any = await this.visitChildrenOf(taggedTemplateExpression, async () => ({
696
715
  prefix: await this.visitSpace(taggedTemplateExpression.prefix, p),
697
716
  markers: await this.visitMarkers(taggedTemplateExpression.markers, p),
698
717
  tag: taggedTemplateExpression.tag && await this.visitRightPadded(taggedTemplateExpression.tag, p),
699
718
  typeArguments: taggedTemplateExpression.typeArguments && await this.visitContainer(taggedTemplateExpression.typeArguments, p),
700
719
  templateExpression: await this.visitDefined<Expression>(taggedTemplateExpression.templateExpression, p),
701
720
  type: taggedTemplateExpression.type && await this.visitType(taggedTemplateExpression.type, p)
702
- };
721
+ }));
703
722
  return updateIfChanged(taggedTemplateExpression, updates);
704
723
  }
705
724
 
@@ -716,13 +735,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
716
735
  }
717
736
  templateExpression = statement as JS.TemplateExpression;
718
737
 
719
- const updates: any = {
738
+ const updates: any = await this.visitChildrenOf(templateExpression, async () => ({
720
739
  prefix: await this.visitSpace(templateExpression.prefix, p),
721
740
  markers: await this.visitMarkers(templateExpression.markers, p),
722
741
  head: await this.visitDefined<J.Literal>(templateExpression.head, p),
723
742
  spans: await mapAsync(templateExpression.spans, item => this.visitRightPadded(item, p)),
724
743
  type: templateExpression.type && await this.visitType(templateExpression.type, p)
725
- };
744
+ }));
726
745
  return updateIfChanged(templateExpression, updates);
727
746
  }
728
747
 
@@ -743,12 +762,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
743
762
  }
744
763
  tuple = expression as JS.Tuple;
745
764
 
746
- const updates: any = {
765
+ const updates: any = await this.visitChildrenOf(tuple, async () => ({
747
766
  prefix: await this.visitSpace(tuple.prefix, p),
748
767
  markers: await this.visitMarkers(tuple.markers, p),
749
768
  elements: await this.visitContainer(tuple.elements, p),
750
769
  type: tuple.type && await this.visitType(tuple.type, p)
751
- };
770
+ }));
752
771
  return updateIfChanged(tuple, updates);
753
772
  }
754
773
 
@@ -759,7 +778,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
759
778
  }
760
779
  typeDeclaration = statement as JS.TypeDeclaration;
761
780
 
762
- const updates: any = {
781
+ const updates: any = await this.visitChildrenOf(typeDeclaration, async () => ({
763
782
  prefix: await this.visitSpace(typeDeclaration.prefix, p),
764
783
  markers: await this.visitMarkers(typeDeclaration.markers, p),
765
784
  modifiers: await mapAsync(typeDeclaration.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
@@ -767,7 +786,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
767
786
  typeParameters: typeDeclaration.typeParameters && await this.visitDefined<J.TypeParameters>(typeDeclaration.typeParameters, p),
768
787
  initializer: await this.visitLeftPadded(typeDeclaration.initializer, p),
769
788
  type: typeDeclaration.type && await this.visitType(typeDeclaration.type, p)
770
- };
789
+ }));
771
790
  return updateIfChanged(typeDeclaration, updates);
772
791
  }
773
792
 
@@ -778,12 +797,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
778
797
  }
779
798
  typeOf = expression as JS.TypeOf;
780
799
 
781
- const updates: any = {
800
+ const updates: any = await this.visitChildrenOf(typeOf, async () => ({
782
801
  prefix: await this.visitSpace(typeOf.prefix, p),
783
802
  markers: await this.visitMarkers(typeOf.markers, p),
784
803
  expression: await this.visitDefined<Expression>(typeOf.expression, p),
785
804
  type: typeOf.type && await this.visitType(typeOf.type, p)
786
- };
805
+ }));
787
806
  return updateIfChanged(typeOf, updates);
788
807
  }
789
808
 
@@ -794,11 +813,22 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
794
813
  }
795
814
  typeTreeExpression = expression as JS.TypeTreeExpression;
796
815
 
797
- const updates: any = {
816
+ const updates: any = await this.visitChildrenOf(typeTreeExpression, async () => ({
798
817
  prefix: await this.visitSpace(typeTreeExpression.prefix, p),
799
818
  markers: await this.visitMarkers(typeTreeExpression.markers, p),
800
819
  expression: await this.visitDefined<Expression>(typeTreeExpression.expression, p)
801
- };
820
+ }));
821
+ // The parser wraps no type tree, so a visit that makes the expression one drops the wrapper
822
+ const visited: J = updates.expression;
823
+ if (visited !== typeTreeExpression.expression && (visited.kind === J.Kind.Identifier ||
824
+ visited.kind === J.Kind.FieldAccess || visited.kind === J.Kind.ArrayType ||
825
+ visited.kind === J.Kind.ParameterizedType)) {
826
+ return {
827
+ ...visited,
828
+ prefix: concatenated(updates.prefix, visited.prefix),
829
+ markers: withOuterMarkers(updates.markers, visited.markers)
830
+ };
831
+ }
802
832
  return updateIfChanged(typeTreeExpression, updates);
803
833
  }
804
834
 
@@ -815,14 +845,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
815
845
  }
816
846
  assignmentOperation = statement as JS.AssignmentOperation;
817
847
 
818
- const updates: any = {
848
+ const updates: any = await this.visitChildrenOf(assignmentOperation, async () => ({
819
849
  prefix: await this.visitSpace(assignmentOperation.prefix, p),
820
850
  markers: await this.visitMarkers(assignmentOperation.markers, p),
821
851
  variable: await this.visitDefined<Expression>(assignmentOperation.variable, p),
822
852
  operator: await this.visitLeftPadded(assignmentOperation.operator, p),
823
853
  assignment: await this.visitDefined<Expression>(assignmentOperation.assignment, p),
824
854
  type: assignmentOperation.type && await this.visitType(assignmentOperation.type, p)
825
- };
855
+ }));
826
856
  return updateIfChanged(assignmentOperation, updates);
827
857
  }
828
858
 
@@ -833,13 +863,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
833
863
  }
834
864
  indexedAccessType = expression as JS.IndexedAccessType;
835
865
 
836
- const updates: any = {
866
+ const updates: any = await this.visitChildrenOf(indexedAccessType, async () => ({
837
867
  prefix: await this.visitSpace(indexedAccessType.prefix, p),
838
868
  markers: await this.visitMarkers(indexedAccessType.markers, p),
839
869
  objectType: await this.visitDefined<TypedTree>(indexedAccessType.objectType, p),
840
870
  indexType: await this.visitDefined<TypedTree>(indexedAccessType.indexType, p),
841
871
  type: indexedAccessType.type && await this.visitType(indexedAccessType.type, p)
842
- };
872
+ }));
843
873
  return updateIfChanged(indexedAccessType, updates);
844
874
  }
845
875
 
@@ -850,12 +880,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
850
880
  }
851
881
  indexType = expression as JS.IndexedAccessType.IndexType;
852
882
 
853
- const updates: any = {
883
+ const updates: any = await this.visitChildrenOf(indexType, async () => ({
854
884
  prefix: await this.visitSpace(indexType.prefix, p),
855
885
  markers: await this.visitMarkers(indexType.markers, p),
856
886
  element: await this.visitRightPadded(indexType.element, p),
857
887
  type: indexType.type && await this.visitType(indexType.type, p)
858
- };
888
+ }));
859
889
  return updateIfChanged(indexType, updates);
860
890
  }
861
891
 
@@ -866,13 +896,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
866
896
  }
867
897
  typeQuery = expression as JS.TypeQuery;
868
898
 
869
- const updates: any = {
899
+ const updates: any = await this.visitChildrenOf(typeQuery, async () => ({
870
900
  prefix: await this.visitSpace(typeQuery.prefix, p),
871
901
  markers: await this.visitMarkers(typeQuery.markers, p),
872
902
  typeExpression: await this.visitDefined<TypedTree>(typeQuery.typeExpression, p),
873
903
  typeArguments: typeQuery.typeArguments && await this.visitContainer(typeQuery.typeArguments, p),
874
904
  type: typeQuery.type && await this.visitType(typeQuery.type, p)
875
- };
905
+ }));
876
906
  return updateIfChanged(typeQuery, updates);
877
907
  }
878
908
 
@@ -883,11 +913,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
883
913
  }
884
914
  typeInfo = expression as JS.TypeInfo;
885
915
 
886
- const updates: any = {
916
+ const updates: any = await this.visitChildrenOf(typeInfo, async () => ({
887
917
  prefix: await this.visitSpace(typeInfo.prefix, p),
888
918
  markers: await this.visitMarkers(typeInfo.markers, p),
889
919
  typeIdentifier: await this.visitDefined<TypedTree>(typeInfo.typeIdentifier, p)
890
- };
920
+ }));
891
921
  return updateIfChanged(typeInfo, updates);
892
922
  }
893
923
 
@@ -898,11 +928,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
898
928
  }
899
929
  computedPropertyName = expression as JS.ComputedPropertyName;
900
930
 
901
- const updates: any = {
931
+ const updates: any = await this.visitChildrenOf(computedPropertyName, async () => ({
902
932
  prefix: await this.visitSpace(computedPropertyName.prefix, p),
903
933
  markers: await this.visitMarkers(computedPropertyName.markers, p),
904
934
  expression: await this.visitRightPadded(computedPropertyName.expression, p)
905
- };
935
+ }));
906
936
  return updateIfChanged(computedPropertyName, updates);
907
937
  }
908
938
 
@@ -913,11 +943,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
913
943
  }
914
944
  typeOperator = expression as JS.TypeOperator;
915
945
 
916
- const updates: any = {
946
+ const updates: any = await this.visitChildrenOf(typeOperator, async () => ({
917
947
  prefix: await this.visitSpace(typeOperator.prefix, p),
918
948
  markers: await this.visitMarkers(typeOperator.markers, p),
919
949
  expression: await this.visitLeftPadded(typeOperator.expression, p)
920
- };
950
+ }));
921
951
  return updateIfChanged(typeOperator, updates);
922
952
  }
923
953
 
@@ -928,14 +958,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
928
958
  }
929
959
  typePredicate = expression as JS.TypePredicate;
930
960
 
931
- const updates: any = {
961
+ const updates: any = await this.visitChildrenOf(typePredicate, async () => ({
932
962
  prefix: await this.visitSpace(typePredicate.prefix, p),
933
963
  markers: await this.visitMarkers(typePredicate.markers, p),
934
964
  asserts: await this.visitLeftPadded(typePredicate.asserts, p),
935
965
  parameterName: await this.visitDefined<J.Identifier>(typePredicate.parameterName, p),
936
966
  expression: typePredicate.expression && await this.visitLeftPadded(typePredicate.expression, p),
937
967
  type: typePredicate.type && await this.visitType(typePredicate.type, p)
938
- };
968
+ }));
939
969
  return updateIfChanged(typePredicate, updates);
940
970
  }
941
971
 
@@ -946,12 +976,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
946
976
  }
947
977
  union = expression as JS.Union;
948
978
 
949
- const updates: any = {
979
+ const updates: any = await this.visitChildrenOf(union, async () => ({
950
980
  prefix: await this.visitSpace(union.prefix, p),
951
981
  markers: await this.visitMarkers(union.markers, p),
952
982
  types: await mapAsync(union.types, item => this.visitRightPadded(item, p)),
953
983
  type: union.type && await this.visitType(union.type, p)
954
- };
984
+ }));
955
985
  return updateIfChanged(union, updates);
956
986
  }
957
987
 
@@ -962,12 +992,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
962
992
  }
963
993
  intersection = expression as JS.Intersection;
964
994
 
965
- const updates: any = {
995
+ const updates: any = await this.visitChildrenOf(intersection, async () => ({
966
996
  prefix: await this.visitSpace(intersection.prefix, p),
967
997
  markers: await this.visitMarkers(intersection.markers, p),
968
998
  types: await mapAsync(intersection.types, item => this.visitRightPadded(item, p)),
969
999
  type: intersection.type && await this.visitType(intersection.type, p)
970
- };
1000
+ }));
971
1001
  return updateIfChanged(intersection, updates);
972
1002
  }
973
1003
 
@@ -978,11 +1008,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
978
1008
  }
979
1009
  void_ = expression as JS.Void;
980
1010
 
981
- const updates: any = {
1011
+ const updates: any = await this.visitChildrenOf(void_, async () => ({
982
1012
  prefix: await this.visitSpace(void_.prefix, p),
983
1013
  markers: await this.visitMarkers(void_.markers, p),
984
1014
  expression: await this.visitDefined<Expression>(void_.expression, p)
985
- };
1015
+ }));
986
1016
  return updateIfChanged(void_, updates);
987
1017
  }
988
1018
 
@@ -993,12 +1023,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
993
1023
  }
994
1024
  withStatement = statement as JS.WithStatement;
995
1025
 
996
- const updates: any = {
1026
+ const updates: any = await this.visitChildrenOf(withStatement, async () => ({
997
1027
  prefix: await this.visitSpace(withStatement.prefix, p),
998
1028
  markers: await this.visitMarkers(withStatement.markers, p),
999
1029
  expression: await this.visitDefined<J.ControlParentheses<Expression>>(withStatement.expression, p),
1000
1030
  body: await this.visitRightPadded(withStatement.body, p)
1001
- };
1031
+ }));
1002
1032
  return updateIfChanged(withStatement, updates);
1003
1033
  }
1004
1034
 
@@ -1009,14 +1039,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1009
1039
  }
1010
1040
  indexSignatureDeclaration = statement as JS.IndexSignatureDeclaration;
1011
1041
 
1012
- const updates: any = {
1042
+ const updates: any = await this.visitChildrenOf(indexSignatureDeclaration, async () => ({
1013
1043
  prefix: await this.visitSpace(indexSignatureDeclaration.prefix, p),
1014
1044
  markers: await this.visitMarkers(indexSignatureDeclaration.markers, p),
1015
1045
  modifiers: await mapAsync(indexSignatureDeclaration.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
1016
1046
  parameters: await this.visitContainer(indexSignatureDeclaration.parameters, p),
1017
1047
  typeExpression: await this.visitLeftPadded(indexSignatureDeclaration.typeExpression, p),
1018
1048
  type: indexSignatureDeclaration.type && await this.visitType(indexSignatureDeclaration.type, p)
1019
- };
1049
+ }));
1020
1050
  return updateIfChanged(indexSignatureDeclaration, updates);
1021
1051
  }
1022
1052
 
@@ -1027,7 +1057,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1027
1057
  }
1028
1058
  computedPropMethod = statement as JS.ComputedPropertyMethodDeclaration;
1029
1059
 
1030
- const updates: any = {
1060
+ const updates: any = await this.visitChildrenOf(computedPropMethod, async () => ({
1031
1061
  prefix: await this.visitSpace(computedPropMethod.prefix, p),
1032
1062
  markers: await this.visitMarkers(computedPropMethod.markers, p),
1033
1063
  leadingAnnotations: await mapAsync(computedPropMethod.leadingAnnotations, item => this.visitDefined<J.Annotation>(item, p)),
@@ -1038,7 +1068,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1038
1068
  parameters: await this.visitContainer(computedPropMethod.parameters, p),
1039
1069
  body: computedPropMethod.body && await this.visitDefined<J.Block>(computedPropMethod.body, p),
1040
1070
  methodType: computedPropMethod.methodType && (await this.visitType(computedPropMethod.methodType, p) as Type.Method)
1041
- };
1071
+ }));
1042
1072
  return updateIfChanged(computedPropMethod, updates);
1043
1073
  }
1044
1074
 
@@ -1049,12 +1079,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1049
1079
  }
1050
1080
  forOfLoop = statement as JS.ForOfLoop;
1051
1081
 
1052
- const updates: any = {
1082
+ const updates: any = await this.visitChildrenOf(forOfLoop, async () => ({
1053
1083
  prefix: await this.visitSpace(forOfLoop.prefix, p),
1054
1084
  markers: await this.visitMarkers(forOfLoop.markers, p),
1055
1085
  await: forOfLoop.await && await this.visitSpace(forOfLoop.await, p),
1056
1086
  loop: await this.visitDefined<J.ForEachLoop>(forOfLoop.loop, p)
1057
- };
1087
+ }));
1058
1088
  return updateIfChanged(forOfLoop, updates);
1059
1089
  }
1060
1090
 
@@ -1065,12 +1095,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1065
1095
  }
1066
1096
  forInLoop = statement as JS.ForInLoop;
1067
1097
 
1068
- const updates: any = {
1098
+ const updates: any = await this.visitChildrenOf(forInLoop, async () => ({
1069
1099
  prefix: await this.visitSpace(forInLoop.prefix, p),
1070
1100
  markers: await this.visitMarkers(forInLoop.markers, p),
1071
1101
  control: await this.visitDefined<JS.ForInLoop.Control>(forInLoop.control, p),
1072
1102
  body: await this.visitRightPadded(forInLoop.body, p)
1073
- };
1103
+ }));
1074
1104
  return updateIfChanged(forInLoop, updates);
1075
1105
  }
1076
1106
 
@@ -1081,14 +1111,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1081
1111
  }
1082
1112
  namespaceDeclaration = statement as JS.NamespaceDeclaration;
1083
1113
 
1084
- const updates: any = {
1114
+ const updates: any = await this.visitChildrenOf(namespaceDeclaration, async () => ({
1085
1115
  prefix: await this.visitSpace(namespaceDeclaration.prefix, p),
1086
1116
  markers: await this.visitMarkers(namespaceDeclaration.markers, p),
1087
1117
  modifiers: await mapAsync(namespaceDeclaration.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
1088
1118
  keywordType: await this.visitLeftPadded(namespaceDeclaration.keywordType, p),
1089
1119
  name: await this.visitRightPadded(namespaceDeclaration.name, p),
1090
1120
  body: namespaceDeclaration.body && await this.visitDefined<J.Block>(namespaceDeclaration.body, p)
1091
- };
1121
+ }));
1092
1122
  return updateIfChanged(namespaceDeclaration, updates);
1093
1123
  }
1094
1124
 
@@ -1099,12 +1129,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1099
1129
  }
1100
1130
  typeLiteral = expression as JS.TypeLiteral;
1101
1131
 
1102
- const updates: any = {
1132
+ const updates: any = await this.visitChildrenOf(typeLiteral, async () => ({
1103
1133
  prefix: await this.visitSpace(typeLiteral.prefix, p),
1104
1134
  markers: await this.visitMarkers(typeLiteral.markers, p),
1105
1135
  members: await this.visitDefined<J.Block>(typeLiteral.members, p),
1106
1136
  type: typeLiteral.type && await this.visitType(typeLiteral.type, p)
1107
- };
1137
+ }));
1108
1138
  return updateIfChanged(typeLiteral, updates);
1109
1139
  }
1110
1140
 
@@ -1115,12 +1145,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1115
1145
  }
1116
1146
  arrayBindingPattern = expression as JS.ArrayBindingPattern;
1117
1147
 
1118
- const updates: any = {
1148
+ const updates: any = await this.visitChildrenOf(arrayBindingPattern, async () => ({
1119
1149
  prefix: await this.visitSpace(arrayBindingPattern.prefix, p),
1120
1150
  markers: await this.visitMarkers(arrayBindingPattern.markers, p),
1121
1151
  elements: await this.visitContainer(arrayBindingPattern.elements, p),
1122
1152
  type: arrayBindingPattern.type && await this.visitType(arrayBindingPattern.type, p)
1123
- };
1153
+ }));
1124
1154
  return updateIfChanged(arrayBindingPattern, updates);
1125
1155
  }
1126
1156
 
@@ -1131,14 +1161,14 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1131
1161
  }
1132
1162
  bindingElement = statement as JS.BindingElement;
1133
1163
 
1134
- const updates: any = {
1164
+ const updates: any = await this.visitChildrenOf(bindingElement, async () => ({
1135
1165
  prefix: await this.visitSpace(bindingElement.prefix, p),
1136
1166
  markers: await this.visitMarkers(bindingElement.markers, p),
1137
1167
  propertyName: bindingElement.propertyName && await this.visitRightPadded(bindingElement.propertyName, p),
1138
1168
  name: await this.visitDefined<TypedTree>(bindingElement.name, p),
1139
1169
  initializer: bindingElement.initializer && await this.visitLeftPadded(bindingElement.initializer, p),
1140
1170
  variableType: bindingElement.variableType && (await this.visitType(bindingElement.variableType, p) as Type.Variable)
1141
- };
1171
+ }));
1142
1172
  return updateIfChanged(bindingElement, updates);
1143
1173
  }
1144
1174
 
@@ -1149,7 +1179,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1149
1179
  }
1150
1180
  exportDeclaration = statement as JS.ExportDeclaration;
1151
1181
 
1152
- const updates: any = {
1182
+ const updates: any = await this.visitChildrenOf(exportDeclaration, async () => ({
1153
1183
  prefix: await this.visitSpace(exportDeclaration.prefix, p),
1154
1184
  markers: await this.visitMarkers(exportDeclaration.markers, p),
1155
1185
  modifiers: await mapAsync(exportDeclaration.modifiers, item => this.visitDefined<J.Modifier>(item, p)),
@@ -1157,7 +1187,7 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1157
1187
  exportClause: exportDeclaration.exportClause && await this.visitDefined<Expression>(exportDeclaration.exportClause, p),
1158
1188
  moduleSpecifier: exportDeclaration.moduleSpecifier && await this.visitLeftPadded(exportDeclaration.moduleSpecifier, p),
1159
1189
  attributes: exportDeclaration.attributes && await this.visitDefined<JS.ImportAttributes>(exportDeclaration.attributes, p)
1160
- };
1190
+ }));
1161
1191
  return updateIfChanged(exportDeclaration, updates);
1162
1192
  }
1163
1193
 
@@ -1168,11 +1198,11 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1168
1198
  }
1169
1199
  exportAssignment = statement as JS.ExportAssignment;
1170
1200
 
1171
- const updates: any = {
1201
+ const updates: any = await this.visitChildrenOf(exportAssignment, async () => ({
1172
1202
  prefix: await this.visitSpace(exportAssignment.prefix, p),
1173
1203
  markers: await this.visitMarkers(exportAssignment.markers, p),
1174
1204
  expression: await this.visitLeftPadded<Expression>(exportAssignment.expression, p)
1175
- };
1205
+ }));
1176
1206
  return updateIfChanged(exportAssignment, updates);
1177
1207
  }
1178
1208
 
@@ -1183,12 +1213,12 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1183
1213
  }
1184
1214
  namedExports = expression as JS.NamedExports;
1185
1215
 
1186
- const updates: any = {
1216
+ const updates: any = await this.visitChildrenOf(namedExports, async () => ({
1187
1217
  prefix: await this.visitSpace(namedExports.prefix, p),
1188
1218
  markers: await this.visitMarkers(namedExports.markers, p),
1189
1219
  elements: await this.visitContainer(namedExports.elements, p),
1190
1220
  type: namedExports.type && await this.visitType(namedExports.type, p)
1191
- };
1221
+ }));
1192
1222
  return updateIfChanged(namedExports, updates);
1193
1223
  }
1194
1224
 
@@ -1199,13 +1229,13 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1199
1229
  }
1200
1230
  exportSpecifier = expression as JS.ExportSpecifier;
1201
1231
 
1202
- const updates: any = {
1232
+ const updates: any = await this.visitChildrenOf(exportSpecifier, async () => ({
1203
1233
  prefix: await this.visitSpace(exportSpecifier.prefix, p),
1204
1234
  markers: await this.visitMarkers(exportSpecifier.markers, p),
1205
1235
  typeOnly: await this.visitLeftPadded(exportSpecifier.typeOnly, p),
1206
1236
  specifier: await this.visitDefined<Expression>(exportSpecifier.specifier, p),
1207
1237
  type: exportSpecifier.type && await this.visitType(exportSpecifier.type, p)
1208
- };
1238
+ }));
1209
1239
  return updateIfChanged(exportSpecifier, updates);
1210
1240
  }
1211
1241
 
@@ -1293,3 +1323,21 @@ export class JavaScriptVisitor<P> extends JavaVisitor<P> {
1293
1323
  return super.accept(j, p);
1294
1324
  }
1295
1325
  }
1326
+
1327
+ /** The prefix that prints as `outer` and then `inner`. */
1328
+ function concatenated(outer: J.Space, inner: J.Space): J.Space {
1329
+ if (outer.comments.length === 0) {
1330
+ return {...inner, whitespace: outer.whitespace + inner.whitespace};
1331
+ }
1332
+ const last = outer.comments[outer.comments.length - 1];
1333
+ return {
1334
+ ...outer,
1335
+ comments: [...outer.comments.slice(0, -1), {...last, suffix: last.suffix + inner.whitespace}, ...inner.comments]
1336
+ };
1337
+ }
1338
+
1339
+ /** `inner`, led by each marker of `outer` it does not already hold, so they print as they did around it. */
1340
+ function withOuterMarkers(outer: Markers, inner: Markers): Markers {
1341
+ const added = outer.markers.filter(marker => !inner.markers.some(own => own.id === marker.id));
1342
+ return added.length === 0 ? inner : {...inner, markers: [...added, ...inner.markers]};
1343
+ }