@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
|
@@ -7,9 +7,9 @@ import {foundSearchResult} from "../../markers";
|
|
|
7
7
|
export class UsesMethod extends JavaVisitor<ExecutionContext> {
|
|
8
8
|
private readonly matcher;
|
|
9
9
|
|
|
10
|
-
constructor(pattern: string) {
|
|
10
|
+
constructor(pattern: string, matchOverrides: boolean = false) {
|
|
11
11
|
super();
|
|
12
|
-
this.matcher = new MethodMatcher(pattern);
|
|
12
|
+
this.matcher = new MethodMatcher(pattern, matchOverrides);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
protected async visitExpression(expression: Expression, p: ExecutionContext): Promise<J | undefined> {
|
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
import {J, JavaVisitor, Type} from "../../java";
|
|
2
|
+
import {JS} from "../tree";
|
|
2
3
|
import {ExecutionContext} from "../../execution";
|
|
3
4
|
import * as picomatch from "picomatch";
|
|
4
5
|
import {foundSearchResult} from "../../markers";
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Marks each tree whose type matches a glob pattern.
|
|
9
|
+
*
|
|
10
|
+
* With `assignable`, a type also matches through a class or interface it extends. A primitive then
|
|
11
|
+
* matches by its keyword. With `includeImplicit`, a call also matches through its method's declaring,
|
|
12
|
+
* return and parameter types.
|
|
13
|
+
*/
|
|
6
14
|
export class UsesType extends JavaVisitor<ExecutionContext> {
|
|
7
15
|
private readonly matcher: picomatch.Matcher;
|
|
16
|
+
private readonly assignable: boolean;
|
|
17
|
+
private readonly includeImplicit: boolean;
|
|
8
18
|
|
|
9
|
-
constructor(typePattern: string
|
|
19
|
+
constructor(typePattern: string, {assignable = false, includeImplicit = false}: {
|
|
20
|
+
assignable?: boolean,
|
|
21
|
+
includeImplicit?: boolean
|
|
22
|
+
} = {}) {
|
|
10
23
|
super();
|
|
11
|
-
// Create a picomatch matcher for the pattern
|
|
12
24
|
this.matcher = picomatch.default ? picomatch.default(typePattern) : (picomatch as any)(typePattern);
|
|
25
|
+
this.assignable = assignable;
|
|
26
|
+
this.includeImplicit = includeImplicit;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
29
|
protected async preVisit(tree: J, _: ExecutionContext): Promise<J | undefined> {
|
|
16
|
-
if (J.hasType(tree)) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
if (J.hasType(tree) && this.matches(tree.type)) {
|
|
31
|
+
return foundSearchResult(tree);
|
|
32
|
+
}
|
|
33
|
+
if (this.includeImplicit && JS.isMethodCall(tree) && tree.methodType) {
|
|
34
|
+
const method = tree.methodType;
|
|
35
|
+
if ([method.declaringType, method.returnType, ...method.parameterTypes].some(t => this.matches(t))) {
|
|
36
|
+
return foundSearchResult(tree);
|
|
23
37
|
}
|
|
24
38
|
}
|
|
25
39
|
return tree;
|
|
26
40
|
}
|
|
41
|
+
|
|
42
|
+
private matches(type: Type | undefined): boolean {
|
|
43
|
+
if (Type.isPrimitive(type)) {
|
|
44
|
+
return this.assignable && type.keyword !== '' && this.matcher(type.keyword);
|
|
45
|
+
}
|
|
46
|
+
return Type.isOfTypeWithName(type, this.assignable, this.matcher);
|
|
47
|
+
}
|
|
27
48
|
}
|
|
@@ -13,64 +13,39 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {J,
|
|
16
|
+
import {J, NameTree} from '../../java';
|
|
17
17
|
import {JavaScriptVisitor} from '../visitor';
|
|
18
|
-
import {
|
|
18
|
+
import {isReference, scopeOf} from '../scope';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Renames the identifiers a template uses for its declared bindings to the names the file
|
|
22
22
|
* actually binds. Runs before parameter substitution, so only the template's own code is in
|
|
23
23
|
* scope and a caller's captured code is never rewritten.
|
|
24
24
|
*/
|
|
25
|
-
export async function renameBindings<T extends J>(tree: T, renames: Record<string, string
|
|
26
|
-
return new RenameBindingsVisitor(renames
|
|
25
|
+
export async function renameBindings<T extends J>(tree: T, renames: Record<string, string>): Promise<T> {
|
|
26
|
+
return new RenameBindingsVisitor(renames).visit(tree, undefined) as Promise<T>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
class RenameBindingsVisitor extends JavaScriptVisitor<undefined> {
|
|
30
|
-
constructor(private readonly renames: Record<string, string
|
|
31
|
-
private readonly modules: Record<string, string>) {
|
|
30
|
+
constructor(private readonly renames: Record<string, string>) {
|
|
32
31
|
super();
|
|
33
32
|
}
|
|
34
33
|
|
|
34
|
+
// The class of `Mocked<T>` and a decorator's name sit behind this hook, which the base visitor holds closed
|
|
35
|
+
protected override async visitTypeName<N extends NameTree>(nameTree: N, p: undefined): Promise<N> {
|
|
36
|
+
return await this.visit(nameTree, p) as N;
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
override async visitIdentifier(identifier: J.Identifier, p: undefined): Promise<J | undefined> {
|
|
36
40
|
const renamed = this.renames[identifier.simpleName];
|
|
37
41
|
if (renamed === undefined || renamed === identifier.simpleName) {
|
|
38
42
|
return identifier;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const refersToBinding = resolved !== undefined
|
|
45
|
-
? resolved === this.modules[identifier.simpleName]
|
|
46
|
-
: isValueReference(this.cursor, identifier);
|
|
45
|
+
// Only the context binds at module scope, so a reference nothing in the template rebinds reads it
|
|
46
|
+
const refersToBinding = isReference(this.cursor, identifier) &&
|
|
47
|
+
!scopeOf(this.cursor).declares(identifier.simpleName);
|
|
47
48
|
|
|
48
49
|
return refersToBinding ? {...identifier, simpleName: renamed} as J.Identifier : identifier;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
-
/** The module an identifier's attribution traces back to, following the owning-class chain to its root. */
|
|
53
|
-
function resolvedModule(identifier: J.Identifier): string | undefined {
|
|
54
|
-
const fieldType = identifier.fieldType;
|
|
55
|
-
if (fieldType?.kind === Type.Kind.Variable) {
|
|
56
|
-
const owner = (fieldType as Type.Variable).owner;
|
|
57
|
-
return owner && Type.isClass(owner) ? rootName(owner as Type.Class) : undefined;
|
|
58
|
-
}
|
|
59
|
-
const type = identifier.type;
|
|
60
|
-
if (type && Type.isMethod(type)) {
|
|
61
|
-
const declaring = (type as Type.Method).declaringType;
|
|
62
|
-
return declaring ? rootName(declaring as Type.Class) : undefined;
|
|
63
|
-
}
|
|
64
|
-
if (type && Type.isClass(type)) {
|
|
65
|
-
return rootName(type as Type.Class);
|
|
66
|
-
}
|
|
67
|
-
return undefined;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function rootName(classType: Type.Class): string {
|
|
71
|
-
let current: Type.Class = classType;
|
|
72
|
-
while (current.owningClass && Type.isClass(current.owningClass)) {
|
|
73
|
-
current = current.owningClass as Type.Class;
|
|
74
|
-
}
|
|
75
|
-
return Type.FullyQualified.getFullyQualifiedName(current);
|
|
76
|
-
}
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {Cursor,
|
|
16
|
+
import {Cursor, Tree} from '../..';
|
|
17
17
|
import {J, Type} from '../../java';
|
|
18
18
|
import {JS} from '../index';
|
|
19
19
|
import {JavaScriptSemanticComparatorVisitor} from '../comparator';
|
|
20
|
-
import {CaptureMarker, CaptureStorageValue, PlaceholderUtils} from './utils';
|
|
20
|
+
import {CaptureMarker, CaptureStorageValue, PlaceholderUtils, TEMPLATE_MODULE} from './utils';
|
|
21
21
|
import {Capture, CaptureConstraintContext, CaptureMap, DebugLogEntry, MatchExplanation} from './types';
|
|
22
22
|
import {CAPTURE_NAME_SYMBOL} from './capture';
|
|
23
23
|
|
|
@@ -54,8 +54,8 @@ export interface MatcherState {
|
|
|
54
54
|
* Part of Layer 1 (Core Instrumentation).
|
|
55
55
|
*/
|
|
56
56
|
export interface MatcherCallbacks {
|
|
57
|
-
handleCapture: (capture: CaptureMarker, target: J, wrapper?: J.RightPadded<J>) => boolean
|
|
58
|
-
handleVariadicCapture: (capture: CaptureMarker, targets: J[], wrappers?: J.RightPadded<J>[]) => boolean
|
|
57
|
+
handleCapture: (capture: CaptureMarker, target: J, wrapper?: J.RightPadded<J>) => Promise<boolean>;
|
|
58
|
+
handleVariadicCapture: (capture: CaptureMarker, targets: J[], wrappers?: J.RightPadded<J>[]) => Promise<boolean>;
|
|
59
59
|
saveState: () => MatcherState;
|
|
60
60
|
restoreState: (state: MatcherState) => void;
|
|
61
61
|
|
|
@@ -175,7 +175,7 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
const success = this.matcher.handleCapture(captureMarker, target, undefined);
|
|
178
|
+
const success = await this.matcher.handleCapture(captureMarker, target, undefined);
|
|
179
179
|
if (!success) {
|
|
180
180
|
const captureName = captureMarker.captureName || 'unnamed';
|
|
181
181
|
return this.captureConflict(captureName) as R;
|
|
@@ -194,9 +194,12 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
194
194
|
return await super.visit(j, p, parent);
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
/**
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
/**
|
|
198
|
+
* A function the pattern's `context` declares lives in no module of the source,
|
|
199
|
+
* so it stands in for any function of its name.
|
|
200
|
+
*/
|
|
201
|
+
protected override declaresAnyCallee(declaringType: Type.FullyQualified): boolean {
|
|
202
|
+
return Type.FullyQualified.getFullyQualifiedName(declaringType) === TEMPLATE_MODULE;
|
|
200
203
|
}
|
|
201
204
|
|
|
202
205
|
protected hasSameKind(j: J, other: J): boolean {
|
|
@@ -252,7 +255,7 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
// Handle the capture with the wrapper - use the element for pattern matching
|
|
255
|
-
const success = this.matcher.handleCapture(captureMarker, targetElement as J, targetWrapper as J.RightPadded<J> | undefined);
|
|
258
|
+
const success = await this.matcher.handleCapture(captureMarker, targetElement as J, targetWrapper as J.RightPadded<J> | undefined);
|
|
256
259
|
if (!success) {
|
|
257
260
|
const captureName = captureMarker.captureName || 'unnamed';
|
|
258
261
|
return this.captureConflict(captureName);
|
|
@@ -337,90 +340,6 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
337
340
|
return this.match;
|
|
338
341
|
}
|
|
339
342
|
|
|
340
|
-
override async visitMethodInvocation(methodInvocation: J.MethodInvocation, other: J): Promise<J | undefined> {
|
|
341
|
-
// Check if any arguments are variadic captures
|
|
342
|
-
const hasVariadicCapture = methodInvocation.arguments.elements.some(arg =>
|
|
343
|
-
PlaceholderUtils.isVariadicCapture(arg)
|
|
344
|
-
);
|
|
345
|
-
|
|
346
|
-
// If no variadic captures, use parent implementation (which includes semantic/type-aware matching)
|
|
347
|
-
if (!hasVariadicCapture) {
|
|
348
|
-
return super.visitMethodInvocation(methodInvocation, other);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Otherwise, handle variadic captures ourselves
|
|
352
|
-
if (!this.match) {
|
|
353
|
-
return this.abort(methodInvocation);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (other.kind !== J.Kind.MethodInvocation) {
|
|
357
|
-
// Set up cursors for kindMismatch
|
|
358
|
-
const savedCursor = this.cursor;
|
|
359
|
-
const savedTargetCursor = this.targetCursor;
|
|
360
|
-
this.cursor = new Cursor(methodInvocation, this.cursor);
|
|
361
|
-
this.targetCursor = new Cursor(other, this.targetCursor);
|
|
362
|
-
try {
|
|
363
|
-
return this.kindMismatch();
|
|
364
|
-
} finally {
|
|
365
|
-
this.cursor = savedCursor;
|
|
366
|
-
this.targetCursor = savedTargetCursor;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const otherMethodInvocation = other as J.MethodInvocation;
|
|
371
|
-
|
|
372
|
-
// Set up cursors for the entire method
|
|
373
|
-
const savedCursor = this.cursor;
|
|
374
|
-
const savedTargetCursor = this.targetCursor;
|
|
375
|
-
this.cursor = new Cursor(methodInvocation, this.cursor);
|
|
376
|
-
this.targetCursor = new Cursor(otherMethodInvocation, this.targetCursor);
|
|
377
|
-
try {
|
|
378
|
-
// Compare select
|
|
379
|
-
if ((methodInvocation.select === undefined) !== (otherMethodInvocation.select === undefined)) {
|
|
380
|
-
return this.structuralMismatch('select');
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Visit select if present
|
|
384
|
-
if (methodInvocation.select && otherMethodInvocation.select) {
|
|
385
|
-
await this.visit(methodInvocation.select.element, otherMethodInvocation.select.element);
|
|
386
|
-
if (!this.match) return methodInvocation;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// A pattern that spells out no type arguments says nothing about them, as with parentheses
|
|
390
|
-
if (methodInvocation.typeParameters) {
|
|
391
|
-
if (!otherMethodInvocation.typeParameters) {
|
|
392
|
-
return this.structuralMismatch('typeParameters');
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (methodInvocation.typeParameters.elements.length !== otherMethodInvocation.typeParameters.elements.length) {
|
|
396
|
-
return this.arrayLengthMismatch('typeParameters.elements');
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// Visit each type parameter in lock step (visit RightPadded to check for markers)
|
|
400
|
-
for (let i = 0; i < methodInvocation.typeParameters.elements.length; i++) {
|
|
401
|
-
await this.visitRightPadded(methodInvocation.typeParameters.elements[i], otherMethodInvocation.typeParameters.elements[i] as any);
|
|
402
|
-
if (!this.match) return methodInvocation;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// Visit name
|
|
407
|
-
await this.visit(methodInvocation.name, otherMethodInvocation.name);
|
|
408
|
-
if (!this.match) {
|
|
409
|
-
return methodInvocation;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Special handling for variadic captures in arguments
|
|
413
|
-
if (!await this.matchArguments(methodInvocation.arguments.elements, otherMethodInvocation.arguments.elements)) {
|
|
414
|
-
return this.structuralMismatch('arguments');
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
return methodInvocation;
|
|
418
|
-
} finally {
|
|
419
|
-
this.cursor = savedCursor;
|
|
420
|
-
this.targetCursor = savedTargetCursor;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
343
|
override async visitBlock(block: J.Block, other: J): Promise<J | undefined> {
|
|
425
344
|
// Check if any statements have CaptureMarker indicating they're variadic
|
|
426
345
|
const hasVariadicCapture = block.statements.some(stmt => {
|
|
@@ -522,14 +441,6 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
522
441
|
}
|
|
523
442
|
}
|
|
524
443
|
|
|
525
|
-
/**
|
|
526
|
-
* Matches argument lists, with special handling for variadic captures.
|
|
527
|
-
* A variadic capture can match zero or more consecutive arguments.
|
|
528
|
-
*/
|
|
529
|
-
private async matchArguments(patternArgs: J.RightPadded<J>[], targetArgs: J.RightPadded<J>[]): Promise<boolean> {
|
|
530
|
-
return await this.matchSequence(patternArgs, targetArgs, true);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
444
|
/**
|
|
534
445
|
* Generic sequence matching with variadic capture support.
|
|
535
446
|
* Works for any sequence of JRightPadded elements (arguments, statements, etc.).
|
|
@@ -693,7 +604,7 @@ export class PatternMatchingComparator extends JavaScriptSemanticComparatorVisit
|
|
|
693
604
|
const savedState = this.matcher.saveState();
|
|
694
605
|
|
|
695
606
|
// Handle the variadic capture
|
|
696
|
-
const success = this.matcher.handleVariadicCapture(captureMarker, capturedElements, capturedWrappers);
|
|
607
|
+
const success = await this.matcher.handleVariadicCapture(captureMarker, capturedElements, capturedWrappers);
|
|
697
608
|
if (!success) {
|
|
698
609
|
// Restore state and try next amount
|
|
699
610
|
this.matcher.restoreState(savedState);
|
|
@@ -958,7 +869,7 @@ export class DebugPatternMatchingComparator extends PatternMatchingComparator {
|
|
|
958
869
|
this.debug.log('debug', 'constraint', `Constraint passed for capture: ${captureMarker.captureName}`);
|
|
959
870
|
}
|
|
960
871
|
|
|
961
|
-
const success = this.matcher.handleCapture(captureMarker, target, undefined);
|
|
872
|
+
const success = await this.matcher.handleCapture(captureMarker, target, undefined);
|
|
962
873
|
if (!success) {
|
|
963
874
|
return this.abort(j) as R;
|
|
964
875
|
}
|
|
@@ -1055,7 +966,7 @@ export class DebugPatternMatchingComparator extends PatternMatchingComparator {
|
|
|
1055
966
|
this.debug.log('debug', 'constraint', `Constraint passed for wrapped capture: ${captureMarker.captureName}`);
|
|
1056
967
|
}
|
|
1057
968
|
|
|
1058
|
-
const success = this.matcher.handleCapture(captureMarker, targetElement as J, targetWrapper as J.RightPadded<J> | undefined);
|
|
969
|
+
const success = await this.matcher.handleCapture(captureMarker, targetElement as J, targetWrapper as J.RightPadded<J> | undefined);
|
|
1059
970
|
if (!success) {
|
|
1060
971
|
return this.abort(right);
|
|
1061
972
|
}
|
|
@@ -1407,7 +1318,7 @@ export class DebugPatternMatchingComparator extends PatternMatchingComparator {
|
|
|
1407
1318
|
|
|
1408
1319
|
const savedState = this.matcher.saveState();
|
|
1409
1320
|
|
|
1410
|
-
const success = this.matcher.handleVariadicCapture(captureMarker, capturedElements, capturedWrappers);
|
|
1321
|
+
const success = await this.matcher.handleVariadicCapture(captureMarker, capturedElements, capturedWrappers);
|
|
1411
1322
|
if (!success) {
|
|
1412
1323
|
this.matcher.restoreState(savedState);
|
|
1413
1324
|
continue;
|
|
@@ -1462,25 +1373,3 @@ export class DebugPatternMatchingComparator extends PatternMatchingComparator {
|
|
|
1462
1373
|
}
|
|
1463
1374
|
}
|
|
1464
1375
|
}
|
|
1465
|
-
|
|
1466
|
-
/** Whether anything under `node`, the padding wrappers a marker moves onto included, is a capture. */
|
|
1467
|
-
function containsCapture(node: unknown): boolean {
|
|
1468
|
-
if (node === null || typeof node !== 'object') {
|
|
1469
|
-
return false;
|
|
1470
|
-
}
|
|
1471
|
-
if (Array.isArray(node)) {
|
|
1472
|
-
return node.some(containsCapture);
|
|
1473
|
-
}
|
|
1474
|
-
const record = node as Record<string, unknown>;
|
|
1475
|
-
if (typeof record.kind !== 'string') {
|
|
1476
|
-
return false;
|
|
1477
|
-
}
|
|
1478
|
-
// Attribution is a cyclic graph, and a capture is never reachable through one
|
|
1479
|
-
if (Type.isType(node)) {
|
|
1480
|
-
return false;
|
|
1481
|
-
}
|
|
1482
|
-
if (record.markers && PlaceholderUtils.getCaptureMarker(node as { markers: Markers })) {
|
|
1483
|
-
return true;
|
|
1484
|
-
}
|
|
1485
|
-
return Object.entries(record).some(([key, value]) => key !== 'markers' && containsCapture(value));
|
|
1486
|
-
}
|