@openrewrite/rewrite 8.91.2 → 8.91.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/execution.d.ts +8 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +31 -0
- package/dist/execution.js.map +1 -1
- package/dist/javascript/add-import.d.ts +64 -9
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +398 -71
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts +11 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +43 -9
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/binding.d.ts +10 -2
- package/dist/javascript/binding.d.ts.map +1 -1
- package/dist/javascript/binding.js +44 -71
- package/dist/javascript/binding.js.map +1 -1
- package/dist/javascript/comparator.d.ts +2 -0
- package/dist/javascript/comparator.d.ts.map +1 -1
- package/dist/javascript/comparator.js +5 -1
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/format/format.d.ts +5 -2
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +51 -11
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/minimum-viable-spacing-visitor.d.ts +19 -0
- package/dist/javascript/format/minimum-viable-spacing-visitor.d.ts.map +1 -1
- package/dist/javascript/format/minimum-viable-spacing-visitor.js +180 -7
- package/dist/javascript/format/minimum-viable-spacing-visitor.js.map +1 -1
- package/dist/javascript/format/prettier-format.d.ts +2 -1
- package/dist/javascript/format/prettier-format.d.ts.map +1 -1
- package/dist/javascript/format/prettier-format.js +33 -23
- package/dist/javascript/format/prettier-format.js.map +1 -1
- package/dist/javascript/index.d.ts +3 -3
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +21 -1
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/parser-utils.d.ts.map +1 -1
- package/dist/javascript/parser-utils.js +5 -9
- package/dist/javascript/parser-utils.js.map +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +48 -3
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/print.d.ts +1 -0
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js +9 -0
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/recipes/change-import.d.ts +6 -3
- package/dist/javascript/recipes/change-import.d.ts.map +1 -1
- package/dist/javascript/recipes/change-import.js +17 -277
- package/dist/javascript/recipes/change-import.js.map +1 -1
- package/dist/javascript/rpc.js +2 -0
- package/dist/javascript/rpc.js.map +1 -1
- package/dist/javascript/scope.d.ts +40 -7
- package/dist/javascript/scope.d.ts.map +1 -1
- package/dist/javascript/scope.js +182 -30
- package/dist/javascript/scope.js.map +1 -1
- package/dist/javascript/templating/bindings.js +2 -20
- package/dist/javascript/templating/bindings.js.map +1 -1
- package/dist/javascript/templating/comparator.d.ts +2 -0
- package/dist/javascript/templating/comparator.d.ts.map +1 -1
- package/dist/javascript/templating/comparator.js +25 -0
- package/dist/javascript/templating/comparator.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts +5 -0
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +30 -12
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/template.d.ts.map +1 -1
- package/dist/javascript/templating/template.js +6 -0
- package/dist/javascript/templating/template.js.map +1 -1
- package/dist/javascript/templating/types.d.ts +5 -0
- package/dist/javascript/templating/types.d.ts.map +1 -1
- package/dist/javascript/tree.d.ts +1 -0
- package/dist/javascript/tree.d.ts.map +1 -1
- package/dist/javascript/tree.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +14 -0
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +1 -0
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/parser.d.ts +6 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +23 -1
- package/dist/parser.js.map +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +5 -2
- package/dist/print.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/rpc/request/parse-project.d.ts +11 -1
- package/dist/rpc/request/parse-project.d.ts.map +1 -1
- package/dist/rpc/request/parse-project.js +7 -2
- package/dist/rpc/request/parse-project.js.map +1 -1
- package/dist/rpc/request/parse.d.ts +13 -1
- package/dist/rpc/request/parse.d.ts.map +1 -1
- package/dist/rpc/request/parse.js +8 -2
- package/dist/rpc/request/parse.js.map +1 -1
- package/package.json +1 -1
- package/src/execution.ts +23 -0
- package/src/javascript/add-import.ts +449 -78
- package/src/javascript/amd.ts +49 -10
- package/src/javascript/binding.ts +60 -74
- package/src/javascript/comparator.ts +6 -1
- package/src/javascript/format/format.ts +56 -12
- package/src/javascript/format/minimum-viable-spacing-visitor.ts +196 -7
- package/src/javascript/format/prettier-format.ts +35 -25
- package/src/javascript/index.ts +10 -3
- package/src/javascript/parser-utils.ts +5 -11
- package/src/javascript/parser.ts +65 -6
- package/src/javascript/print.ts +10 -0
- package/src/javascript/recipes/change-import.ts +19 -349
- package/src/javascript/rpc.ts +2 -0
- package/src/javascript/scope.ts +210 -31
- package/src/javascript/templating/bindings.ts +2 -25
- package/src/javascript/templating/comparator.ts +29 -2
- package/src/javascript/templating/engine.ts +41 -14
- package/src/javascript/templating/template.ts +6 -0
- package/src/javascript/templating/types.ts +6 -0
- package/src/javascript/tree.ts +1 -0
- package/src/javascript/type-mapping.ts +15 -0
- package/src/javascript/visitor.ts +1 -0
- package/src/parser.ts +24 -1
- package/src/print.ts +5 -2
- package/src/rpc/request/parse-project.ts +6 -2
- package/src/rpc/request/parse.ts +7 -2
|
@@ -86,9 +86,10 @@ export class MinimumViableSpacingVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
86
86
|
// e.g., "class DataTable<Row>" not "class DataTable <Row>"
|
|
87
87
|
// Note: body.prefix spacing (space before '{') is handled by SpacesVisitor, not here.
|
|
88
88
|
|
|
89
|
-
if (c.extends
|
|
89
|
+
if (c.extends) {
|
|
90
90
|
c = produce(c, draft => {
|
|
91
91
|
this.ensureSpace(draft.extends!.before);
|
|
92
|
+
this.ensureSpace(draft.extends!.element.prefix);
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
95
|
|
|
@@ -156,10 +157,9 @@ export class MinimumViableSpacingVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
156
157
|
protected async visitNewClass(newClass: J.NewClass, p: P): Promise<J | undefined> {
|
|
157
158
|
const ret = await super.visitNewClass(newClass, p) as J.NewClass;
|
|
158
159
|
return produce(ret, draft => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
160
|
+
// a parenthesized class expression separates itself from `new`
|
|
161
|
+
if (draft.class && draft.class.kind !== J.Kind.Parentheses) {
|
|
162
|
+
this.ensureSpace((draft.class as Draft<J>).prefix);
|
|
163
163
|
}
|
|
164
164
|
});
|
|
165
165
|
}
|
|
@@ -232,12 +232,54 @@ export class MinimumViableSpacingVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
232
232
|
return ret;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
+
protected async visitAlias(alias: JS.Alias, p: P): Promise<J | undefined> {
|
|
236
|
+
const ret = await super.visitAlias(alias, p) as JS.Alias;
|
|
237
|
+
return produce(ret, draft => {
|
|
238
|
+
this.ensureSpace(draft.propertyName.after);
|
|
239
|
+
this.ensureSpace(draft.alias.prefix);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
protected async visitAs(as_: JS.As, p: P): Promise<J | undefined> {
|
|
244
|
+
const ret = await super.visitAs(as_, p) as JS.As;
|
|
245
|
+
return produce(ret, draft => {
|
|
246
|
+
this.ensureSpace(draft.left.after);
|
|
247
|
+
this.ensureSpace(draft.right.prefix);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
protected async visitBinaryExtensions(jsBinary: JS.Binary, p: P): Promise<J | undefined> {
|
|
252
|
+
const ret = await super.visitBinaryExtensions(jsBinary, p) as JS.Binary;
|
|
253
|
+
// `in` is the only word operator here; the rest are punctuators that need no separation
|
|
254
|
+
if (ret.operator.element !== JS.Binary.Type.In) {
|
|
255
|
+
return ret;
|
|
256
|
+
}
|
|
257
|
+
return produce(ret, draft => {
|
|
258
|
+
this.ensureSpace(draft.operator.before);
|
|
259
|
+
this.ensureSpace(draft.right.prefix);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
protected async visitBreak(breakNode: J.Break, p: P): Promise<J | undefined> {
|
|
264
|
+
const ret = await super.visitBreak(breakNode, p) as J.Break;
|
|
265
|
+
return ret.label ? produce(ret, draft => {
|
|
266
|
+
this.ensureSpace(draft.label!.prefix);
|
|
267
|
+
}) : ret;
|
|
268
|
+
}
|
|
235
269
|
|
|
236
270
|
protected async visitCase(caseNode: J.Case, p: P): Promise<J | undefined> {
|
|
237
|
-
|
|
271
|
+
let c = await super.visitCase(caseNode, p) as J.Case;
|
|
272
|
+
|
|
273
|
+
// `default` prints without the `case` keyword, so its label needs no separator
|
|
274
|
+
const first = c.caseLabels.elements[0]?.element;
|
|
275
|
+
if (first && (first.kind !== J.Kind.Identifier || (first as J.Identifier).simpleName !== "default")) {
|
|
276
|
+
c = produce(c, draft => {
|
|
277
|
+
this.ensureSpace(draft.caseLabels.before);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
238
280
|
|
|
239
281
|
if (c.guard && c.caseLabels.elements.length > 0 && c.caseLabels.elements[c.caseLabels.elements.length - 1].after.whitespace === "") {
|
|
240
|
-
|
|
282
|
+
c = produce(c, draft => {
|
|
241
283
|
const last = draft.caseLabels.elements.length - 1;
|
|
242
284
|
draft.caseLabels.elements[last].after.whitespace = " ";
|
|
243
285
|
});
|
|
@@ -246,6 +288,153 @@ export class MinimumViableSpacingVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
246
288
|
return c;
|
|
247
289
|
}
|
|
248
290
|
|
|
291
|
+
protected async visitContinue(continueNode: J.Continue, p: P): Promise<J | undefined> {
|
|
292
|
+
const ret = await super.visitContinue(continueNode, p) as J.Continue;
|
|
293
|
+
return ret.label ? produce(ret, draft => {
|
|
294
|
+
this.ensureSpace(draft.label!.prefix);
|
|
295
|
+
}) : ret;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
protected async visitDelete(delete_: JS.Delete, p: P): Promise<J | undefined> {
|
|
299
|
+
const ret = await super.visitDelete(delete_, p) as JS.Delete;
|
|
300
|
+
return produce(ret, draft => {
|
|
301
|
+
this.ensureSpace(draft.expression.prefix);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
protected async visitExportAssignment(exportAssignment: JS.ExportAssignment, p: P): Promise<J | undefined> {
|
|
306
|
+
const ret = await super.visitExportAssignment(exportAssignment, p) as JS.ExportAssignment;
|
|
307
|
+
if (ret.exportEquals) {
|
|
308
|
+
return ret;
|
|
309
|
+
}
|
|
310
|
+
return produce(ret, draft => {
|
|
311
|
+
this.ensureSpace(draft.expression.before);
|
|
312
|
+
this.ensureSpace(draft.expression.element.prefix);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
protected async visitExportDeclaration(exportDeclaration: JS.ExportDeclaration, p: P): Promise<J | undefined> {
|
|
317
|
+
const ret = await super.visitExportDeclaration(exportDeclaration, p) as JS.ExportDeclaration;
|
|
318
|
+
return produce(ret, draft => {
|
|
319
|
+
if (draft.typeOnly.element) {
|
|
320
|
+
this.ensureSpace(draft.typeOnly.before);
|
|
321
|
+
}
|
|
322
|
+
// a namespace re-export ends its clause with the alias, unlike `}` or a bare `*`
|
|
323
|
+
if (draft.moduleSpecifier && draft.exportClause?.kind === JS.Kind.Alias) {
|
|
324
|
+
this.ensureSpace(draft.moduleSpecifier.before);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
protected async visitForInLoop(forInLoop: JS.ForInLoop, p: P): Promise<J | undefined> {
|
|
330
|
+
const ret = await super.visitForInLoop(forInLoop, p) as JS.ForInLoop;
|
|
331
|
+
return produce(ret, draft => {
|
|
332
|
+
this.ensureSpace(draft.control.variable.after);
|
|
333
|
+
this.ensureSpace(draft.control.iterable.element.prefix);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
protected async visitForOfLoop(forOfLoop: JS.ForOfLoop, p: P): Promise<J | undefined> {
|
|
338
|
+
const ret = await super.visitForOfLoop(forOfLoop, p) as JS.ForOfLoop;
|
|
339
|
+
return produce(ret, draft => {
|
|
340
|
+
this.ensureSpace(draft.loop.control.variable.after);
|
|
341
|
+
this.ensureSpace(draft.loop.control.iterable.element.prefix);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
protected async visitImportClause(importClause: JS.ImportClause, p: P): Promise<J | undefined> {
|
|
346
|
+
const ret = await super.visitImportClause(importClause, p) as JS.ImportClause;
|
|
347
|
+
return produce(ret, draft => {
|
|
348
|
+
// named bindings open with a punctuator, which separates itself from `import` and `type`
|
|
349
|
+
if (draft.typeOnly || draft.name) {
|
|
350
|
+
this.ensureSpace(draft.prefix);
|
|
351
|
+
}
|
|
352
|
+
if (draft.typeOnly && draft.name) {
|
|
353
|
+
this.ensureSpace(draft.name.element.prefix);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
protected async visitImportDeclaration(jsImport: JS.Import, p: P): Promise<J | undefined> {
|
|
359
|
+
const ret = await super.visitImportDeclaration(jsImport, p) as JS.Import;
|
|
360
|
+
// `from` prints only with a clause, and not at all in the `= require(...)` form; `}` separates
|
|
361
|
+
// named imports from it, and the specifier after it is always a string literal
|
|
362
|
+
const bindings = ret.importClause?.namedBindings;
|
|
363
|
+
if (!ret.importClause || !ret.moduleSpecifier || bindings?.kind === JS.Kind.NamedImports) {
|
|
364
|
+
return ret;
|
|
365
|
+
}
|
|
366
|
+
return produce(ret, draft => {
|
|
367
|
+
this.ensureSpace(draft.moduleSpecifier!.before);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
protected async visitInstanceOf(instanceOf: J.InstanceOf, p: P): Promise<J | undefined> {
|
|
372
|
+
const ret = await super.visitInstanceOf(instanceOf, p) as J.InstanceOf;
|
|
373
|
+
return produce(ret, draft => {
|
|
374
|
+
this.ensureSpace(draft.expression.after);
|
|
375
|
+
this.ensureSpace(draft.class.prefix);
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
protected async visitSatisfiesExpression(satisfies: JS.SatisfiesExpression, p: P): Promise<J | undefined> {
|
|
380
|
+
const ret = await super.visitSatisfiesExpression(satisfies, p) as JS.SatisfiesExpression;
|
|
381
|
+
return produce(ret, draft => {
|
|
382
|
+
this.ensureSpace(draft.satisfiesType.before);
|
|
383
|
+
this.ensureSpace(draft.satisfiesType.element.prefix);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
protected async visitScopedVariableDeclarations(scoped: JS.ScopedVariableDeclarations, p: P): Promise<J | undefined> {
|
|
388
|
+
const ret = await super.visitScopedVariableDeclarations(scoped, p) as JS.ScopedVariableDeclarations;
|
|
389
|
+
if (ret.modifiers.length === 0 || ret.variables.length === 0) {
|
|
390
|
+
return ret;
|
|
391
|
+
}
|
|
392
|
+
return produce(ret, draft => {
|
|
393
|
+
for (let i = 1; i < draft.modifiers.length; i++) {
|
|
394
|
+
this.ensureSpace(draft.modifiers[i].prefix);
|
|
395
|
+
}
|
|
396
|
+
this.ensureSpace(draft.variables[0].element.prefix);
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
protected async visitTypeOperator(typeOperator: JS.TypeOperator, p: P): Promise<J | undefined> {
|
|
401
|
+
const ret = await super.visitTypeOperator(typeOperator, p) as JS.TypeOperator;
|
|
402
|
+
return produce(ret, draft => {
|
|
403
|
+
this.ensureSpace(draft.expression.before);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
protected async visitTypePredicate(typePredicate: JS.TypePredicate, p: P): Promise<J | undefined> {
|
|
408
|
+
const ret = await super.visitTypePredicate(typePredicate, p) as JS.TypePredicate;
|
|
409
|
+
return produce(ret, draft => {
|
|
410
|
+
if (draft.asserts.element) {
|
|
411
|
+
this.ensureSpace(draft.parameterName.prefix);
|
|
412
|
+
}
|
|
413
|
+
if (draft.expression) {
|
|
414
|
+
this.ensureSpace(draft.expression.before);
|
|
415
|
+
this.ensureSpace(draft.expression.element.prefix);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
protected async visitVoid(void_: JS.Void, p: P): Promise<J | undefined> {
|
|
421
|
+
const ret = await super.visitVoid(void_, p) as JS.Void;
|
|
422
|
+
return produce(ret, draft => {
|
|
423
|
+
this.ensureSpace(draft.expression.prefix);
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
protected async visitYield(aYield: J.Yield, p: P): Promise<J | undefined> {
|
|
428
|
+
const ret = await super.visitYield(aYield, p) as J.Yield;
|
|
429
|
+
// `yield*` separates itself from the value
|
|
430
|
+
if (!ret.value || findMarker(ret, JS.Markers.DelegatedYield)) {
|
|
431
|
+
return ret;
|
|
432
|
+
}
|
|
433
|
+
return produce(ret, draft => {
|
|
434
|
+
this.ensureSpace(draft.value!.prefix);
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
249
438
|
private ensureSpace(spaceDraft: Draft<J.Space>) {
|
|
250
439
|
if (spaceDraft.whitespace.length === 0 && spaceDraft.comments.length === 0) {
|
|
251
440
|
spaceDraft.whitespace = " ";
|
|
@@ -357,6 +357,15 @@ function pruneNode(node: any, path: PathSegment[], pathIndex: number, target: an
|
|
|
357
357
|
return node;
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
+
// A compilation unit's statements are laid out at column 0, so nothing beside the target bears
|
|
361
|
+
// on how Prettier lays it out and the printed program can be the target alone.
|
|
362
|
+
if (node.kind === JS.Kind.CompilationUnit && segment.property === 'statements' && segment.index !== undefined) {
|
|
363
|
+
const statements = value as J.RightPadded<Statement>[];
|
|
364
|
+
return updateIfChanged(node, {
|
|
365
|
+
statements: [pruneNode(statements[segment.index], path, pathIndex + 1, target)]
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
360
369
|
// Handle J.Block#statements specially - prune siblings
|
|
361
370
|
if (node.kind === J.Kind.Block && segment.property === 'statements' && segment.index !== undefined) {
|
|
362
371
|
const statements = value as J.RightPadded<Statement>[];
|
|
@@ -430,10 +439,10 @@ function findByPath(tree: any, path: PathSegment[]): any {
|
|
|
430
439
|
if (value == null) return undefined;
|
|
431
440
|
|
|
432
441
|
if (Array.isArray(value) && segment.index !== undefined) {
|
|
433
|
-
//
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const index =
|
|
442
|
+
// In pruned statement lists the target is last, following siblings having been omitted
|
|
443
|
+
const isPrunedStatements = segment.property === 'statements' &&
|
|
444
|
+
(current.kind === J.Kind.Block || current.kind === JS.Kind.CompilationUnit);
|
|
445
|
+
const index = isPrunedStatements ? value.length - 1 : segment.index;
|
|
437
446
|
const item = value[index];
|
|
438
447
|
if (item == null) return undefined;
|
|
439
448
|
current = item;
|
|
@@ -474,6 +483,12 @@ export async function prettierFormatSubtree<T extends J>(
|
|
|
474
483
|
return undefined;
|
|
475
484
|
}
|
|
476
485
|
|
|
486
|
+
// Whatever stands between a statement and the top of its file is the file's business, so a whole
|
|
487
|
+
// statement keeps the prefix it came with. Prettier sees it, for the directives — a leading
|
|
488
|
+
// `prettier-ignore` — that a statement's own layout answers to.
|
|
489
|
+
const wholeStatement = path.length === 2 && path[0].property === 'statements' &&
|
|
490
|
+
path[0].index !== undefined && path[1].property === 'element';
|
|
491
|
+
|
|
477
492
|
// Prune the tree for efficient formatting and substitute the (potentially modified) target.
|
|
478
493
|
// This ensures that if the visitor modified the target before calling autoFormat,
|
|
479
494
|
// we format the modified content, not the original from the cursor.
|
|
@@ -492,7 +507,12 @@ export async function prettierFormatSubtree<T extends J>(
|
|
|
492
507
|
const reconciler = new WhitespaceReconciler();
|
|
493
508
|
const reconciled = reconciler.reconcile(target as J, formattedTarget as J, undefined, stopAfter);
|
|
494
509
|
|
|
495
|
-
|
|
510
|
+
// The walk that carries whitespace back pairs the two trees node for node, which a change to
|
|
511
|
+
// the code itself — Prettier dropping redundant parentheses, say — makes impossible
|
|
512
|
+
if (!reconciler.isCompatible()) {
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
return (wholeStatement ? {...reconciled as T, prefix: target.prefix} : reconciled as T);
|
|
496
516
|
}
|
|
497
517
|
|
|
498
518
|
/**
|
|
@@ -554,7 +574,8 @@ export function getPrettierStyle(
|
|
|
554
574
|
* @param p The visitor parameter
|
|
555
575
|
* @param cursor Optional cursor for subtree formatting
|
|
556
576
|
* @param stopAfter Optional tree to stop after
|
|
557
|
-
* @returns The formatted tree
|
|
577
|
+
* @returns The formatted tree, or `undefined` where Prettier's result cannot be carried back,
|
|
578
|
+
* leaving the caller to lay the tree out itself
|
|
558
579
|
*/
|
|
559
580
|
export async function applyPrettierFormatting<R extends J, P>(
|
|
560
581
|
tree: R,
|
|
@@ -589,31 +610,20 @@ export async function applyPrettierFormatting<R extends J, P>(
|
|
|
589
610
|
prettierVersion: prettierStyle.prettierVersion,
|
|
590
611
|
};
|
|
591
612
|
|
|
613
|
+
const wholeFile = t.kind === JS.Kind.CompilationUnit;
|
|
592
614
|
try {
|
|
593
|
-
if (
|
|
615
|
+
if (wholeFile) {
|
|
594
616
|
// Format and reconcile the entire compilation unit
|
|
595
617
|
const formatted = await prettierFormat(t as unknown as JS.CompilationUnit, prettierOpts, stopAfter as J | undefined);
|
|
596
618
|
return formatted as unknown as R;
|
|
597
619
|
}
|
|
598
620
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
console.warn('Prettier formatting: No cursor provided for subtree, returning with essential formatting only');
|
|
602
|
-
return t;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
// Use prettierFormatSubtree for subtree formatting
|
|
606
|
-
const formatted = await prettierFormatSubtree(t, cursor, prettierOpts, stopAfter as J | undefined);
|
|
607
|
-
if (formatted) {
|
|
608
|
-
return formatted as R;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// Subtree formatting failed, return with essential formatting applied
|
|
612
|
-
console.warn('Prettier formatting: Subtree formatting failed, returning with essential formatting only');
|
|
613
|
-
return t;
|
|
621
|
+
// Pruning and reconciling a subtree both go by where it sits in its file
|
|
622
|
+
return cursor && await prettierFormatSubtree(t, cursor, prettierOpts, stopAfter as J | undefined) as R | undefined;
|
|
614
623
|
} catch (e) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
624
|
+
console.warn('Prettier formatting failed:', e);
|
|
625
|
+
// The built-in visitors lay out every line they are given, so a whole file — the author's
|
|
626
|
+
// layout rather than a recipe's — keeps the one it came with; a subtree is handed on.
|
|
627
|
+
return wholeFile ? t : undefined;
|
|
618
628
|
}
|
|
619
629
|
}
|
package/src/javascript/index.ts
CHANGED
|
@@ -32,13 +32,20 @@ export * from "./tree-debug";
|
|
|
32
32
|
export * from "./project-parser";
|
|
33
33
|
|
|
34
34
|
export type {Scope} from "./scope";
|
|
35
|
-
|
|
35
|
+
// `cursorOf` is deliberately absent: a visitor of one's own reaches `this.cursor` directly, and
|
|
36
|
+
// the free functions that have no visitor to reach it through are already in this list.
|
|
37
|
+
export {
|
|
38
|
+
scopeOf, namesDeclaredIn, namesDeclaredWithin, namesUsedIn, bindingNames, deconflict,
|
|
39
|
+
isValueReference, declarationsOf, compilationUnitOf, walk
|
|
40
|
+
} from "./scope";
|
|
36
41
|
export type {QuoteChar, AddImportOptions} from "./add-import";
|
|
37
42
|
export {ImportStyle, moduleNameOf, AddImport} from "./add-import";
|
|
38
43
|
// AMD mechanics `recipes-ui5` builds on directly, beyond the `maybeBind` surface below.
|
|
39
|
-
export type {AmdBlock} from "./amd";
|
|
44
|
+
export type {AmdBlock, AmdCalleeOptions} from "./amd";
|
|
40
45
|
export {
|
|
41
|
-
DEFAULT_AMD_CALLEES, amdBlockOf,
|
|
46
|
+
DEFAULT_AMD_CALLEES, amdBlockOf, enclosingAmdBlock, present, elementsOf, parametersOf, identifierOf,
|
|
47
|
+
dependencyNames, parameterNames, bodyOf, references, namesUsed, lastSegment, derivedBindingName,
|
|
48
|
+
withDependency, withUnboundDependency, withoutDependencyAt,
|
|
42
49
|
RemoveAmdDependency, removeNewlyUnusedAmdBindings
|
|
43
50
|
} from "./amd";
|
|
44
51
|
export type {MaybeBindOptions, MaybeUnbindOptions, MaybeRebindOptions, ModuleBindings} from "./binding";
|
|
@@ -351,8 +351,9 @@ export function hasFlowAnnotation(sourceFile: ts.SourceFile) {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
export function checkSyntaxErrors(program: ts.Program, sourceFile: ts.SourceFile) {
|
|
354
|
-
|
|
355
|
-
//
|
|
354
|
+
// Only parse diagnostics decide whether a file gets an LST, so the visitor has to map every slot the
|
|
355
|
+
// parser fills — including ones the checker would reject — or the file loses text on print.
|
|
356
|
+
const diagnostics = program.getSyntacticDiagnostics(sourceFile);
|
|
356
357
|
let syntaxErrors : [errorMsg: string, errorCode: number][] = [];
|
|
357
358
|
if (diagnostics.length > 0) {
|
|
358
359
|
const errors = diagnostics.filter(d => (d.category === ts.DiagnosticCategory.Error) && isCriticalDiagnostic(d.code, sourceFile));
|
|
@@ -373,18 +374,11 @@ export function checkSyntaxErrors(program: ts.Program, sourceFile: ts.SourceFile
|
|
|
373
374
|
return syntaxErrors;
|
|
374
375
|
}
|
|
375
376
|
|
|
376
|
-
const additionalCriticalCodes = new Set([
|
|
377
|
-
// Syntax errors
|
|
378
|
-
17019, // "'{0}' at the end of a type is not valid TypeScript syntax. Did you mean to write '{1}'?"
|
|
379
|
-
17020, // "'{0}' at the start of a type is not valid TypeScript syntax. Did you mean to write '{1}'?"
|
|
380
|
-
|
|
381
|
-
// Other critical errors
|
|
382
|
-
]);
|
|
383
|
-
|
|
384
377
|
// errors code description available at https://github.com/microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json
|
|
385
378
|
const excludedCodes = new Set([
|
|
386
379
|
1039, // Initializers are not allowed in ambient contexts.
|
|
387
380
|
1064, // The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<{0}>'?
|
|
381
|
+
1101, // 'with' statements are not allowed in strict mode.
|
|
388
382
|
1107, // Jump target cannot cross function boundary.
|
|
389
383
|
1111, // Private field '{0}' must be declared in an enclosing class.
|
|
390
384
|
1117, // An object literal cannot have multiple properties with the same name.
|
|
@@ -446,7 +440,7 @@ function isCriticalDiagnostic(code: number, sourceFile: ts.SourceFile): boolean
|
|
|
446
440
|
}
|
|
447
441
|
}
|
|
448
442
|
|
|
449
|
-
return
|
|
443
|
+
return code > 1000 && code < 2000 && !excludedCodes.has(code);
|
|
450
444
|
}
|
|
451
445
|
|
|
452
446
|
export function isValidSurrogateRange(unicodeString: string): boolean {
|
package/src/javascript/parser.ts
CHANGED
|
@@ -79,6 +79,15 @@ function getScriptKindFromFileName(fileName: string): ts.ScriptKind {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* TypeScript's public typings model valid syntax only, so slots its parser still fills for invalid code —
|
|
84
|
+
* an initializer on a type member, a modifier on an object literal member — are missing from them.
|
|
85
|
+
*/
|
|
86
|
+
type WithInvalidSyntaxSlots<T> = T & {
|
|
87
|
+
initializer?: ts.Expression;
|
|
88
|
+
modifiers?: ts.NodeArray<ts.ModifierLike>;
|
|
89
|
+
};
|
|
90
|
+
|
|
82
91
|
export class JavaScriptParser extends Parser {
|
|
83
92
|
|
|
84
93
|
private readonly compilerOptions: ts.CompilerOptions;
|
|
@@ -379,14 +388,14 @@ export class JavaScriptParser extends Parser {
|
|
|
379
388
|
}
|
|
380
389
|
|
|
381
390
|
try {
|
|
382
|
-
yield produce(
|
|
391
|
+
yield await this.requirePrintEqualsInput(produce(
|
|
383
392
|
new JavaScriptParserVisitor(sourceFile, this.relativePath(input), typeMapping)
|
|
384
393
|
.visit(sourceFile) as SourceFile,
|
|
385
394
|
draft => {
|
|
386
395
|
if (this.styles) {
|
|
387
396
|
draft.markers = this.styles.reduce((m, s) => replaceMarkerByKind(m, s), draft.markers);
|
|
388
397
|
}
|
|
389
|
-
});
|
|
398
|
+
}), input, escapeLoneSurrogates(sourceFile.getFullText()));
|
|
390
399
|
} catch (error) {
|
|
391
400
|
yield this.error(input, error instanceof Error ? error : new Error('Parser threw unknown error: ' + error));
|
|
392
401
|
}
|
|
@@ -573,7 +582,12 @@ export class JavaScriptParserVisitor {
|
|
|
573
582
|
| ts.FunctionDeclaration | ts.ParameterDeclaration | ts.MethodDeclaration | ts.EnumDeclaration | ts.InterfaceDeclaration
|
|
574
583
|
| ts.PropertySignature | ts.ConstructorDeclaration | ts.ModuleDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration
|
|
575
584
|
| ts.ArrowFunction | ts.IndexSignatureDeclaration | ts.TypeAliasDeclaration | ts.ExportDeclaration | ts.ExportAssignment | ts.FunctionExpression
|
|
576
|
-
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration | ts.ImportDeclaration | ts.ImportEqualsDeclaration
|
|
585
|
+
| ts.ConstructorTypeNode | ts.TypeParameterDeclaration | ts.ImportDeclaration | ts.ImportEqualsDeclaration
|
|
586
|
+
| ts.PropertyAssignment | ts.ShorthandPropertyAssignment): J.Modifier[] {
|
|
587
|
+
if (ts.isPropertyAssignment(node) || ts.isShorthandPropertyAssignment(node)) {
|
|
588
|
+
const modifiers = (node as WithInvalidSyntaxSlots<typeof node>).modifiers;
|
|
589
|
+
return modifiers ? modifiers.filter(ts.isModifier).map(this.mapModifier) : [];
|
|
590
|
+
}
|
|
577
591
|
if (ts.isVariableStatement(node) || ts.isModuleDeclaration(node) || ts.isClassDeclaration(node) || ts.isEnumDeclaration(node)
|
|
578
592
|
|| ts.isInterfaceDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isParameter(node)
|
|
579
593
|
|| ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isArrowFunction(node)
|
|
@@ -1175,6 +1189,8 @@ export class JavaScriptParserVisitor {
|
|
|
1175
1189
|
visitPropertySignature(node: ts.PropertySignature): J.VariableDeclarations {
|
|
1176
1190
|
// FIXME We are mapping the literals in things like type ascii = { " ": 32; "!": 33; } to
|
|
1177
1191
|
// named variables, which is not a good use of this construct.
|
|
1192
|
+
|
|
1193
|
+
const initializer = (node as WithInvalidSyntaxSlots<ts.PropertySignature>).initializer;
|
|
1178
1194
|
return {
|
|
1179
1195
|
kind: J.Kind.VariableDeclarations,
|
|
1180
1196
|
id: randomId(),
|
|
@@ -1193,6 +1209,7 @@ export class JavaScriptParserVisitor {
|
|
|
1193
1209
|
draft.markers = this.maybeAddOptionalMarker(draft, node);
|
|
1194
1210
|
}) as VariableDeclarator,
|
|
1195
1211
|
dimensionsAfterName: [],
|
|
1212
|
+
initializer: initializer && this.leftPadded(this.prefix(node.getChildAt(node.getChildren().indexOf(initializer) - 1)), this.visit(initializer)),
|
|
1196
1213
|
variableType: this.mapVariableType(node)
|
|
1197
1214
|
},
|
|
1198
1215
|
emptySpace
|
|
@@ -1355,7 +1372,8 @@ export class JavaScriptParserVisitor {
|
|
|
1355
1372
|
|
|
1356
1373
|
private mapTypeInfo(node: ts.MethodDeclaration | ts.PropertyDeclaration | ts.VariableDeclaration | ts.ParameterDeclaration
|
|
1357
1374
|
| ts.PropertySignature | ts.MethodSignature | ts.ArrowFunction | ts.CallSignatureDeclaration | ts.GetAccessorDeclaration
|
|
1358
|
-
| ts.FunctionDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionExpression | ts.NamedTupleMember
|
|
1375
|
+
| ts.FunctionDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionExpression | ts.NamedTupleMember
|
|
1376
|
+
| ts.ConstructorDeclaration | ts.SetAccessorDeclaration): JS.TypeInfo | undefined {
|
|
1359
1377
|
return node.type && {
|
|
1360
1378
|
kind: JS.Kind.TypeInfo,
|
|
1361
1379
|
id: randomId(),
|
|
@@ -1397,6 +1415,7 @@ export class JavaScriptParserVisitor {
|
|
|
1397
1415
|
leadingAnnotations: this.mapDecorators(node),
|
|
1398
1416
|
modifiers: this.mapModifiers(node),
|
|
1399
1417
|
nameAnnotations: [],
|
|
1418
|
+
returnTypeExpression: this.mapTypeInfo(node),
|
|
1400
1419
|
name: {...this.mapIdentifier(constructorKeyword, constructorKeyword.getText(), false), type: methodType},
|
|
1401
1420
|
parameters: this.mapCommaSeparatedList(this.getParameterListNodes(node)),
|
|
1402
1421
|
dimensionsAfterName: [],
|
|
@@ -1416,6 +1435,7 @@ export class JavaScriptParserVisitor {
|
|
|
1416
1435
|
markers: emptyMarkers,
|
|
1417
1436
|
leadingAnnotations: this.mapDecorators(node),
|
|
1418
1437
|
modifiers: this.mapModifiers(node),
|
|
1438
|
+
typeParameters: node.typeParameters && this.mapTypeParametersAsObject(node),
|
|
1419
1439
|
returnTypeExpression: this.mapTypeInfo(node),
|
|
1420
1440
|
name: name as ComputedPropertyName,
|
|
1421
1441
|
parameters: this.mapCommaSeparatedList(this.getParameterListNodes(node)),
|
|
@@ -1431,6 +1451,7 @@ export class JavaScriptParserVisitor {
|
|
|
1431
1451
|
markers: emptyMarkers,
|
|
1432
1452
|
leadingAnnotations: this.mapDecorators(node),
|
|
1433
1453
|
modifiers: this.mapModifiers(node),
|
|
1454
|
+
typeParameters: node.typeParameters && this.mapTypeParametersAsObject(node),
|
|
1434
1455
|
returnTypeExpression: this.mapTypeInfo(node),
|
|
1435
1456
|
nameAnnotations: [],
|
|
1436
1457
|
name: name as J.Identifier,
|
|
@@ -1452,6 +1473,8 @@ export class JavaScriptParserVisitor {
|
|
|
1452
1473
|
markers: emptyMarkers,
|
|
1453
1474
|
leadingAnnotations: this.mapDecorators(node),
|
|
1454
1475
|
modifiers: this.mapModifiers(node),
|
|
1476
|
+
typeParameters: node.typeParameters && this.mapTypeParametersAsObject(node),
|
|
1477
|
+
returnTypeExpression: this.mapTypeInfo(node),
|
|
1455
1478
|
name: name as ComputedPropertyName,
|
|
1456
1479
|
parameters: this.mapCommaSeparatedList(this.getParameterListNodes(node)),
|
|
1457
1480
|
body: node.body && this.convert<J.Block>(node.body),
|
|
@@ -1466,6 +1489,8 @@ export class JavaScriptParserVisitor {
|
|
|
1466
1489
|
markers: emptyMarkers,
|
|
1467
1490
|
leadingAnnotations: this.mapDecorators(node),
|
|
1468
1491
|
modifiers: this.mapModifiers(node),
|
|
1492
|
+
typeParameters: node.typeParameters && this.mapTypeParametersAsObject(node),
|
|
1493
|
+
returnTypeExpression: this.mapTypeInfo(node),
|
|
1469
1494
|
nameAnnotations: [],
|
|
1470
1495
|
name: name as J.Identifier,
|
|
1471
1496
|
parameters: this.mapCommaSeparatedList(this.getParameterListNodes(node)),
|
|
@@ -4219,6 +4244,7 @@ export class JavaScriptParserVisitor {
|
|
|
4219
4244
|
id: randomId(),
|
|
4220
4245
|
prefix: this.prefix(node),
|
|
4221
4246
|
markers: emptyMarkers,
|
|
4247
|
+
modifiers: this.mapModifiers(node),
|
|
4222
4248
|
name: this.rightPadded(this.visit(node.name), this.suffix(node.name)),
|
|
4223
4249
|
assigmentToken: JS.PropertyAssignment.Token.Colon,
|
|
4224
4250
|
initializer: this.visit(node.initializer)
|
|
@@ -4231,6 +4257,7 @@ export class JavaScriptParserVisitor {
|
|
|
4231
4257
|
id: randomId(),
|
|
4232
4258
|
prefix: this.prefix(node),
|
|
4233
4259
|
markers: emptyMarkers,
|
|
4260
|
+
modifiers: this.mapModifiers(node),
|
|
4234
4261
|
name: this.rightPadded(this.visit(node.name), this.suffix(node.name)),
|
|
4235
4262
|
assigmentToken: JS.PropertyAssignment.Token.Equals,
|
|
4236
4263
|
initializer: node.objectAssignmentInitializer && this.visit(node.objectAssignmentInitializer)
|
|
@@ -4654,7 +4681,8 @@ export class JavaScriptParserVisitor {
|
|
|
4654
4681
|
}
|
|
4655
4682
|
|
|
4656
4683
|
private mapTypeParametersAsObject(node: ts.MethodDeclaration | ts.MethodSignature | ts.FunctionDeclaration
|
|
4657
|
-
| ts.CallSignatureDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionExpression | ts.ArrowFunction | ts.TypeAliasDeclaration | ts.FunctionTypeNode | ts.ConstructorTypeNode
|
|
4684
|
+
| ts.CallSignatureDeclaration | ts.ConstructSignatureDeclaration | ts.FunctionExpression | ts.ArrowFunction | ts.TypeAliasDeclaration | ts.FunctionTypeNode | ts.ConstructorTypeNode
|
|
4685
|
+
| ts.GetAccessorDeclaration | ts.SetAccessorDeclaration): J.TypeParameters | undefined {
|
|
4658
4686
|
const typeParameters = node.typeParameters;
|
|
4659
4687
|
if (!typeParameters) return undefined;
|
|
4660
4688
|
|
|
@@ -4806,6 +4834,8 @@ class FlowSyntaxNotSupportedError extends SyntaxError {
|
|
|
4806
4834
|
|
|
4807
4835
|
const SURR_FIRST = 0xD800;
|
|
4808
4836
|
const SURR_LAST = 0xDFFF;
|
|
4837
|
+
const HIGH_SURR_LAST = 0xDBFF;
|
|
4838
|
+
const LOW_SURR_FIRST = 0xDC00;
|
|
4809
4839
|
|
|
4810
4840
|
/**
|
|
4811
4841
|
* Extracts invalid UTF-16 surrogate pairs from a string literal's value source.
|
|
@@ -4819,6 +4849,26 @@ const SURR_LAST = 0xDFFF;
|
|
|
4819
4849
|
* 1. Unicode escape sequences (\uXXXX) where XXXX is in the surrogate range
|
|
4820
4850
|
* 2. Raw surrogate characters in the source (character codes 0xD800-0xDFFF)
|
|
4821
4851
|
*/
|
|
4852
|
+
/** The form {@link extractSurrogateEscapes} can hold, against which print idempotence is measured. */
|
|
4853
|
+
function escapeLoneSurrogates(source: string): string {
|
|
4854
|
+
let escaped = '';
|
|
4855
|
+
for (let j = 0; j < source.length; j++) {
|
|
4856
|
+
const charCode = source.charCodeAt(j);
|
|
4857
|
+
if (charCode >= SURR_FIRST && charCode <= SURR_LAST) {
|
|
4858
|
+
const next = source.charCodeAt(j + 1);
|
|
4859
|
+
if (charCode <= HIGH_SURR_LAST && next >= LOW_SURR_FIRST && next <= SURR_LAST) {
|
|
4860
|
+
escaped += source.charAt(j) + source.charAt(j + 1);
|
|
4861
|
+
j++;
|
|
4862
|
+
continue;
|
|
4863
|
+
}
|
|
4864
|
+
escaped += "\\u" + charCode.toString(16).toUpperCase().padStart(4, '0');
|
|
4865
|
+
continue;
|
|
4866
|
+
}
|
|
4867
|
+
escaped += source.charAt(j);
|
|
4868
|
+
}
|
|
4869
|
+
return escaped;
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4822
4872
|
function extractSurrogateEscapes(valueSource: string): { cleanedSource: string, unicodeEscapes: J.LiteralUnicodeEscape[] } {
|
|
4823
4873
|
const unicodeEscapes: J.LiteralUnicodeEscape[] = [];
|
|
4824
4874
|
let cleanedSource = '';
|
|
@@ -4842,8 +4892,17 @@ function extractSurrogateEscapes(valueSource: string): { cleanedSource: string,
|
|
|
4842
4892
|
}
|
|
4843
4893
|
}
|
|
4844
4894
|
|
|
4845
|
-
//
|
|
4895
|
+
// A raw surrogate pair spells one code point — an emoji, say — and is carried as itself. A lone
|
|
4896
|
+
// surrogate is not text on its own and does not survive serialization (#6599), so it is held as a
|
|
4897
|
+
// `\uXXXX` escape and prints back as one.
|
|
4846
4898
|
if (charCode >= SURR_FIRST && charCode <= SURR_LAST) {
|
|
4899
|
+
const next = valueSource.charCodeAt(j + 1);
|
|
4900
|
+
if (charCode <= HIGH_SURR_LAST && next >= LOW_SURR_FIRST && next <= SURR_LAST) {
|
|
4901
|
+
cleanedSource += c + valueSource.charAt(j + 1);
|
|
4902
|
+
cleanedIndex += 2;
|
|
4903
|
+
j++;
|
|
4904
|
+
continue;
|
|
4905
|
+
}
|
|
4847
4906
|
const codePoint = charCode.toString(16).toUpperCase().padStart(4, '0');
|
|
4848
4907
|
unicodeEscapes.push({ valueSourceIndex: cleanedIndex, codePoint });
|
|
4849
4908
|
continue;
|
package/src/javascript/print.ts
CHANGED
|
@@ -950,6 +950,13 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
950
950
|
return typeDeclaration;
|
|
951
951
|
}
|
|
952
952
|
|
|
953
|
+
override async visitUnknownSource(source: J.UnknownSource, p: PrintOutputCapture): Promise<J | undefined> {
|
|
954
|
+
await this.beforeSyntax(source, p);
|
|
955
|
+
p.append(source.text);
|
|
956
|
+
await this.afterSyntax(source, p);
|
|
957
|
+
return source;
|
|
958
|
+
}
|
|
959
|
+
|
|
953
960
|
override async visitLiteralType(literalType: JS.LiteralType, p: PrintOutputCapture): Promise<J | undefined> {
|
|
954
961
|
await this.beforeSyntax(literalType, p);
|
|
955
962
|
await this.visit(literalType.literal, p);
|
|
@@ -1413,6 +1420,9 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1413
1420
|
override async visitPropertyAssignment(propertyAssignment: JS.PropertyAssignment, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1414
1421
|
await this.beforeSyntax(propertyAssignment, p);
|
|
1415
1422
|
|
|
1423
|
+
for (const m of propertyAssignment.modifiers) {
|
|
1424
|
+
await this.visitModifier(m, p);
|
|
1425
|
+
}
|
|
1416
1426
|
await this.visitRightPadded(propertyAssignment.name, p);
|
|
1417
1427
|
|
|
1418
1428
|
if (propertyAssignment.initializer) {
|