Skip to content

Commit 5c21a88

Browse files
authored
fix: renaming of generics (#6458)
1 parent cb8fe84 commit 5c21a88

File tree

4 files changed

+108
-4
lines changed

4 files changed

+108
-4
lines changed

src/main/java/spoon/refactoring/Refactoring.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public static void changeTypeName(final CtType<?> type, String name) {
4545
final List<CtTypeReference<?>> references = Query.getElements(type.getFactory(), new TypeFilter<CtTypeReference<?>>(CtTypeReference.class) {
4646
@Override
4747
public boolean matches(CtTypeReference<?> reference) {
48-
String refFQN = reference.getQualifiedName();
49-
return typeQFN.equals(refFQN);
48+
return type == reference.getDeclaration();
5049
}
5150
});
5251

@@ -79,7 +78,6 @@ public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
7978
* If the method is a CtAnnotationMethod, the references in the annotations are changed too.
8079
*/
8180
public static void changeMethodName(final CtMethod<?> method, String newName) {
82-
8381
renameExecutableReferences(method, newName);
8482

8583
if (method instanceof CtAnnotationMethod<?> annotationMethod) {

src/test/java/spoon/test/refactoring/RefactoringTest.java

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@
5656
import spoon.support.compiler.VirtualFile;
5757
import spoon.test.refactoring.processors.ThisTransformationProcessor;
5858
import spoon.test.refactoring.testclasses.AClass;
59+
import spoon.test.refactoring.testclasses.GenericRenaming;
60+
import spoon.test.refactoring.testclasses.MethodGenericRenaming;
61+
import spoon.testing.utils.ModelUtils;
5962
import spoon.test.refactoring.testclasses.AnnotationMethodRenaming;
6063
import spoon.test.refactoring.testclasses.ExampleAnnotation;
6164
import spoon.test.refactoring.testclasses.InterfaceRenaming;
6265
import spoon.test.refactoring.testclasses.MethodRenaming;
63-
import spoon.testing.utils.ModelUtils;
6466

6567
public class RefactoringTest {
6668
@Test
@@ -223,6 +225,69 @@ void renameClassInVirtualFile() {
223225
);
224226
}
225227

228+
@Test
229+
void testRenameType() throws Exception {
230+
Factory factory = ModelUtils.build(GenericRenaming.class);
231+
CtClass<?> clazz = factory.Class().get(GenericRenaming.class);
232+
var nestedClass = clazz.getNestedType("SomeNestedType");
233+
Refactoring.changeTypeName(nestedClass, "RenamedNestedType");
234+
235+
assertEquals("RenamedNestedType", nestedClass.getSimpleName());
236+
237+
var refs = clazz.getElements(new TypeFilter<>(CtTypeReference.class)).stream().filter(t -> t.getSimpleName().equals("RenamedNestedType")).toList();
238+
assertEquals(2, refs.size());
239+
for (var ref : refs) {
240+
assertEquals(nestedClass, ref.getDeclaration());
241+
}
242+
}
243+
244+
@Test
245+
void testRenameGenerics() throws Exception {
246+
Factory factory = ModelUtils.build(GenericRenaming.class);
247+
CtClass<?> clazz = factory.Class().get(GenericRenaming.class);
248+
List<CtType<?>> types = clazz.getElements(new TypeFilter<>(CtType.class));
249+
250+
renameAndCheckClassGeneric(clazz, types, "SomeIdentifier", "TNew1", 15);
251+
renameAndCheckClassGeneric(clazz, types, "SomeOther", "TNew2", 17);
252+
renameAndCheckMethodGeneric(clazz, "doTheThing", types, "SomeMethodGeneric", "TNew3", 2);
253+
}
254+
255+
@Test
256+
void testRenameGenericsShouldRespectScope() throws Exception {
257+
Factory factory = ModelUtils.build(MethodGenericRenaming.class);
258+
CtClass<?> clazz = factory.Class().get(MethodGenericRenaming.class);
259+
List<CtType<?>> types = clazz.getElements(new TypeFilter<>(CtType.class));
260+
renameAndCheckMethodGeneric(clazz, "sort", types, "T", "TNew", 3);
261+
}
262+
263+
private static void renameAndCheckMethodGeneric(CtClass<?> clazz, String method, List<CtType<?>> types, String oldName, String newName, int expectedRefs) {
264+
var generic = clazz.getMethodsByName(method).get(0).getElements(new TypeFilter<>(CtType.class))
265+
.stream().filter(t -> t.getSimpleName().equals(oldName)).findFirst().orElseThrow();
266+
Refactoring.changeTypeName(generic, newName);
267+
assertEquals(newName, generic.getSimpleName());
268+
269+
var typeRefs = clazz.getElements(new TypeFilter<>(CtTypeReference.class))
270+
.stream().filter(typeRef -> typeRef.getSimpleName().equals(newName)).toList();
271+
assertEquals(expectedRefs, typeRefs.size());
272+
for (var typeRef : typeRefs) {
273+
assertEquals(generic.getParent(CtMethod.class), typeRef.getParent(CtMethod.class));
274+
}
275+
}
276+
277+
private static void renameAndCheckClassGeneric(CtClass<?> clazz, List<CtType<?>> types, String oldName, String newName, int expectedRefs) {
278+
var classGeneric = types.stream().filter((CtType<?> t) -> t.getSimpleName().equals(oldName)).findFirst().orElseThrow();
279+
Refactoring.changeTypeName(classGeneric, newName);
280+
assertEquals(newName, classGeneric.getSimpleName());
281+
282+
var typeRefs = clazz.getElements(new TypeFilter<>(CtTypeReference.class))
283+
.stream().filter(typeRef -> typeRef.getSimpleName().equals(newName)).toList();
284+
285+
assertEquals(expectedRefs, typeRefs.size());
286+
for (var typeRef : typeRefs) {
287+
assertEquals(classGeneric, typeRef.getDeclaration());
288+
}
289+
}
290+
226291
@Test
227292
void testChangeMethodName() throws Exception {
228293
String newName = "methodRenamed";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package spoon.test.refactoring.testclasses;
2+
3+
public class GenericRenaming<SomeIdentifier, SomeOther> {
4+
private SomeIdentifier content;
5+
private SomeOther header;
6+
7+
public GenericRenaming() {
8+
new SomeNestedType();
9+
}
10+
11+
public void setContent(SomeIdentifier content, SomeOther header) {
12+
this.content = content;
13+
this.header = header;
14+
}
15+
16+
public <SomeMethodGeneric extends SomeOther> SomeMethodGeneric doTheThing() {
17+
return (SomeMethodGeneric) header;
18+
}
19+
20+
public SomeIdentifier getContent() {
21+
return content;
22+
}
23+
24+
public SomeOther getHeader() {
25+
return header;
26+
}
27+
28+
public class SomeNestedType {
29+
}
30+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package spoon.test.refactoring.testclasses;
2+
3+
public class MethodGenericRenaming {
4+
public <T> T[] sort(T[] array) {
5+
return sort(array, false);
6+
}
7+
8+
public <T> T[] sort(T[] array, boolean order) {
9+
return array;
10+
}
11+
}

0 commit comments

Comments
 (0)