Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit fc4360f

Browse files
author
Dart CI
committed
Version 2.13.0-41.0.dev
Merge commit '4302f058dd6a4a54b602e9a5a4db0bc5cedd578e' into 'dev'
2 parents a2ba4b5 + 4302f05 commit fc4360f

37 files changed

+656
-186
lines changed

pkg/analysis_server/lib/src/lsp/mapping.dart

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ lsp.WorkspaceEdit createWorkspaceEdit(
116116
server.clientCapabilities?.workspace,
117117
edits
118118
.map((e) => FileEditInformation(
119-
server.getVersionedDocumentIdentifier(e.file),
120-
server.getLineInfo(e.file),
121-
e.edits))
119+
server.getVersionedDocumentIdentifier(e.file),
120+
server.getLineInfo(e.file),
121+
e.edits,
122+
// fileStamp == 1 is used by the server to indicate the file needs creating.
123+
newFile: e.fileStamp == -1,
124+
))
122125
.toList());
123126
}
124127

@@ -1253,14 +1256,36 @@ lsp.WorkspaceEdit toWorkspaceEdit(
12531256
final clientSupportsTextDocumentEdits =
12541257
capabilities?.workspaceEdit?.documentChanges == true;
12551258
if (clientSupportsTextDocumentEdits) {
1259+
final clientSupportsCreate = capabilities?.workspaceEdit?.resourceOperations
1260+
?.contains(ResourceOperationKind.Create) ??
1261+
false;
1262+
final changes = <
1263+
Either4<lsp.TextDocumentEdit, lsp.CreateFile, lsp.RenameFile,
1264+
lsp.DeleteFile>>[];
1265+
1266+
// Convert each SourceEdit to either a TextDocumentEdit or a
1267+
// CreateFile + a TextDocumentEdit depending on whether it's a new
1268+
// file.
1269+
for (final edit in edits) {
1270+
if (clientSupportsCreate && edit.newFile) {
1271+
final create = lsp.CreateFile(uri: edit.doc.uri);
1272+
final createUnion = Either4<lsp.TextDocumentEdit, lsp.CreateFile,
1273+
lsp.RenameFile, lsp.DeleteFile>.t2(create);
1274+
changes.add(createUnion);
1275+
}
1276+
1277+
final textDocEdit = toTextDocumentEdit(edit);
1278+
final textDocEditUnion = Either4<lsp.TextDocumentEdit, lsp.CreateFile,
1279+
lsp.RenameFile, lsp.DeleteFile>.t1(textDocEdit);
1280+
changes.add(textDocEditUnion);
1281+
}
1282+
12561283
return lsp.WorkspaceEdit(
12571284
documentChanges: Either2<
12581285
List<lsp.TextDocumentEdit>,
12591286
List<
12601287
Either4<lsp.TextDocumentEdit, lsp.CreateFile, lsp.RenameFile,
1261-
lsp.DeleteFile>>>.t1(
1262-
edits.map(toTextDocumentEdit).toList(),
1263-
));
1288+
lsp.DeleteFile>>>.t2(changes));
12641289
} else {
12651290
return lsp.WorkspaceEdit(changes: toWorkspaceEditChanges(edits));
12661291
}

pkg/analysis_server/lib/src/lsp/source_edits.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ class FileEditInformation {
305305
final OptionalVersionedTextDocumentIdentifier doc;
306306
final LineInfo lineInfo;
307307
final List<server.SourceEdit> edits;
308+
final bool newFile;
308309

309-
FileEditInformation(this.doc, this.lineInfo, this.edits);
310+
FileEditInformation(this.doc, this.lineInfo, this.edits,
311+
{this.newFile = false});
310312
}

pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ import 'package:analyzer/error/error.dart';
161161
import 'package:analyzer/src/error/codes.dart';
162162
import 'package:analyzer/src/generated/java_core.dart';
163163
import 'package:analyzer/src/generated/parser.dart';
164-
import 'package:analyzer_plugin/protocol/protocol_common.dart'
165-
hide AnalysisError, Element, ElementKind;
166164
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
167165
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
168166
import 'package:analyzer_plugin/utilities/change_builder/conflicting_edit_exception.dart';
@@ -182,96 +180,13 @@ class DartFixContributor implements FixContributor {
182180
try {
183181
var processor = FixProcessor(context);
184182
var fixes = await processor.compute();
185-
var fixAllFixes = await _computeFixAllFixes(context, fixes);
186-
return List.from(fixes)..addAll(fixAllFixes);
183+
// todo (pq): add fixes from FixInFileProcessor
184+
// https://github.com/dart-lang/sdk/issues/45026
185+
return fixes;
187186
} on CancelCorrectionException {
188187
return const <Fix>[];
189188
}
190189
}
191-
192-
Future<List<Fix>> _computeFixAllFixes(
193-
DartFixContext context, List<Fix> fixes) async {
194-
final analysisError = context.error;
195-
final allAnalysisErrors = context.resolveResult.errors.toList();
196-
197-
// Validate inputs:
198-
// - return if no fixes
199-
// - return if no other analysis errors
200-
if (fixes.isEmpty || allAnalysisErrors.length < 2) {
201-
return const <Fix>[];
202-
}
203-
204-
// Remove any analysis errors that don't have the expected error code name
205-
allAnalysisErrors
206-
.removeWhere((e) => analysisError.errorCode.name != e.errorCode.name);
207-
if (allAnalysisErrors.length < 2) {
208-
return const <Fix>[];
209-
}
210-
211-
// A map between each FixKind and the List of associated fixes
212-
var map = <FixKind, List<Fix>>{};
213-
214-
// Populate the HashMap by looping through all AnalysisErrors, creating a
215-
// new FixProcessor to compute the other fixes that can be applied with this
216-
// one.
217-
// For each fix, put the fix into the HashMap.
218-
for (var i = 0; i < allAnalysisErrors.length; i++) {
219-
final FixContext fixContext = DartFixContextImpl(
220-
context.instrumentationService,
221-
context.workspace,
222-
context.resolveResult,
223-
allAnalysisErrors[i],
224-
(name) => [],
225-
);
226-
var processorI = FixProcessor(fixContext);
227-
var fixesListI = await processorI.compute();
228-
for (var f in fixesListI) {
229-
if (!map.containsKey(f.kind)) {
230-
map[f.kind] = <Fix>[]..add(f);
231-
} else {
232-
map[f.kind].add(f);
233-
}
234-
}
235-
}
236-
237-
// For each FixKind in the HashMap, union each list together, then return
238-
// the set of unioned fixes.
239-
var result = <Fix>[];
240-
map.forEach((FixKind kind, List<Fix> fixesList) {
241-
if (fixesList.first.kind.canBeAppliedTogether()) {
242-
var unionFix = _unionFixList(fixesList);
243-
if (unionFix != null) {
244-
result.add(unionFix);
245-
}
246-
}
247-
});
248-
return result;
249-
}
250-
251-
Fix _unionFixList(List<Fix> fixList) {
252-
if (fixList == null || fixList.isEmpty) {
253-
return null;
254-
} else if (fixList.length == 1) {
255-
return fixList[0];
256-
}
257-
var sourceChange = SourceChange(fixList[0].kind.appliedTogetherMessage);
258-
sourceChange.edits = List.from(fixList[0].change.edits);
259-
var edits = <SourceEdit>[];
260-
edits.addAll(fixList[0].change.edits[0].edits);
261-
sourceChange.linkedEditGroups =
262-
List.from(fixList[0].change.linkedEditGroups);
263-
for (var i = 1; i < fixList.length; i++) {
264-
edits.addAll(fixList[i].change.edits[0].edits);
265-
sourceChange.linkedEditGroups.addAll(fixList[i].change.linkedEditGroups);
266-
}
267-
// Sort the list of SourceEdits so that when the edits are applied, they
268-
// are applied from the end of the file to the top of the file.
269-
edits.sort((s1, s2) => s2.offset - s1.offset);
270-
271-
sourceChange.edits[0].edits = edits;
272-
273-
return Fix(fixList[0].kind, sourceChange);
274-
}
275190
}
276191

277192
/// Computer for Dart "fix all in file" fixes.

pkg/analysis_server/test/lsp/code_actions_fixes_test.dart

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
66
import 'package:linter/src/rules.dart';
7+
import 'package:path/path.dart' as path;
78
import 'package:test/test.dart';
89
import 'package:test_reflective_loader/test_reflective_loader.dart';
910

@@ -96,6 +97,38 @@ class FixesCodeActionsTest extends AbstractCodeActionsTest {
9697
expect(contents[mainFilePath], equals(expectedContent));
9798
}
9899

100+
Future<void> test_createFile() async {
101+
const content = '''
102+
import '[[newfile.dart]]';
103+
''';
104+
105+
final expectedCreatedFile =
106+
path.join(path.dirname(mainFilePath), 'newfile.dart');
107+
108+
newFile(mainFilePath, content: withoutMarkers(content));
109+
await initialize(
110+
textDocumentCapabilities: withCodeActionKinds(
111+
emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
112+
workspaceCapabilities: withResourceOperationKinds(
113+
emptyWorkspaceClientCapabilities, [ResourceOperationKind.Create]),
114+
);
115+
116+
final codeActions = await getCodeActions(mainFileUri.toString(),
117+
range: rangeFromMarkers(content));
118+
final fixAction = findEditAction(codeActions,
119+
CodeActionKind('quickfix.create.file'), "Create file 'newfile.dart'");
120+
121+
expect(fixAction, isNotNull);
122+
expect(fixAction.edit.documentChanges, isNotNull);
123+
124+
// Ensure applying the changes creates the file and with the expected content.
125+
final contents = {
126+
mainFilePath: withoutMarkers(content),
127+
};
128+
applyDocumentChanges(contents, fixAction.edit.documentChanges);
129+
expect(contents[expectedCreatedFile], isNotEmpty);
130+
}
131+
99132
Future<void> test_filtersCorrectly() async {
100133
const content = '''
101134
import 'dart:async';
@@ -239,8 +272,6 @@ class FixesCodeActionsWithNullSafetyTest extends AbstractCodeActionsTest {
239272
@override
240273
String get testPackageLanguageVersion => latestLanguageVersion;
241274

242-
/// todo (pq): prefer_is_empty newly produces fix-all-fixes; update this test appropriately
243-
@failingTest
244275
Future<void> test_fixAll_notForAmbigiousProducers() async {
245276
// The ReplaceWithIsEmpty producer does not provide a FixKind up-front, as
246277
// it may produce `REPLACE_WITH_IS_EMPTY` or `REPLACE_WITH_IS_NOT_EMPTY`

pkg/analysis_server/test/lsp/server_abstract.dart

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,19 @@ mixin ClientCapabilitiesHelperMixin {
403403
});
404404
}
405405

406+
ClientCapabilitiesWorkspace withResourceOperationKinds(
407+
ClientCapabilitiesWorkspace source,
408+
List<ResourceOperationKind> kinds,
409+
) {
410+
return extendWorkspaceCapabilities(source, {
411+
'workspaceEdit': {
412+
'documentChanges':
413+
true, // docChanges aren't included in resourceOperations
414+
'resourceOperations': kinds.map((k) => k.toJson()).toList(),
415+
}
416+
});
417+
}
418+
406419
TextDocumentClientCapabilities withSignatureHelpContentFormat(
407420
TextDocumentClientCapabilities source,
408421
List<MarkupKind> formats,
@@ -572,8 +585,23 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
572585
Map<String, String> oldFileContent,
573586
List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>> changes,
574587
) {
575-
// TODO(dantup): Implement handling of resource changes (not currently used).
576-
throw 'Test helper applyResourceChanges not currently supported';
588+
for (final change in changes) {
589+
change.map(
590+
(textDocEdit) => applyTextDocumentEdits(oldFileContent, [textDocEdit]),
591+
(create) => applyResourceCreate(oldFileContent, create),
592+
(rename) => throw 'applyResourceChanges:Delete not currently supported',
593+
(delete) => throw 'applyResourceChanges:Delete not currently supported',
594+
);
595+
}
596+
}
597+
598+
void applyResourceCreate(
599+
Map<String, String> oldFileContent, CreateFile create) {
600+
final path = Uri.parse(create.uri).toFilePath();
601+
if (oldFileContent.containsKey(path)) {
602+
throw 'Recieved create instruction for $path which already existed.';
603+
}
604+
oldFileContent[path] = '';
577605
}
578606

579607
String applyTextDocumentEdit(String content, TextDocumentEdit edit) {
@@ -585,7 +613,8 @@ mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
585613
edits.forEach((edit) {
586614
final path = Uri.parse(edit.textDocument.uri).toFilePath();
587615
if (!oldFileContent.containsKey(path)) {
588-
throw 'Recieved edits for $path which was not provided as a file to be edited';
616+
throw 'Recieved edits for $path which was not provided as a file to be edited. '
617+
'Perhaps a CreateFile change was missing from the edits?';
589618
}
590619
oldFileContent[path] = applyTextDocumentEdit(oldFileContent[path], edit);
591620
});

pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class B {}
5656
''');
5757
}
5858

59+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
5960
Future<void> test_assignment_general_all() async {
6061
await resolveTestCode('''
6162
f(A a) {
@@ -98,6 +99,7 @@ class B {}
9899
''');
99100
}
100101

102+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
101103
Future<void> test_assignment_list_all() async {
102104
await resolveTestCode('''
103105
f(List<A> a) {
@@ -140,6 +142,7 @@ class B {}
140142
''');
141143
}
142144

145+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
143146
Future<void> test_assignment_map_all() async {
144147
await resolveTestCode('''
145148
f(Map<A, B> a) {
@@ -186,6 +189,7 @@ class B {}
186189
''');
187190
}
188191

192+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
189193
Future<void> test_assignment_needsParens_all() async {
190194
await resolveTestCode('''
191195
f(A a) {
@@ -232,6 +236,7 @@ class B {}
232236
''');
233237
}
234238

239+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
235240
Future<void> test_assignment_set_all() async {
236241
await resolveTestCode('''
237242
f(Set<A> a) {
@@ -284,6 +289,7 @@ class B {}
284289
''');
285290
}
286291

292+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
287293
Future<void> test_declaration_general_all() async {
288294
await resolveTestCode('''
289295
f(A a) {
@@ -322,6 +328,7 @@ class B {}
322328
''');
323329
}
324330

331+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
325332
Future<void> test_declaration_list_all() async {
326333
await resolveTestCode('''
327334
f(List<A> a) {
@@ -360,6 +367,7 @@ class B {}
360367
''');
361368
}
362369

370+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
363371
Future<void> test_declaration_map_all() async {
364372
await resolveTestCode('''
365373
f(Map<A, B> a) {
@@ -402,6 +410,7 @@ class B {}
402410
''');
403411
}
404412

413+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
405414
Future<void> test_declaration_needsParens_all() async {
406415
await resolveTestCode('''
407416
f(A a) {
@@ -444,6 +453,7 @@ class B {}
444453
''');
445454
}
446455

456+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
447457
Future<void> test_declaration_set_all() async {
448458
await resolveTestCode('''
449459
f(Set<A> a) {

pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ main(String p) {
3737
''');
3838
}
3939

40+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
4041
Future<void> test_nonBoolCondition_all() async {
4142
await resolveTestCode('''
4243
main(String p, String q) {

pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ main(Object p) {
3939
''');
4040
}
4141

42+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
4243
Future<void> test_assignment_all() async {
4344
await resolveTestCode('''
4445
main(Object p, Object q) {

pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class RemoveUnnecessaryParenthesesTest extends FixProcessorLintTest {
2323
@override
2424
String get lintCode => LintNames.unnecessary_parenthesis;
2525

26+
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/45026')
2627
Future<void> test_all() async {
2728
await resolveTestCode('''
2829
void f() {

0 commit comments

Comments
 (0)