[analysis_server] rename to handle private named parameters

Fixes #49872
Change-Id: Ied484a817713a922133fed070e6703f57336ffb2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/257102
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
index 1560b6b..ef703a6 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/encapsulate_field.dart
@@ -84,9 +84,8 @@
                   builder.addSimpleReplacement(
                       range.startEnd(start, normalParam.period), '$type ');
 
-                  var previous = constructor.initializers.isEmpty
-                      ? constructor.parameters
-                      : constructor.separator!;
+                  var previous =
+                      constructor.separator ?? constructor.parameters;
                   var replacement = constructor.initializers.isEmpty
                       ? ' : _$name = $name'
                       : ' _$name = $name,';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
index 6f22e4bd..763d923 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/extract_method.dart
@@ -451,7 +451,7 @@
           AnalysisSessionHelper(resolveResult.session), interfaceElement, name);
     }
     // OK
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   /// Checks if [selectionRange] selects [Expression] which can be extracted,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
index e6351cc..004264c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/inline_method.dart
@@ -264,17 +264,17 @@
     // prepare method information
     result.addStatus(await _prepareMethod());
     if (result.hasFatalError) {
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // maybe operator
     if (_methodElement!.isOperator) {
       result = RefactoringStatus.fatal('Cannot inline operator.');
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // maybe [a]sync*
     if (_methodElement!.isGenerator) {
       result = RefactoringStatus.fatal('Cannot inline a generator.');
-      return Future<RefactoringStatus>.value(result);
+      return result;
     }
     // analyze method body
     result.addStatus(_prepareMethodParts());
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
index b5a7198..8c1675b 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/refactoring.dart
@@ -18,6 +18,7 @@
 import 'package:analysis_server/src/services/refactoring/legacy/rename_label.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_library.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_local.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename_parameter.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/analysis/results.dart';
@@ -28,6 +29,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/utilities/cancellation.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show RefactoringMethodParameter, SourceChange;
@@ -407,39 +409,45 @@
   /// type.
   static RenameRefactoring? create(RefactoringWorkspace workspace,
       ResolvedUnitResult resolvedUnit, Element? element) {
-    var session = resolvedUnit.session;
     if (element == null) {
       return null;
     }
+    var session = resolvedUnit.session;
+    var sessionHelper = AnalysisSessionHelper(session);
     if (element is PropertyAccessorElement) {
       element = element.variable;
     }
     var enclosingElement = element.enclosingElement3;
     if (enclosingElement is CompilationUnitElement) {
-      return RenameUnitMemberRefactoringImpl(workspace, resolvedUnit, element);
+      return RenameUnitMemberRefactoringImpl(
+          workspace, sessionHelper, resolvedUnit, element);
     }
     if (element is ConstructorElement) {
-      return RenameConstructorRefactoringImpl(workspace, session, element);
+      return RenameConstructorRefactoringImpl(
+          workspace, sessionHelper, element);
     }
     if (element is LibraryImportElement) {
-      return RenameImportRefactoringImpl(workspace, session, element);
+      return RenameImportRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LabelElement) {
-      return RenameLabelRefactoringImpl(workspace, element);
+      return RenameLabelRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LibraryElement) {
-      return RenameLibraryRefactoringImpl(workspace, element);
+      return RenameLibraryRefactoringImpl(workspace, sessionHelper, element);
+    }
+    if (element is ParameterElement) {
+      return RenameParameterRefactoringImpl(workspace, sessionHelper, element);
     }
     if (element is LocalElement) {
-      return RenameLocalRefactoringImpl(workspace, session, element);
+      return RenameLocalRefactoringImpl(workspace, sessionHelper, element);
     }
     if (enclosingElement is InterfaceElement) {
       return RenameClassMemberRefactoringImpl(
-          workspace, session, enclosingElement, element);
+          workspace, sessionHelper, enclosingElement, element);
     }
     if (enclosingElement is ExtensionElement) {
       return RenameExtensionMemberRefactoringImpl(
-          workspace, session, enclosingElement, element);
+          workspace, sessionHelper, enclosingElement, element);
     }
     return null;
   }
@@ -483,10 +491,6 @@
       element = declaredParameterElement(node, element);
     }
 
-    if (element is FieldFormalParameterElement) {
-      element = element.field;
-    }
-
     // Use the prefix offset/length when renaming an import directive.
     if (node is ImportDirective && element is LibraryImportElement) {
       var prefix = node.prefix;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
index bc26e15..4cd7efe 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename.dart
@@ -9,16 +9,19 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 /// Helper for renaming one or more [Element]s.
 class RenameProcessor {
   final RefactoringWorkspace workspace;
+  final AnalysisSessionHelper sessionHelper;
   final SourceChange change;
   final String newName;
 
-  RenameProcessor(this.workspace, this.change, this.newName);
+  RenameProcessor(
+      this.workspace, this.sessionHelper, this.change, this.newName);
 
   /// Add the edit that updates the [element] declaration.
   void addDeclarationEdit(Element? element) {
@@ -52,6 +55,7 @@
 abstract class RenameRefactoringImpl extends RefactoringImpl
     implements RenameRefactoring {
   final RefactoringWorkspace workspace;
+  final AnalysisSessionHelper sessionHelper;
   final SearchEngine searchEngine;
   final Element _element;
   @override
@@ -62,7 +66,7 @@
 
   late String newName;
 
-  RenameRefactoringImpl(this.workspace, Element element)
+  RenameRefactoringImpl(this.workspace, this.sessionHelper, Element element)
       : searchEngine = workspace.searchEngine,
         _element = element,
         elementKindName = element.kind.displayName,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
index 46d7874..c677f90 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_class_member.dart
@@ -14,7 +14,6 @@
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -36,15 +35,16 @@
 
 /// A [Refactoring] for renaming class member [Element]s.
 class RenameClassMemberRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
   final InterfaceElement interfaceElement;
 
   late _RenameClassMemberValidator _validator;
 
-  RenameClassMemberRefactoringImpl(RefactoringWorkspace workspace,
-      AnalysisSession session, this.interfaceElement, Element element)
-      : sessionHelper = AnalysisSessionHelper(session),
-        super(workspace, element);
+  RenameClassMemberRefactoringImpl(
+      RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper,
+      this.interfaceElement,
+      Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -70,7 +70,7 @@
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
     }
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   @override
@@ -87,7 +87,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     // update declarations
     for (var renameElement in _validator.elements) {
       if (renameElement.isSynthetic && renameElement is FieldElement) {
@@ -95,10 +95,24 @@
         processor.addDeclarationEdit(renameElement.setter);
       } else {
         processor.addDeclarationEdit(renameElement);
+        if (!newName.startsWith('_')) {
+          var interfaceElement = renameElement.enclosingElement3;
+          if (interfaceElement is InterfaceElement) {
+            for (var constructor in interfaceElement.constructors) {
+              for (var parameter in constructor.parameters) {
+                if (parameter is FieldFormalParameterElement &&
+                    parameter.field == renameElement) {
+                  await workspace.searchEngine
+                      .searchReferences(parameter)
+                      .then(processor.addReferenceEdits);
+                }
+              }
+            }
+          }
+        }
       }
     }
-    // update references
-    processor.addReferenceEdits(_validator.references);
+    await _updateReferences();
     // potential matches
     if (includePotential) {
       var nameMatches = await searchEngine.searchMemberReferences(oldName);
@@ -118,12 +132,56 @@
     }
   }
 
+  Future<void> _addPrivateNamedFormalParameterEdit(
+      SourceReference reference, FieldFormalParameterElement element) async {
+    var result = await sessionHelper.getElementDeclaration(element);
+    var node = result?.node;
+    if (node is! DefaultFormalParameter) return;
+    var parameter = node.parameter as FieldFormalParameter;
+
+    var start = parameter.thisKeyword.offset;
+    var type = element.type.getDisplayString(withNullability: true);
+    var edit = SourceEdit(start, parameter.period.end - start, '$type ');
+    doSourceChange_addSourceEdit(change, reference.unitSource, edit);
+
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
+    if (constructor != null) {
+      var previous = constructor.separator ?? constructor.parameters;
+      var replacement = '$newName = ${parameter.name.lexeme}';
+      replacement = constructor.initializers.isEmpty
+          ? ' : $replacement'
+          : ' $replacement,';
+      var edit = SourceEdit(previous.end, 0, replacement);
+      doSourceChange_addSourceEdit(change, reference.unitSource, edit);
+    }
+  }
+
   String _newPotentialId() {
     assert(includePotential);
     var id = potentialEditIds.length.toString();
     potentialEditIds.add(id);
     return id;
   }
+
+  Future<void> _updateReferences() async {
+    var references = getSourceReferences(_validator.references);
+
+    for (var reference in references) {
+      var element = reference.element;
+      if (!workspace.containsElement(element)) {
+        continue;
+      }
+
+      if (newName.startsWith('_') &&
+          element is FieldFormalParameterElement &&
+          element.isNamed) {
+        await _addPrivateNamedFormalParameterEdit(reference, element);
+        continue;
+      }
+
+      reference.addEdit(change, newName);
+    }
+  }
 }
 
 /// The base class for the create and rename validators.
@@ -290,8 +348,8 @@
 class _RenameClassMemberValidator extends _BaseClassMemberValidator {
   final Element element;
 
-  Set<Element> elements = <Element>{};
-  List<SearchMatch> references = <SearchMatch>[];
+  Set<Element> elements = {};
+  List<SearchMatch> references = [];
 
   _RenameClassMemberValidator(
     SearchEngine searchEngine,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
index d4972cb..dab16f2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_constructor.dart
@@ -10,21 +10,16 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 /// A [Refactoring] for renaming [ConstructorElement]s.
 class RenameConstructorRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSession session;
-
   RenameConstructorRefactoringImpl(
-      RefactoringWorkspace workspace, this.session, ConstructorElement element)
-      : super(workspace, element);
+      super.workspace, super.sessionHelper, ConstructorElement super.element);
 
   @override
   ConstructorElement get element => super.element as ConstructorElement;
@@ -109,8 +104,7 @@
   Future<void> _replaceSynthetic() async {
     var classElement = element.enclosingElement3;
 
-    var result = await AnalysisSessionHelper(session)
-        .getElementDeclaration(classElement);
+    var result = await sessionHelper.getElementDeclaration(classElement);
     if (result == null) {
       return;
     }
@@ -123,7 +117,8 @@
     var node = result.node;
     if (node is ClassDeclaration) {
       var utils = CorrectionUtils(resolvedUnit);
-      var location = utils.prepareNewConstructorLocation(session, node);
+      var location =
+          utils.prepareNewConstructorLocation(sessionHelper.session, node);
       if (location == null) {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
index e6ff856..3c92e80 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_extension_member.dart
@@ -12,7 +12,6 @@
 import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -22,15 +21,16 @@
 
 /// A [Refactoring] for renaming extension member [Element]s.
 class RenameExtensionMemberRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
   final ExtensionElement extensionElement;
 
   late _ExtensionMemberValidator _validator;
 
-  RenameExtensionMemberRefactoringImpl(RefactoringWorkspace workspace,
-      AnalysisSession session, this.extensionElement, Element element)
-      : sessionHelper = AnalysisSessionHelper(session),
-        super(workspace, element);
+  RenameExtensionMemberRefactoringImpl(
+      RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper,
+      this.extensionElement,
+      Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -56,7 +56,7 @@
     if (element is MethodElement && (element as MethodElement).isOperator) {
       result.addFatalError('Cannot rename operator.');
     }
-    return Future<RefactoringStatus>.value(result);
+    return result;
   }
 
   @override
@@ -73,7 +73,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
 
     // Update the declaration.
     var renameElement = element;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
index 01e2ccd..d01ad6f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_import.dart
@@ -9,7 +9,6 @@
 import 'package:analysis_server/src/services/refactoring/legacy/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -18,11 +17,8 @@
 
 /// A [Refactoring] for renaming [LibraryImportElement]s.
 class RenameImportRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSession session;
-
-  RenameImportRefactoringImpl(RefactoringWorkspace workspace, this.session,
-      LibraryImportElement element)
-      : super(workspace, element);
+  RenameImportRefactoringImpl(
+      super.workspace, super.sessionHelper, LibraryImportElement super.element);
 
   @override
   LibraryImportElement get element => super.element as LibraryImportElement;
@@ -102,7 +98,7 @@
   Future<ImportDirective?> _findNode() async {
     var library = element.library;
     var path = library.source.fullName;
-    var unitResult = session.getParsedUnit(path);
+    var unitResult = sessionHelper.session.getParsedUnit(path);
     if (unitResult is! ParsedUnitResult) {
       return null;
     }
@@ -118,7 +114,7 @@
     SourceReference reference,
   ) async {
     var source = reference.element.source!;
-    var unitResult = session.getParsedUnit(source.fullName);
+    var unitResult = sessionHelper.session.getParsedUnit(source.fullName);
     if (unitResult is! ParsedUnitResult) {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
index b6c3710..9421528 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_label.dart
@@ -10,7 +10,8 @@
 
 /// A [Refactoring] for renaming [LabelElement]s.
 class RenameLabelRefactoringImpl extends RenameRefactoringImpl {
-  RenameLabelRefactoringImpl(super.workspace, LabelElement super.element);
+  RenameLabelRefactoringImpl(
+      super.workspace, super.sessionHelper, LabelElement super.element);
 
   @override
   LabelElement get element => super.element as LabelElement;
@@ -33,7 +34,7 @@
 
   @override
   Future<void> fillChange() {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     return processor.renameElement(element);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
index 1423092..74371dc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_library.dart
@@ -10,7 +10,8 @@
 
 /// A [Refactoring] for renaming [LibraryElement]s.
 class RenameLibraryRefactoringImpl extends RenameRefactoringImpl {
-  RenameLibraryRefactoringImpl(super.workspace, LibraryElement super.element);
+  RenameLibraryRefactoringImpl(
+      super.workspace, super.sessionHelper, LibraryElement super.element);
 
   @override
   LibraryElement get element => super.element as LibraryElement;
@@ -35,7 +36,7 @@
 
   @override
   Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     await processor.renameElement(element);
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
index d142d90..bca4747 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_local.dart
@@ -11,114 +11,20 @@
 import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
 import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/source.dart';
 
-/// A [Refactoring] for renaming [LocalElement]s.
-class RenameLocalRefactoringImpl extends RenameRefactoringImpl {
-  final AnalysisSessionHelper sessionHelper;
-
-  List<LocalElement> elements = [];
-
-  RenameLocalRefactoringImpl(
-      super.workspace, AnalysisSession session, LocalElement super.element)
-      : sessionHelper = AnalysisSessionHelper(session);
-
-  @override
-  LocalElement get element => super.element as LocalElement;
-
-  @override
-  String get refactoringName {
-    if (element is ParameterElement) {
-      return 'Rename Parameter';
-    }
-    if (element is FunctionElement) {
-      return 'Rename Local Function';
-    }
-    return 'Rename Local Variable';
-  }
-
-  @override
-  Future<RefactoringStatus> checkFinalConditions() async {
-    var result = RefactoringStatus();
-    await _prepareElements();
-    for (var element in elements) {
-      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
-      var unit = resolvedUnit?.unit;
-      unit?.accept(
-        _ConflictValidatorVisitor(
-          result,
-          newName,
-          element,
-          VisibleRangesComputer.forNode(unit),
-        ),
-      );
-    }
-    return result;
-  }
-
-  @override
-  RefactoringStatus checkNewName() {
-    var result = super.checkNewName();
-    if (element is LocalVariableElement) {
-      result.addStatus(validateVariableName(newName));
-    } else if (element is ParameterElement) {
-      result.addStatus(validateParameterName(newName));
-    } else if (element is FunctionElement) {
-      result.addStatus(validateFunctionName(newName));
-    }
-    return result;
-  }
-
-  @override
-  Future<void> fillChange() async {
-    var processor = RenameProcessor(workspace, change, newName);
-    for (Element element in elements) {
-      processor.addDeclarationEdit(element);
-      var references = await searchEngine.searchReferences(element);
-
-      // Remove references that don't have to have the same name.
-      if (element is ParameterElement) {
-        // Implicit references to optional positional parameters.
-        if (element.isOptionalPositional) {
-          references.removeWhere((match) => match.sourceRange.length == 0);
-        }
-        // References to positional parameters from super-formal.
-        if (element.isPositional) {
-          references.removeWhere(
-            (match) => match.element is SuperFormalParameterElement,
-          );
-        }
-      }
-
-      processor.addReferenceEdits(references);
-    }
-  }
-
-  /// Fills [elements] with [Element]s to rename.
-  Future _prepareElements() async {
-    final element = this.element;
-    if (element is ParameterElement && element.isNamed) {
-      elements = await getHierarchyNamedParameters(searchEngine, element);
-    } else {
-      elements = [element];
-    }
-  }
-}
-
-class _ConflictValidatorVisitor extends RecursiveAstVisitor<void> {
+class ConflictValidatorVisitor extends RecursiveAstVisitor<void> {
   final RefactoringStatus result;
   final String newName;
   final LocalElement target;
   final Map<Element, SourceRange> visibleRangeMap;
   final Set<Element> conflictingLocals = <Element>{};
 
-  _ConflictValidatorVisitor(
+  ConflictValidatorVisitor(
     this.result,
     this.newName,
     this.target,
@@ -205,3 +111,55 @@
     return parent is Label && parent.parent is NamedExpression;
   }
 }
+
+/// A [Refactoring] for renaming [LocalElement]s (excluding [ParameterElement]).
+class RenameLocalRefactoringImpl extends RenameRefactoringImpl {
+  RenameLocalRefactoringImpl(
+      super.workspace, super.sessionHelper, LocalElement super.element);
+
+  @override
+  LocalElement get element => super.element as LocalElement;
+
+  @override
+  String get refactoringName {
+    if (element is FunctionElement) {
+      return 'Rename Local Function';
+    }
+    return 'Rename Local Variable';
+  }
+
+  @override
+  Future<RefactoringStatus> checkFinalConditions() async {
+    var result = RefactoringStatus();
+    var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+    var unit = resolvedUnit?.unit;
+    unit?.accept(
+      ConflictValidatorVisitor(
+        result,
+        newName,
+        element,
+        VisibleRangesComputer.forNode(unit),
+      ),
+    );
+    return result;
+  }
+
+  @override
+  RefactoringStatus checkNewName() {
+    var result = super.checkNewName();
+    if (element is LocalVariableElement) {
+      result.addStatus(validateVariableName(newName));
+    } else if (element is FunctionElement) {
+      result.addStatus(validateFunctionName(newName));
+    }
+    return result;
+  }
+
+  @override
+  Future<void> fillChange() async {
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
+    processor.addDeclarationEdit(element);
+    var references = await searchEngine.searchReferences(element);
+    processor.addReferenceEdits(references);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart
new file mode 100644
index 0000000..0e81559
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_parameter.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// 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:analysis_server/src/services/correction/status.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/naming_conventions.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/refactoring.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/rename_local.dart';
+import 'package:analysis_server/src/services/refactoring/legacy/visible_ranges_computer.dart';
+import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+
+/// A [Refactoring] for renaming [ParameterElement]s.
+class RenameParameterRefactoringImpl extends RenameRefactoringImpl {
+  List<ParameterElement> elements = [];
+
+  RenameParameterRefactoringImpl(
+      super.workspace, super.sessionHelper, ParameterElement super.element);
+
+  @override
+  ParameterElement get element => super.element as ParameterElement;
+
+  @override
+  String get refactoringName {
+    return 'Rename Parameter';
+  }
+
+  @override
+  Future<RefactoringStatus> checkFinalConditions() async {
+    var result = RefactoringStatus();
+    await _prepareElements();
+    for (var element in elements) {
+      if (newName.startsWith('_') && element.isNamed) {
+        result.addError(
+          format("The parameter '{0}' is named and can not be private.",
+              element.name),
+        );
+        break;
+      }
+      var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+      var unit = resolvedUnit?.unit;
+      unit?.accept(
+        ConflictValidatorVisitor(
+          result,
+          newName,
+          element,
+          VisibleRangesComputer.forNode(unit),
+        ),
+      );
+    }
+    return result;
+  }
+
+  @override
+  RefactoringStatus checkNewName() {
+    var result = super.checkNewName();
+    result.addStatus(validateParameterName(newName));
+    return result;
+  }
+
+  @override
+  Future<void> fillChange() async {
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
+    for (var element in elements) {
+      var fieldRenamed = false;
+      if (element is FieldFormalParameterElement) {
+        var field = element.field;
+        if (field != null) {
+          await processor.renameElement(field);
+          fieldRenamed = true;
+        }
+      }
+
+      if (!fieldRenamed) {
+        processor.addDeclarationEdit(element);
+      }
+      var references = await searchEngine.searchReferences(element);
+
+      // Remove references that don't have to have the same name.
+
+      // Implicit references to optional positional parameters.
+      if (element.isOptionalPositional) {
+        references.removeWhere((match) => match.sourceRange.length == 0);
+      }
+      // References to positional parameters from super-formal.
+      if (element.isPositional) {
+        references.removeWhere(
+          (match) => match.element is SuperFormalParameterElement,
+        );
+      }
+
+      processor.addReferenceEdits(references);
+    }
+  }
+
+  /// Fills [elements] with [Element]s to rename.
+  Future<void> _prepareElements() async {
+    final element = this.element;
+    if (element.isNamed) {
+      elements = await getHierarchyNamedParameters(searchEngine, element);
+    } else {
+      elements = [element];
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
index bb5c728..cf575bf 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/legacy/rename_unit_member.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart' show Identifier;
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /// Checks if creating a top-level function with the given [name] in [library]
@@ -44,9 +45,9 @@
   /// If [_flutterWidgetState] is set, this is the new name of it.
   String? _flutterWidgetStateNewName;
 
-  RenameUnitMemberRefactoringImpl(
-      RefactoringWorkspace workspace, this.resolvedUnit, Element element)
-      : super(workspace, element);
+  RenameUnitMemberRefactoringImpl(RefactoringWorkspace workspace,
+      AnalysisSessionHelper sessionHelper, this.resolvedUnit, Element element)
+      : super(workspace, sessionHelper, element);
 
   @override
   String get refactoringName {
@@ -123,7 +124,7 @@
     }
 
     // Rename each element and references to it.
-    var processor = RenameProcessor(workspace, change, newName);
+    var processor = RenameProcessor(workspace, sessionHelper, change, newName);
     for (var element in elements) {
       await processor.renameElement(element);
     }
@@ -134,6 +135,7 @@
       _updateFlutterWidgetStateName();
       await RenameProcessor(
         workspace,
+        sessionHelper,
         change,
         _flutterWidgetStateNewName!,
       ).renameElement(flutterWidgetState);
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 44121d1..4125c09 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -90,7 +90,7 @@
   // static elements
   if (member.isStatic || member is ConstructorElement) {
     result.add(member);
-    return Future.value(result);
+    return result;
   }
   // method, field, etc
   if (enclosingElement is InterfaceElement) {
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index f080f50..c759aa8 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -1745,6 +1745,27 @@
 ''');
   }
 
+  Future<void> test_classMember_field_onFieldFormalParameter_named_private() {
+    addTestFile('''
+class A {
+  final int test;
+  A({this.test = 0});
+}
+void f() {
+  A(test: 42);
+}
+''');
+
+    return getRefactoringResult(() {
+      return sendRenameRequest('test: 42', '_new');
+    }).then((result) {
+      var problems = result.finalProblems;
+      expect(problems, hasLength(1));
+      assertResultProblemsError(
+          problems, "The parameter 'test' is named and can not be private.");
+    });
+  }
+
   Future<void> test_classMember_getter() {
     addTestFile('''
 class A {
@@ -2187,6 +2208,27 @@
     });
   }
 
+  Future<void> test_parameter_onDefaultParameter() {
+    addTestFile('''
+class A {
+  final int test;
+  A({int t = 0}) : test = t;
+}
+void f() {
+  A(t: 42);
+}
+''');
+
+    return getRefactoringResult(() {
+      return sendRenameRequest('t: 42', '_new');
+    }).then((result) {
+      var problems = result.finalProblems;
+      expect(problems, hasLength(1));
+      assertResultProblemsError(
+          problems, "The parameter 't' is named and can not be private.");
+    });
+  }
+
   Future<void> test_reset_afterCreateChange() {
     test_simulateRefactoringReset_afterCreateChange = true;
     addTestFile('''
diff --git a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
index 010a1ca..c464865 100644
--- a/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/legacy/rename_class_member_test.dart
@@ -1487,6 +1487,95 @@
 ''');
   }
 
+  Future<void> test_createChange_FieldElement_private() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  C(this.field);
+}
+void f() {
+  var c = C(1);
+  c.field = 1;
+}
+''');
+    // configure refactoring
+    createRenameRefactoringAtString('field;');
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  C(this._field);
+}
+void f() {
+  var c = C(1);
+  c._field = 1;
+}
+''');
+  }
+
+  Future<void> test_createChange_FieldElement_private_initializer() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  int? other;
+  C({this.field}) : other = field;
+}
+void f() {
+  var c = C(field: 0);
+  c.field = 1;
+}
+''');
+    // configure refactoring
+    var element = findElement.field('field');
+    createRenameRefactoringForElement(element);
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  int? other;
+  C({int? field}) : _field = field, other = field;
+}
+void f() {
+  var c = C(field: 0);
+  c._field = 1;
+}
+''');
+  }
+
+  Future<void> test_createChange_FieldElement_private_positional() async {
+    await indexTestUnit('''
+class C {
+  int? field;
+  C([this.field]);
+}
+void f() {
+  C().field;
+}
+''');
+    // configure refactoring
+    var element = findElement.field('field');
+    createRenameRefactoringForElement(element);
+    expect(refactoring.refactoringName, 'Rename Field');
+    expect(refactoring.oldName, 'field');
+    refactoring.newName = '_field';
+    // validate change
+    return assertSuccessfulRefactoring('''
+class C {
+  int? _field;
+  C([this._field]);
+}
+void f() {
+  C()._field;
+}
+''');
+  }
+
   Future<void> test_createChange_MethodElement() async {
     await indexTestUnit('''
 enum E {
diff --git a/pkg/analysis_server/test/timing/timing_framework.dart b/pkg/analysis_server/test/timing/timing_framework.dart
index 31ed32a..07f7ade 100644
--- a/pkg/analysis_server/test/timing/timing_framework.dart
+++ b/pkg/analysis_server/test/timing/timing_framework.dart
@@ -178,7 +178,7 @@
     await _repeat(warmupCount, null);
     await _repeat(timingCount, times);
     await oneTimeTearDown();
-    return Future<TimingResult>.value(TimingResult(times));
+    return TimingResult(times);
   }
 
   /// Perform any operations that need to be performed before each iteration.
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index c17311f..e8bafaf 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -511,12 +511,10 @@
       args.add('{${optionalArgs.join(', ')}}');
     }
     write('$className(${args.join(', ')})');
-    if (initializers.isEmpty) {
-      writeln(';');
-    } else {
+    if (initializers.isNotEmpty) {
       writeln(' : ${initializers.join(', ')}');
-      writeln(';');
     }
+    writeln(';');
   }
 
   /// Emit the operator== code for an object class.
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 08b184d..ecd362c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -859,12 +859,6 @@
       }
       recordNameRelation(node, kind, isQualified);
     }
-    // this.field parameter
-    if (element is FieldFormalParameterElement) {
-      IndexRelationKind kind = IndexRelationKind.IS_REFERENCED_BY;
-      recordRelation(element.field, kind, node, true);
-      return;
-    }
     // ignore a local reference to a parameter
     if (element is ParameterElement && node.parent is! Label) {
       return;
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 03522d3..2279006 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -1065,15 +1065,17 @@
     FieldElement field = findElement.field('field');
     PropertyAccessorElement getter = field.getter!;
     PropertyAccessorElement setter = field.setter!;
+
     // A()
-    assertThat(field).isWrittenAt('field});', true, length: 5);
+    assertThat(field)
+      ..isWrittenAt('field});', true, length: 5)
+      ..hasRelationCount(1);
     // m()
     assertThat(setter).isReferencedAt('field = 2; // nq', false, length: 5);
     assertThat(getter).isReferencedAt('field); // nq', false, length: 5);
     // main()
     assertThat(setter).isReferencedAt('field = 3; // q', true, length: 5);
     assertThat(getter).isReferencedAt('field); // q', true, length: 5);
-    assertThat(field).isReferencedAt('field: 4', true, length: 5);
   }
 
   test_isReferencedBy_FieldElement_class_multiple() async {
@@ -1164,15 +1166,17 @@
     FieldElement field = findElement.field('field');
     PropertyAccessorElement getter = field.getter!;
     PropertyAccessorElement setter = field.setter!;
+
     // E()
-    assertThat(field).isWrittenAt('field});', true, length: 5);
+    assertThat(field)
+      ..isWrittenAt('field});', true, length: 5)
+      ..hasRelationCount(1);
     // foo()
     assertThat(setter).isReferencedAt('field = 2; // nq', false, length: 5);
     assertThat(getter).isReferencedAt('field; // nq', false, length: 5);
     // f()
     assertThat(setter).isReferencedAt('field = 3; // q', true, length: 5);
     assertThat(getter).isReferencedAt('field; // q', true, length: 5);
-    assertThat(field).isReferencedAt('field: 4', true, length: 5);
   }
 
   test_isReferencedBy_FieldElement_enum_index() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 244406f..ca34986 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -1071,7 +1071,6 @@
     var fieldParameter = findElement.parameter('field');
     var expected = [
       _expectIdQ(fieldParameter, SearchResultKind.WRITE, 'field}', length: 5),
-      _expectIdQ(main, SearchResultKind.REFERENCE, 'field: 1'),
       _expectId(main, SearchResultKind.READ, 'field); // ref-nq'),
       _expectIdQ(main, SearchResultKind.READ, 'field); // ref-q'),
       _expectId(main, SearchResultKind.READ, 'field(); // inv-nq'),
@@ -1125,8 +1124,6 @@
 }
 ''');
     await _verifyReferences(findElement.field('field'), [
-      _expectIdQ(
-          findElement.field('v'), SearchResultKind.REFERENCE, 'field: 0'),
       _expectIdQ(findElement.parameter('field'), SearchResultKind.WRITE,
           'field}); // 1',
           length: 5),