All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.java.ChangeType Maven / Gradle / Ivy

/*
 * Copyright 2020 the original author or authors.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openrewrite.java; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; import org.openrewrite.Tree; import org.openrewrite.Validated; import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.tree.*; import java.util.ArrayList; import java.util.List; import static org.openrewrite.Tree.randomId; import static org.openrewrite.Validated.required; /** * NOTE: Does not currently transform all possible type references, and accomplishing this would be non-trivial. * For example, a method invocation select might refer to field `A a` whose type has now changed to `A2`, and so the type * on the select should change as well. But how do we identify the set of all method selects which refer to `a`? Suppose * it were prefixed like `this.a`, or `MyClass.this.a`, or indirectly via a separate method call like `getA()` where `getA()` * is defined on the super class. */ public class ChangeType extends JavaIsoRefactorVisitor { private String type; private JavaType.Class targetType; public void setType(String type) { this.type = type; } public void setTargetType(String targetType) { this.targetType = JavaType.Class.build(targetType); } public void setTargetType(JavaType.Class targetType) { this.targetType = targetType; } @Override public Validated validate() { return required("type", type) .and(required("target.type", targetType.getFullyQualifiedName())); } @Override public Iterable getTags() { return Tags.of("type", type, "target.type", targetType.getFullyQualifiedName()); } @Override public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu) { maybeAddImport(targetType); maybeRemoveImport(type); return super.visitCompilationUnit(cu); } @Override public NameTree visitTypeName(NameTree name) { JavaType.Class oldTypeAsClass = TypeUtils.asClass(name.getType()); NameTree n = super.visitTypeName(name); if (!(name instanceof TypeTree) && oldTypeAsClass != null && oldTypeAsClass.getFullyQualifiedName().equals(type)) { n = n.withType(targetType); } return n; } @Override public J.Annotation visitAnnotation(J.Annotation annotation) { J.Annotation a = super.visitAnnotation(annotation); return a.withAnnotationType(transformName(a.getAnnotationType())); } @Override public J.ArrayType visitArrayType(J.ArrayType arrayType) { J.ArrayType a = super.visitArrayType(arrayType); return a.withElementType(transformName(a.getElementType())); } @Override public J.ClassDecl visitClassDecl(J.ClassDecl classDecl) { J.ClassDecl c = super.visitClassDecl(classDecl); if (c.getExtends() != null) { c = c.withExtends(c.getExtends().withFrom(transformName(c.getExtends().getFrom()))); } if (c.getImplements() != null) { c = c.withImplements(c.getImplements().withFrom(transformNames(c.getImplements().getFrom()))); } return c; } @Override public J.FieldAccess visitFieldAccess(J.FieldAccess fieldAccess) { J.FieldAccess f = super.visitFieldAccess(fieldAccess); if (f.isFullyQualifiedClassReference(type)) { return TreeBuilder.buildName(targetType.getFullyQualifiedName(), f.getFormatting(), f.getId()); } return f; } @Override public J.Ident visitIdentifier(J.Ident ident) { // 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 // Then transform it, otherwise leave it alone J.Ident i = super.visitIdentifier(ident); JavaType.Class originalType = JavaType.Class.build(type); if (TypeUtils.isOfClassType(i.getType(), type) && i.getSimpleName().equals(originalType.getClassName())) { i = i.withName(targetType.getClassName()); i = i.withType(targetType); } return i; } @Override public J.MethodDecl visitMethod(J.MethodDecl method) { J.MethodDecl m = super.visitMethod(method); m = m.withReturnTypeExpr(transformName(m.getReturnTypeExpr())); return m.withThrows(m.getThrows() == null ? null : m.getThrows().withExceptions(transformNames(m.getThrows().getExceptions()))); } @Override public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method) { J.MethodInvocation m = super.visitMethodInvocation(method); if (m.getSelect() instanceof NameTree && m.getType() != null && m.getType().hasFlags(Flag.Static)) { m = m.withSelect(transformName(m.getSelect())); } if (m.getSelect() != null) { JavaType.Class selectType = TypeUtils.asClass(m.getSelect().getType()); if (selectType != null && selectType.getFullyQualifiedName().equals(type)) { m = m.withSelect(m.getSelect().withType(targetType)); } } if (m.getType() != null) { if(m.getType().getDeclaringType().getFullyQualifiedName().equals(type)) { m = m.withDeclaringType(targetType); } } return m; } @Override public J.MultiCatch visitMultiCatch(J.MultiCatch multiCatch) { J.MultiCatch m = super.visitMultiCatch(multiCatch); return m.withAlternatives(transformNames(m.getAlternatives())); } @Override public J.VariableDecls visitMultiVariable(J.VariableDecls multiVariable) { if (multiVariable.getTypeExpr() instanceof J.MultiCatch) { return super.visitMultiVariable(multiVariable); } J.VariableDecls m = super.visitMultiVariable(multiVariable); return m.withTypeExpr(transformName(m.getTypeExpr())); } @Override public J.VariableDecls.NamedVar visitVariable(J.VariableDecls.NamedVar variable) { J.VariableDecls.NamedVar v = super.visitVariable(variable); JavaType.Class varType = TypeUtils.asClass(variable.getType()); if (varType != null && varType.getFullyQualifiedName().equals(type)) { v = v.withType(targetType).withName(v.getName().withType(targetType)); } return v; } @Override public J.NewArray visitNewArray(J.NewArray newArray) { J.NewArray n = super.visitNewArray(newArray); return n.withTypeExpr(transformName(n.getTypeExpr())); } @Override public J.NewClass visitNewClass(J.NewClass newClass) { J.NewClass n = super.visitNewClass(newClass); return n.withClazz(transformName(n.getClazz())); } @Override public J.TypeCast visitTypeCast(J.TypeCast typeCast) { J.TypeCast t = super.visitTypeCast(typeCast); return t.withClazz(t.getClazz().withTree(transformName(t.getClazz().getTree()))); } @Override public J.TypeParameter visitTypeParameter(J.TypeParameter typeParam) { J.TypeParameter t = super.visitTypeParameter(typeParam); t = t.withBounds(t.getBounds() == null ? null : t.getBounds().withTypes(transformNames(t.getBounds().getTypes()))); return t.withName(transformName(t.getName())); } @Override public J.Wildcard visitWildcard(J.Wildcard wildcard) { J.Wildcard w = super.visitWildcard(wildcard); return w.withBoundedType(transformName(w.getBoundedType())); } @SuppressWarnings("unchecked") private T transformName(@Nullable T nameField) { if (nameField instanceof NameTree) { JavaType.Class nameTreeClass = TypeUtils.asClass(((NameTree) nameField).getType()); if (nameTreeClass != null && nameTreeClass.getFullyQualifiedName().equals(type)) { return (T) J.Ident.build(randomId(), targetType.getClassName(), targetType, nameField.getFormatting()); } } return nameField; } @SuppressWarnings("unchecked") private List transformNames(@Nullable List trees) { if (trees == null) { return null; } boolean atLeastOneChanged = false; List transformed = new ArrayList<>(); for (T tree : trees) { if (tree instanceof NameTree) { JavaType.Class nodeTypeAsClass = TypeUtils.asClass(((NameTree) tree).getType()); if (nodeTypeAsClass != null && nodeTypeAsClass.getFullyQualifiedName().equals(type)) { atLeastOneChanged = true; transformed.add((T) J.Ident.build(randomId(), targetType.getClassName(), targetType, tree.getFormatting())); continue; } } transformed.add(tree); } return atLeastOneChanged ? transformed : trees; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy