[analysis_server] Don't warn on renames of private named parameters

Fixes https://github.com/dart-lang/sdk/issues/63433

Change-Id: I6e39d3b8c9379df07a677cabfcd9028a7bca79db
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510840
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny
2026-06-10 11:57:21 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent bf71251dcd
commit ff0cd5e0d6
2 changed files with 182 additions and 0 deletions
@@ -574,6 +574,11 @@ class _RenameClassMemberValidator extends _BaseClassMemberValidator {
return;
}
for (var reference in references) {
// If the reference is a named argument, we can allow this because it
// will become a private named parameter.
if (reference.kind == MatchKind.REFERENCE_BY_NAMED_ARGUMENT) {
continue;
}
var refElement = reference.element;
var refLibrary = refElement.library!;
if (refLibrary != library) {
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_testing/package_config_file_builder.dart';
@@ -339,6 +340,91 @@ class B extends NewName {
);
}
/// Private named parameters can be renamed without warning about becoming
/// invisible to other libraries because the parameter name is public.
Future<void>
test_checkFinalConditions_declaringParameter_privateNamedParameter_privateToPrivate() async {
await indexTestUnit(
'''
class A({final int? _f^oo});
''',
ignore: [diag.unusedFieldFromPrimaryConstructor],
);
await indexUnit('$testPackageLibPath/lib.dart', '''
import 'test.dart';
var a = A(foo: 1);
''');
createRenameRefactoring();
// check status
refactoring.newName = '_newName';
var status = await refactoring.checkFinalConditions();
assertRefactoringStatusOK(status);
}
/// Private named parameters can be created without warning about becoming
/// invisible to other libraries because the parameter name remains public.
Future<void>
test_checkFinalConditions_declaringParameter_privateNamedParameter_publicToPrivate() async {
await indexTestUnit('''
class A({final int? f^oo});
''');
await indexUnit('$testPackageLibPath/lib.dart', '''
import 'test.dart';
var a = A(foo: 1);
''');
createRenameRefactoring();
// check status
refactoring.newName = '_newName';
var status = await refactoring.checkFinalConditions();
assertRefactoringStatusOK(status);
}
/// Private named parameters can be renamed without warning about becoming
/// invisible to other libraries because the parameter name is public.
Future<void>
test_checkFinalConditions_fieldFormalParameter_privateNamedParameter_privateToPrivate() async {
await indexTestUnit('''
class A {
final int? _foo;
A({this._f^oo});
}
''');
await indexUnit('$testPackageLibPath/lib.dart', '''
import 'test.dart';
var a = A(foo: 1);
''');
createRenameRefactoring();
// check status
refactoring.newName = '_newName';
var status = await refactoring.checkFinalConditions();
assertRefactoringStatusOK(status);
}
/// Private named parameters can be created without warning about becoming
/// invisible to other libraries because the parameter name remains public.
Future<void>
test_checkFinalConditions_fieldFormalParameter_privateNamedParameter_publicToPrivate() async {
await indexTestUnit('''
class A {
final int? foo;
A({this.f^oo});
}
''');
await indexUnit('$testPackageLibPath/lib.dart', '''
import 'test.dart';
var a = A(foo: 1);
''');
createRenameRefactoring();
// check status
refactoring.newName = '_newName';
var status = await refactoring.checkFinalConditions();
assertRefactoringStatusOK(status);
}
Future<void> test_checkFinalConditions_hasMember_MethodElement() async {
await indexTestUnit('''
class A {
@@ -1701,6 +1787,97 @@ class A<NewName> {
''');
}
/// Private named parameters can be renamed without warning about becoming
/// invisible to other libraries because the parameter name is public.
Future<void>
test_FieldElement_declaringParameter_privateNamedParameter_privateToPrivate() async {
await indexTestUnit(
'''
class A({final int? _f^oo});
var a = A(foo: 1);
''',
ignore: [diag.unusedFieldFromPrimaryConstructor],
);
createRenameRefactoring();
refactoring.newName = '_newName';
// validate change
return assertSuccessfulRefactoring('''
class A({final int? _newName});
var a = A(newName: 1);
''');
}
/// Private named parameters can be created without warning about becoming
/// invisible to other libraries because the parameter name remains public.
Future<void>
test_FieldElement_declaringParameter_privateNamedParameter_publicToPrivate() async {
await indexTestUnit('''
class A({final int? f^oo});
var a = A(foo: 1);
''');
createRenameRefactoring();
refactoring.newName = '_newName';
// validate change
return assertSuccessfulRefactoring('''
class A({final int? _newName});
var a = A(newName: 1);
''');
}
/// Private named parameters can be renamed without warning about becoming
/// invisible to other libraries because the parameter name is public.
Future<void>
test_FieldElement_fieldFormalParameter_privateNamedParameter_privateToPrivate() async {
await indexTestUnit('''
class A {
final int? _foo;
A({this._f^oo});
}
var a = A(foo: 1);
''');
createRenameRefactoring();
refactoring.newName = '_newName';
// validate change
return assertSuccessfulRefactoring('''
class A {
final int? _newName;
A({this._newName});
}
var a = A(newName: 1);
''');
}
/// Private named parameters can be created without warning about becoming
/// invisible to other libraries because the parameter name remains public.
Future<void>
test_FieldElement_fieldFormalParameter_privateNamedParameter_publicToPrivate() async {
await indexTestUnit('''
class A {
final int? foo;
A({this.f^oo});
}
var a = A(foo: 1);
''');
createRenameRefactoring();
refactoring.newName = '_newName';
// validate change
return assertSuccessfulRefactoring('''
class A {
final int? _newName;
A({this._newName});
}
var a = A(newName: 1);
''');
}
Future<void> test_instance_outsideClass() async {
await indexTestUnit('''
void foo(A a) {