Issue 52177. Fix rename refactoring for type parameter of a class.

It does not work for function / method type parameters though.

Bug: https://github.com/dart-lang/sdk/issues/52177
Change-Id: I51ae5379425e156640ae32d0cea6fd59cdc62b15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298960
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-04-27 04:51:26 +00:00 committed by Commit Queue
parent 5ef021b116
commit ea2d6a7659
3 changed files with 121 additions and 0 deletions

View file

@ -488,6 +488,8 @@ abstract class RenameRefactoring implements Refactoring {
nameNode = node.name;
} else if (node is SimpleIdentifier) {
nameNode = node.token;
} else if (node is TypeParameter) {
nameNode = node.name;
} else if (node is VariableDeclaration) {
nameNode = node.name;
}

View file

@ -1086,6 +1086,12 @@ void f(A a) {
''', 'test();');
}
Future<void> test_rename_hasElement_typeParameter_class() {
return assertHasRenameRefactoring('''
class A<T> {}
''', 'T> {}');
}
Future<void> test_rename_noElement() async {
addTestFile('''
void f() {
@ -1682,6 +1688,36 @@ void f() {
});
}
Future<void> test_class_typeParameter_atDeclaration() {
addTestFile('''
class A<Test> {
void foo(Test a) {}
}
''');
return assertSuccessfulRefactoring(() {
return sendRenameRequest('Test> {', 'NewName');
}, '''
class A<NewName> {
void foo(NewName a) {}
}
''');
}
Future<void> test_class_typeParameter_atReference() {
addTestFile('''
class A<Test> {
final List<Test> values = [];
}
''');
return assertSuccessfulRefactoring(() {
return sendRenameRequest('Test> values', 'NewName');
}, '''
class A<NewName> {
final List<NewName> values = [];
}
''');
}
Future<void> test_class_validateOnly() {
addTestFile('''
class Test {}
@ -2031,6 +2067,23 @@ enum E {
);
}
Future<void> test_enum_typeParameter_atDeclaration() {
addTestFile('''
enum E2<Test> {
v<int>();
void foo(Test a) {}
}
''');
return assertSuccessfulRefactoring(() {
return sendRenameRequest('Test> {', 'NewName');
}, '''
enum E2<NewName> {
v<int>();
void foo(NewName a) {}
}
''');
}
Future<void> test_extension_atDeclaration() {
addTestFile('''
extension Test on int {
@ -2089,6 +2142,21 @@ void f() {
);
}
Future<void> test_extension_typeParameter_atDeclaration() {
addTestFile('''
extension E<Test> on int {
void foo(Test a) {}
}
''');
return assertSuccessfulRefactoring(() {
return sendRenameRequest('Test> on', 'NewName');
}, '''
extension E<NewName> on int {
void foo(NewName a) {}
}
''');
}
Future<void> test_feedback() {
addTestFile('''
class Test {}
@ -2326,6 +2394,21 @@ void f() {
});
}
Future<void> test_mixin_typeParameter_atDeclaration() {
addTestFile('''
mixin M<Test> {
final List<Test> values = [];
}
''');
return assertSuccessfulRefactoring(() {
return sendRenameRequest('Test> {', 'NewName');
}, '''
mixin M<NewName> {
final List<NewName> values = [];
}
''');
}
Future<void> test_parameter_onDefaultParameter() {
addTestFile('''
class A {

View file

@ -27,6 +27,26 @@ class RenameTest extends AbstractLspAnalysisServerTest {
return _test_prepare(content, 'MyClass');
}
Future<void> test_prepare_class_typeParameter_atDeclaration() async {
const content = '''
class A<[[T^]]> {
final List<T> values = [];
}
''';
return _test_prepare(content, 'T');
}
Future<void> test_prepare_class_typeParameter_atReference() async {
const content = '''
class A<T> {
final List<[[T^]]> values = [];
}
''';
return _test_prepare(content, 'T');
}
Future<void> test_prepare_classNewKeyword() async {
const content = '''
class MyClass {}
@ -377,6 +397,22 @@ void f(List<int> values) {
);
}
Future<void> test_rename_class_typeParameter_atDeclaration() {
const content = '''
class A<[[T^]]> {
final List<T> values = [];
}
''';
const expectedContent = '''
class A<U> {
final List<U> values = [];
}
''';
return _test_rename_withDocumentChanges(content, 'U', expectedContent);
}
Future<void> test_rename_classNewKeyword() {
const content = '''
class MyClass {}