@openrewrite/rewrite 8.62.3 → 8.62.5
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.map +1 -1
- package/dist/execution.js.map +1 -1
- package/dist/java/rpc.d.ts +1 -0
- package/dist/java/rpc.d.ts.map +1 -1
- package/dist/java/rpc.js +81 -0
- package/dist/java/rpc.js.map +1 -1
- package/dist/java/tree.d.ts +12 -6
- package/dist/java/tree.d.ts.map +1 -1
- package/dist/java/tree.js +12 -92
- package/dist/java/tree.js.map +1 -1
- package/dist/java/type.d.ts +2 -0
- package/dist/java/type.d.ts.map +1 -1
- package/dist/java/type.js +12 -0
- package/dist/java/type.js.map +1 -1
- package/dist/java/visitor.d.ts +12 -4
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +23 -1
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/format.d.ts +2 -2
- package/dist/javascript/format.d.ts.map +1 -1
- package/dist/javascript/format.js.map +1 -1
- package/dist/javascript/index.d.ts +3 -0
- package/dist/javascript/index.d.ts.map +1 -1
- package/dist/javascript/index.js +3 -0
- package/dist/javascript/index.js.map +1 -1
- package/dist/javascript/method-matcher.d.ts +16 -0
- package/dist/javascript/method-matcher.d.ts.map +1 -0
- package/dist/javascript/method-matcher.js +222 -0
- package/dist/javascript/method-matcher.js.map +1 -0
- package/dist/javascript/parser.d.ts +1 -1
- package/dist/javascript/parser.d.ts.map +1 -1
- package/dist/javascript/parser.js +27 -5
- package/dist/javascript/parser.js.map +1 -1
- package/dist/javascript/preconditions.d.ts +6 -0
- package/dist/javascript/preconditions.d.ts.map +1 -0
- package/dist/javascript/preconditions.js +58 -0
- package/dist/javascript/preconditions.js.map +1 -0
- package/dist/javascript/print.d.ts +2 -2
- package/dist/javascript/print.d.ts.map +1 -1
- package/dist/javascript/print.js.map +1 -1
- package/dist/javascript/remove-import.d.ts +56 -0
- package/dist/javascript/remove-import.d.ts.map +1 -0
- package/dist/javascript/remove-import.js +715 -0
- package/dist/javascript/remove-import.js.map +1 -0
- package/dist/javascript/rpc.js +3 -18
- package/dist/javascript/rpc.js.map +1 -1
- package/dist/javascript/search/index.d.ts +3 -0
- package/dist/javascript/search/index.d.ts.map +1 -0
- package/dist/javascript/search/index.js +19 -0
- package/dist/javascript/search/index.js.map +1 -0
- package/dist/javascript/search/uses-method.d.ts +8 -0
- package/dist/javascript/search/uses-method.d.ts.map +1 -0
- package/dist/javascript/search/uses-method.js +35 -0
- package/dist/javascript/search/uses-method.js.map +1 -0
- package/dist/javascript/search/uses-type.d.ts +8 -0
- package/dist/javascript/search/uses-type.d.ts.map +1 -0
- package/dist/javascript/search/uses-type.js +71 -0
- package/dist/javascript/search/uses-type.js.map +1 -0
- package/dist/javascript/templating.d.ts +1 -1
- package/dist/javascript/templating.d.ts.map +1 -1
- package/dist/javascript/templating.js +1 -1
- package/dist/javascript/templating.js.map +1 -1
- package/dist/javascript/tree.d.ts +3 -3
- package/dist/javascript/tree.d.ts.map +1 -1
- package/dist/javascript/tree.js +28 -0
- package/dist/javascript/tree.js.map +1 -1
- package/dist/javascript/type-mapping.d.ts +7 -18
- package/dist/javascript/type-mapping.d.ts.map +1 -1
- package/dist/javascript/type-mapping.js +290 -203
- package/dist/javascript/type-mapping.js.map +1 -1
- package/dist/javascript/visitor.d.ts +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +1 -1
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/json/print.js.map +1 -1
- package/dist/json/rpc.js +46 -17
- package/dist/json/rpc.js.map +1 -1
- package/dist/json/visitor.d.ts +2 -2
- package/dist/json/visitor.d.ts.map +1 -1
- package/dist/json/visitor.js.map +1 -1
- package/dist/print.d.ts +1 -0
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +6 -0
- package/dist/print.js.map +1 -1
- package/dist/rpc/queue.d.ts +15 -6
- package/dist/rpc/queue.d.ts.map +1 -1
- package/dist/rpc/queue.js +37 -13
- package/dist/rpc/queue.js.map +1 -1
- package/dist/rpc/request/generate.d.ts +4 -0
- package/dist/rpc/request/generate.d.ts.map +1 -1
- package/dist/rpc/request/generate.js +9 -4
- package/dist/rpc/request/generate.js.map +1 -1
- package/dist/rpc/request/get-object.d.ts +2 -2
- package/dist/rpc/request/get-object.d.ts.map +1 -1
- package/dist/rpc/request/get-object.js +4 -12
- 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.map +1 -1
- package/dist/rpc/request/print.d.ts +1 -1
- package/dist/rpc/request/print.d.ts.map +1 -1
- package/dist/rpc/request/print.js +1 -1
- package/dist/rpc/request/print.js.map +1 -1
- package/dist/rpc/request/visit.d.ts +3 -2
- package/dist/rpc/request/visit.d.ts.map +1 -1
- package/dist/rpc/request/visit.js +5 -4
- package/dist/rpc/request/visit.js.map +1 -1
- package/dist/rpc/rewrite-rpc.d.ts +4 -4
- package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
- package/dist/rpc/rewrite-rpc.js +16 -17
- package/dist/rpc/rewrite-rpc.js.map +1 -1
- package/dist/search/index.d.ts +2 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +18 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/is-source-file.d.ts +8 -0
- package/dist/search/is-source-file.d.ts.map +1 -0
- package/dist/search/is-source-file.js +70 -0
- package/dist/search/is-source-file.js.map +1 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +3 -0
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/text/rpc.js +37 -40
- package/dist/text/rpc.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +13 -0
- package/dist/util.js.map +1 -1
- package/dist/version.txt +1 -1
- package/dist/visitor.d.ts +1 -1
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +3 -2
- package/dist/visitor.js.map +1 -1
- package/package.json +3 -1
- package/src/execution.ts +0 -2
- package/src/java/rpc.ts +68 -0
- package/src/java/tree.ts +20 -76
- package/src/java/type.ts +14 -0
- package/src/java/visitor.ts +32 -12
- package/src/javascript/format.ts +2 -2
- package/src/javascript/index.ts +4 -0
- package/src/javascript/method-matcher.ts +250 -0
- package/src/javascript/parser.ts +20 -6
- package/src/javascript/preconditions.ts +40 -0
- package/src/javascript/print.ts +3 -3
- package/src/javascript/remove-import.ts +780 -0
- package/src/javascript/rpc.ts +6 -19
- package/src/javascript/search/index.ts +2 -0
- package/src/javascript/search/uses-method.ts +21 -0
- package/src/javascript/search/uses-type.ts +27 -0
- package/src/javascript/templating.ts +4 -3
- package/src/javascript/tree.ts +47 -3
- package/src/javascript/type-mapping.ts +320 -214
- package/src/javascript/visitor.ts +126 -126
- package/src/json/print.ts +1 -1
- package/src/json/rpc.ts +40 -19
- package/src/json/visitor.ts +2 -2
- package/src/print.ts +9 -3
- package/src/rpc/queue.ts +36 -12
- package/src/rpc/request/generate.ts +18 -6
- package/src/rpc/request/get-object.ts +6 -13
- package/src/rpc/request/parse.ts +1 -1
- package/src/rpc/request/print.ts +2 -2
- package/src/rpc/request/visit.ts +6 -5
- package/src/rpc/rewrite-rpc.ts +22 -21
- package/src/search/index.ts +1 -0
- package/src/search/is-source-file.ts +26 -0
- package/src/test/rewrite-test.ts +5 -2
- package/src/text/rpc.ts +33 -37
- package/src/util.ts +19 -4
- package/src/visitor.ts +3 -3
package/src/java/rpc.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {produceAsync} from "../visitor";
|
|
|
20
20
|
import {createDraft, Draft, finishDraft, WritableDraft} from "immer";
|
|
21
21
|
import {isTree} from "../tree";
|
|
22
22
|
import {Type} from "./type";
|
|
23
|
+
import Space = J.Space;
|
|
23
24
|
|
|
24
25
|
export class JavaSender extends JavaVisitor<RpcSendQueue> {
|
|
25
26
|
|
|
@@ -1382,3 +1383,70 @@ export class JavaReceiver extends JavaVisitor<RpcReceiveQueue> {
|
|
|
1382
1383
|
return undefined;
|
|
1383
1384
|
}
|
|
1384
1385
|
}
|
|
1386
|
+
|
|
1387
|
+
export function registerJLanguageCodecs(sourceFileType: string,
|
|
1388
|
+
receiver: JavaVisitor<RpcReceiveQueue>,
|
|
1389
|
+
sender: JavaVisitor<RpcSendQueue>,
|
|
1390
|
+
extendedKinds?: any) {
|
|
1391
|
+
const kinds = new Set([
|
|
1392
|
+
...Object.values(J.Kind),
|
|
1393
|
+
...(extendedKinds ? Object.values(extendedKinds) : [])
|
|
1394
|
+
]);
|
|
1395
|
+
|
|
1396
|
+
// Register codec for all Java AST node types
|
|
1397
|
+
for (const kind of kinds) {
|
|
1398
|
+
if (kind === J.Kind.Space) {
|
|
1399
|
+
RpcCodecs.registerCodec(kind, {
|
|
1400
|
+
async rpcReceive(before: J.Space, q: RpcReceiveQueue): Promise<J.Space> {
|
|
1401
|
+
return (await receiver.visitSpace(before, q))!;
|
|
1402
|
+
},
|
|
1403
|
+
|
|
1404
|
+
async rpcSend(after: J.Space, q: RpcSendQueue): Promise<void> {
|
|
1405
|
+
await sender.visitSpace(after, q);
|
|
1406
|
+
}
|
|
1407
|
+
}, sourceFileType);
|
|
1408
|
+
} else if (kind === J.Kind.RightPadded) {
|
|
1409
|
+
RpcCodecs.registerCodec(kind, {
|
|
1410
|
+
async rpcReceive<T extends J | boolean>(before: J.RightPadded<T>, q: RpcReceiveQueue): Promise<J.RightPadded<T>> {
|
|
1411
|
+
return (await receiver.visitRightPadded(before, q))!;
|
|
1412
|
+
},
|
|
1413
|
+
|
|
1414
|
+
async rpcSend<T extends J | boolean>(after: J.RightPadded<T>, q: RpcSendQueue): Promise<void> {
|
|
1415
|
+
await sender.visitRightPadded(after, q);
|
|
1416
|
+
}
|
|
1417
|
+
}, sourceFileType);
|
|
1418
|
+
} else if (kind === J.Kind.LeftPadded) {
|
|
1419
|
+
RpcCodecs.registerCodec(kind, {
|
|
1420
|
+
async rpcReceive<T extends J | Space | number | string | boolean>(before: J.LeftPadded<T>, q: RpcReceiveQueue): Promise<J.LeftPadded<T>> {
|
|
1421
|
+
return (await receiver.visitLeftPadded(before, q))!;
|
|
1422
|
+
},
|
|
1423
|
+
|
|
1424
|
+
async rpcSend<T extends J | Space | number | string | boolean>(after: J.LeftPadded<T>, q: RpcSendQueue): Promise<void> {
|
|
1425
|
+
await sender.visitLeftPadded(after, q);
|
|
1426
|
+
}
|
|
1427
|
+
}, sourceFileType);
|
|
1428
|
+
} else if (kind === J.Kind.Container) {
|
|
1429
|
+
RpcCodecs.registerCodec(kind, {
|
|
1430
|
+
async rpcReceive<T extends J>(before: J.Container<T>, q: RpcReceiveQueue): Promise<J.Container<T>> {
|
|
1431
|
+
return (await receiver.visitContainer(before, q))!;
|
|
1432
|
+
},
|
|
1433
|
+
|
|
1434
|
+
async rpcSend<T extends J>(after: J.Container<T>, q: RpcSendQueue): Promise<void> {
|
|
1435
|
+
await sender.visitContainer(after, q);
|
|
1436
|
+
}
|
|
1437
|
+
}, sourceFileType);
|
|
1438
|
+
} else {
|
|
1439
|
+
RpcCodecs.registerCodec(kind as string, {
|
|
1440
|
+
async rpcReceive(before: J, q: RpcReceiveQueue): Promise<J> {
|
|
1441
|
+
return (await receiver.visit(before, q))!;
|
|
1442
|
+
},
|
|
1443
|
+
|
|
1444
|
+
async rpcSend(after: J, q: RpcSendQueue): Promise<void> {
|
|
1445
|
+
await sender.visit(after, q);
|
|
1446
|
+
}
|
|
1447
|
+
}, sourceFileType);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
registerJLanguageCodecs(J.Kind.CompilationUnit, new JavaReceiver(), new JavaSender());
|
package/src/java/tree.ts
CHANGED
|
@@ -17,19 +17,32 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import {emptyMarkers, Markers} from "../markers";
|
|
20
|
-
import {SourceFile, Tree
|
|
20
|
+
import {SourceFile, Tree} from "../tree";
|
|
21
21
|
import {Type} from "./type";
|
|
22
|
-
import {RpcCodec, RpcCodecs, RpcReceiveQueue, RpcSendQueue} from "../rpc";
|
|
23
|
-
import {JavaReceiver, JavaSender} from "./rpc";
|
|
24
|
-
import Space = J.Space;
|
|
25
22
|
|
|
26
23
|
export interface J extends Tree {
|
|
27
24
|
readonly prefix: J.Space;
|
|
28
25
|
}
|
|
29
26
|
|
|
27
|
+
export namespace J {
|
|
28
|
+
export function isMethodCall(e?: Expression): e is MethodCall {
|
|
29
|
+
return e?.kind === J.Kind.NewClass ||
|
|
30
|
+
e?.kind === J.Kind.MethodInvocation ||
|
|
31
|
+
e?.kind === J.Kind.MemberReference;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function hasType<T extends J>(tree: T): tree is T & { type: Type } {
|
|
35
|
+
return tree && 'type' in tree && tree.type != null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
export interface Expression extends J {
|
|
31
40
|
}
|
|
32
41
|
|
|
42
|
+
export interface MethodCall extends Expression {
|
|
43
|
+
readonly methodType?: Type.Method;
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
export interface TypedTree extends J {
|
|
34
47
|
}
|
|
35
48
|
|
|
@@ -461,13 +474,12 @@ export namespace J {
|
|
|
461
474
|
readonly codePoint: string;
|
|
462
475
|
}
|
|
463
476
|
|
|
464
|
-
export interface MemberReference extends J,
|
|
477
|
+
export interface MemberReference extends J, MethodCall {
|
|
465
478
|
readonly kind: typeof Kind.MemberReference;
|
|
466
479
|
readonly containing: RightPadded<Expression>;
|
|
467
480
|
readonly typeParameters?: Container<Expression>;
|
|
468
481
|
readonly reference: LeftPadded<Identifier>;
|
|
469
482
|
readonly type?: Type;
|
|
470
|
-
readonly methodType?: Type.Method;
|
|
471
483
|
readonly variableType?: Type.Variable;
|
|
472
484
|
}
|
|
473
485
|
|
|
@@ -486,13 +498,12 @@ export namespace J {
|
|
|
486
498
|
readonly methodType?: Type.Method;
|
|
487
499
|
}
|
|
488
500
|
|
|
489
|
-
export interface MethodInvocation extends J, TypedTree,
|
|
501
|
+
export interface MethodInvocation extends J, TypedTree, MethodCall {
|
|
490
502
|
readonly kind: typeof Kind.MethodInvocation;
|
|
491
503
|
readonly select?: RightPadded<Expression>;
|
|
492
504
|
readonly typeParameters?: Container<Expression>;
|
|
493
505
|
readonly name: Identifier;
|
|
494
506
|
readonly arguments: Container<Expression>;
|
|
495
|
-
readonly methodType?: Type.Method;
|
|
496
507
|
}
|
|
497
508
|
|
|
498
509
|
export interface Modifier extends J {
|
|
@@ -539,7 +550,7 @@ export namespace J {
|
|
|
539
550
|
readonly type?: Type;
|
|
540
551
|
}
|
|
541
552
|
|
|
542
|
-
export interface NewClass extends J, TypedTree,
|
|
553
|
+
export interface NewClass extends J, TypedTree, MethodCall {
|
|
543
554
|
readonly kind: typeof Kind.NewClass;
|
|
544
555
|
readonly enclosing?: RightPadded<Expression>;
|
|
545
556
|
readonly new: Space;
|
|
@@ -817,12 +828,6 @@ export interface DocComment extends Comment {
|
|
|
817
828
|
// TODO implement me!
|
|
818
829
|
}
|
|
819
830
|
|
|
820
|
-
const javaKindValues = new Set(Object.values(J.Kind));
|
|
821
|
-
|
|
822
|
-
export function isJava(tree: any): tree is J {
|
|
823
|
-
return javaKindValues.has(tree["kind"]);
|
|
824
|
-
}
|
|
825
|
-
|
|
826
831
|
export function isLiteral(tree: any): tree is J.Literal {
|
|
827
832
|
return tree["kind"] === J.Kind.Literal;
|
|
828
833
|
}
|
|
@@ -874,64 +879,3 @@ export namespace TypedTree {
|
|
|
874
879
|
registerTypeGetter(J.Kind.Wildcard, () => Type.unknownType);
|
|
875
880
|
registerTypeGetter(J.Kind.Unknown, () => Type.unknownType);
|
|
876
881
|
}
|
|
877
|
-
|
|
878
|
-
const javaReceiver = new JavaReceiver();
|
|
879
|
-
const javaSender = new JavaSender();
|
|
880
|
-
|
|
881
|
-
const javaCodec: RpcCodec<J> = {
|
|
882
|
-
async rpcReceive(before: J, q: RpcReceiveQueue): Promise<J> {
|
|
883
|
-
return (await javaReceiver.visit(before, q))!;
|
|
884
|
-
},
|
|
885
|
-
|
|
886
|
-
async rpcSend(after: J, q: RpcSendQueue): Promise<void> {
|
|
887
|
-
await javaSender.visit(after, q);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
// Register codec for all Java AST node types
|
|
892
|
-
Object.values(J.Kind).forEach(kind => {
|
|
893
|
-
if (kind === J.Kind.Space) {
|
|
894
|
-
RpcCodecs.registerCodec(kind, {
|
|
895
|
-
async rpcReceive(before: J.Space, q: RpcReceiveQueue): Promise<J.Space> {
|
|
896
|
-
return (await javaReceiver.visitSpace(before, q))!;
|
|
897
|
-
},
|
|
898
|
-
|
|
899
|
-
async rpcSend(after: J.Space, q: RpcSendQueue): Promise<void> {
|
|
900
|
-
await javaSender.visitSpace(after, q);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
);
|
|
904
|
-
} else if (kind === J.Kind.RightPadded) {
|
|
905
|
-
RpcCodecs.registerCodec(kind, {
|
|
906
|
-
async rpcReceive<T extends J | boolean>(before: J.RightPadded<T>, q: RpcReceiveQueue): Promise<J.RightPadded<T>> {
|
|
907
|
-
return (await javaReceiver.visitRightPadded(before, q))!;
|
|
908
|
-
},
|
|
909
|
-
|
|
910
|
-
async rpcSend<T extends J | boolean>(after: J.RightPadded<T>, q: RpcSendQueue): Promise<void> {
|
|
911
|
-
await javaSender.visitRightPadded(after, q);
|
|
912
|
-
}
|
|
913
|
-
})
|
|
914
|
-
} else if (kind === J.Kind.LeftPadded) {
|
|
915
|
-
RpcCodecs.registerCodec(kind, {
|
|
916
|
-
async rpcReceive<T extends J | Space | number | string | boolean>(before: J.LeftPadded<T>, q: RpcReceiveQueue): Promise<J.LeftPadded<T>> {
|
|
917
|
-
return (await javaReceiver.visitLeftPadded(before, q))!;
|
|
918
|
-
},
|
|
919
|
-
|
|
920
|
-
async rpcSend<T extends J | Space | number | string | boolean>(after: J.LeftPadded<T>, q: RpcSendQueue): Promise<void> {
|
|
921
|
-
await javaSender.visitLeftPadded(after, q);
|
|
922
|
-
}
|
|
923
|
-
})
|
|
924
|
-
} else if (kind === J.Kind.Container) {
|
|
925
|
-
RpcCodecs.registerCodec(kind, {
|
|
926
|
-
async rpcReceive<T extends J>(before: J.Container<T>, q: RpcReceiveQueue): Promise<J.Container<T>> {
|
|
927
|
-
return (await javaReceiver.visitContainer(before, q))!;
|
|
928
|
-
},
|
|
929
|
-
|
|
930
|
-
async rpcSend<T extends J>(after: J.Container<T>, q: RpcSendQueue): Promise<void> {
|
|
931
|
-
await javaSender.visitContainer(after, q);
|
|
932
|
-
}
|
|
933
|
-
})
|
|
934
|
-
} else {
|
|
935
|
-
RpcCodecs.registerCodec(kind, javaCodec);
|
|
936
|
-
}
|
|
937
|
-
});
|
package/src/java/type.ts
CHANGED
|
@@ -237,6 +237,10 @@ export namespace Type {
|
|
|
237
237
|
return type?.kind === Type.Kind.Class;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
export function isMethod(type?: Type): type is Type.Method {
|
|
241
|
+
return type?.kind === Type.Kind.Method;
|
|
242
|
+
}
|
|
243
|
+
|
|
240
244
|
export function isArray(type?: Type): type is Type.Array {
|
|
241
245
|
return type?.kind === Type.Kind.Array;
|
|
242
246
|
}
|
|
@@ -245,6 +249,16 @@ export namespace Type {
|
|
|
245
249
|
return type?.kind === Type.Kind.Parameterized;
|
|
246
250
|
}
|
|
247
251
|
|
|
252
|
+
export function isFullyQualified(type?: Type): type is Type.FullyQualified {
|
|
253
|
+
return type != null && (
|
|
254
|
+
type.kind === Type.Kind.Class ||
|
|
255
|
+
type.kind === Type.Kind.Annotation ||
|
|
256
|
+
type.kind === Type.Kind.Parameterized ||
|
|
257
|
+
type.kind === Type.Kind.Array ||
|
|
258
|
+
type.kind === Type.Kind.ShallowClass
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
248
262
|
export interface FullyQualified extends Type {
|
|
249
263
|
}
|
|
250
264
|
|
package/src/java/visitor.ts
CHANGED
|
@@ -16,17 +16,33 @@
|
|
|
16
16
|
import {Cursor, isTree, SourceFile} from "../tree";
|
|
17
17
|
import {mapAsync} from "../util";
|
|
18
18
|
import {produceAsync, TreeVisitor, ValidImmerRecipeReturnType} from "../visitor";
|
|
19
|
-
import {
|
|
20
|
-
Expression,
|
|
21
|
-
isJava,
|
|
22
|
-
isSpace,
|
|
23
|
-
J,
|
|
24
|
-
NameTree,
|
|
25
|
-
Statement, TypedTree, TypeTree
|
|
26
|
-
} from "./tree";
|
|
19
|
+
import {Expression, isSpace, J, NameTree, Statement, TypedTree, TypeTree} from "./tree";
|
|
27
20
|
import {createDraft, Draft, finishDraft} from "immer";
|
|
28
21
|
import {Type} from "./type";
|
|
29
22
|
|
|
23
|
+
const javaKindValues = new Set(Object.values(J.Kind));
|
|
24
|
+
|
|
25
|
+
const extendedJavaKinds = new Map<string, <P>(visitor: JavaVisitor<P>) => JavaVisitor<P>>();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Register additional kind values for interfaces that extend J.
|
|
29
|
+
* This allows isJava to recognize implementations of those interfaces.
|
|
30
|
+
* @param kinds - Array of kind values to register
|
|
31
|
+
* @param adapter - Adapter function to transform a JavaVisitor to, for example, a JavaScriptVisitor
|
|
32
|
+
*/
|
|
33
|
+
export function registerJavaExtensionKinds(
|
|
34
|
+
kinds: readonly string[],
|
|
35
|
+
adapter: <P>(visitor: JavaVisitor<P>) => JavaVisitor<P>
|
|
36
|
+
): void {
|
|
37
|
+
for (const kind of kinds) {
|
|
38
|
+
extendedJavaKinds.set(kind, adapter);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isJava(tree: any): tree is J {
|
|
43
|
+
return javaKindValues.has(tree["kind"]) || extendedJavaKinds.has(tree["kind"]);
|
|
44
|
+
}
|
|
45
|
+
|
|
30
46
|
export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
31
47
|
// protected javadocVisitor: any | null = null;
|
|
32
48
|
|
|
@@ -45,7 +61,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
45
61
|
}
|
|
46
62
|
|
|
47
63
|
// noinspection JSUnusedLocalSymbols
|
|
48
|
-
|
|
64
|
+
public async visitSpace(space: J.Space, p: P): Promise<J.Space> {
|
|
49
65
|
return space;
|
|
50
66
|
}
|
|
51
67
|
|
|
@@ -995,7 +1011,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
995
1011
|
return right ? this.visitRightPadded(right, p) : undefined;
|
|
996
1012
|
}
|
|
997
1013
|
|
|
998
|
-
|
|
1014
|
+
public async visitRightPadded<T extends J | boolean>(right: J.RightPadded<T>, p: P): Promise<J.RightPadded<T>> {
|
|
999
1015
|
return produceAsync<J.RightPadded<T>>(right, async draft => {
|
|
1000
1016
|
this.cursor = new Cursor(right, this.cursor);
|
|
1001
1017
|
if (isTree(right.element)) {
|
|
@@ -1011,7 +1027,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
1011
1027
|
return left ? this.visitLeftPadded(left, p) : undefined;
|
|
1012
1028
|
}
|
|
1013
1029
|
|
|
1014
|
-
|
|
1030
|
+
public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T>> {
|
|
1015
1031
|
return produceAsync<J.LeftPadded<T>>(left, async draft => {
|
|
1016
1032
|
this.cursor = new Cursor(left, this.cursor);
|
|
1017
1033
|
draft.before = await this.visitSpace(left.before, p);
|
|
@@ -1029,7 +1045,7 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
1029
1045
|
return container ? this.visitContainer(container, p) : undefined;
|
|
1030
1046
|
}
|
|
1031
1047
|
|
|
1032
|
-
|
|
1048
|
+
public async visitContainer<T extends J>(container: J.Container<T>, p: P): Promise<J.Container<T>> {
|
|
1033
1049
|
return produceAsync<J.Container<T>>(container, async draft => {
|
|
1034
1050
|
this.cursor = new Cursor(container, this.cursor);
|
|
1035
1051
|
draft.before = await this.visitSpace(container.before, p);
|
|
@@ -1200,6 +1216,10 @@ export class JavaVisitor<P> extends TreeVisitor<J, P> {
|
|
|
1200
1216
|
case J.Kind.Yield:
|
|
1201
1217
|
return this.visitYield(t as J.Yield, p);
|
|
1202
1218
|
default:
|
|
1219
|
+
const adapter = extendedJavaKinds.get(t.kind)
|
|
1220
|
+
if (adapter) {
|
|
1221
|
+
return adapter(this).visit(t, p);
|
|
1222
|
+
}
|
|
1203
1223
|
return Promise.resolve(t);
|
|
1204
1224
|
}
|
|
1205
1225
|
}
|
package/src/javascript/format.ts
CHANGED
|
@@ -159,7 +159,7 @@ export class SpacesVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
159
159
|
}) as J.ClassDeclaration;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
public async visitContainer<T extends J>(container: J.Container<T>, p: P): Promise<J.Container<T>> {
|
|
163
163
|
const ret = await super.visitContainer(container, p) as J.Container<T>;
|
|
164
164
|
return produce(ret, draft => {
|
|
165
165
|
if (draft.elements.length > 1) {
|
|
@@ -1088,7 +1088,7 @@ export class TabsAndIndentsVisitor<P> extends JavaScriptVisitor<P> {
|
|
|
1088
1088
|
});
|
|
1089
1089
|
}
|
|
1090
1090
|
|
|
1091
|
-
|
|
1091
|
+
public async visitLeftPadded<T extends J | J.Space | number | string | boolean>(left: J.LeftPadded<T>, p: P): Promise<J.LeftPadded<T>> {
|
|
1092
1092
|
const ret = await super.visitLeftPadded(left, p);
|
|
1093
1093
|
if (ret == undefined) {
|
|
1094
1094
|
return ret;
|
package/src/javascript/index.ts
CHANGED
|
@@ -19,7 +19,11 @@ export * from "./assertions";
|
|
|
19
19
|
export * from "./parser";
|
|
20
20
|
export * from "./style";
|
|
21
21
|
export * from "./markers";
|
|
22
|
+
export * from "./preconditions";
|
|
22
23
|
export * from "./templating";
|
|
24
|
+
export * from "./method-matcher";
|
|
25
|
+
|
|
26
|
+
export * from "./remove-import";
|
|
23
27
|
|
|
24
28
|
import "./print";
|
|
25
29
|
import "./rpc";
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {Type} from "../java";
|
|
2
|
+
import FullyQualified = Type.FullyQualified;
|
|
3
|
+
|
|
4
|
+
export class MethodMatcher {
|
|
5
|
+
private readonly packagePattern: string;
|
|
6
|
+
private readonly typePattern: string;
|
|
7
|
+
private readonly methodPattern: string;
|
|
8
|
+
private readonly argumentPatterns: string[];
|
|
9
|
+
|
|
10
|
+
constructor(pattern: string) {
|
|
11
|
+
// Find the last space before the method spec (which contains parentheses)
|
|
12
|
+
const firstParenIndex = pattern.indexOf('(');
|
|
13
|
+
if (firstParenIndex === -1) {
|
|
14
|
+
throw new Error(`Invalid pattern format: ${pattern} - missing method arguments`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Find the last space before the opening parenthesis
|
|
18
|
+
const lastSpaceBeforeParen = pattern.lastIndexOf(' ', firstParenIndex);
|
|
19
|
+
if (lastSpaceBeforeParen === -1) {
|
|
20
|
+
throw new Error(`Invalid pattern format: ${pattern}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const typeSpec = pattern.substring(0, lastSpaceBeforeParen).trim();
|
|
24
|
+
const methodSpec = pattern.substring(lastSpaceBeforeParen + 1).trim();
|
|
25
|
+
|
|
26
|
+
// Parse type specification (package.Type or just Type)
|
|
27
|
+
// Special case: *..* pattern (any package, any type)
|
|
28
|
+
if (typeSpec === '*..*') {
|
|
29
|
+
this.packagePattern = '*..';
|
|
30
|
+
this.typePattern = '*';
|
|
31
|
+
} else {
|
|
32
|
+
const lastDotIndex = typeSpec.lastIndexOf('.');
|
|
33
|
+
if (lastDotIndex === -1) {
|
|
34
|
+
this.packagePattern = '*';
|
|
35
|
+
this.typePattern = typeSpec;
|
|
36
|
+
} else {
|
|
37
|
+
// Check if we're splitting a *.. pattern incorrectly
|
|
38
|
+
const potentialPackage = typeSpec.substring(0, lastDotIndex);
|
|
39
|
+
if (potentialPackage.endsWith('*..')) {
|
|
40
|
+
// Don't split *.. pattern - it should stay together
|
|
41
|
+
this.packagePattern = potentialPackage;
|
|
42
|
+
this.typePattern = typeSpec.substring(lastDotIndex + 1);
|
|
43
|
+
} else {
|
|
44
|
+
this.packagePattern = potentialPackage;
|
|
45
|
+
this.typePattern = typeSpec.substring(lastDotIndex + 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Parse method specification methodName(args)
|
|
51
|
+
const methodParenIndex = methodSpec.indexOf('(');
|
|
52
|
+
if (methodParenIndex === -1 || !methodSpec.endsWith(')')) {
|
|
53
|
+
throw new Error(`Invalid method specification: ${methodSpec}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.methodPattern = methodSpec.substring(0, methodParenIndex);
|
|
57
|
+
const argsString = methodSpec.substring(methodParenIndex + 1, methodSpec.length - 1);
|
|
58
|
+
|
|
59
|
+
// Parse arguments
|
|
60
|
+
if (argsString.trim() === '..') {
|
|
61
|
+
this.argumentPatterns = ['..'];
|
|
62
|
+
} else if (argsString.trim() === '') {
|
|
63
|
+
this.argumentPatterns = [];
|
|
64
|
+
} else {
|
|
65
|
+
this.argumentPatterns = argsString.split(',').map(arg => arg.trim());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
matches(method?: Type.Method): boolean {
|
|
70
|
+
if (!method) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Extract fully qualified name from declaringType
|
|
75
|
+
const fullyQualifiedName = FullyQualified.getFullyQualifiedName(method.declaringType);
|
|
76
|
+
|
|
77
|
+
// Split fully qualified name into package and type
|
|
78
|
+
const lastDotIndex = fullyQualifiedName.lastIndexOf('.');
|
|
79
|
+
const packageName = lastDotIndex === -1 ? '' : fullyQualifiedName.substring(0, lastDotIndex);
|
|
80
|
+
const typeName = lastDotIndex === -1 ? fullyQualifiedName : fullyQualifiedName.substring(lastDotIndex + 1);
|
|
81
|
+
|
|
82
|
+
// Match package
|
|
83
|
+
if (!this.matchesPackage(packageName)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Match type (normalize primitives for matching)
|
|
88
|
+
const normalizedTypePattern = this.normalizePrimitiveType(this.typePattern);
|
|
89
|
+
const normalizedTypeName = this.normalizePrimitiveType(typeName);
|
|
90
|
+
if (!this.matchesPattern(normalizedTypePattern, normalizedTypeName)) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Match method name
|
|
95
|
+
if (!this.matchesPattern(this.methodPattern, method.name)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Match arguments - convert Type[] to string representations
|
|
100
|
+
const argStrings = method.parameterTypes.map(type => this.typeToString(type));
|
|
101
|
+
return this.matchesArguments(argStrings);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private typeToString(type: Type): string {
|
|
105
|
+
switch (type.kind) {
|
|
106
|
+
case Type.Kind.Primitive:
|
|
107
|
+
return (type as Type.Primitive).keyword;
|
|
108
|
+
case Type.Kind.Class:
|
|
109
|
+
return (type as Type.Class).fullyQualifiedName;
|
|
110
|
+
case Type.Kind.Parameterized:
|
|
111
|
+
return FullyQualified.getFullyQualifiedName((type as Type.Parameterized).type);
|
|
112
|
+
case Type.Kind.Array:
|
|
113
|
+
const arrayType = type as Type.Array;
|
|
114
|
+
return this.typeToString(arrayType.elemType) + '[]';
|
|
115
|
+
case Type.Kind.GenericTypeVariable:
|
|
116
|
+
return (type as Type.GenericTypeVariable).name;
|
|
117
|
+
default:
|
|
118
|
+
return 'unknown';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private matchesPackage(packageName?: string): boolean {
|
|
123
|
+
const pkg = packageName || '';
|
|
124
|
+
|
|
125
|
+
// Handle *..* pattern (any package including nested)
|
|
126
|
+
if (this.packagePattern === '*..') {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Handle * pattern (no package or any single-level package)
|
|
131
|
+
if (this.packagePattern === '*') {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Handle lib.* pattern (lib and any subpackage)
|
|
136
|
+
if (this.packagePattern.endsWith('.*')) {
|
|
137
|
+
const prefix = this.packagePattern.slice(0, -2);
|
|
138
|
+
return pkg === prefix || pkg.startsWith(prefix + '.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Exact match
|
|
142
|
+
return pkg === this.packagePattern;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private matchesPattern(pattern: string, value: string): boolean {
|
|
146
|
+
if (pattern === '*') {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Handle patterns with wildcards
|
|
151
|
+
if (pattern.includes('*')) {
|
|
152
|
+
// Convert pattern to regex
|
|
153
|
+
const regexPattern = pattern
|
|
154
|
+
.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special chars except *
|
|
155
|
+
.replace(/\*/g, '.*'); // Replace * with .*
|
|
156
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
157
|
+
return regex.test(value);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return pattern === value;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private matchesArguments(args: string[]): boolean {
|
|
164
|
+
// Handle .. pattern (any arguments)
|
|
165
|
+
if (this.argumentPatterns.length === 1 && this.argumentPatterns[0] === '..') {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Handle patterns with .. in arguments
|
|
170
|
+
let patternIndex = 0;
|
|
171
|
+
let argIndex = 0;
|
|
172
|
+
|
|
173
|
+
while (patternIndex < this.argumentPatterns.length && argIndex < args.length) {
|
|
174
|
+
const pattern = this.argumentPatterns[patternIndex];
|
|
175
|
+
|
|
176
|
+
if (pattern === '..') {
|
|
177
|
+
// If .. is the last pattern, it matches all remaining args
|
|
178
|
+
if (patternIndex === this.argumentPatterns.length - 1) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Otherwise, try to match the next pattern with remaining args
|
|
183
|
+
const nextPattern = this.argumentPatterns[patternIndex + 1];
|
|
184
|
+
let matched = false;
|
|
185
|
+
for (let i = argIndex; i < args.length; i++) {
|
|
186
|
+
if (this.matchesArgumentPattern(nextPattern, args[i])) {
|
|
187
|
+
argIndex = i + 1;
|
|
188
|
+
patternIndex += 2;
|
|
189
|
+
matched = true;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!matched) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
if (!this.matchesArgumentPattern(pattern, args[argIndex])) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
patternIndex++;
|
|
201
|
+
argIndex++;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Check if all patterns and arguments are consumed
|
|
206
|
+
if (patternIndex < this.argumentPatterns.length) {
|
|
207
|
+
// Allow trailing .. to match zero arguments
|
|
208
|
+
return patternIndex === this.argumentPatterns.length - 1 &&
|
|
209
|
+
this.argumentPatterns[patternIndex] === '..';
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return argIndex === args.length;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private matchesArgumentPattern(pattern: string, arg: string): boolean {
|
|
216
|
+
// Handle type patterns like lib.Array
|
|
217
|
+
if (pattern.includes('.')) {
|
|
218
|
+
// Also check if the pattern is a TypeScript primitive class (lib.Number, lib.String, lib.Boolean)
|
|
219
|
+
const normalizedPattern = this.normalizePrimitiveType(pattern);
|
|
220
|
+
const normalizedArg = this.normalizePrimitiveType(arg);
|
|
221
|
+
return normalizedPattern === normalizedArg;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Normalize TypeScript primitive names to match both primitive and class representations
|
|
225
|
+
const normalizedPattern = this.normalizePrimitiveType(pattern);
|
|
226
|
+
const normalizedArg = this.normalizePrimitiveType(arg);
|
|
227
|
+
|
|
228
|
+
return normalizedPattern === normalizedArg;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private normalizePrimitiveType(type: string): string {
|
|
232
|
+
switch (type) {
|
|
233
|
+
case 'number':
|
|
234
|
+
case 'Number':
|
|
235
|
+
case 'lib.Number':
|
|
236
|
+
case 'double':
|
|
237
|
+
return 'Number';
|
|
238
|
+
case 'string':
|
|
239
|
+
case 'String':
|
|
240
|
+
case 'lib.String':
|
|
241
|
+
return 'String';
|
|
242
|
+
case 'boolean':
|
|
243
|
+
case 'Boolean':
|
|
244
|
+
case 'lib.Boolean':
|
|
245
|
+
return 'Boolean';
|
|
246
|
+
default:
|
|
247
|
+
return type;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|