-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update ChangeType
and ChangePackage
to work with SourceFileWithReference
#4648
Changes from 7 commits
138c3fa
a2d9983
6ec8490
d49040e
1085bde
122438e
12432ce
4675e65
9e6eafd
112cc2b
a388a03
dbcae71
6cd26b7
56221b8
da2a719
53226cd
830d915
b36375b
9db1867
8a13c49
b84950e
6ad31cd
d31607b
7197966
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,13 +23,13 @@ | |
import org.openrewrite.internal.ListUtils; | ||
import org.openrewrite.java.tree.*; | ||
import org.openrewrite.marker.SearchResult; | ||
import org.openrewrite.trait.TypeReference; | ||
|
||
import java.nio.file.Paths; | ||
import java.util.HashMap; | ||
import java.util.IdentityHashMap; | ||
import java.util.Map; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* A recipe that will rename a package name in package statements, imports, and fully-qualified types (see: NOTE). | ||
* <p> | ||
|
@@ -83,11 +83,11 @@ public Validated<Object> validate() { | |
|
||
@Override | ||
public TreeVisitor<?, ExecutionContext> getVisitor() { | ||
JavaIsoVisitor<ExecutionContext> condition = new JavaIsoVisitor<ExecutionContext>() { | ||
TreeVisitor<?, ExecutionContext> condition = new TreeVisitor<Tree, ExecutionContext>() { | ||
@Override | ||
public @Nullable J preVisit(J tree, ExecutionContext ctx) { | ||
public @Nullable Tree preVisit(Tree tree, ExecutionContext ctx) { | ||
if (tree instanceof JavaSourceFile) { | ||
JavaSourceFile cu = (JavaSourceFile) requireNonNull(tree); | ||
JavaSourceFile cu = (JavaSourceFile) tree; | ||
if (cu.getPackageDeclaration() != null) { | ||
String original = cu.getPackageDeclaration().getExpression() | ||
.printTrimmed(getCursor()).replaceAll("\\s", ""); | ||
|
@@ -113,14 +113,52 @@ public TreeVisitor<?, ExecutionContext> getVisitor() { | |
} | ||
stopAfterPreVisit(); | ||
Laurens-W marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
if (tree instanceof SourceFileWithTypeReferences) { | ||
SourceFileWithTypeReferences cu = (SourceFileWithTypeReferences) tree; | ||
boolean recursive = Boolean.TRUE.equals(ChangePackage.this.recursive); | ||
String recursivePackageNamePrefix = oldPackageName + "."; | ||
for (TypeReference ref : cu.getTypeReferences().getTypeReferences()) { | ||
if (ref.getName().equals(oldPackageName) || recursive && ref.getName().startsWith(recursivePackageNamePrefix)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One example I keep thinking about here is when we have |
||
return SearchResult.found(cu); | ||
knutwannheden marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
stopAfterPreVisit(); | ||
} | ||
return super.preVisit(tree, ctx); | ||
} | ||
}; | ||
|
||
return Preconditions.check(condition, new ChangePackageVisitor()); | ||
return Preconditions.check(condition, new TreeVisitor<Tree, ExecutionContext>() { | ||
@Override | ||
public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { | ||
return sourceFile instanceof JavaSourceFile || sourceFile instanceof SourceFileWithTypeReferences; | ||
} | ||
|
||
@Override | ||
public @Nullable Tree preVisit(@Nullable Tree tree, ExecutionContext ctx) { | ||
Laurens-W marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (tree instanceof JavaSourceFile) { | ||
return new JavaChangePackageVisitor().visit(tree, ctx); | ||
Laurens-W marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else if (tree instanceof SourceFileWithTypeReferences) { | ||
SourceFileWithTypeReferences sourceFile = (SourceFileWithTypeReferences) tree; | ||
SourceFileWithTypeReferences.TypeReferences typeReferences = sourceFile.getTypeReferences(); | ||
boolean recursive = Boolean.TRUE.equals(ChangePackage.this.recursive); | ||
String recursivePackageNamePrefix = oldPackageName + "."; | ||
Map<Tree, TypeReference> matches = new HashMap<>(); | ||
for (TypeReference ref : typeReferences.getTypeReferences()) { | ||
if (ref.supportsRename()) { | ||
if (ref.getName().equals(oldPackageName) || recursive && ref.getName().startsWith(recursivePackageNamePrefix)) { | ||
matches.put(tree, ref); | ||
} | ||
} | ||
} | ||
return new TypeReferenceChangePackageVisitor(matches, oldPackageName, newPackageName).visit(tree, ctx, getCursor().getParent()); | ||
} | ||
return tree; | ||
} | ||
}); | ||
} | ||
|
||
private class ChangePackageVisitor extends JavaVisitor<ExecutionContext> { | ||
private class JavaChangePackageVisitor extends JavaVisitor<ExecutionContext> { | ||
private static final String RENAME_TO_KEY = "renameTo"; | ||
private static final String RENAME_FROM_KEY = "renameFrom"; | ||
|
||
|
@@ -349,4 +387,23 @@ private boolean isTargetRecursivePackageName(String packageName) { | |
} | ||
|
||
} | ||
|
||
@Value | ||
@EqualsAndHashCode(callSuper = false) | ||
private static class TypeReferenceChangePackageVisitor extends TreeVisitor<Tree, ExecutionContext> { | ||
Map<Tree, TypeReference> matches; | ||
String oldPackageName; | ||
String newPackageName; | ||
|
||
@Override | ||
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) { | ||
Laurens-W marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Tree tree1 = super.visit(tree, ctx); | ||
TypeReference ref = matches.get(tree); | ||
if (ref != null) { | ||
return ref.renameTo(ref.getName().replace(oldPackageName, newPackageName)).visit(tree, ctx, getCursor().getParent()); | ||
} | ||
return tree1; | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should consider renaming this to something more generic like SymbolReference or just Reference and then have a "kind" property, which would probably be an enum like
Kind
with constants forType
andNamespace
(orPackage
) for now.That "name" property will probably also have to be complemented by a structured "symbol" property at some point (so that the caller can query a method reference for name, declaring type, and parameters). But this can wait, I think.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree but I also feel like this is a creep of the scope, could we log it somewhere as future improvement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. It would just be good if we could get the API finalized before people try to start using it.