18
18
import lombok .EqualsAndHashCode ;
19
19
import lombok .Value ;
20
20
import org .jspecify .annotations .Nullable ;
21
- import org .openrewrite .*;
21
+ import org .openrewrite .Cursor ;
22
+ import org .openrewrite .ExecutionContext ;
23
+ import org .openrewrite .Option ;
24
+ import org .openrewrite .Preconditions ;
25
+ import org .openrewrite .Recipe ;
26
+ import org .openrewrite .SourceFile ;
27
+ import org .openrewrite .SourceFileWithReferences ;
28
+ import org .openrewrite .Tree ;
29
+ import org .openrewrite .TreeVisitor ;
22
30
import org .openrewrite .internal .ListUtils ;
31
+ import org .openrewrite .internal .StringUtils ;
23
32
import org .openrewrite .java .search .UsesType ;
24
- import org .openrewrite .java .tree .*;
33
+ import org .openrewrite .java .tree .Expression ;
34
+ import org .openrewrite .java .tree .Flag ;
35
+ import org .openrewrite .java .tree .J ;
36
+ import org .openrewrite .java .tree .JavaSourceFile ;
37
+ import org .openrewrite .java .tree .JavaType ;
38
+ import org .openrewrite .java .tree .Space ;
39
+ import org .openrewrite .java .tree .TypeTree ;
40
+ import org .openrewrite .java .tree .TypeUtils ;
41
+ import org .openrewrite .java .tree .TypedTree ;
25
42
import org .openrewrite .marker .Markers ;
26
43
import org .openrewrite .marker .SearchResult ;
27
44
import org .openrewrite .trait .Reference ;
28
45
29
46
import java .nio .file .Path ;
30
47
import java .nio .file .Paths ;
31
- import java .util .*;
48
+ import java .util .HashMap ;
49
+ import java .util .HashSet ;
50
+ import java .util .IdentityHashMap ;
51
+ import java .util .Map ;
52
+ import java .util .Optional ;
53
+ import java .util .Set ;
54
+ import java .util .Stack ;
32
55
import java .util .concurrent .atomic .AtomicBoolean ;
33
56
34
57
import static java .util .Objects .requireNonNull ;
58
+ import static org .openrewrite .internal .StringUtils .decapitalize ;
35
59
36
60
@ Value
37
61
@ EqualsAndHashCode (callSuper = false )
@@ -49,7 +73,7 @@ public class ChangeType extends Recipe {
49
73
50
74
@ Option (displayName = "Ignore type definition" ,
51
75
description = "When set to `true` the definition of the old type will be left untouched. " +
52
- "This is useful when you're replacing usage of a class but don't want to rename it." ,
76
+ "This is useful when you're replacing usage of a class but don't want to rename it." ,
53
77
required = false )
54
78
@ Nullable
55
79
Boolean ignoreDefinition ;
@@ -337,7 +361,7 @@ public J visitFieldAccess(J.FieldAccess fieldAccess, ExecutionContext ctx) {
337
361
public J visitIdentifier (J .Identifier ident , ExecutionContext ctx ) {
338
362
// Do not modify the identifier if it's on a inner class definition.
339
363
if (Boolean .TRUE .equals (ignoreDefinition ) && getCursor ().getParent () != null &&
340
- getCursor ().getParent ().getValue () instanceof J .ClassDeclaration ) {
364
+ getCursor ().getParent ().getValue () instanceof J .ClassDeclaration ) {
341
365
return super .visitIdentifier (ident , ctx );
342
366
}
343
367
// if the ident's type is equal to the type we're looking for, and the classname of the type we're looking for is equal to the ident's string representation
@@ -368,13 +392,26 @@ public J visitIdentifier(J.Identifier ident, ExecutionContext ctx) {
368
392
}
369
393
}
370
394
395
+ // Rename variable if it matches class name (starting with a lowercase character)
396
+ if (ident .getSimpleName ().equals (decapitalize (className ))) {
397
+ if (targetType instanceof JavaType .FullyQualified ) {
398
+ String newName = decapitalize (((JavaType .FullyQualified ) targetType ).getClassName ());
399
+
400
+ ident = ident .withSimpleName (newName );
401
+
402
+ if (ident .getFieldType () != null ) {
403
+ ident = ident .withFieldType (ident .getFieldType ().withName (newName ));
404
+ }
405
+ }
406
+ }
407
+
371
408
// Recreate any static imports as needed
372
409
if (sf != null ) {
373
410
for (J .Import anImport : sf .getImports ()) {
374
411
if (anImport .isStatic () && anImport .getQualid ().getTarget ().getType () != null ) {
375
412
JavaType .FullyQualified fqn = TypeUtils .asFullyQualified (anImport .getQualid ().getTarget ().getType ());
376
413
if (fqn != null && TypeUtils .isOfClassType (fqn , originalType .getFullyQualifiedName ()) &&
377
- ident .getSimpleName ().equals (anImport .getQualid ().getSimpleName ())) {
414
+ ident .getSimpleName ().equals (anImport .getQualid ().getSimpleName ())) {
378
415
JavaType .FullyQualified targetFqn = (JavaType .FullyQualified ) targetType ;
379
416
maybeAddImport ((targetFqn ).getFullyQualifiedName (), ident .getSimpleName ());
380
417
break ;
@@ -387,6 +424,15 @@ public J visitIdentifier(J.Identifier ident, ExecutionContext ctx) {
387
424
return visitAndCast (ident , ctx , super ::visitIdentifier );
388
425
}
389
426
427
+ @ Override
428
+ public J .VariableDeclarations .NamedVariable visitVariable (J .VariableDeclarations .NamedVariable variable , ExecutionContext executionContext ) {
429
+ J .VariableDeclarations .NamedVariable v = (J .VariableDeclarations .NamedVariable ) super .visitVariable (variable , executionContext );
430
+ if (v .getVariableType () != null && !v .getSimpleName ().equals (v .getVariableType ().getName ())) {
431
+ return v .withVariableType (v .getVariableType ().withName (v .getSimpleName ()));
432
+ }
433
+ return v ;
434
+ }
435
+
390
436
@ Override
391
437
public J visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
392
438
if (method .getMethodType () != null && method .getMethodType ().hasFlags (Flag .Static )) {
@@ -397,7 +443,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx)
397
443
if (anImport .isStatic () && anImport .getQualid ().getTarget ().getType () != null ) {
398
444
JavaType .FullyQualified fqn = TypeUtils .asFullyQualified (anImport .getQualid ().getTarget ().getType ());
399
445
if (fqn != null && TypeUtils .isOfClassType (fqn , originalType .getFullyQualifiedName ()) &&
400
- method .getSimpleName ().equals (anImport .getQualid ().getSimpleName ())) {
446
+ method .getSimpleName ().equals (anImport .getQualid ().getSimpleName ())) {
401
447
JavaType .FullyQualified targetFqn = (JavaType .FullyQualified ) targetType ;
402
448
403
449
addImport (targetFqn );
@@ -567,9 +613,9 @@ private boolean hasNoConflictingImport(@Nullable JavaSourceFile sf) {
567
613
for (J .Import anImport : sf .getImports ()) {
568
614
JavaType .FullyQualified currType = TypeUtils .asFullyQualified (anImport .getQualid ().getType ());
569
615
if (currType != null &&
570
- !TypeUtils .isOfType (currType , oldType ) &&
571
- !TypeUtils .isOfType (currType , newType ) &&
572
- currType .getClassName ().equals (newType .getClassName ())) {
616
+ !TypeUtils .isOfType (currType , oldType ) &&
617
+ !TypeUtils .isOfType (currType , newType ) &&
618
+ currType .getClassName ().equals (newType .getClassName ())) {
573
619
return false ;
574
620
}
575
621
}
@@ -640,8 +686,8 @@ private String fqnToPath(String fullyQualifiedName) {
640
686
private boolean updatePath (JavaSourceFile sf , String oldPath , String newPath ) {
641
687
return !oldPath .equals (newPath ) && sf .getClasses ().stream ()
642
688
.anyMatch (o -> !o .hasModifier (J .Modifier .Type .Private ) &&
643
- o .getType () != null && !o .getType ().getFullyQualifiedName ().contains ("$" ) &&
644
- TypeUtils .isOfClassType (o .getType (), getTopLevelClassName (originalType ).getFullyQualifiedName ()));
689
+ o .getType () != null && !o .getType ().getFullyQualifiedName ().contains ("$" ) &&
690
+ TypeUtils .isOfClassType (o .getType (), getTopLevelClassName (originalType ).getFullyQualifiedName ()));
645
691
}
646
692
647
693
@ Override
0 commit comments