diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html index c1b807a1402..e65f669da95 100644 --- a/pkg/analysis_server/doc/api.html +++ b/pkg/analysis_server/doc/api.html @@ -2161,6 +2161,7 @@ a:focus, a:hover { +

Requests

edit.format
request: {
   "id": String
   "method": "edit.format"
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index e8a4e7e6f26..0a14c4fa069 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -194,6 +194,8 @@ const String EDIT_REQUEST_BULK_FIXES_INCLUDED = 'included';
 const String EDIT_REQUEST_BULK_FIXES_IN_TEST_MODE = 'inTestMode';
 const String EDIT_REQUEST_FORMAT = 'edit.format';
 const String EDIT_REQUEST_FORMAT_FILE = 'file';
+const String EDIT_REQUEST_FORMAT_IF_ENABLED = 'edit.formatIfEnabled';
+const String EDIT_REQUEST_FORMAT_IF_ENABLED_DIRECTORIES = 'directories';
 const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength';
 const String EDIT_REQUEST_FORMAT_SELECTION_LENGTH = 'selectionLength';
 const String EDIT_REQUEST_FORMAT_SELECTION_OFFSET = 'selectionOffset';
@@ -242,6 +244,7 @@ const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file';
 const String EDIT_RESPONSE_BULK_FIXES_DETAILS = 'details';
 const String EDIT_RESPONSE_BULK_FIXES_EDITS = 'edits';
 const String EDIT_RESPONSE_FORMAT_EDITS = 'edits';
+const String EDIT_RESPONSE_FORMAT_IF_ENABLED_EDITS = 'edits';
 const String EDIT_RESPONSE_FORMAT_SELECTION_LENGTH = 'selectionLength';
 const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset';
 const String EDIT_RESPONSE_GET_ASSISTS_ASSISTS = 'assists';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index dc2c12a74e0..37339eee119 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -6258,6 +6258,140 @@ class EditBulkFixesResult implements ResponseResult {
       );
 }
 
+/// edit.formatIfEnabled params
+///
+/// {
+///   "directories": List
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class EditFormatIfEnabledParams implements RequestParams {
+  /// The paths of the directories containing the code to be formatted.
+  List directories;
+
+  EditFormatIfEnabledParams(this.directories);
+
+  factory EditFormatIfEnabledParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+    json ??= {};
+    if (json is Map) {
+      List directories;
+      if (json.containsKey('directories')) {
+        directories = jsonDecoder.decodeList(jsonPath + '.directories',
+            json['directories'], jsonDecoder.decodeString);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'directories');
+      }
+      return EditFormatIfEnabledParams(directories);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'edit.formatIfEnabled params', json);
+    }
+  }
+
+  factory EditFormatIfEnabledParams.fromRequest(Request request) {
+    return EditFormatIfEnabledParams.fromJson(
+        RequestDecoder(request), 'params', request.params);
+  }
+
+  @override
+  Map toJson() {
+    var result = {};
+    result['directories'] = directories;
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return Request(id, 'edit.formatIfEnabled', toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditFormatIfEnabledParams) {
+      return listEqual(
+          directories, other.directories, (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => directories.hashCode;
+}
+
+/// edit.formatIfEnabled result
+///
+/// {
+///   "edits": List
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class EditFormatIfEnabledResult implements ResponseResult {
+  /// The edit(s) to be applied in order to format the code. The list will be
+  /// empty if none of the files were formatted, whether because they were not
+  /// eligible to be formatted or because they were already formatted.
+  List edits;
+
+  EditFormatIfEnabledResult(this.edits);
+
+  factory EditFormatIfEnabledResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+    json ??= {};
+    if (json is Map) {
+      List edits;
+      if (json.containsKey('edits')) {
+        edits = jsonDecoder.decodeList(
+            jsonPath + '.edits',
+            json['edits'],
+            (String jsonPath, Object? json) =>
+                SourceFileEdit.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, 'edits');
+      }
+      return EditFormatIfEnabledResult(edits);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, 'edit.formatIfEnabled result', json);
+    }
+  }
+
+  factory EditFormatIfEnabledResult.fromResponse(Response response) {
+    return EditFormatIfEnabledResult.fromJson(
+        ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        'result',
+        response.result);
+  }
+
+  @override
+  Map toJson() {
+    var result = {};
+    result['edits'] =
+        edits.map((SourceFileEdit value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditFormatIfEnabledResult) {
+      return listEqual(
+          edits, other.edits, (SourceFileEdit a, SourceFileEdit b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode => edits.hashCode;
+}
+
 /// edit.format params
 ///
 /// {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 86bffa8844e..be22f294190 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -9,6 +9,7 @@ import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
 import 'package:analysis_server/src/handler/legacy/edit_bulk_fixes.dart';
+import 'package:analysis_server/src/handler/legacy/edit_format_if_enabled.dart';
 import 'package:analysis_server/src/handler/legacy/edit_get_assists.dart';
 import 'package:analysis_server/src/handler/legacy/edit_get_fixes.dart';
 import 'package:analysis_server/src/handler/legacy/edit_get_postfix_completion.dart';
@@ -119,6 +120,9 @@ class EditDomainHandler extends AbstractRequestHandler {
       var requestName = request.method;
       if (requestName == EDIT_REQUEST_FORMAT) {
         return format(request);
+      } else if (requestName == EDIT_REQUEST_FORMAT_IF_ENABLED) {
+        EditFormatIfEnabledHandler(server, request, cancellationToken).handle();
+        return Response.DELAYED_RESPONSE;
       } else if (requestName == EDIT_REQUEST_GET_ASSISTS) {
         EditGetAssistsHandler(server, request, cancellationToken).handle();
         return Response.DELAYED_RESPONSE;
diff --git a/pkg/analysis_server/lib/src/handler/legacy/edit_format_if_enabled.dart b/pkg/analysis_server/lib/src/handler/legacy/edit_format_if_enabled.dart
new file mode 100644
index 00000000000..5e404d4c87d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/handler/legacy/edit_format_if_enabled.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/utilities/progress.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+import 'package:dart_style/src/dart_formatter.dart';
+import 'package:dart_style/src/exceptions.dart';
+import 'package:dart_style/src/source_code.dart';
+
+/// The handler for the `edit.formatIfEnabled` request.
+class EditFormatIfEnabledHandler extends LegacyHandler {
+  /// Initialize a newly created handler to be able to service requests for the
+  /// [server].
+  EditFormatIfEnabledHandler(AnalysisServer server, Request request,
+      CancellationToken cancellationToken)
+      : super(server, request, cancellationToken);
+
+  /// Format the file at the given [filePath].
+  ///
+  /// Throws a [FileSystemException] if the file doesn't exist or can't be read.
+  /// Throws a [FormatterException] if the code could not be formatted.
+  List formatFile(String filePath) {
+    // TODO(brianwilkerson) Move this to a superclass when `edit.format` is
+    //  implemented by a handler class so the code can be shared.
+    var resource = server.resourceProvider.getFile(filePath);
+    var originalContent = resource.readAsStringSync();
+    var code = SourceCode(originalContent, uri: null, isCompilationUnit: true);
+
+    var formatter = DartFormatter();
+    var formatResult = formatter.formatSource(code);
+    var formattedContent = formatResult.text;
+
+    var edits = [];
+    if (formattedContent != originalContent) {
+      // TODO(brianwilkerson) Replace full replacements with smaller, more
+      //  targeted edits.
+      var edit = SourceEdit(0, originalContent.length, formattedContent);
+      edits.add(edit);
+    }
+    return edits;
+  }
+
+  @override
+  Future handle() async {
+    var params = EditFormatIfEnabledParams.fromRequest(request);
+    var collection = AnalysisContextCollectionImpl(
+      includedPaths: params.directories,
+      resourceProvider: server.resourceProvider,
+      sdkPath: server.sdkPath,
+    );
+    var sourceFileEdits = [];
+    for (var context in collection.contexts) {
+      if (context.analysisOptions.codeStyleOptions.useFormatter) {
+        _formatInContext(context, sourceFileEdits);
+      }
+    }
+    sendResult(EditFormatIfEnabledResult(sourceFileEdits));
+  }
+
+  /// Format all of the files in the given [context], adding the edits to the
+  /// list of [sourceFileEdits].
+  void _formatInContext(DriverBasedAnalysisContext context,
+      List sourceFileEdits) {
+    for (var filePath in context.contextRoot.analyzedFiles()) {
+      var pathContext = context.resourceProvider.pathContext;
+      if (file_paths.isDart(pathContext, filePath)) {
+        try {
+          var sourceEdits = formatFile(filePath);
+          if (sourceEdits.isNotEmpty) {
+            sourceFileEdits
+                .add(SourceFileEdit(filePath, 0, edits: sourceEdits));
+          }
+        } catch (exception) {
+          // Ignore files that can't be formatted.
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 60d9c6a254d..1bf61f70f1e 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -212,7 +212,7 @@ class AbstractAnalysisTest with ResourceProviderMixin {
   }
 
   /// Returns a [Future] that completes when the server's analysis is complete.
-  Future waitForTasksFinished() {
+  Future waitForTasksFinished() {
     return server.onAnalysisComplete;
   }
 
diff --git a/pkg/analysis_server/test/edit/format_if_enabled_test.dart b/pkg/analysis_server/test/edit/format_if_enabled_test.dart
new file mode 100644
index 00000000000..df10b4192ab
--- /dev/null
+++ b/pkg/analysis_server/test/edit/format_if_enabled_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/edit/edit_domain.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../analysis_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FormatIfEnabledTest);
+  });
+}
+
+@reflectiveTest
+class FormatIfEnabledTest extends AbstractAnalysisTest {
+  @override
+  Future setUp() async {
+    super.setUp();
+    await createProject();
+    handler = EditDomainHandler(server);
+  }
+
+  Future test_enabled() async {
+    newAnalysisOptionsYamlFile2(testFolder, '''
+code-style:
+  format: true
+''');
+    addTestFile('''
+void f() { int x = 3; }
+''');
+    newFile2('$testFolder/a.dart', '''
+class A { A(); }
+''');
+    var edits = await _format();
+    expect(edits, isNotNull);
+    expect(edits, hasLength(2));
+  }
+
+  Future test_notEnabled() async {
+    addTestFile('''
+void f() { int x = 3; }
+''');
+    var edits = await _format();
+    expect(edits, isNotNull);
+    expect(edits, hasLength(0));
+  }
+
+  Future test_withErrors() async {
+    addTestFile('''
+void f() { int x =
+''');
+    var edits = await _format();
+    expect(edits, isNotNull);
+    expect(edits, hasLength(0));
+  }
+
+  Future> _format() async {
+    await waitForTasksFinished();
+    var request = EditFormatIfEnabledParams([testFolder]).toRequest('0');
+    var response = await waitResponse(request);
+    return EditFormatIfEnabledResult.fromResponse(response).edits;
+  }
+}
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 21cf0bc3322..69ec29cc488 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -7,6 +7,7 @@ import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'assists_test.dart' as assists;
 import 'bulk_fixes_test.dart' as bulk_fixes;
 import 'fixes_test.dart' as fixes;
+import 'format_if_enabled_test.dart' as format_if_enabled;
 import 'format_test.dart' as format;
 import 'organize_directives_test.dart' as organize_directives;
 import 'postfix_completion_test.dart' as postfix_completion;
@@ -20,6 +21,7 @@ void main() {
     bulk_fixes.main();
     fixes.main();
     format.main();
+    format_if_enabled.main();
     organize_directives.main();
     postfix_completion.main();
     refactoring.main();
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index 9cd7a7635f4..c8b21e4e33a 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -47,6 +47,7 @@ server calls. This file is validated by `coverage_test.dart`.
 ## edit domain
 - [x] edit.bulkFixes
 - [x] edit.format
+- [ ] edit.formatIfEnabled
 - [x] edit.getAssists
 - [x] edit.getAvailableRefactorings
 - [x] edit.getFixes
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index bf671b22b61..e577b4f5c72 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1610,6 +1610,36 @@ abstract class IntegrationTestMixin {
     return EditFormatResult.fromJson(decoder, 'result', result);
   }
 
+  /// Format the contents of the files in one or more directories, but only if
+  /// the analysis options file for those files has enabled the 'format'
+  /// option.
+  ///
+  /// If any of the specified directories does not exist, that directory will
+  /// be ignored. If any of the files that are eligible for being formatted
+  /// cannot be formatted because of a syntax error in the file, that file will
+  /// be ignored.
+  ///
+  /// Parameters
+  ///
+  /// directories: List
+  ///
+  ///   The paths of the directories containing the code to be formatted.
+  ///
+  /// Returns
+  ///
+  /// edits: List
+  ///
+  ///   The edit(s) to be applied in order to format the code. The list will be
+  ///   empty if none of the files were formatted, whether because they were
+  ///   not eligible to be formatted or because they were already formatted.
+  Future sendEditFormatIfEnabled(
+      List directories) async {
+    var params = EditFormatIfEnabledParams(directories).toJson();
+    var result = await server.send('edit.formatIfEnabled', params);
+    var decoder = ResponseDecoder(null);
+    return EditFormatIfEnabledResult.fromJson(decoder, 'result', result);
+  }
+
   /// Return the set of assists that are available at the given location. An
   /// assist is distinguished from a refactoring primarily by the fact that it
   /// affects a single file and does not require user input in order to be
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index ddf2b9b836d..84aeaf6d240 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -2314,6 +2314,22 @@ final Matcher isEditBulkFixesResult = LazyMatcher(() => MatchesJsonObject(
     'edit.bulkFixes result',
     {'edits': isListOf(isSourceFileEdit), 'details': isListOf(isBulkFix)}));
 
+/// edit.formatIfEnabled params
+///
+/// {
+///   "directories": List
+/// }
+final Matcher isEditFormatIfEnabledParams = LazyMatcher(() => MatchesJsonObject(
+    'edit.formatIfEnabled params', {'directories': isListOf(isFilePath)}));
+
+/// edit.formatIfEnabled result
+///
+/// {
+///   "edits": List
+/// }
+final Matcher isEditFormatIfEnabledResult = LazyMatcher(() => MatchesJsonObject(
+    'edit.formatIfEnabled result', {'edits': isListOf(isSourceFileEdit)}));
+
 /// edit.format params
 ///
 /// {
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index d2dda69fec2..d8f6a6c9cde 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -541,6 +541,20 @@ public interface AnalysisServer {
    */
   public void edit_format(String file, int selectionOffset, int selectionLength, int lineLength, FormatConsumer consumer);
 
+  /**
+   * {@code edit.formatIfEnabled}
+   *
+   * Format the contents of the files in one or more directories, but only if the analysis options
+   * file for those files has enabled the 'format' option.
+   *
+   * If any of the specified directories does not exist, that directory will be ignored. If any of
+   * the files that are eligible for being formatted cannot be formatted because of a syntax error in
+   * the file, that file will be ignored.
+   *
+   * @param directories The paths of the directories containing the code to be formatted.
+   */
+  public void edit_formatIfEnabled(List directories, FormatIfEnabledConsumer consumer);
+
   /**
    * {@code edit.getAssists}
    *
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 5c07676f559..d1dbf063590 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -2272,6 +2272,41 @@
       
     
   
+  
+    

+ Format the contents of the files in one or more directories, but only if + the analysis options file for those files has enabled the 'format' option. +

+

+ If any of the specified directories does not exist, that directory will be + ignored. If any of the files that are eligible for being formatted cannot + be formatted because of a syntax error in the file, that file will be + ignored. +

+ + + + FilePath + +

+ The paths of the directories containing the code to be formatted. +

+
+
+ + + + SourceFileEdit + +

+ The edit(s) to be applied in order to format the code. The list will + be empty if none of the files were formatted, whether because they + were not eligible to be formatted or because they were already + formatted. +

+
+
+

Return the set of assists that are available at the given diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart index e8a4e7e6f26..0a14c4fa069 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart @@ -194,6 +194,8 @@ const String EDIT_REQUEST_BULK_FIXES_INCLUDED = 'included'; const String EDIT_REQUEST_BULK_FIXES_IN_TEST_MODE = 'inTestMode'; const String EDIT_REQUEST_FORMAT = 'edit.format'; const String EDIT_REQUEST_FORMAT_FILE = 'file'; +const String EDIT_REQUEST_FORMAT_IF_ENABLED = 'edit.formatIfEnabled'; +const String EDIT_REQUEST_FORMAT_IF_ENABLED_DIRECTORIES = 'directories'; const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength'; const String EDIT_REQUEST_FORMAT_SELECTION_LENGTH = 'selectionLength'; const String EDIT_REQUEST_FORMAT_SELECTION_OFFSET = 'selectionOffset'; @@ -242,6 +244,7 @@ const String EDIT_REQUEST_SORT_MEMBERS_FILE = 'file'; const String EDIT_RESPONSE_BULK_FIXES_DETAILS = 'details'; const String EDIT_RESPONSE_BULK_FIXES_EDITS = 'edits'; const String EDIT_RESPONSE_FORMAT_EDITS = 'edits'; +const String EDIT_RESPONSE_FORMAT_IF_ENABLED_EDITS = 'edits'; const String EDIT_RESPONSE_FORMAT_SELECTION_LENGTH = 'selectionLength'; const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset'; const String EDIT_RESPONSE_GET_ASSISTS_ASSISTS = 'assists'; diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart index 58d9f356efc..f4bb221b7e8 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart @@ -6258,6 +6258,140 @@ class EditBulkFixesResult implements ResponseResult { ); } +/// edit.formatIfEnabled params +/// +/// { +/// "directories": List +/// } +/// +/// Clients may not extend, implement or mix-in this class. +class EditFormatIfEnabledParams implements RequestParams { + /// The paths of the directories containing the code to be formatted. + List directories; + + EditFormatIfEnabledParams(this.directories); + + factory EditFormatIfEnabledParams.fromJson( + JsonDecoder jsonDecoder, String jsonPath, Object? json) { + json ??= {}; + if (json is Map) { + List directories; + if (json.containsKey('directories')) { + directories = jsonDecoder.decodeList(jsonPath + '.directories', + json['directories'], jsonDecoder.decodeString); + } else { + throw jsonDecoder.mismatch(jsonPath, 'directories'); + } + return EditFormatIfEnabledParams(directories); + } else { + throw jsonDecoder.mismatch(jsonPath, 'edit.formatIfEnabled params', json); + } + } + + factory EditFormatIfEnabledParams.fromRequest(Request request) { + return EditFormatIfEnabledParams.fromJson( + RequestDecoder(request), 'params', request.params); + } + + @override + Map toJson() { + var result = {}; + result['directories'] = directories; + return result; + } + + @override + Request toRequest(String id) { + return Request(id, 'edit.formatIfEnabled', toJson()); + } + + @override + String toString() => json.encode(toJson()); + + @override + bool operator ==(other) { + if (other is EditFormatIfEnabledParams) { + return listEqual( + directories, other.directories, (String a, String b) => a == b); + } + return false; + } + + @override + int get hashCode => directories.hashCode; +} + +/// edit.formatIfEnabled result +/// +/// { +/// "edits": List +/// } +/// +/// Clients may not extend, implement or mix-in this class. +class EditFormatIfEnabledResult implements ResponseResult { + /// The edit(s) to be applied in order to format the code. The list will be + /// empty if none of the files were formatted, whether because they were not + /// eligible to be formatted or because they were already formatted. + List edits; + + EditFormatIfEnabledResult(this.edits); + + factory EditFormatIfEnabledResult.fromJson( + JsonDecoder jsonDecoder, String jsonPath, Object? json) { + json ??= {}; + if (json is Map) { + List edits; + if (json.containsKey('edits')) { + edits = jsonDecoder.decodeList( + jsonPath + '.edits', + json['edits'], + (String jsonPath, Object? json) => + SourceFileEdit.fromJson(jsonDecoder, jsonPath, json)); + } else { + throw jsonDecoder.mismatch(jsonPath, 'edits'); + } + return EditFormatIfEnabledResult(edits); + } else { + throw jsonDecoder.mismatch(jsonPath, 'edit.formatIfEnabled result', json); + } + } + + factory EditFormatIfEnabledResult.fromResponse(Response response) { + return EditFormatIfEnabledResult.fromJson( + ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), + 'result', + response.result); + } + + @override + Map toJson() { + var result = {}; + result['edits'] = + edits.map((SourceFileEdit value) => value.toJson()).toList(); + return result; + } + + @override + Response toResponse(String id) { + return Response(id, result: toJson()); + } + + @override + String toString() => json.encode(toJson()); + + @override + bool operator ==(other) { + if (other is EditFormatIfEnabledResult) { + return listEqual( + edits, other.edits, (SourceFileEdit a, SourceFileEdit b) => a == b); + } + return false; + } + + @override + int get hashCode => edits.hashCode; +} + /// edit.format params /// /// {