Skip to content

Commit 3d5df93

Browse files
pqcommit-bot@chromium.org
authored andcommitted
bulk fix protocol
Change-Id: Id8505d5ad6f0f3d1c5289ab12d4932c6174f72e5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153623 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Phil Quitslund <[email protected]>
1 parent 7a1d6a9 commit 3d5df93

File tree

14 files changed

+536
-0
lines changed

14 files changed

+536
-0
lines changed

pkg/analysis_server/doc/api.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,7 @@ <h2 class="domain"><a name="domain_edit">edit domain</a></h2>
20832083

20842084

20852085

2086+
20862087
<h3>Requests</h3><dl><dt class="request"><a name="request_edit.format">edit.format</a></dt><dd><div class="box"><pre>request: {
20872088
"id": String
20882089
"method": "edit.format"

pkg/analysis_server/lib/protocol/protocol_constants.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
164164
const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
165165
const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
166166
const String DIAGNOSTIC_RESPONSE_GET_SERVER_PORT_PORT = 'port';
167+
const String EDIT_REQUEST_BULK_FIXES = 'edit.bulkFixes';
168+
const String EDIT_REQUEST_BULK_FIXES_INCLUDED = 'included';
167169
const String EDIT_REQUEST_DARTFIX = 'edit.dartfix';
168170
const String EDIT_REQUEST_DARTFIX_EXCLUDED_FIXES = 'excludedFixes';
169171
const String EDIT_REQUEST_DARTFIX_INCLUDED = 'included';
@@ -220,6 +222,7 @@ const String EDIT_REQUEST_ORGANIZE_DIRECTIVES = 'edit.organizeDirectives';
220222
const String EDIT_REQUEST_ORGANIZE_DIRECTIVES_FILE = 'file';
221223
const String EDIT_REQUEST_SORT_MEMBERS = 'edit.sortMembers';
222224
const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
225+
const String EDIT_RESPONSE_BULK_FIXES_EDITS = 'edits';
223226
const String EDIT_RESPONSE_DARTFIX_DETAILS = 'details';
224227
const String EDIT_RESPONSE_DARTFIX_EDITS = 'edits';
225228
const String EDIT_RESPONSE_DARTFIX_HAS_ERRORS = 'hasErrors';

pkg/analysis_server/lib/protocol/protocol_generated.dart

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7115,6 +7115,180 @@ class DiagnosticGetServerPortResult implements ResponseResult {
71157115
}
71167116
}
71177117

7118+
/// edit.bulkFixes params
7119+
///
7120+
/// {
7121+
/// "included": List<FilePath>
7122+
/// }
7123+
///
7124+
/// Clients may not extend, implement or mix-in this class.
7125+
class EditBulkFixesParams implements RequestParams {
7126+
List<String> _included;
7127+
7128+
/// A list of the files and directories for which edits should be suggested.
7129+
///
7130+
/// If a request is made with a path that is invalid, e.g. is not absolute
7131+
/// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
7132+
/// generated. If a request is made for a file which does not exist, or which
7133+
/// is not currently subject to analysis (e.g. because it is not associated
7134+
/// with any analysis root specified to analysis.setAnalysisRoots), an error
7135+
/// of type FILE_NOT_ANALYZED will be generated.
7136+
List<String> get included => _included;
7137+
7138+
/// A list of the files and directories for which edits should be suggested.
7139+
///
7140+
/// If a request is made with a path that is invalid, e.g. is not absolute
7141+
/// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
7142+
/// generated. If a request is made for a file which does not exist, or which
7143+
/// is not currently subject to analysis (e.g. because it is not associated
7144+
/// with any analysis root specified to analysis.setAnalysisRoots), an error
7145+
/// of type FILE_NOT_ANALYZED will be generated.
7146+
set included(List<String> value) {
7147+
assert(value != null);
7148+
_included = value;
7149+
}
7150+
7151+
EditBulkFixesParams(List<String> included) {
7152+
this.included = included;
7153+
}
7154+
7155+
factory EditBulkFixesParams.fromJson(
7156+
JsonDecoder jsonDecoder, String jsonPath, Object json) {
7157+
json ??= {};
7158+
if (json is Map) {
7159+
List<String> included;
7160+
if (json.containsKey('included')) {
7161+
included = jsonDecoder.decodeList(
7162+
jsonPath + '.included', json['included'], jsonDecoder.decodeString);
7163+
} else {
7164+
throw jsonDecoder.mismatch(jsonPath, 'included');
7165+
}
7166+
return EditBulkFixesParams(included);
7167+
} else {
7168+
throw jsonDecoder.mismatch(jsonPath, 'edit.bulkFixes params', json);
7169+
}
7170+
}
7171+
7172+
factory EditBulkFixesParams.fromRequest(Request request) {
7173+
return EditBulkFixesParams.fromJson(
7174+
RequestDecoder(request), 'params', request.params);
7175+
}
7176+
7177+
@override
7178+
Map<String, dynamic> toJson() {
7179+
var result = <String, dynamic>{};
7180+
result['included'] = included;
7181+
return result;
7182+
}
7183+
7184+
@override
7185+
Request toRequest(String id) {
7186+
return Request(id, 'edit.bulkFixes', toJson());
7187+
}
7188+
7189+
@override
7190+
String toString() => json.encode(toJson());
7191+
7192+
@override
7193+
bool operator ==(other) {
7194+
if (other is EditBulkFixesParams) {
7195+
return listEqual(
7196+
included, other.included, (String a, String b) => a == b);
7197+
}
7198+
return false;
7199+
}
7200+
7201+
@override
7202+
int get hashCode {
7203+
var hash = 0;
7204+
hash = JenkinsSmiHash.combine(hash, included.hashCode);
7205+
return JenkinsSmiHash.finish(hash);
7206+
}
7207+
}
7208+
7209+
/// edit.bulkFixes result
7210+
///
7211+
/// {
7212+
/// "edits": List<SourceFileEdit>
7213+
/// }
7214+
///
7215+
/// Clients may not extend, implement or mix-in this class.
7216+
class EditBulkFixesResult implements ResponseResult {
7217+
List<SourceFileEdit> _edits;
7218+
7219+
/// A list of source edits to apply the recommended changes.
7220+
List<SourceFileEdit> get edits => _edits;
7221+
7222+
/// A list of source edits to apply the recommended changes.
7223+
set edits(List<SourceFileEdit> value) {
7224+
assert(value != null);
7225+
_edits = value;
7226+
}
7227+
7228+
EditBulkFixesResult(List<SourceFileEdit> edits) {
7229+
this.edits = edits;
7230+
}
7231+
7232+
factory EditBulkFixesResult.fromJson(
7233+
JsonDecoder jsonDecoder, String jsonPath, Object json) {
7234+
json ??= {};
7235+
if (json is Map) {
7236+
List<SourceFileEdit> edits;
7237+
if (json.containsKey('edits')) {
7238+
edits = jsonDecoder.decodeList(
7239+
jsonPath + '.edits',
7240+
json['edits'],
7241+
(String jsonPath, Object json) =>
7242+
SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
7243+
} else {
7244+
throw jsonDecoder.mismatch(jsonPath, 'edits');
7245+
}
7246+
return EditBulkFixesResult(edits);
7247+
} else {
7248+
throw jsonDecoder.mismatch(jsonPath, 'edit.bulkFixes result', json);
7249+
}
7250+
}
7251+
7252+
factory EditBulkFixesResult.fromResponse(Response response) {
7253+
return EditBulkFixesResult.fromJson(
7254+
ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
7255+
'result',
7256+
response.result);
7257+
}
7258+
7259+
@override
7260+
Map<String, dynamic> toJson() {
7261+
var result = <String, dynamic>{};
7262+
result['edits'] =
7263+
edits.map((SourceFileEdit value) => value.toJson()).toList();
7264+
return result;
7265+
}
7266+
7267+
@override
7268+
Response toResponse(String id) {
7269+
return Response(id, result: toJson());
7270+
}
7271+
7272+
@override
7273+
String toString() => json.encode(toJson());
7274+
7275+
@override
7276+
bool operator ==(other) {
7277+
if (other is EditBulkFixesResult) {
7278+
return listEqual(
7279+
edits, other.edits, (SourceFileEdit a, SourceFileEdit b) => a == b);
7280+
}
7281+
return false;
7282+
}
7283+
7284+
@override
7285+
int get hashCode {
7286+
var hash = 0;
7287+
hash = JenkinsSmiHash.combine(hash, edits.hashCode);
7288+
return JenkinsSmiHash.finish(hash);
7289+
}
7290+
}
7291+
71187292
/// edit.dartfix params
71197293
///
71207294
/// {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analysis_server/protocol/protocol.dart';
6+
import 'package:analysis_server/protocol/protocol_generated.dart';
7+
import 'package:analysis_server/src/analysis_server.dart';
8+
9+
class EditBulkFixes {
10+
final AnalysisServer server;
11+
final Request request;
12+
13+
EditBulkFixes(this.server, this.request);
14+
15+
Future<Response> compute() async {
16+
// todo (pq): implemennt
17+
return EditBulkFixesResult([]).toResponse(request.id);
18+
}
19+
}

pkg/analysis_server/lib/src/edit/edit_domain.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'package:analysis_server/src/collections.dart';
1212
import 'package:analyzer/src/exception/exception.dart';
1313
import 'package:analysis_server/src/computer/import_elements_computer.dart';
1414
import 'package:analysis_server/src/domain_abstract.dart';
15+
import 'package:analysis_server/src/edit/edit_bulk_fixes.dart'
16+
show EditBulkFixes;
1517
import 'package:analysis_server/src/edit/edit_dartfix.dart' show EditDartFix;
1618
import 'package:analysis_server/src/edit/fix/dartfix_info.dart' show allFixes;
1719
import 'package:analysis_server/src/plugin/plugin_manager.dart';
@@ -92,6 +94,21 @@ class EditDomainHandler extends AbstractRequestHandler {
9294
_newRefactoringManager();
9395
}
9496

97+
Future bulkFixes(Request request) async {
98+
//
99+
// Compute fixes
100+
//
101+
try {
102+
var bulkFix = EditBulkFixes(server, request);
103+
var response = await bulkFix.compute();
104+
105+
server.sendResponse(response);
106+
} catch (exception, stackTrace) {
107+
server.sendServerErrorNotification('Exception while getting bulk fixes',
108+
CaughtException(exception, stackTrace), stackTrace);
109+
}
110+
}
111+
95112
Future dartfix(Request request) async {
96113
// TODO(danrubel): Add support for dartfix plugins
97114

@@ -356,6 +373,9 @@ class EditDomainHandler extends AbstractRequestHandler {
356373
return Response.DELAYED_RESPONSE;
357374
} else if (requestName == EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS) {
358375
return _getAvailableRefactorings(request);
376+
} else if (requestName == EDIT_REQUEST_BULK_FIXES) {
377+
bulkFixes(request);
378+
return Response.DELAYED_RESPONSE;
359379
} else if (requestName == EDIT_REQUEST_GET_DARTFIX_INFO) {
360380
return getDartfixInfo(request);
361381
} else if (requestName == EDIT_REQUEST_GET_FIXES) {

pkg/analysis_server/test/integration/coverage.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ server calls. This file is validated by `coverage_test.dart`.
4444
- [x] diagnostic.getServerPort
4545

4646
## edit domain
47+
- [x] edit.bulkFixes
4748
- [x] edit.dartfix
4849
- [x] edit.format
4950
- [x] edit.getAssists
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:test/test.dart';
6+
import 'package:test_reflective_loader/test_reflective_loader.dart';
7+
8+
import '../support/integration_tests.dart';
9+
10+
void main() {
11+
defineReflectiveSuite(() {
12+
defineReflectiveTests(BulkFixesTest);
13+
});
14+
}
15+
16+
@reflectiveTest
17+
class BulkFixesTest extends AbstractAnalysisServerIntegrationTest {
18+
void setupTarget() {
19+
writeFile(sourcePath('test.dart'), '''
20+
class A {
21+
void f() {}
22+
}
23+
class B extends A {
24+
void f() { }
25+
}
26+
''');
27+
standardAnalysisSetup();
28+
}
29+
30+
@failingTest
31+
Future<void> test_bulk_fix_override() async {
32+
setupTarget();
33+
34+
var result = await sendEditBulkFixes([sourceDirectory.path]);
35+
expect(result.edits.length, 1);
36+
}
37+
}

pkg/analysis_server/test/integration/edit/test_all.dart

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

55
import 'package:test_reflective_loader/test_reflective_loader.dart';
66

7+
import 'bulk_fixes_test.dart' as bulk_fixes_test;
78
import 'dartfix_test.dart' as dartfix_test;
89
import 'format_test.dart' as format_test;
910
import 'get_assists_test.dart' as get_assists_test;
@@ -24,6 +25,7 @@ import 'sort_members_test.dart' as sort_members_test;
2425

2526
void main() {
2627
defineReflectiveSuite(() {
28+
bulk_fixes_test.main();
2729
dartfix_test.main();
2830
format_test.main();
2931
get_assists_test.main();

pkg/analysis_server/test/integration/support/integration_test_methods.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,38 @@ abstract class IntegrationTestMixin {
15621562
return EditGetDartfixInfoResult.fromJson(decoder, 'result', result);
15631563
}
15641564

1565+
/// Analyze the specified sources for fixes that can be applied in bulk and
1566+
/// return a set of suggested edits for those sources. These edits may
1567+
/// include changes to sources outside the set of specified sources if a
1568+
/// change in a specified source requires it.
1569+
///
1570+
/// Parameters
1571+
///
1572+
/// included: List<FilePath>
1573+
///
1574+
/// A list of the files and directories for which edits should be
1575+
/// suggested.
1576+
///
1577+
/// If a request is made with a path that is invalid, e.g. is not absolute
1578+
/// and normalized, an error of type INVALID_FILE_PATH_FORMAT will be
1579+
/// generated. If a request is made for a file which does not exist, or
1580+
/// which is not currently subject to analysis (e.g. because it is not
1581+
/// associated with any analysis root specified to
1582+
/// analysis.setAnalysisRoots), an error of type FILE_NOT_ANALYZED will be
1583+
/// generated.
1584+
///
1585+
/// Returns
1586+
///
1587+
/// edits: List<SourceFileEdit>
1588+
///
1589+
/// A list of source edits to apply the recommended changes.
1590+
Future<EditBulkFixesResult> sendEditBulkFixes(List<String> included) async {
1591+
var params = EditBulkFixesParams(included).toJson();
1592+
var result = await server.send('edit.bulkFixes', params);
1593+
var decoder = ResponseDecoder(null);
1594+
return EditBulkFixesResult.fromJson(decoder, 'result', result);
1595+
}
1596+
15651597
/// Analyze the specified sources for recommended changes and return a set of
15661598
/// suggested edits for those sources. These edits may include changes to
15671599
/// sources outside the set of specified sources if a change in a specified

pkg/analysis_server/test/integration/support/protocol_matchers.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,22 @@ final Matcher isDiagnosticGetServerPortParams = isNull;
22052205
final Matcher isDiagnosticGetServerPortResult = LazyMatcher(() =>
22062206
MatchesJsonObject('diagnostic.getServerPort result', {'port': isInt}));
22072207

2208+
/// edit.bulkFixes params
2209+
///
2210+
/// {
2211+
/// "included": List<FilePath>
2212+
/// }
2213+
final Matcher isEditBulkFixesParams = LazyMatcher(() => MatchesJsonObject(
2214+
'edit.bulkFixes params', {'included': isListOf(isFilePath)}));
2215+
2216+
/// edit.bulkFixes result
2217+
///
2218+
/// {
2219+
/// "edits": List<SourceFileEdit>
2220+
/// }
2221+
final Matcher isEditBulkFixesResult = LazyMatcher(() => MatchesJsonObject(
2222+
'edit.bulkFixes result', {'edits': isListOf(isSourceFileEdit)}));
2223+
22082224
/// edit.dartfix params
22092225
///
22102226
/// {

0 commit comments

Comments
 (0)