@openrewrite/rewrite 8.92.16 → 8.92.18
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/README.md +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/java/formatting-utils.d.ts +2 -1
- package/dist/java/formatting-utils.d.ts.map +1 -1
- package/dist/java/formatting-utils.js +4 -3
- package/dist/java/formatting-utils.js.map +1 -1
- package/dist/java/rpc.d.ts.map +1 -1
- package/dist/java/rpc.js +2 -0
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/tree.d.ts +8 -0
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/tree.js +11 -1
- package/dist/java/tree.js.map +1 -1
- package/dist/java/type.d.ts +7 -1
- package/dist/java/type.d.ts.map +1 -1
- package/dist/java/type.js +16 -1
- package/dist/java/type.js.map +1 -1
- package/dist/javascript/add-import.d.ts +27 -21
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +303 -143
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +25 -10
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/autodetect.js +36 -45
- package/dist/javascript/autodetect.js.map +1 -1
- package/dist/javascript/binding.d.ts +6 -4
- package/dist/javascript/binding.d.ts.map +1 -1
- package/dist/javascript/binding.js +54 -18
- package/dist/javascript/binding.js.map +1 -1
- package/dist/javascript/comparator.d.ts +22 -5
- package/dist/javascript/comparator.d.ts.map +1 -1
- package/dist/javascript/comparator.js +120 -38
- package/dist/javascript/comparator.js.map +1 -1
- package/dist/javascript/format/format.d.ts +2 -0
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +11 -1
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +31 -4
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/index.d.ts +4 -2
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +10 -1
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/markers.d.ts +12 -0
- package/dist/javascript/markers.d.ts.map +1 -1
- package/dist/javascript/markers.js +81 -2
- package/dist/javascript/markers.js.map +1 -1
- package/dist/javascript/method-matcher.d.ts +13 -2
- package/dist/javascript/method-matcher.d.ts.map +1 -1
- package/dist/javascript/method-matcher.js +32 -19
- package/dist/javascript/method-matcher.js.map +1 -1
- package/dist/javascript/node-resolution-result.js +3 -2
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/package-name.d.ts +6 -0
- package/dist/javascript/package-name.d.ts.map +1 -0
- package/dist/javascript/package-name.js +47 -0
- package/dist/javascript/package-name.js.map +1 -0
- package/dist/javascript/parser.d.ts +9 -0
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +185 -88
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/preconditions.d.ts +4 -1
- package/dist/javascript/preconditions.d.ts.map +1 -1
- package/dist/javascript/preconditions.js +7 -4
- package/dist/javascript/preconditions.js.map +1 -1
- package/dist/javascript/print.d.ts +10 -1
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js +120 -77
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/recipes/change-method-target-to-import.d.ts +29 -0
- package/dist/javascript/recipes/change-method-target-to-import.d.ts.map +1 -0
- package/dist/javascript/recipes/change-method-target-to-import.js +164 -0
- package/dist/javascript/recipes/change-method-target-to-import.js.map +1 -0
- package/dist/javascript/recipes/index.d.ts +1 -0
- package/dist/javascript/recipes/index.d.ts.map +1 -1
- package/dist/javascript/recipes/index.js +1 -0
- package/dist/javascript/recipes/index.js.map +1 -1
- package/dist/javascript/scope.d.ts +60 -16
- package/dist/javascript/scope.d.ts.map +1 -1
- package/dist/javascript/scope.js +596 -131
- package/dist/javascript/scope.js.map +1 -1
- package/dist/javascript/search/uses-method.d.ts +1 -1
- package/dist/javascript/search/uses-method.d.ts.map +1 -1
- package/dist/javascript/search/uses-method.js +2 -2
- package/dist/javascript/search/uses-method.js.map +1 -1
- package/dist/javascript/search/uses-type.d.ts +14 -1
- package/dist/javascript/search/uses-type.d.ts.map +1 -1
- package/dist/javascript/search/uses-type.js +24 -9
- package/dist/javascript/search/uses-type.js.map +1 -1
- package/dist/javascript/templating/bindings.d.ts +1 -1
- package/dist/javascript/templating/bindings.d.ts.map +1 -1
- package/dist/javascript/templating/bindings.js +10 -50
- package/dist/javascript/templating/bindings.js.map +1 -1
- package/dist/javascript/templating/comparator.d.ts +8 -11
- package/dist/javascript/templating/comparator.d.ts.map +1 -1
- package/dist/javascript/templating/comparator.js +12 -110
- package/dist/javascript/templating/comparator.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts +34 -24
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +208 -115
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts +11 -5
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +86 -20
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts +34 -3
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +126 -60
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/templating/precedence.d.ts +3 -1
- package/dist/javascript/templating/precedence.d.ts.map +1 -1
- package/dist/javascript/templating/precedence.js +28 -8
- package/dist/javascript/templating/precedence.js.map +1 -1
- package/dist/javascript/templating/template.d.ts +7 -6
- package/dist/javascript/templating/template.d.ts.map +1 -1
- package/dist/javascript/templating/template.js +31 -28
- package/dist/javascript/templating/template.js.map +1 -1
- package/dist/javascript/templating/types.d.ts +6 -3
- package/dist/javascript/templating/types.d.ts.map +1 -1
- package/dist/javascript/templating/utils.d.ts +10 -1
- package/dist/javascript/templating/utils.d.ts.map +1 -1
- package/dist/javascript/templating/utils.js +22 -3
- package/dist/javascript/templating/utils.js.map +1 -1
- package/dist/javascript/tree-debug.d.ts +2 -0
- package/dist/javascript/tree-debug.d.ts.map +1 -1
- package/dist/javascript/tree-debug.js +6 -0
- package/dist/javascript/tree-debug.js.map +1 -1
- package/dist/javascript/tsconfig.d.ts.map +1 -1
- package/dist/javascript/tsconfig.js +7 -17
- package/dist/javascript/tsconfig.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +35 -16
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +271 -252
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/type-report-cli.d.ts +7 -0
- package/dist/javascript/type-report-cli.d.ts.map +1 -0
- package/dist/javascript/type-report-cli.js +129 -0
- package/dist/javascript/type-report-cli.js.map +1 -0
- package/dist/javascript/type-report.d.ts +61 -0
- package/dist/javascript/type-report.d.ts.map +1 -0
- package/dist/javascript/type-report.js +488 -0
- package/dist/javascript/type-report.js.map +1 -0
- package/dist/markers.d.ts +4 -0
- package/dist/markers.d.ts.map +1 -1
- package/dist/markers.js +8 -0
- package/dist/markers.js.map +1 -1
- package/dist/print.d.ts +6 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +21 -7
- package/dist/print.js.map +1 -1
- package/dist/recipe.d.ts +5 -0
- package/dist/recipe.d.ts.map +1 -1
- package/dist/recipe.js +5 -0
- package/dist/recipe.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/rpc/java-rpc-client.d.ts +2 -0
- package/dist/rpc/java-rpc-client.d.ts.map +1 -1
- package/dist/rpc/java-rpc-client.js +1 -0
- package/dist/rpc/java-rpc-client.js.map +1 -1
- package/dist/rpc/queue.d.ts +24 -0
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +71 -11
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/get-object.d.ts +4 -0
- package/dist/rpc/request/get-object.d.ts.map +1 -1
- package/dist/rpc/request/get-object.js +23 -1
- package/dist/rpc/request/get-object.js.map +1 -1
- package/dist/rpc/request/parse.d.ts.map +1 -1
- package/dist/rpc/request/parse.js +3 -1
- package/dist/rpc/request/parse.js.map +1 -1
- package/dist/rpc/request/prepare-recipe.d.ts +3 -1
- package/dist/rpc/request/prepare-recipe.d.ts.map +1 -1
- package/dist/rpc/request/prepare-recipe.js +13 -6
- package/dist/rpc/request/prepare-recipe.js.map +1 -1
- package/dist/rpc/request/print.d.ts +8 -2
- package/dist/rpc/request/print.d.ts.map +1 -1
- package/dist/rpc/request/print.js +12 -9
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts +3 -2
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +9 -3
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +19 -5
- package/dist/rpc/server.js.map +1 -1
- package/dist/search/is-source-file.d.ts +1 -0
- package/dist/search/is-source-file.d.ts.map +1 -1
- package/dist/search/is-source-file.js +7 -2
- package/dist/search/is-source-file.js.map +1 -1
- package/dist/test/java-rpc.d.ts.map +1 -1
- package/dist/test/java-rpc.js +3 -0
- package/dist/test/java-rpc.js.map +1 -1
- package/dist/test/rewrite-test.d.ts +5 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +14 -3
- package/dist/test/rewrite-test.js.map +1 -1
- package/package.json +4 -3
- package/src/index.ts +3 -1
- package/src/java/formatting-utils.ts +5 -4
- package/src/java/rpc.ts +2 -0
- package/src/java/tree.ts +15 -0
- package/src/java/type.ts +19 -2
- package/src/javascript/add-import.ts +338 -152
- package/src/javascript/amd.ts +28 -12
- package/src/javascript/autodetect.ts +32 -41
- package/src/javascript/binding.ts +64 -22
- package/src/javascript/comparator.ts +129 -43
- package/src/javascript/format/format.ts +9 -0
- package/src/javascript/format/tabs-and-indents-visitor.ts +30 -3
- package/src/javascript/index.ts +6 -3
- package/src/javascript/markers.ts +77 -5
- package/src/javascript/method-matcher.ts +34 -22
- package/src/javascript/node-resolution-result.ts +3 -2
- package/src/javascript/package-name.ts +45 -0
- package/src/javascript/parser.ts +200 -91
- package/src/javascript/preconditions.ts +7 -4
- package/src/javascript/print.ts +123 -76
- package/src/javascript/recipes/change-method-target-to-import.ts +178 -0
- package/src/javascript/recipes/index.ts +1 -0
- package/src/javascript/scope.ts +705 -169
- package/src/javascript/search/uses-method.ts +2 -2
- package/src/javascript/search/uses-type.ts +30 -9
- package/src/javascript/templating/bindings.ts +13 -38
- package/src/javascript/templating/comparator.ts +16 -127
- package/src/javascript/templating/engine.ts +236 -129
- package/src/javascript/templating/pattern.ts +107 -28
- package/src/javascript/templating/placeholder-replacement.ts +154 -62
- package/src/javascript/templating/precedence.ts +33 -11
- package/src/javascript/templating/template.ts +35 -30
- package/src/javascript/templating/types.ts +6 -3
- package/src/javascript/templating/utils.ts +24 -2
- package/src/javascript/tree-debug.ts +9 -0
- package/src/javascript/tsconfig.ts +7 -17
- package/src/javascript/type-mapping.ts +277 -255
- package/src/javascript/type-report-cli.ts +96 -0
- package/src/javascript/type-report.ts +575 -0
- package/src/markers.ts +8 -0
- package/src/print.ts +23 -8
- package/src/recipe.ts +6 -0
- package/src/rpc/java-rpc-client.ts +3 -0
- package/src/rpc/queue.ts +80 -7
- package/src/rpc/request/get-object.ts +24 -0
- package/src/rpc/request/parse.ts +4 -1
- package/src/rpc/request/prepare-recipe.ts +16 -6
- package/src/rpc/request/print.ts +12 -8
- package/src/rpc/rewrite-rpc.ts +16 -5
- package/src/rpc/server.ts +18 -6
- package/src/search/is-source-file.ts +8 -3
- package/src/test/java-rpc.ts +3 -0
- package/src/test/rewrite-test.ts +14 -3
|
@@ -68,6 +68,8 @@ export function isVendoredOrBundled(): RecipeRef {
|
|
|
68
68
|
* ``methodPattern`` follows the OpenRewrite method-pattern syntax:
|
|
69
69
|
* ``<receiver-type> <method-name>(<args>)`` — e.g.
|
|
70
70
|
* ``"*..* tostring(..)"`` or ``"java.util.Collections emptyList()"``.
|
|
71
|
+
* For a pattern that does not fire, ``REWRITE_JAVASCRIPT_DUMP_TYPES=1`` prints the
|
|
72
|
+
* declaring type each call got during the test run.
|
|
71
73
|
*
|
|
72
74
|
* Delegates to {@code org.openrewrite.java.search.HasMethod}.
|
|
73
75
|
*/
|
|
@@ -75,7 +77,7 @@ export function usesMethod(methodPattern: string, matchOverrides: boolean = fals
|
|
|
75
77
|
return new RecipeRef(
|
|
76
78
|
"org.openrewrite.java.search.HasMethod",
|
|
77
79
|
{methodPattern, matchOverrides},
|
|
78
|
-
new UsesMethod(methodPattern),
|
|
80
|
+
new UsesMethod(methodPattern, matchOverrides),
|
|
79
81
|
);
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -86,13 +88,14 @@ export function usesMethod(methodPattern: string, matchOverrides: boolean = fals
|
|
|
86
88
|
* {@link UsesType} visitor for in-process evaluation; see
|
|
87
89
|
* {@link hasSourcePath} for the introspection / lazy-evaluation pattern.
|
|
88
90
|
*
|
|
89
|
-
* Delegates to {@code org.openrewrite.java.search.HasType}
|
|
91
|
+
* Delegates to {@code org.openrewrite.java.search.HasType}, which matches a type through any class
|
|
92
|
+
* or interface it extends and reads `checkAssignability` as `UsesType`'s `includeImplicit`.
|
|
90
93
|
*/
|
|
91
94
|
export function usesType(fullyQualifiedTypeName: string, checkAssignability: boolean = false): RecipeRef {
|
|
92
95
|
return new RecipeRef(
|
|
93
96
|
"org.openrewrite.java.search.HasType",
|
|
94
97
|
{fullyQualifiedTypeName, checkAssignability},
|
|
95
|
-
new UsesType(fullyQualifiedTypeName),
|
|
98
|
+
new UsesType(fullyQualifiedTypeName, {assignable: true, includeImplicit: checkAssignability}),
|
|
96
99
|
);
|
|
97
100
|
}
|
|
98
101
|
|
|
@@ -109,7 +112,7 @@ export function findMethods(methodPattern: string, matchOverrides: boolean = fal
|
|
|
109
112
|
return new RecipeRef(
|
|
110
113
|
"org.openrewrite.java.search.FindMethods",
|
|
111
114
|
{methodPattern, matchOverrides},
|
|
112
|
-
new UsesMethod(methodPattern),
|
|
115
|
+
new UsesMethod(methodPattern, matchOverrides),
|
|
113
116
|
);
|
|
114
117
|
}
|
|
115
118
|
|
package/src/javascript/print.ts
CHANGED
|
@@ -21,7 +21,7 @@ import {PrintOutputCapture, TreePrinters} from "../print";
|
|
|
21
21
|
import {Cursor, isTree, Tree} from "../tree";
|
|
22
22
|
import {Comment, emptySpace, J, Statement, TextComment, TrailingComma, TypedTree} from "../java";
|
|
23
23
|
import {findMarker, Marker, Markers} from "../markers";
|
|
24
|
-
import {DelegatedYield, FunctionDeclaration, Generator, NonNullAssertion, Optional} from "./markers";
|
|
24
|
+
import {Computed, DelegatedYield, FunctionDeclaration, Generator, NonNullAssertion, Optional} from "./markers";
|
|
25
25
|
|
|
26
26
|
export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
27
27
|
|
|
@@ -140,10 +140,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
140
140
|
override async visitJsxAttribute(attribute: JSX.Attribute, p: PrintOutputCapture): Promise<J | undefined> {
|
|
141
141
|
await this.beforeSyntax(attribute, p);
|
|
142
142
|
await this.visit(attribute.key, p);
|
|
143
|
-
|
|
144
|
-
p.append("=");
|
|
145
|
-
await this.visit(attribute.value.element, p);
|
|
146
|
-
}
|
|
143
|
+
await this.visitLeftPaddedLocal("=", attribute.value, p);
|
|
147
144
|
await this.afterSyntax(attribute, p);
|
|
148
145
|
return attribute;
|
|
149
146
|
}
|
|
@@ -308,6 +305,10 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
308
305
|
p.append("catch");
|
|
309
306
|
if (aCatch.parameter.tree.element.variables.length > 0) {
|
|
310
307
|
await this.visit(aCatch.parameter, p);
|
|
308
|
+
} else {
|
|
309
|
+
this.beforeSyntaxMarkers(aCatch.parameter.markers, p);
|
|
310
|
+
await this.markersOnly(aCatch.parameter.tree.element, p);
|
|
311
|
+
await this.afterSyntax(aCatch.parameter, p);
|
|
311
312
|
}
|
|
312
313
|
await this.visit(aCatch.body, p);
|
|
313
314
|
await this.afterSyntax(aCatch, p);
|
|
@@ -662,15 +663,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
662
663
|
if (functionType.constructorType.element) {
|
|
663
664
|
await this.visitLeftPaddedLocal("new", functionType.constructorType, p);
|
|
664
665
|
}
|
|
665
|
-
|
|
666
|
-
if (typeParameters) {
|
|
667
|
-
await this.visitNodes(typeParameters.annotations, p);
|
|
668
|
-
await this.visitSpace(typeParameters.prefix, p);
|
|
669
|
-
await this.visitMarkers(typeParameters.markers, p);
|
|
670
|
-
p.append("<");
|
|
671
|
-
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
672
|
-
p.append(">");
|
|
673
|
-
}
|
|
666
|
+
await this.printTypeParameters(functionType.typeParameters, p);
|
|
674
667
|
|
|
675
668
|
await this.visitContainerLocal("(", functionType.parameters, ",", ")", p);
|
|
676
669
|
await this.visitLeftPaddedLocal("=>", functionType.returnType, p);
|
|
@@ -679,9 +672,9 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
679
672
|
return functionType;
|
|
680
673
|
}
|
|
681
674
|
|
|
682
|
-
override async
|
|
675
|
+
override async visitClassDeclarationKind(classKind: J.ClassDeclaration.Kind, p: PrintOutputCapture): Promise<J | undefined> {
|
|
683
676
|
let kind = "";
|
|
684
|
-
switch (
|
|
677
|
+
switch (classKind.type) {
|
|
685
678
|
case J.ClassDeclaration.Kind.Type.Class:
|
|
686
679
|
kind = "class";
|
|
687
680
|
break;
|
|
@@ -699,15 +692,21 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
699
692
|
break;
|
|
700
693
|
}
|
|
701
694
|
|
|
695
|
+
await this.visitNodes(classKind.annotations, p);
|
|
696
|
+
await this.beforeSyntax(classKind, p);
|
|
697
|
+
p.append(kind);
|
|
698
|
+
await this.afterSyntax(classKind, p);
|
|
699
|
+
return classKind;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
override async visitClassDeclaration(classDecl: J.ClassDeclaration, p: PrintOutputCapture): Promise<J | undefined> {
|
|
702
703
|
await this.beforeSyntax(classDecl, p);
|
|
703
704
|
await this.visitSpace(emptySpace, p);
|
|
704
705
|
await this.visitNodes(classDecl.leadingAnnotations, p);
|
|
705
706
|
for (const m of classDecl.modifiers) {
|
|
706
707
|
await this.visitModifier(m, p);
|
|
707
708
|
}
|
|
708
|
-
await this.
|
|
709
|
-
await this.visitSpace(classDecl.classKind.prefix, p);
|
|
710
|
-
p.append(kind);
|
|
709
|
+
await this.visitClassDeclarationKind(classDecl.classKind, p);
|
|
711
710
|
await this.visit(classDecl.name, p);
|
|
712
711
|
classDecl.typeParameters && await this.visitContainerLocal("<", classDecl.typeParameters, ",", ">", p);
|
|
713
712
|
classDecl.primaryConstructor && await this.visitContainerLocal("(", classDecl.primaryConstructor, ",", ")", p);
|
|
@@ -727,6 +726,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
727
726
|
for (const m of method.modifiers) {
|
|
728
727
|
await this.visitModifier(m, p);
|
|
729
728
|
}
|
|
729
|
+
await this.visitNodes(method.nameAnnotations, p);
|
|
730
730
|
|
|
731
731
|
let m;
|
|
732
732
|
if ((m = findMarker<FunctionDeclaration>(method, JS.Markers.FunctionDeclaration))) {
|
|
@@ -742,15 +742,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
742
742
|
|
|
743
743
|
await this.visit(method.name, p);
|
|
744
744
|
|
|
745
|
-
|
|
746
|
-
if (typeParameters) {
|
|
747
|
-
await this.visitNodes(typeParameters.annotations, p);
|
|
748
|
-
await this.visitSpace(typeParameters.prefix, p);
|
|
749
|
-
await this.visitMarkers(typeParameters.markers, p);
|
|
750
|
-
p.append("<");
|
|
751
|
-
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
752
|
-
p.append(">");
|
|
753
|
-
}
|
|
745
|
+
await this.printTypeParameters(method.typeParameters, p);
|
|
754
746
|
|
|
755
747
|
await this.visitContainerLocal("(", method.parameters, ",", ")", p);
|
|
756
748
|
|
|
@@ -779,15 +771,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
779
771
|
|
|
780
772
|
await this.visit(method.name, p);
|
|
781
773
|
|
|
782
|
-
|
|
783
|
-
if (typeParameters) {
|
|
784
|
-
await this.visitNodes(typeParameters.annotations, p);
|
|
785
|
-
await this.visitSpace(typeParameters.prefix, p);
|
|
786
|
-
await this.visitMarkers(typeParameters.markers, p);
|
|
787
|
-
p.append("<");
|
|
788
|
-
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
789
|
-
p.append(">");
|
|
790
|
-
}
|
|
774
|
+
await this.printTypeParameters(method.typeParameters, p);
|
|
791
775
|
|
|
792
776
|
await this.visitContainerLocal("(", method.parameters, ",", ")", p);
|
|
793
777
|
if (method.returnTypeExpression) {
|
|
@@ -839,12 +823,16 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
839
823
|
if (!(constraintType.element.kind === J.Kind.Empty)) {
|
|
840
824
|
p.append("extends");
|
|
841
825
|
await this.visitRightPadded(constraintType, p);
|
|
826
|
+
} else {
|
|
827
|
+
await this.markersOnly(constraintType.element, p);
|
|
842
828
|
}
|
|
843
829
|
|
|
844
830
|
const defaultType = bounds.elements[1];
|
|
845
831
|
if (!(defaultType.element.kind === J.Kind.Empty)) {
|
|
846
832
|
p.append("=");
|
|
847
833
|
await this.visitRightPadded(defaultType, p);
|
|
834
|
+
} else {
|
|
835
|
+
await this.markersOnly(defaultType.element, p);
|
|
848
836
|
}
|
|
849
837
|
}
|
|
850
838
|
|
|
@@ -859,26 +847,21 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
859
847
|
await this.visitModifier(m, p);
|
|
860
848
|
}
|
|
861
849
|
|
|
862
|
-
|
|
863
|
-
if (typeParameters) {
|
|
864
|
-
await this.visitNodes(typeParameters.annotations, p);
|
|
865
|
-
await this.visitSpace(typeParameters.prefix, p);
|
|
866
|
-
await this.visitMarkers(typeParameters.markers, p);
|
|
867
|
-
p.append("<");
|
|
868
|
-
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
869
|
-
p.append(">");
|
|
870
|
-
}
|
|
850
|
+
await this.printTypeParameters(arrowFunction.typeParameters, p);
|
|
871
851
|
|
|
872
852
|
const lambda = arrowFunction.lambda;
|
|
853
|
+
this.beforeSyntaxMarkers(lambda.markers, p);
|
|
873
854
|
|
|
874
855
|
if (lambda.parameters.parenthesized) {
|
|
875
|
-
await this.
|
|
856
|
+
await this.beforeSyntax(lambda.parameters, p);
|
|
876
857
|
p.append("(");
|
|
877
858
|
await this.visitRightPaddedLocal(lambda.parameters.parameters, ",", p);
|
|
878
859
|
p.append(")");
|
|
879
860
|
} else {
|
|
861
|
+
this.beforeSyntaxMarkers(lambda.parameters.markers, p);
|
|
880
862
|
await this.visitRightPaddedLocal(lambda.parameters.parameters, ",", p);
|
|
881
863
|
}
|
|
864
|
+
await this.afterSyntax(lambda.parameters, p);
|
|
882
865
|
|
|
883
866
|
if (arrowFunction.returnTypeExpression) {
|
|
884
867
|
await this.visit(arrowFunction.returnTypeExpression, p);
|
|
@@ -887,6 +870,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
887
870
|
await this.visitSpace(lambda.arrow, p);
|
|
888
871
|
p.append("=>");
|
|
889
872
|
await this.visit(lambda.body, p);
|
|
873
|
+
await this.afterSyntax(lambda, p);
|
|
890
874
|
|
|
891
875
|
await this.afterSyntax(arrowFunction, p);
|
|
892
876
|
return arrowFunction;
|
|
@@ -934,15 +918,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
934
918
|
|
|
935
919
|
await this.visitLeftPaddedLocal("type", typeDeclaration.name, p);
|
|
936
920
|
|
|
937
|
-
|
|
938
|
-
if (typeParameters) {
|
|
939
|
-
await this.visitNodes(typeParameters.annotations, p);
|
|
940
|
-
await this.visitSpace(typeParameters.prefix, p);
|
|
941
|
-
await this.visitMarkers(typeParameters.markers, p);
|
|
942
|
-
p.append("<");
|
|
943
|
-
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
944
|
-
p.append(">");
|
|
945
|
-
}
|
|
921
|
+
await this.printTypeParameters(typeDeclaration.typeParameters, p);
|
|
946
922
|
|
|
947
923
|
await this.visitLeftPaddedLocal("=", typeDeclaration.initializer, p);
|
|
948
924
|
|
|
@@ -985,11 +961,11 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
985
961
|
}
|
|
986
962
|
|
|
987
963
|
override async visitExportDeclaration(ed: JS.ExportDeclaration, p: PrintOutputCapture): Promise<J | undefined> {
|
|
988
|
-
await this.beforeSyntax(ed, p);
|
|
989
|
-
p.append("export");
|
|
990
964
|
for (const it of ed.modifiers) {
|
|
991
965
|
await this.visitModifier(it, p);
|
|
992
966
|
}
|
|
967
|
+
await this.beforeSyntax(ed, p);
|
|
968
|
+
p.append("export");
|
|
993
969
|
|
|
994
970
|
if (ed.typeOnly.element) {
|
|
995
971
|
await this.visitLeftPaddedLocal("type", ed.typeOnly, p);
|
|
@@ -1520,16 +1496,22 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1520
1496
|
|
|
1521
1497
|
override async visitEnumValue(enum_: J.EnumValue, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1522
1498
|
await this.beforeSyntax(enum_, p);
|
|
1499
|
+
const computed = findMarker<Computed>(enum_.name, JS.Markers.Computed);
|
|
1500
|
+
computed && p.append("[");
|
|
1523
1501
|
await this.visit(enum_.name, p);
|
|
1502
|
+
if (computed) {
|
|
1503
|
+
await this.visitSpace(computed.suffix, p);
|
|
1504
|
+
p.append("]");
|
|
1505
|
+
}
|
|
1524
1506
|
|
|
1525
1507
|
const initializer = enum_.initializer;
|
|
1526
1508
|
if (initializer) {
|
|
1527
|
-
await this.
|
|
1509
|
+
await this.beforeSyntax(initializer, p);
|
|
1528
1510
|
p.append("=");
|
|
1529
1511
|
// There can be only one argument
|
|
1530
1512
|
const expression = initializer.arguments.elements[0];
|
|
1531
1513
|
await this.visitRightPadded(expression, p);
|
|
1532
|
-
|
|
1514
|
+
await this.afterSyntax(initializer, p);
|
|
1533
1515
|
}
|
|
1534
1516
|
|
|
1535
1517
|
await this.afterSyntax(enum_, p);
|
|
@@ -1717,13 +1699,14 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1717
1699
|
await this.beforeSyntax(forLoop, p);
|
|
1718
1700
|
p.append("for");
|
|
1719
1701
|
const ctrl = forLoop.control;
|
|
1720
|
-
await this.
|
|
1702
|
+
await this.beforeSyntax(ctrl, p);
|
|
1721
1703
|
p.append('(');
|
|
1722
1704
|
await this.visitRightPaddedLocal(ctrl.init, ",", p);
|
|
1723
1705
|
p.append(';');
|
|
1724
1706
|
ctrl.condition && await this.visitRightPaddedLocalSingle(ctrl.condition, ";", p);
|
|
1725
1707
|
await this.visitRightPaddedLocal(ctrl.update, ",", p);
|
|
1726
1708
|
p.append(')');
|
|
1709
|
+
await this.afterSyntax(ctrl, p);
|
|
1727
1710
|
await this.visitStatementLocal(forLoop.body, p);
|
|
1728
1711
|
await this.afterSyntax(forLoop, p);
|
|
1729
1712
|
return forLoop;
|
|
@@ -1737,14 +1720,17 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1737
1720
|
p.append("await");
|
|
1738
1721
|
}
|
|
1739
1722
|
|
|
1723
|
+
this.beforeSyntaxMarkers(loop.loop.markers, p);
|
|
1740
1724
|
const control = loop.loop.control;
|
|
1741
|
-
await this.
|
|
1725
|
+
await this.beforeSyntax(control, p);
|
|
1742
1726
|
p.append('(');
|
|
1743
1727
|
await this.visitRightPadded(control.variable, p);
|
|
1744
1728
|
p.append("of");
|
|
1745
1729
|
await this.visitRightPadded(control.iterable, p);
|
|
1746
1730
|
p.append(')');
|
|
1731
|
+
await this.afterSyntax(control, p);
|
|
1747
1732
|
await this.visitRightPadded(loop.loop.body, p);
|
|
1733
|
+
await this.afterSyntax(loop.loop, p);
|
|
1748
1734
|
await this.afterSyntax(loop, p);
|
|
1749
1735
|
return loop;
|
|
1750
1736
|
}
|
|
@@ -1754,12 +1740,13 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1754
1740
|
p.append("for");
|
|
1755
1741
|
|
|
1756
1742
|
const control = loop.control;
|
|
1757
|
-
await this.
|
|
1743
|
+
await this.beforeSyntax(control, p);
|
|
1758
1744
|
p.append('(');
|
|
1759
1745
|
await this.visitRightPadded(control.variable, p);
|
|
1760
1746
|
p.append("in");
|
|
1761
1747
|
await this.visitRightPadded(control.iterable, p);
|
|
1762
1748
|
p.append(')');
|
|
1749
|
+
await this.afterSyntax(control, p);
|
|
1763
1750
|
await this.visitRightPadded(loop.body, p);
|
|
1764
1751
|
await this.afterSyntax(loop, p);
|
|
1765
1752
|
return loop;
|
|
@@ -1769,8 +1756,8 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1769
1756
|
|
|
1770
1757
|
private async visitStatements(statements: J.RightPadded<Statement>[], p: PrintOutputCapture) {
|
|
1771
1758
|
const objectLiteral =
|
|
1772
|
-
this.
|
|
1773
|
-
this.
|
|
1759
|
+
this.cursor.value.kind === J.Kind.Block &&
|
|
1760
|
+
this.parentTree()?.kind === J.Kind.NewClass;
|
|
1774
1761
|
|
|
1775
1762
|
for (let i = 0; i < statements.length; i++) {
|
|
1776
1763
|
const paddedStat = statements[i];
|
|
@@ -1789,13 +1776,73 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1789
1776
|
}
|
|
1790
1777
|
}
|
|
1791
1778
|
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1779
|
+
// A cursor handed in by a caller holds the padding between a tree and the tree enclosing it.
|
|
1780
|
+
private parentTree(): Tree | undefined {
|
|
1781
|
+
return this.cursor.parentTree()?.value;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
override async visitArrayAccess(arrayAccess: J.ArrayAccess, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1785
|
+
await this.beforeSyntax(arrayAccess, p);
|
|
1786
|
+
await this.visit(arrayAccess.indexed, p);
|
|
1787
|
+
await this.visit(arrayAccess.dimension, p);
|
|
1788
|
+
await this.afterSyntax(arrayAccess, p);
|
|
1789
|
+
return arrayAccess;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
override async visitTypeCast(typeCast: J.TypeCast, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1793
|
+
await this.beforeSyntax(typeCast, p);
|
|
1794
|
+
await this.visit(typeCast.class, p);
|
|
1795
|
+
await this.visit(typeCast.expression, p);
|
|
1796
|
+
await this.afterSyntax(typeCast, p);
|
|
1797
|
+
return typeCast;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
override async visitParenthesizedTypeTree(parTypeTree: J.ParenthesizedTypeTree, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1801
|
+
await this.beforeSyntax(parTypeTree, p);
|
|
1802
|
+
await this.visitNodes(parTypeTree.annotations, p);
|
|
1803
|
+
await this.visit(parTypeTree.parenthesizedType, p);
|
|
1804
|
+
await this.afterSyntax(parTypeTree, p);
|
|
1805
|
+
return parTypeTree;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
override async visitEmpty(empty: J.Empty, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1809
|
+
await this.beforeSyntax(empty, p);
|
|
1810
|
+
await this.afterSyntax(empty, p);
|
|
1811
|
+
return empty;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
override async visitUnknown(unknown: J.Unknown, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1815
|
+
await this.beforeSyntax(unknown, p);
|
|
1816
|
+
await this.visit(unknown.source, p);
|
|
1817
|
+
await this.afterSyntax(unknown, p);
|
|
1818
|
+
return unknown;
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
private async printTypeParameters(typeParameters: J.TypeParameters | undefined, p: PrintOutputCapture) {
|
|
1822
|
+
if (typeParameters) {
|
|
1823
|
+
await this.visitNodes(typeParameters.annotations, p);
|
|
1824
|
+
await this.beforeSyntaxExt(typeParameters.prefix, typeParameters.markers, p);
|
|
1825
|
+
p.append("<");
|
|
1826
|
+
await this.visitRightPaddedLocal(typeParameters.typeParameters, ",", p);
|
|
1827
|
+
p.append(">");
|
|
1828
|
+
await this.afterSyntaxMarkers(typeParameters.markers, p);
|
|
1796
1829
|
}
|
|
1830
|
+
}
|
|
1797
1831
|
|
|
1798
|
-
|
|
1832
|
+
// A tree that stands for something left out of the source is still printed where a recipe marked it.
|
|
1833
|
+
private async markersOnly(j: J, p: PrintOutputCapture) {
|
|
1834
|
+
this.beforeSyntaxMarkers(j.markers, p);
|
|
1835
|
+
await this.afterSyntax(j, p);
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
// For a tree printed as part of another, whose prefix is not printed.
|
|
1839
|
+
private beforeSyntaxMarkers(markers: Markers, p: PrintOutputCapture) {
|
|
1840
|
+
for (const marker of markers.markers) {
|
|
1841
|
+
p.append(p.markerPrinter.beforePrefix(marker, new Cursor(marker, this.cursor), this.JAVA_SCRIPT_MARKER_WRAPPER));
|
|
1842
|
+
}
|
|
1843
|
+
for (const marker of markers.markers) {
|
|
1844
|
+
p.append(p.markerPrinter.beforeSyntax(marker, new Cursor(marker, this.cursor), this.JAVA_SCRIPT_MARKER_WRAPPER));
|
|
1845
|
+
}
|
|
1799
1846
|
}
|
|
1800
1847
|
|
|
1801
1848
|
protected async afterSyntax(j: J, p: PrintOutputCapture) {
|
|
@@ -1940,10 +1987,10 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1940
1987
|
}
|
|
1941
1988
|
if (marker.kind === JS.Markers.Optional) {
|
|
1942
1989
|
await this.visitSpace((marker as Optional).prefix, p);
|
|
1943
|
-
|
|
1944
|
-
|
|
1990
|
+
const parent = this.parentTree()?.kind;
|
|
1991
|
+
if (parent !== J.Kind.MethodInvocation && parent !== JS.Kind.FunctionCall) {
|
|
1945
1992
|
p.append("?");
|
|
1946
|
-
if (
|
|
1993
|
+
if (parent === J.Kind.ArrayAccess) {
|
|
1947
1994
|
p.append(".");
|
|
1948
1995
|
}
|
|
1949
1996
|
}
|
|
@@ -1954,7 +2001,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1954
2001
|
|
|
1955
2002
|
private printComment(comment: Comment, cursor: Cursor, p: PrintOutputCapture): void {
|
|
1956
2003
|
for (const marker of comment.markers.markers) {
|
|
1957
|
-
p.append(p.markerPrinter.beforeSyntax(marker, new Cursor(
|
|
2004
|
+
p.append(p.markerPrinter.beforeSyntax(marker, new Cursor(comment, cursor), this.JAVA_SCRIPT_MARKER_WRAPPER));
|
|
1958
2005
|
}
|
|
1959
2006
|
|
|
1960
2007
|
if (comment.kind === J.Kind.TextComment) {
|
|
@@ -1963,7 +2010,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1963
2010
|
}
|
|
1964
2011
|
|
|
1965
2012
|
for (const marker of comment.markers.markers) {
|
|
1966
|
-
p.append(p.markerPrinter.afterSyntax(marker, new Cursor(
|
|
2013
|
+
p.append(p.markerPrinter.afterSyntax(marker, new Cursor(comment, cursor), this.JAVA_SCRIPT_MARKER_WRAPPER));
|
|
1967
2014
|
}
|
|
1968
2015
|
}
|
|
1969
2016
|
|
|
@@ -1978,7 +2025,7 @@ export class JavaScriptPrinter extends JavaScriptVisitor<PrintOutputCapture> {
|
|
|
1978
2025
|
override async visitControlParentheses<T extends J>(controlParens: J.ControlParentheses<T>, p: PrintOutputCapture): Promise<J | undefined> {
|
|
1979
2026
|
await this.beforeSyntax(controlParens, p);
|
|
1980
2027
|
|
|
1981
|
-
if (this.
|
|
2028
|
+
if (this.parentTree()?.kind === J.Kind.TypeCast) {
|
|
1982
2029
|
p.append('<');
|
|
1983
2030
|
await this.visitRightPaddedLocalSingle(controlParens.tree, ">", p);
|
|
1984
2031
|
} else {
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 the original author or authors.
|
|
3
|
+
* <p>
|
|
4
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
* <p>
|
|
8
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
9
|
+
* <p>
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import {Option, Recipe} from "../../recipe";
|
|
17
|
+
import {TreeVisitor} from "../../visitor";
|
|
18
|
+
import {ExecutionContext} from "../../execution";
|
|
19
|
+
import {check} from "../../preconditions";
|
|
20
|
+
import {emptyMarkers} from "../../markers";
|
|
21
|
+
import {randomId} from "../../uuid";
|
|
22
|
+
import {emptySpace, isIdentifier, J, rightPadded, Type} from "../../java";
|
|
23
|
+
import {JavaScriptVisitor} from "../visitor";
|
|
24
|
+
import {MethodMatcher} from "../method-matcher";
|
|
25
|
+
import {usesMethod} from "../preconditions";
|
|
26
|
+
import {maybeBind, maybeUnbind} from "../binding";
|
|
27
|
+
import {moduleScopeBindings} from "../add-import";
|
|
28
|
+
import {compilationUnitOf, scopeOf} from "../scope";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Moves calls matching a method pattern onto a member imported from a module, such as `jest.fn()`
|
|
32
|
+
* to `vi.fn()` with `import {vi} from "vitest"`.
|
|
33
|
+
*
|
|
34
|
+
* A call through an import of the old target, whether a namespace, default or named import, moves
|
|
35
|
+
* too, and the import goes once nothing else uses it.
|
|
36
|
+
*/
|
|
37
|
+
export class ChangeMethodTargetToImport extends Recipe {
|
|
38
|
+
readonly name = "org.openrewrite.javascript.change-method-target-to-import";
|
|
39
|
+
readonly displayName = "Change method target to an import";
|
|
40
|
+
readonly description = "Changes the target of calls matching a method pattern to a member imported from a module, " +
|
|
41
|
+
"adding the import. A CommonJS file changes only where it already requires the target, and an AMD module not at all.";
|
|
42
|
+
|
|
43
|
+
@Option({
|
|
44
|
+
displayName: "Method pattern",
|
|
45
|
+
description: "A method pattern matching the calls to move, as `<declaring type> <name>(<args>)`.",
|
|
46
|
+
example: "jest *(..)"
|
|
47
|
+
})
|
|
48
|
+
methodPattern!: string;
|
|
49
|
+
|
|
50
|
+
@Option({
|
|
51
|
+
displayName: "Target module",
|
|
52
|
+
description: "The module the new target is imported from.",
|
|
53
|
+
example: "vitest"
|
|
54
|
+
})
|
|
55
|
+
targetModule!: string;
|
|
56
|
+
|
|
57
|
+
@Option({
|
|
58
|
+
displayName: "Target member",
|
|
59
|
+
description: "The member of the target module the calls move onto.",
|
|
60
|
+
example: "vi"
|
|
61
|
+
})
|
|
62
|
+
targetMember!: string;
|
|
63
|
+
|
|
64
|
+
@Option({
|
|
65
|
+
displayName: "Target type",
|
|
66
|
+
description: "The fully-qualified type of the target member, which declares the methods the calls move to. " +
|
|
67
|
+
"Without it, the moved calls are attributed to an unknown declaring type.",
|
|
68
|
+
example: "vitest.VitestUtils",
|
|
69
|
+
required: false
|
|
70
|
+
})
|
|
71
|
+
targetType?: string;
|
|
72
|
+
|
|
73
|
+
@Option({
|
|
74
|
+
displayName: "Match on overrides",
|
|
75
|
+
description: "When enabled, find methods that are overrides of the method pattern.",
|
|
76
|
+
required: false
|
|
77
|
+
})
|
|
78
|
+
matchOverrides?: boolean;
|
|
79
|
+
|
|
80
|
+
constructor(options?: {
|
|
81
|
+
methodPattern?: string;
|
|
82
|
+
targetModule?: string;
|
|
83
|
+
targetMember?: string;
|
|
84
|
+
targetType?: string;
|
|
85
|
+
matchOverrides?: boolean;
|
|
86
|
+
}) {
|
|
87
|
+
super(options);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async editor(): Promise<TreeVisitor<any, ExecutionContext>> {
|
|
91
|
+
const matcher = new MethodMatcher(this.methodPattern, this.matchOverrides);
|
|
92
|
+
const module = this.targetModule;
|
|
93
|
+
const member = this.targetMember;
|
|
94
|
+
// Named after the specifier, as the parser names a module object.
|
|
95
|
+
const moduleObject = classNamed(module);
|
|
96
|
+
const memberType = this.targetType ? classNamed(this.targetType) : Type.unknownType as Type.FullyQualified;
|
|
97
|
+
|
|
98
|
+
return check(usesMethod(this.methodPattern, this.matchOverrides), new class extends JavaScriptVisitor<ExecutionContext> {
|
|
99
|
+
protected override async visitMethodInvocation(method: J.MethodInvocation, ctx: ExecutionContext): Promise<J | undefined> {
|
|
100
|
+
const m = await super.visitMethodInvocation(method, ctx) as J.MethodInvocation;
|
|
101
|
+
if (!matcher.matches(m.methodType)) {
|
|
102
|
+
return m;
|
|
103
|
+
}
|
|
104
|
+
const select = m.select?.element;
|
|
105
|
+
if (select !== undefined && !isIdentifier(select)) {
|
|
106
|
+
return m;
|
|
107
|
+
}
|
|
108
|
+
const oldName = select?.simpleName ?? m.name.simpleName;
|
|
109
|
+
const cu = compilationUnitOf(this)!;
|
|
110
|
+
const owner = scopeOf(this.cursor).declaringScope(oldName);
|
|
111
|
+
const imported = owner === cu ?
|
|
112
|
+
moduleScopeBindings(cu).find(b => b.name === oldName && b.module !== undefined) : undefined;
|
|
113
|
+
if (owner !== undefined && !imported) {
|
|
114
|
+
return m;
|
|
115
|
+
}
|
|
116
|
+
// A call without a receiver names the member it was imported as, which a default import lacks.
|
|
117
|
+
const methodName = select || !imported ? m.name.simpleName : imported.member;
|
|
118
|
+
if (methodName === undefined) {
|
|
119
|
+
return m;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const name = maybeBind(this, {module, member, onlyIfReferenced: false});
|
|
123
|
+
if (name === undefined) {
|
|
124
|
+
return m;
|
|
125
|
+
}
|
|
126
|
+
if (imported) {
|
|
127
|
+
maybeUnbind(this, {module: imported.module!, member: imported.member ?? 'default'});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const methodType = m.methodType && {...m.methodType, declaringType: memberType};
|
|
131
|
+
const target: J.Identifier = {
|
|
132
|
+
kind: J.Kind.Identifier,
|
|
133
|
+
id: randomId(),
|
|
134
|
+
prefix: select?.prefix ?? m.name.prefix,
|
|
135
|
+
markers: emptyMarkers,
|
|
136
|
+
annotations: [],
|
|
137
|
+
simpleName: name,
|
|
138
|
+
type: memberType,
|
|
139
|
+
fieldType: {
|
|
140
|
+
kind: Type.Kind.Variable,
|
|
141
|
+
name: member,
|
|
142
|
+
flags: 0,
|
|
143
|
+
owner: moduleObject,
|
|
144
|
+
type: memberType,
|
|
145
|
+
annotations: []
|
|
146
|
+
} as Type.Variable
|
|
147
|
+
};
|
|
148
|
+
const moved: J.MethodInvocation = {
|
|
149
|
+
...m,
|
|
150
|
+
select: m.select ? {...m.select, element: target} : rightPadded(target, emptySpace),
|
|
151
|
+
name: {
|
|
152
|
+
...m.name,
|
|
153
|
+
prefix: m.select ? m.name.prefix : emptySpace,
|
|
154
|
+
simpleName: methodName,
|
|
155
|
+
type: Type.isMethod(m.name.type) ? methodType : m.name.type,
|
|
156
|
+
fieldType: m.name.fieldType && {...m.name.fieldType, name: methodName, owner: memberType}
|
|
157
|
+
},
|
|
158
|
+
methodType
|
|
159
|
+
};
|
|
160
|
+
return moved;
|
|
161
|
+
}
|
|
162
|
+
}());
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function classNamed(fullyQualifiedName: string): Type.Class {
|
|
167
|
+
return {
|
|
168
|
+
kind: Type.Kind.Class,
|
|
169
|
+
flags: 0,
|
|
170
|
+
classKind: Type.Class.Kind.Interface,
|
|
171
|
+
fullyQualifiedName,
|
|
172
|
+
typeParameters: [],
|
|
173
|
+
annotations: [],
|
|
174
|
+
interfaces: [],
|
|
175
|
+
members: [],
|
|
176
|
+
methods: []
|
|
177
|
+
} as Type.Class;
|
|
178
|
+
}
|