Skip to content

Commit bd12fd1

Browse files
author
Dart CI
committed
Version 2.18.0-147.0.dev
Merge commit '1c27154f41827e1155d948c9dda67ecc39e79655' into 'dev'
2 parents 2b6cf80 + 1c27154 commit bd12fd1

File tree

33 files changed

+969
-516
lines changed

33 files changed

+969
-516
lines changed

pkg/analysis_server/lib/src/cider/rename.dart

Lines changed: 104 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class CanRenameResponse {
5353
} else if (element is ConstructorElement) {
5454
status = validateConstructorName(name);
5555
_analyzePossibleConflicts(element, status, name);
56+
} else if (element is ImportElement) {
57+
status = validateImportPrefixName(name);
5658
}
5759

5860
if (status == null) {
@@ -125,34 +127,9 @@ class CheckNameResponse {
125127
for (var element in elements) {
126128
matches.addAll(await fileResolver.findReferences2(element));
127129
}
128-
129130
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();
156133
}
157134
var replaceMatches = <CiderReplaceMatch>[];
158135
if (element is ConstructorElement) {
@@ -179,6 +156,30 @@ class CheckNameResponse {
179156
replaceMatches.addMatch(result.path, result.matches.toList());
180157
}
181158
}
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+
}
182183
} else {
183184
for (var match in matches) {
184185
replaceMatches.addMatch(
@@ -213,6 +214,32 @@ class CheckNameResponse {
213214
lineInfo.getLocation(element.setter!.nameOffset),
214215
element.setter!.nameLength));
215216
}
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+
}
216243
} else {
217244
var location = (await canRename._fileResolver.resolve2(path: sourcePath))
218245
.lineInfo
@@ -222,6 +249,53 @@ class CheckNameResponse {
222249
return infos;
223250
}
224251

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+
225299
Future<CiderReplaceMatch?> _replaceSyntheticConstructor() async {
226300
var element = canRename.refactoringElement.element;
227301
var classElement = element.enclosingElement;
@@ -313,6 +387,9 @@ class CiderRenameComputer {
313387
if (element is ConstructorElement) {
314388
return true;
315389
}
390+
if (element is ImportElement) {
391+
return true;
392+
}
316393
if (element is LabelElement || element is LocalElement) {
317394
return true;
318395
}

pkg/analysis_server/test/src/cider/rename_test.dart

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,131 @@ void f() {
651651
[ReplaceInfo('bar', CharacterLocation(1, 1), 3)]);
652652
}
653653

654+
void test_rename_import() async {
655+
var testCode = '''
656+
import 'dart:async';
657+
^import 'dart:math' show Random, min hide max;
658+
void f() {
659+
Future f;
660+
Random r;
661+
min(1, 2);
662+
}
663+
''';
664+
665+
var result = await _rename(testCode, 'newName');
666+
_assertTestChangeResult('''
667+
import 'dart:async';
668+
import 'dart:math' as newName show Random, min hide max;
669+
void f() {
670+
Future f;
671+
newName.Random r;
672+
newName.min(1, 2);
673+
}
674+
''', result!.replaceMatches.first.matches);
675+
}
676+
677+
void test_rename_import_hasCurlyBrackets() async {
678+
var testCode = r'''
679+
// test
680+
^import 'dart:async';
681+
void f() {
682+
Future f;
683+
print('Future type: ${Future}');
684+
}
685+
''';
686+
687+
var result = await _rename(testCode, 'newName');
688+
_assertTestChangeResult(r'''
689+
// test
690+
import 'dart:async' as newName;
691+
void f() {
692+
newName.Future f;
693+
print('Future type: ${newName.Future}');
694+
}
695+
''', result!.replaceMatches.first.matches);
696+
}
697+
698+
void test_rename_import_noCurlyBrackets() async {
699+
var testCode = r'''
700+
// test
701+
^import 'dart:async';
702+
void f() {
703+
Future f;
704+
print('Future type: $Future');
705+
}
706+
''';
707+
var result = await _rename(testCode, 'newName');
708+
_assertTestChangeResult(r'''
709+
// test
710+
import 'dart:async' as newName;
711+
void f() {
712+
newName.Future f;
713+
print('Future type: ${newName.Future}');
714+
}
715+
''', result!.replaceMatches.first.matches);
716+
}
717+
718+
void test_rename_import_onPrefixElement() async {
719+
var testCode = '''
720+
import 'dart:async' as test;
721+
import 'dart:math' as test;
722+
void f() {
723+
test.Future f;
724+
^test.pi;
725+
test.e;
726+
}
727+
''';
728+
var result = await _rename(testCode, 'newName');
729+
_assertTestChangeResult('''
730+
import 'dart:async' as test;
731+
import 'dart:math' as newName;
732+
void f() {
733+
test.Future f;
734+
newName.pi;
735+
newName.e;
736+
}
737+
''', result!.replaceMatches.first.matches);
738+
}
739+
740+
void test_rename_import_prefix() async {
741+
var testCode = '''
742+
import 'dart:math' as test;
743+
^import 'dart:async' as test;
744+
void f() {
745+
test.max(1, 2);
746+
test.Future f;
747+
}
748+
''';
749+
var result = await _rename(testCode, 'newName');
750+
_assertTestChangeResult('''
751+
import 'dart:math' as test;
752+
import 'dart:async' as newName;
753+
void f() {
754+
test.max(1, 2);
755+
newName.Future f;
756+
}
757+
''', result!.replaceMatches.first.matches);
758+
}
759+
760+
void test_rename_import_remove_prefix() async {
761+
var testCode = '''
762+
import 'dart:math' as test;
763+
^import 'dart:async' as test;
764+
void f() {
765+
test.Future f;
766+
}
767+
''';
768+
769+
var result = await _rename(testCode, '');
770+
_assertTestChangeResult('''
771+
import 'dart:math' as test;
772+
import 'dart:async';
773+
void f() {
774+
Future f;
775+
}
776+
''', result!.replaceMatches.first.matches);
777+
}
778+
654779
void test_rename_local() async {
655780
var testCode = '''
656781
void foo() {

pkg/analysis_server/tool/code_completion/corpus.dart

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import 'dart:convert';
66
import 'dart:io';
77

88
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
9-
import 'package:html/parser.dart' show parse;
10-
import 'package:http/http.dart' as http;
119
import 'package:path/path.dart' as path;
1210

1311
/// Generate or update corpus data.
@@ -63,7 +61,6 @@ final updateExistingClones = false;
6361

6462
final _appDir =
6563
path.join(_homeDir, 'completion_metrics', 'third_party', 'apps');
66-
final _client = http.Client();
6764

6865
final _homeDir = Platform.isWindows
6966
? Platform.environment['LOCALAPPDATA']!
@@ -90,12 +87,6 @@ Future<CloneResult> _clone(String repo) async {
9087
return CloneResult(result.exitCode, cloneDir, msg: result.stderr as String);
9188
}
9289

93-
Future<String> _getBody(String url) async => (await _getResponse(url)).body;
94-
95-
Future<http.Response> _getResponse(String url) async =>
96-
_client.get(Uri.parse(url),
97-
headers: const {'User-Agent': 'dart.pkg.completion_metrics'});
98-
9990
bool _hasPubspec(FileSystemEntity f) =>
10091
f is Directory &&
10192
File(path.join(f.path, file_paths.pubspecYaml)).existsSync();
@@ -130,38 +121,3 @@ class CloneResult {
130121
final String msg;
131122
CloneResult(this.exitCode, this.directory, {this.msg = ''});
132123
}
133-
134-
class RepoList {
135-
static const itsallwidgetsRssFeed = 'https://itsallwidgets.com/app/feed';
136-
137-
// (Re) generate the list of github repos on itsallwidgets.com
138-
static Future<List<String>> fromItsAllWidgetsRssFeed() async {
139-
final repos = <String>{};
140-
141-
final body = await _getBody(itsallwidgetsRssFeed);
142-
final doc = parse(body);
143-
final entries = doc.querySelectorAll('entry');
144-
for (var entry in entries) {
145-
final link = entry.querySelector('link');
146-
if (link == null) {
147-
continue;
148-
}
149-
final href = link.attributes['href'];
150-
if (href == null) {
151-
continue;
152-
}
153-
final body = await _getBody(href);
154-
final doc = parse(body);
155-
final links = doc.querySelectorAll('a');
156-
for (var link in links) {
157-
final href = link.attributes['href'];
158-
if (href != null && href.startsWith('https://github.com/')) {
159-
print(href);
160-
repos.add(href);
161-
continue;
162-
}
163-
}
164-
}
165-
return repos.toList();
166-
}
167-
}

0 commit comments

Comments
 (0)