[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),