@@ -12,6 +12,7 @@ import 'package:analysis_server/src/services/search/hierarchy.dart';
1212import 'package:analysis_server/src/services/search/search_engine.dart' ;
1313import 'package:analysis_server_plugin/edit/correction_utils.dart' ;
1414import 'package:analysis_server_plugin/src/utilities/selection.dart' ;
15+ import 'package:analyzer/dart/analysis/features.dart' ;
1516import 'package:analyzer/dart/analysis/results.dart' ;
1617import 'package:analyzer/dart/ast/ast.dart' ;
1718import 'package:analyzer/dart/ast/token.dart' ;
@@ -63,11 +64,48 @@ sealed class Available extends Availability {
6364
6465 Available ({required this .refactoringContext});
6566
66- bool get hasPositionalParameters;
67+ /// Whether there are any positional parameters and, if so, if all of them
68+ /// can be converted to named parameters.
69+ ///
70+ /// Even if a parameter is positional, it may not be convertible if it has a
71+ /// private name and isn't in a context where it could become a private named
72+ /// parameter. If that case, this returns `false` .
73+ bool get hasPositionalParametersToConvertToNamed {
74+ var supportsPrivateNamedParameters = refactoringContext
75+ .resolvedLibraryResult
76+ .element
77+ .featureSet
78+ .isEnabled (Feature .private_named_parameters);
79+
80+ var hasPositional = false ;
81+ for (var parameter in _formalParameters) {
82+ if (parameter.isNamed) continue ;
83+
84+ hasPositional = true ;
85+
86+ // If the parameter has a private name, we must be able to convert it to
87+ // a private named parameter.
88+ if (Identifier .isPrivateName (parameter.name! )) {
89+ if (! supportsPrivateNamedParameters) {
90+ return false ;
91+ }
92+
93+ // TODO(rnystrom): Check for primary constructor declaring parameter
94+ // here once those are implemented.
95+ if (parameter is ! FieldFormalParameterElement ) {
96+ return false ;
97+ }
98+ }
99+ }
100+
101+ return hasPositional;
102+ }
67103
68104 bool get hasSelectedFormalParametersToConvertToNamed => false ;
69105
70106 bool get hasSelectedFormalParametersToMoveLeft => false ;
107+
108+ List <FormalParameterElement > get _formalParameters;
71109}
72110
73111/// The supertype return types from [computeSourceChange] .
@@ -408,11 +446,6 @@ final class _AvailableWithDeclaration extends Available {
408446 required this .declaration,
409447 });
410448
411- @override
412- bool get hasPositionalParameters {
413- return declaration.element.formalParameters.any ((e) => e.isPositional);
414- }
415-
416449 @override
417450 bool get hasSelectedFormalParametersToConvertToNamed {
418451 var selected = declaration.selected;
@@ -472,6 +505,10 @@ final class _AvailableWithDeclaration extends Available {
472505
473506 return true ;
474507 }
508+
509+ @override
510+ List <FormalParameterElement > get _formalParameters =>
511+ declaration.element.formalParameters;
475512}
476513
477514final class _AvailableWithExecutableElement extends Available {
@@ -483,9 +520,8 @@ final class _AvailableWithExecutableElement extends Available {
483520 });
484521
485522 @override
486- bool get hasPositionalParameters {
487- return element.formalParameters.any ((e) => e.isPositional);
488- }
523+ List <FormalParameterElement > get _formalParameters =>
524+ element.formalParameters;
489525}
490526
491527/// The target method declaration.
0 commit comments