@@ -17,11 +17,57 @@ import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
17
17
import 'package:analyzer_plugin/utilities/range_factory.dart' ;
18
18
19
19
class CreateMethodOrFunction extends ResolvedCorrectionProducer {
20
- FixKind _fixKind = DartFixKind .CREATE_METHOD ;
20
+ @override
21
+ final FixKind fixKind;
21
22
22
23
String _functionName = '' ;
23
24
24
- CreateMethodOrFunction ({required super .context});
25
+ /// The [Element] for the target of the node's parent, if that is a
26
+ /// [PrefixedIdentifier] or [PropertyAccess] , and `null` otherwise.
27
+ final Element ? _targetElement;
28
+
29
+ factory CreateMethodOrFunction ({required CorrectionProducerContext context}) {
30
+ if (context is StubCorrectionProducerContext ) {
31
+ return CreateMethodOrFunction ._(context: context);
32
+ }
33
+
34
+ if (context.node case SimpleIdentifier node) {
35
+ // Prepare the argument expression (to get the parameter).
36
+ Element ? targetElement;
37
+ var target = getQualifiedPropertyTarget (node);
38
+ if (target == null ) {
39
+ targetElement = node.enclosingInterfaceElement;
40
+ } else {
41
+ var targetType = target.staticType;
42
+ if (targetType is InterfaceType ) {
43
+ targetElement = targetType.element;
44
+ } else {
45
+ targetElement = switch (target) {
46
+ SimpleIdentifier () => target.element,
47
+ PrefixedIdentifier () => target.identifier.element,
48
+ _ => null ,
49
+ };
50
+ }
51
+ }
52
+
53
+ return CreateMethodOrFunction ._(
54
+ context: context,
55
+ targetElement: targetElement,
56
+ fixKind:
57
+ targetElement is InterfaceElement
58
+ ? DartFixKind .CREATE_METHOD
59
+ : DartFixKind .CREATE_FUNCTION ,
60
+ );
61
+ }
62
+
63
+ return CreateMethodOrFunction ._(context: context);
64
+ }
65
+
66
+ CreateMethodOrFunction ._({
67
+ required super .context,
68
+ Element ? targetElement,
69
+ this .fixKind = DartFixKind .CREATE_METHOD ,
70
+ }) : _targetElement = targetElement;
25
71
26
72
@override
27
73
CorrectionApplicability get applicability =>
@@ -31,103 +77,27 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
31
77
@override
32
78
List <String > get fixArguments => [_functionName];
33
79
34
- @override
35
- FixKind get fixKind => _fixKind;
36
-
37
80
@override
38
81
Future <void > compute (ChangeBuilder builder) async {
39
- var isStatic = false ;
40
- var nameNode = node;
41
- if (nameNode is SimpleIdentifier ) {
42
- // prepare argument expression (to get parameter)
43
- InterfaceElement ? targetElement;
44
- Expression argument;
82
+ if (node case SimpleIdentifier node) {
45
83
var target = getQualifiedPropertyTarget (node);
46
- if (target != null ) {
47
- var targetType = target.staticType;
48
- if (targetType is InterfaceType ) {
49
- targetElement = targetType.element;
50
- argument = target.parent as Expression ;
51
- } else if (target case SimpleIdentifier (
52
- : InterfaceElement ? element,
53
- : Expression parent,
54
- )) {
55
- isStatic = true ;
56
- targetElement = element;
57
- argument = parent;
58
- } else if (target
59
- case SimpleIdentifier identifier ||
60
- PrefixedIdentifier (: var identifier)) {
61
- if (identifier.element case InterfaceElement element) {
62
- isStatic = true ;
63
- targetElement = element;
64
- argument = target.parent as Expression ;
65
- } else {
66
- return ;
67
- }
68
- } else {
69
- return ;
70
- }
71
- } else {
72
- targetElement = node.enclosingInterfaceElement;
73
- argument = nameNode;
74
- }
75
- argument = stepUpNamedExpression (argument);
76
- // should be argument of some invocation
77
- // or child of an expression that is one
78
- var parameterElement = argument.correspondingParameter;
79
- int ? recordFieldIndex;
80
- if (argument.parent case ConditionalExpression parent) {
81
- if (argument == parent.condition) {
82
- return ;
83
- }
84
- parameterElement = parent.correspondingParameter;
85
- } else if (argument.parent case RecordLiteral record) {
86
- parameterElement = record.correspondingParameter;
87
- for (var (index, field)
88
- in record.fields.whereNotType <NamedExpression >().indexed) {
89
- if (field == argument) {
90
- recordFieldIndex = index;
91
- break ;
92
- }
93
- }
94
- }
95
- if (parameterElement == null ) {
96
- return ;
97
- }
98
- // should be parameter of function type
99
- var parameterType = parameterElement.type;
100
- if (parameterType is RecordType ) {
101
- // Finds the corresponding field for argument
102
- if (argument is NamedExpression ) {
103
- var fieldName = argument.name.label.name;
104
- for (var field in parameterType.namedFields) {
105
- if (field.name == fieldName) {
106
- parameterType = field.type;
107
- break ;
108
- }
109
- }
110
- } else if (recordFieldIndex != null ) {
111
- var field = parameterType.positionalFields[recordFieldIndex];
112
- parameterType = field.type;
113
- }
114
- }
115
- if (parameterType is InterfaceType && parameterType.isDartCoreFunction) {
116
- parameterType = FunctionTypeImpl (
117
- typeFormals: const [],
118
- parameters: const [],
119
- returnType: DynamicTypeImpl .instance,
120
- nullabilitySuffix: NullabilitySuffix .none,
121
- );
122
- }
84
+
85
+ // In order to fix this by creating a function or a method,
86
+ // `parameterType` should be be a function type.
87
+ var parameterType = _computeParameterType (node, target);
123
88
if (parameterType is ! FunctionType ) {
124
89
return ;
125
90
}
126
- // add proposal
127
- if (targetElement != null ) {
91
+
92
+ if (_targetElement is InterfaceElement ) {
93
+ var isStatic =
94
+ (target is SimpleIdentifier &&
95
+ target.element is InterfaceElement ) ||
96
+ (target is PrefixedIdentifier &&
97
+ target.identifier.element is InterfaceElement );
128
98
await _createMethod (
129
99
builder,
130
- targetElement ,
100
+ _targetElement ,
131
101
parameterType,
132
102
isStatic: isStatic,
133
103
);
@@ -137,6 +107,69 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
137
107
}
138
108
}
139
109
110
+ DartType ? _computeParameterType (SimpleIdentifier node, Expression ? target) {
111
+ // `argument` should be an argument of some invocation or child of an
112
+ // expression that is one.
113
+ Expression argument;
114
+ if (target == null ) {
115
+ argument = node;
116
+ } else {
117
+ var targetParent = target.parent;
118
+ if (targetParent is ! Expression ) {
119
+ return null ;
120
+ }
121
+ argument = targetParent;
122
+ }
123
+ argument = stepUpNamedExpression (argument);
124
+
125
+ var parameterElement = argument.correspondingParameter;
126
+ int ? recordFieldIndex;
127
+ if (argument.parent case ConditionalExpression parent) {
128
+ if (argument == parent.condition) {
129
+ return null ;
130
+ }
131
+ parameterElement = parent.correspondingParameter;
132
+ } else if (argument.parent case RecordLiteral record) {
133
+ parameterElement = record.correspondingParameter;
134
+ for (var (index, field)
135
+ in record.fields.whereNotType <NamedExpression >().indexed) {
136
+ if (field == argument) {
137
+ recordFieldIndex = index;
138
+ break ;
139
+ }
140
+ }
141
+ }
142
+ if (parameterElement == null ) {
143
+ return null ;
144
+ }
145
+
146
+ var parameterType = parameterElement.type;
147
+ if (parameterType is RecordType ) {
148
+ // Finds the corresponding field for argument
149
+ if (argument is NamedExpression ) {
150
+ var fieldName = argument.name.label.name;
151
+ for (var field in parameterType.namedFields) {
152
+ if (field.name == fieldName) {
153
+ parameterType = field.type;
154
+ break ;
155
+ }
156
+ }
157
+ } else if (recordFieldIndex != null ) {
158
+ var field = parameterType.positionalFields[recordFieldIndex];
159
+ parameterType = field.type;
160
+ }
161
+ }
162
+ if (parameterType is InterfaceType && parameterType.isDartCoreFunction) {
163
+ return FunctionTypeImpl (
164
+ typeFormals: const [],
165
+ parameters: const [],
166
+ returnType: DynamicTypeImpl .instance,
167
+ nullabilitySuffix: NullabilitySuffix .none,
168
+ );
169
+ }
170
+ return parameterType;
171
+ }
172
+
140
173
/// Prepares proposal for creating function corresponding to the given
141
174
/// [FunctionType] .
142
175
Future <void > _createExecutable (
@@ -211,7 +244,6 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
211
244
sourcePrefix,
212
245
sourceSuffix,
213
246
);
214
- _fixKind = DartFixKind .CREATE_FUNCTION ;
215
247
_functionName = name;
216
248
}
217
249
@@ -270,7 +302,6 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
270
302
sourcePrefix,
271
303
sourceSuffix,
272
304
);
273
- _fixKind = DartFixKind .CREATE_METHOD ;
274
305
_functionName = name;
275
306
}
276
307
}
0 commit comments