@@ -53,6 +53,8 @@ class CanRenameResponse {
53
53
} else if (element is ConstructorElement ) {
54
54
status = validateConstructorName (name);
55
55
_analyzePossibleConflicts (element, status, name);
56
+ } else if (element is ImportElement ) {
57
+ status = validateImportPrefixName (name);
56
58
}
57
59
58
60
if (status == null ) {
@@ -125,34 +127,9 @@ class CheckNameResponse {
125
127
for (var element in elements) {
126
128
matches.addAll (await fileResolver.findReferences2 (element));
127
129
}
128
-
129
130
FlutterWidgetRename ? flutterRename;
130
- var flutterState = canRename._flutterWidgetState;
131
- if (flutterState != null ) {
132
- var stateClass = flutterState.state;
133
- var stateName = flutterState.newName;
134
- var match = await fileResolver.findReferences2 (stateClass);
135
- var sourcePath = stateClass.source.fullName;
136
- var location = stateClass.enclosingElement.lineInfo
137
- .getLocation (stateClass.nameOffset);
138
- CiderSearchMatch ciderMatch;
139
- var searchInfo = CiderSearchInfo (
140
- location, stateClass.nameLength, MatchKind .DECLARATION );
141
- try {
142
- ciderMatch = match.firstWhere ((m) => m.path == sourcePath);
143
- ciderMatch.references.add (searchInfo);
144
- } catch (_) {
145
- match.add (CiderSearchMatch (sourcePath, [], [searchInfo]));
146
- }
147
- var replacements = match
148
- .map ((m) => CiderReplaceMatch (
149
- m.path,
150
- m.references
151
- .map ((p) => ReplaceInfo (
152
- stateName, p.startPosition, stateClass.nameLength))
153
- .toList ()))
154
- .toList ();
155
- flutterRename = FlutterWidgetRename (stateName, match, replacements);
131
+ if (canRename._flutterWidgetState != null ) {
132
+ flutterRename = await _computeFlutterStateName ();
156
133
}
157
134
var replaceMatches = < CiderReplaceMatch > [];
158
135
if (element is ConstructorElement ) {
@@ -179,6 +156,30 @@ class CheckNameResponse {
179
156
replaceMatches.addMatch (result.path, result.matches.toList ());
180
157
}
181
158
}
159
+ } else if (element is ImportElement ) {
160
+ var replaceInfo = < ReplaceInfo > [];
161
+ for (var match in matches) {
162
+ for (var ref in match.references) {
163
+ if (newName.isEmpty) {
164
+ replaceInfo.add (ReplaceInfo ('' , ref.startPosition, ref.length));
165
+ } else {
166
+ var identifier = await _getInterpolationIdentifier (
167
+ match.path, ref.startPosition);
168
+ if (identifier != null ) {
169
+ var lineInfo = canRename.lineInfo;
170
+ replaceInfo.add (ReplaceInfo ('{$newName .${identifier .name }}' ,
171
+ lineInfo.getLocation (identifier.offset), identifier.length));
172
+ } else {
173
+ replaceInfo
174
+ .add (ReplaceInfo ('$newName .' , ref.startPosition, ref.length));
175
+ }
176
+ }
177
+ }
178
+ replaceMatches.addMatch (match.path, replaceInfo);
179
+ var sourcePath = element.source.fullName;
180
+ var infos = await _addElementDeclaration (element, sourcePath);
181
+ replaceMatches.addMatch (sourcePath, infos);
182
+ }
182
183
} else {
183
184
for (var match in matches) {
184
185
replaceMatches.addMatch (
@@ -213,6 +214,32 @@ class CheckNameResponse {
213
214
lineInfo.getLocation (element.setter! .nameOffset),
214
215
element.setter! .nameLength));
215
216
}
217
+ } else if (element is ImportElement ) {
218
+ var prefix = element.prefix;
219
+ var unit =
220
+ (await canRename._fileResolver.resolve2 (path: sourcePath)).unit;
221
+ var index = element.library.imports.indexOf (element);
222
+ var node = unit.directives.whereType <ImportDirective >().elementAt (index);
223
+ if (newName.isEmpty) {
224
+ // We should not get `prefix == null` because we check in
225
+ // `checkNewName` that the new name is different.
226
+ if (prefix == null ) {
227
+ return infos;
228
+ }
229
+ var prefixEnd = prefix.nameOffset + prefix.nameLength;
230
+ infos.add (ReplaceInfo (newName, lineInfo.getLocation (node.uri.end),
231
+ prefixEnd - node.uri.end));
232
+ } else {
233
+ if (prefix == null ) {
234
+ var uriEnd = node.uri.end;
235
+ infos.add (
236
+ ReplaceInfo (' as $newName ' , lineInfo.getLocation (uriEnd), 0 ));
237
+ } else {
238
+ var offset = prefix.nameOffset;
239
+ var length = prefix.nameLength;
240
+ infos.add (ReplaceInfo (newName, lineInfo.getLocation (offset), length));
241
+ }
242
+ }
216
243
} else {
217
244
var location = (await canRename._fileResolver.resolve2 (path: sourcePath))
218
245
.lineInfo
@@ -222,6 +249,53 @@ class CheckNameResponse {
222
249
return infos;
223
250
}
224
251
252
+ Future <FlutterWidgetRename ?> _computeFlutterStateName () async {
253
+ var flutterState = canRename._flutterWidgetState;
254
+ var stateClass = flutterState! .state;
255
+ var stateName = flutterState.newName;
256
+ var match = await canRename._fileResolver.findReferences2 (stateClass);
257
+ var sourcePath = stateClass.source.fullName;
258
+ var location =
259
+ stateClass.enclosingElement.lineInfo.getLocation (stateClass.nameOffset);
260
+ CiderSearchMatch ciderMatch;
261
+ var searchInfo =
262
+ CiderSearchInfo (location, stateClass.nameLength, MatchKind .DECLARATION );
263
+ try {
264
+ ciderMatch = match.firstWhere ((m) => m.path == sourcePath);
265
+ ciderMatch.references.add (searchInfo);
266
+ } catch (_) {
267
+ match.add (CiderSearchMatch (sourcePath, [searchInfo]));
268
+ }
269
+ var replacements = match
270
+ .map ((m) => CiderReplaceMatch (
271
+ m.path,
272
+ m.references
273
+ .map ((p) => ReplaceInfo (
274
+ stateName, p.startPosition, stateClass.nameLength))
275
+ .toList ()))
276
+ .toList ();
277
+ return FlutterWidgetRename (stateName, match, replacements);
278
+ }
279
+
280
+ /// If the given [reference] is before an interpolated [SimpleIdentifier] in
281
+ /// an [InterpolationExpression] without surrounding curly brackets, return
282
+ /// it. Otherwise return `null` .
283
+ Future <SimpleIdentifier ?> _getInterpolationIdentifier (
284
+ String path, CharacterLocation loc) async {
285
+ var resolvedUnit = await canRename._fileResolver.resolve2 (path: path);
286
+ var lineInfo = resolvedUnit.lineInfo;
287
+ var node = NodeLocator (
288
+ lineInfo.getOffsetOfLine (loc.lineNumber - 1 ) + loc.columnNumber)
289
+ .searchWithin (resolvedUnit.unit);
290
+ if (node is SimpleIdentifier ) {
291
+ var parent = node.parent;
292
+ if (parent is InterpolationExpression && parent.rightBracket == null ) {
293
+ return node;
294
+ }
295
+ }
296
+ return null ;
297
+ }
298
+
225
299
Future <CiderReplaceMatch ?> _replaceSyntheticConstructor () async {
226
300
var element = canRename.refactoringElement.element;
227
301
var classElement = element.enclosingElement;
@@ -313,6 +387,9 @@ class CiderRenameComputer {
313
387
if (element is ConstructorElement ) {
314
388
return true ;
315
389
}
390
+ if (element is ImportElement ) {
391
+ return true ;
392
+ }
316
393
if (element is LabelElement || element is LocalElement ) {
317
394
return true ;
318
395
}
0 commit comments