[analysis_server] Allow action in response to showMessageRequest to be null

This allows for users to dismiss a notification without taking any action (something that VS Code / LSP allows for but this API did not).

Change-Id: Icf384008cfcfde6f150c63d3f2889e81e79d1dc1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292080
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny 2023-03-30 19:48:18 +00:00 committed by Commit Queue
parent 4176d8a02c
commit 2ff94f8882
7 changed files with 57 additions and 29 deletions

View file

@ -627,7 +627,7 @@ a:focus, a:hover {
"id": String
"error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
"result": {
"<b>action</b>": String
"<b>action</b>": <span style="color:#999999">optional</span> String
}
}</pre></div>
<p><b>Note:</b> This is a request from the server to the client.</p>
@ -666,10 +666,12 @@ a:focus, a:hover {
<p>
The labels of the buttons by which the user can dismiss the message.
</p>
</dd></dl><h4>returns:</h4><dl><dt class="field"><b>action: String</b></dt><dd>
</dd></dl><h4>returns:</h4><dl><dt class="field"><b>action: String<span style="color:#999999"> (optional)</span></b></dt><dd>
<p>
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.
</p>
</dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_server.connected">server.connected</a></dt><dd><div class="box"><pre>notification: {
"event": "server.connected"

View file

@ -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<String, Object> toJson() {
var result = <String, Object>{};
result['action'] = action;
var action = this.action;
if (action != null) {
result['action'] = action;
}
return result;
}

View file

@ -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<void> 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<void> test_shutdown() async {
var request = ServerShutdownParams().toRequest('0');
await handleSuccessfulRequest(request);

View file

@ -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<ServerShowMessageRequestResult> sendServerShowMessageRequest(
MessageType type, String message, List<MessageAction> actions) async {
var params =

View file

@ -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;

View file

@ -451,10 +451,12 @@
</field>
</params>
<result>
<field name="action">
<field name="action" optional="true">
<ref>String</ref>
<p>
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.
</p>
</field>
</result>

View file

@ -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<String, Object> toJson() {
var result = <String, Object>{};
result['action'] = action;
var action = this.action;
if (action != null) {
result['action'] = action;
}
return result;
}