diff --git a/rewrite-java-test/src/test/java/org/openrewrite/java/RenameVariableTest.java b/rewrite-java-test/src/test/java/org/openrewrite/java/RenameVariableTest.java index 63f2e64fe42..75ef8d00cf9 100644 --- a/rewrite-java-test/src/test/java/org/openrewrite/java/RenameVariableTest.java +++ b/rewrite-java-test/src/test/java/org/openrewrite/java/RenameVariableTest.java @@ -77,33 +77,33 @@ void renameFieldWithSameNameAsParameterWithJavaDoc() { spec -> spec.recipe(renameVariableTest("name", "_name", false)), java( """ - public class A { - private String name; - - /** - * The length of name added to the length of {@link #name}. - * - * @param name My parameter. - */ - int fooA(String name) { - return name.length() + this.name.length(); - } - } - """, - """ - public class A { - private String _name; - - /** - * The length of name added to the length of {@link #_name}. - * - * @param name My parameter. - */ - int fooA(String name) { - return name.length() + this._name.length(); - } - } + public class A { + private String name; + + /** + * The length of name added to the length of {@link #name}. + * + * @param name My parameter. + */ + int fooA(String name) { + return name.length() + this.name.length(); + } + } + """, """ + public class A { + private String _name; + + /** + * The length of name added to the length of {@link #_name}. + * + * @param name My parameter. + */ + int fooA(String name) { + return name.length() + this._name.length(); + } + } + """ ) ); } @@ -180,7 +180,7 @@ void isParameterizedClass() { java( """ package org.openrewrite; - + public class A { private String _val; private String name; @@ -193,7 +193,7 @@ public class A { """, """ package org.openrewrite; - + public class A { private String v; private String name; @@ -820,7 +820,7 @@ public J visitVariableDeclarations(J.VariableDeclarations multiVariable, Executi """ public class B { int n; - + { n++; // do not change. int n; @@ -838,7 +838,7 @@ public int foo(int n) { """ public class B { int n; - + { n++; // do not change. int n1; @@ -955,4 +955,44 @@ class A { ) ); } + + @Test + @Issue("https://github.com/openrewrite/rewrite/issues/4059") + void renameTypeCastedField() { + rewriteRun( + spec -> spec.recipe(renameVariableTest("objArray", "objects", false)), + java( + """ + import java.util.Arrays; + + public class A { + private Object[] objArray; + + public boolean isEqualTo(Object object) { + return Arrays.equals(objArray, ((A) object).objArray); + } + + public int length() { + return objArray.length; + } + } + """, + """ + import java.util.Arrays; + + public class A { + private Object[] objects; + + public boolean isEqualTo(Object object) { + return Arrays.equals(objects, ((A) object).objects); + } + + public int length() { + return objects.length; + } + } + """ + ) + ); + } } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/RenameVariable.java b/rewrite-java/src/main/java/org/openrewrite/java/RenameVariable.java index 09407432bf8..b7c98f77923 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/RenameVariable.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/RenameVariable.java @@ -152,18 +152,53 @@ private boolean isVariableName(Object value, J.Identifier ident) { * FieldAccess targets the variable if its target is an Identifier and either * its target FieldType equals variable.Name.FieldType * or its target Type equals variable.Name.FieldType.Owner + * or if FieldAccess targets a TypCast and either + * its type equals variable.Name.FieldType + * or its type equals variable.Name.FieldType.Owner. + * In case the FieldAccess targets another FieldAccess, the target is followed + * until it is either an Identifier or a TypeCast. */ private boolean fieldAccessTargetsVariable(J.FieldAccess fieldAccess) { - if (renameVariable.getName().getFieldType() != null && fieldAccess.getTarget() instanceof J.Identifier) { - J.Identifier fieldAccessTarget = (J.Identifier) fieldAccess.getTarget(); + if (renameVariable.getName().getFieldType() != null) { + Expression target = getTarget(fieldAccess); + JavaType targetType = resolveType(target.getType()); JavaType.Variable variableNameFieldType = renameVariable.getName().getFieldType(); - JavaType fieldAccessTargetType = fieldAccessTarget.getType() instanceof JavaType.Parameterized ? ((JavaType.Parameterized) fieldAccessTarget.getType()).getType() : fieldAccessTarget.getType(); - return variableNameFieldType.equals(fieldAccessTarget.getFieldType()) || - (fieldAccessTargetType != null && fieldAccessTargetType.equals(variableNameFieldType.getOwner())); + if (TypeUtils.isOfType(variableNameFieldType.getOwner(), targetType)) { + return true; + } + if (target instanceof J.TypeCast) { + return TypeUtils.isOfType(variableNameFieldType, targetType); + } else if (target instanceof J.Identifier) { + return TypeUtils.isOfType(variableNameFieldType, ((J.Identifier) target).getFieldType()); + } } return false; } + @Nullable + private Expression getTarget(J.FieldAccess fieldAccess) { + Expression target = fieldAccess.getTarget(); + if (target instanceof J.Identifier) { + return target; + } + if (target instanceof J.FieldAccess) { + return getTarget((J.FieldAccess) target); + } + if (target instanceof J.Parentheses) { + J tree = ((J.Parentheses) target).getTree(); + if (tree instanceof J.TypeCast) { + return (J.TypeCast) tree; + } + return null; + } + return null; + } + + @Nullable + private JavaType resolveType(@Nullable JavaType type) { + return type instanceof JavaType.Parameterized ? ((JavaType.Parameterized) type).getType() : type; + } + @Override public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations.NamedVariable namedVariable, P p) { boolean nameEquals = namedVariable.getSimpleName().equals(renameVariable.getSimpleName());