diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html index 338d07b6144..6b9305a17ef 100644 --- a/pkg/analysis_server/doc/api.html +++ b/pkg/analysis_server/doc/api.html @@ -627,7 +627,7 @@ a:focus, a:hover { "id": String "error": optional RequestError "result": { - "action": String + "action": optional String } }

Note: This is a request from the server to the client.

@@ -666,10 +666,12 @@ a:focus, a:hover {

The labels of the buttons by which the user can dismiss the message.

-

returns:

action: String
+

returns:

action: String (optional)

- The label of the action that was selected by the user. + The label of the action that was selected by the user. May be + omitted or `null` if the user dismissed the message without + clicking an action button.

Notifications

server.connected
notification: {
   "event": "server.connected"
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 31d8f505b0b..ce86acd1449 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -16717,27 +16717,27 @@ class ServerShowMessageRequestParams implements RequestParams {
 /// server.showMessageRequest result
 ///
 /// {
-///   "action": String
+///   "action": optional String
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
 class ServerShowMessageRequestResult implements ResponseResult {
-  /// The label of the action that was selected by the user.
-  String action;
+  /// The label of the action that was selected by the user. May be omitted or
+  /// `null` if the user dismissed the message without clicking an action
+  /// button.
+  String? action;
 
-  ServerShowMessageRequestResult(this.action);
+  ServerShowMessageRequestResult({this.action});
 
   factory ServerShowMessageRequestResult.fromJson(
       JsonDecoder jsonDecoder, String jsonPath, Object? json) {
     json ??= {};
     if (json is Map) {
-      String action;
+      String? action;
       if (json.containsKey('action')) {
         action = jsonDecoder.decodeString('$jsonPath.action', json['action']);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, 'action');
       }
-      return ServerShowMessageRequestResult(action);
+      return ServerShowMessageRequestResult(action: action);
     } else {
       throw jsonDecoder.mismatch(
           jsonPath, 'server.showMessageRequest result', json);
@@ -16754,7 +16754,10 @@ class ServerShowMessageRequestResult implements ResponseResult {
   @override
   Map toJson() {
     var result = {};
-    result['action'] = action;
+    var action = this.action;
+    if (action != null) {
+      result['action'] = action;
+    }
     return result;
   }
 
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index cc26ec6712c..9934509e1ad 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -152,11 +152,27 @@ class ServerDomainTest extends PubPackageAnalysisServerTest {
     // Simulate the response.
     var request = serverChannel.serverRequestsSent[0];
     await serverChannel.simulateResponseFromClient(
-        ServerShowMessageRequestResult('a').toResponse(request.id));
+        ServerShowMessageRequestResult(action: 'a').toResponse(request.id));
     var response = await responseFuture;
     expect(response, 'a');
   }
 
+  Future test_showMessage_nullResponse() async {
+    server.clientCapabilities.requests = ['showMessageRequest'];
+
+    // Send the request.
+    var responseFuture =
+        server.showUserPrompt(MessageType.warning, 'message', ['a', 'b']);
+    expect(serverChannel.serverRequestsSent, hasLength(1));
+
+    // Simulate the response.
+    var request = serverChannel.serverRequestsSent[0];
+    await serverChannel.simulateResponseFromClient(
+        ServerShowMessageRequestResult().toResponse(request.id));
+    var response = await responseFuture;
+    expect(response, isNull);
+  }
+
   Future test_shutdown() async {
     var request = ServerShutdownParams().toRequest('0');
     await handleSuccessfulRequest(request);
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 fe4d899d9e1..a8360d42e27 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -161,9 +161,11 @@ abstract class IntegrationTest {
   ///
   /// Returns
   ///
-  /// action: String
+  /// action: String (optional)
   ///
-  ///   The label of the action that was selected by the user.
+  ///   The label of the action that was selected by the user. May be omitted
+  ///   or `null` if the user dismissed the message without clicking an action
+  ///   button.
   Future sendServerShowMessageRequest(
       MessageType type, String message, List actions) async {
     var params =
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 9c9c12d8b1e..a8814019009 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -3135,11 +3135,11 @@ final Matcher isServerShowMessageRequestParams = LazyMatcher(() =>
 /// server.showMessageRequest result
 ///
 /// {
-///   "action": String
+///   "action": optional String
 /// }
 final Matcher isServerShowMessageRequestResult = LazyMatcher(() =>
-    MatchesJsonObject(
-        'server.showMessageRequest result', {'action': isString}));
+    MatchesJsonObject('server.showMessageRequest result', null,
+        optionalFields: {'action': isString}));
 
 /// server.shutdown params
 final Matcher isServerShutdownParams = isNull;
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 1a56abe270e..d24388425d2 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -451,10 +451,12 @@
       
     
     
-      
+      
         String
         

- The label of the action that was selected by the user. + The label of the action that was selected by the user. May be + omitted or `null` if the user dismissed the message without + clicking an action button.

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 67c546fc745..c099d3b58fb 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart @@ -16717,27 +16717,27 @@ class ServerShowMessageRequestParams implements RequestParams { /// server.showMessageRequest result /// /// { -/// "action": String +/// "action": optional String /// } /// /// Clients may not extend, implement or mix-in this class. class ServerShowMessageRequestResult implements ResponseResult { - /// The label of the action that was selected by the user. - String action; + /// The label of the action that was selected by the user. May be omitted or + /// `null` if the user dismissed the message without clicking an action + /// button. + String? action; - ServerShowMessageRequestResult(this.action); + ServerShowMessageRequestResult({this.action}); factory ServerShowMessageRequestResult.fromJson( JsonDecoder jsonDecoder, String jsonPath, Object? json) { json ??= {}; if (json is Map) { - String action; + String? action; if (json.containsKey('action')) { action = jsonDecoder.decodeString('$jsonPath.action', json['action']); - } else { - throw jsonDecoder.mismatch(jsonPath, 'action'); } - return ServerShowMessageRequestResult(action); + return ServerShowMessageRequestResult(action: action); } else { throw jsonDecoder.mismatch( jsonPath, 'server.showMessageRequest result', json); @@ -16754,7 +16754,10 @@ class ServerShowMessageRequestResult implements ResponseResult { @override Map toJson() { var result = {}; - result['action'] = action; + var action = this.action; + if (action != null) { + result['action'] = action; + } return result; }