[analysis_server] Move LSP JSON-RPC types to custom generation

Change-Id: Ie84f7aa099bdeeb1be2a565faf1ffa0bb3ef4b21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245365
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny
2022-05-19 18:18:01 +00:00
committed by Commit Bot
parent 48ff7ca62f
commit aae961063f
8 changed files with 887 additions and 796 deletions
@@ -1087,6 +1087,361 @@ class FlutterOutlineAttribute implements ToJsonable {
String toString() => jsonEncoder.convert(toJson());
}
class IncomingMessage implements Message, ToJsonable {
static const jsonHandler = LspJsonHandler(
IncomingMessage.canParse,
IncomingMessage.fromJson,
);
IncomingMessage({
this.clientRequestTime,
required this.jsonrpc,
required this.method,
this.params,
});
static IncomingMessage fromJson(Map<String, Object?> json) {
if (RequestMessage.canParse(json, nullLspJsonReporter)) {
return RequestMessage.fromJson(json);
}
if (NotificationMessage.canParse(json, nullLspJsonReporter)) {
return NotificationMessage.fromJson(json);
}
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final methodJson = json['method'];
final method = Method.fromJson(methodJson as String);
final paramsJson = json['params'];
final params = paramsJson;
return IncomingMessage(
clientRequestTime: clientRequestTime,
jsonrpc: jsonrpc,
method: method,
params: params,
);
}
final int? clientRequestTime;
final String jsonrpc;
final Method method;
final Object? params;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['jsonrpc'] = jsonrpc;
__result['method'] = method.toJson();
if (params != null) {
__result['params'] = params;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('method');
try {
if (!obj.containsKey('method')) {
reporter.reportError('must not be undefined');
return false;
}
final method = obj['method'];
if (method == null) {
reporter.reportError('must not be null');
return false;
}
if (!(Method.canParse(method, reporter))) {
reporter.reportError('must be of type Method');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type IncomingMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is IncomingMessage && other.runtimeType == IncomingMessage) {
return clientRequestTime == other.clientRequestTime &&
jsonrpc == other.jsonrpc &&
method == other.method &&
params == other.params &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
jsonrpc,
method,
params,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class Message implements ToJsonable {
static const jsonHandler = LspJsonHandler(
Message.canParse,
Message.fromJson,
);
Message({
this.clientRequestTime,
required this.jsonrpc,
});
static Message fromJson(Map<String, Object?> json) {
if (IncomingMessage.canParse(json, nullLspJsonReporter)) {
return IncomingMessage.fromJson(json);
}
if (ResponseMessage.canParse(json, nullLspJsonReporter)) {
return ResponseMessage.fromJson(json);
}
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
return Message(
clientRequestTime: clientRequestTime,
jsonrpc: jsonrpc,
);
}
final int? clientRequestTime;
final String jsonrpc;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['jsonrpc'] = jsonrpc;
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type Message');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is Message && other.runtimeType == Message) {
return clientRequestTime == other.clientRequestTime &&
jsonrpc == other.jsonrpc &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
jsonrpc,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class NotificationMessage implements IncomingMessage, ToJsonable {
static const jsonHandler = LspJsonHandler(
NotificationMessage.canParse,
NotificationMessage.fromJson,
);
NotificationMessage({
this.clientRequestTime,
required this.jsonrpc,
required this.method,
this.params,
});
static NotificationMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final methodJson = json['method'];
final method = Method.fromJson(methodJson as String);
final paramsJson = json['params'];
final params = paramsJson;
return NotificationMessage(
clientRequestTime: clientRequestTime,
jsonrpc: jsonrpc,
method: method,
params: params,
);
}
final int? clientRequestTime;
final String jsonrpc;
final Method method;
final Object? params;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['jsonrpc'] = jsonrpc;
__result['method'] = method.toJson();
if (params != null) {
__result['params'] = params;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('method');
try {
if (!obj.containsKey('method')) {
reporter.reportError('must not be undefined');
return false;
}
final method = obj['method'];
if (method == null) {
reporter.reportError('must not be null');
return false;
}
if (!(Method.canParse(method, reporter))) {
reporter.reportError('must be of type Method');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type NotificationMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is NotificationMessage &&
other.runtimeType == NotificationMessage) {
return clientRequestTime == other.clientRequestTime &&
jsonrpc == other.jsonrpc &&
method == other.method &&
params == other.params &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
jsonrpc,
method,
params,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class Outline implements ToJsonable {
static const jsonHandler = LspJsonHandler(
Outline.canParse,
@@ -1598,6 +1953,432 @@ class PublishOutlineParams implements ToJsonable {
String toString() => jsonEncoder.convert(toJson());
}
class RequestMessage implements IncomingMessage, ToJsonable {
static const jsonHandler = LspJsonHandler(
RequestMessage.canParse,
RequestMessage.fromJson,
);
RequestMessage({
this.clientRequestTime,
required this.id,
required this.jsonrpc,
required this.method,
this.params,
});
static RequestMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final idJson = json['id'];
final id = idJson is int
? Either2<int, String>.t1(idJson)
: (idJson is String
? Either2<int, String>.t2(idJson)
: (throw '''$idJson was not one of (int, String)'''));
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final methodJson = json['method'];
final method = Method.fromJson(methodJson as String);
final paramsJson = json['params'];
final params = paramsJson;
return RequestMessage(
clientRequestTime: clientRequestTime,
id: id,
jsonrpc: jsonrpc,
method: method,
params: params,
);
}
final int? clientRequestTime;
final Either2<int, String> id;
final String jsonrpc;
final Method method;
final Object? params;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['id'] = id;
__result['jsonrpc'] = jsonrpc;
__result['method'] = method.toJson();
if (params != null) {
__result['params'] = params;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('id');
try {
if (!obj.containsKey('id')) {
reporter.reportError('must not be undefined');
return false;
}
final id = obj['id'];
if (id == null) {
reporter.reportError('must not be null');
return false;
}
if (!((id is int || id is String))) {
reporter.reportError('must be of type Either2<int, String>');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('method');
try {
if (!obj.containsKey('method')) {
reporter.reportError('must not be undefined');
return false;
}
final method = obj['method'];
if (method == null) {
reporter.reportError('must not be null');
return false;
}
if (!(Method.canParse(method, reporter))) {
reporter.reportError('must be of type Method');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type RequestMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is RequestMessage && other.runtimeType == RequestMessage) {
return clientRequestTime == other.clientRequestTime &&
id == other.id &&
jsonrpc == other.jsonrpc &&
method == other.method &&
params == other.params &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
id,
jsonrpc,
method,
params,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class ResponseError implements ToJsonable {
static const jsonHandler = LspJsonHandler(
ResponseError.canParse,
ResponseError.fromJson,
);
ResponseError({
required this.code,
this.data,
required this.message,
});
static ResponseError fromJson(Map<String, Object?> json) {
final codeJson = json['code'];
final code = ErrorCodes.fromJson(codeJson as int);
final dataJson = json['data'];
final data = dataJson as String?;
final messageJson = json['message'];
final message = messageJson as String;
return ResponseError(
code: code,
data: data,
message: message,
);
}
final ErrorCodes code;
/// A string that contains additional information about the error. Can be
/// omitted.
final String? data;
final String message;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
__result['code'] = code.toJson();
if (data != null) {
__result['data'] = data;
}
__result['message'] = message;
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('code');
try {
if (!obj.containsKey('code')) {
reporter.reportError('must not be undefined');
return false;
}
final code = obj['code'];
if (code == null) {
reporter.reportError('must not be null');
return false;
}
if (!(ErrorCodes.canParse(code, reporter))) {
reporter.reportError('must be of type ErrorCodes');
return false;
}
} finally {
reporter.pop();
}
reporter.push('data');
try {
final data = obj['data'];
if (data != null && !(data is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('message');
try {
if (!obj.containsKey('message')) {
reporter.reportError('must not be undefined');
return false;
}
final message = obj['message'];
if (message == null) {
reporter.reportError('must not be null');
return false;
}
if (!(message is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type ResponseError');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is ResponseError && other.runtimeType == ResponseError) {
return code == other.code &&
data == other.data &&
message == other.message &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
code,
data,
message,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class ResponseMessage implements Message, ToJsonable {
static const jsonHandler = LspJsonHandler(
ResponseMessage.canParse,
ResponseMessage.fromJson,
);
ResponseMessage({
this.clientRequestTime,
this.error,
this.id,
required this.jsonrpc,
this.result,
});
static ResponseMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final errorJson = json['error'];
final error = errorJson != null
? ResponseError.fromJson(errorJson as Map<String, Object?>)
: null;
final idJson = json['id'];
final id = idJson == null
? null
: (idJson is int
? Either2<int, String>.t1(idJson)
: (idJson is String
? Either2<int, String>.t2(idJson)
: (throw '''$idJson was not one of (int, String)''')));
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final resultJson = json['result'];
final result = resultJson;
return ResponseMessage(
clientRequestTime: clientRequestTime,
error: error,
id: id,
jsonrpc: jsonrpc,
result: result,
);
}
final int? clientRequestTime;
final ResponseError? error;
final Either2<int, String>? id;
final String jsonrpc;
final Object? result;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['id'] = id;
__result['jsonrpc'] = jsonrpc;
if (error != null && result != null) {
throw 'result and error cannot both be set';
} else if (error != null) {
__result['error'] = error;
} else {
__result['result'] = result;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('error');
try {
final error = obj['error'];
if (error != null && !(ResponseError.canParse(error, reporter))) {
reporter.reportError('must be of type ResponseError');
return false;
}
} finally {
reporter.pop();
}
reporter.push('id');
try {
if (!obj.containsKey('id')) {
reporter.reportError('must not be undefined');
return false;
}
final id = obj['id'];
if (id != null && !((id is int || id is String))) {
reporter.reportError('must be of type Either2<int, String>');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type ResponseMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is ResponseMessage && other.runtimeType == ResponseMessage) {
return clientRequestTime == other.clientRequestTime &&
error == other.error &&
id == other.id &&
jsonrpc == other.jsonrpc &&
result == other.result &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
error,
id,
jsonrpc,
result,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class SnippetTextEdit implements TextEdit, ToJsonable {
static const jsonHandler = LspJsonHandler(
SnippetTextEdit.canParse,
@@ -23783,105 +23783,6 @@ class MarkupKind implements ToJsonable {
bool operator ==(Object o) => o is MarkupKind && o._value == _value;
}
class Message implements ToJsonable {
static const jsonHandler = LspJsonHandler(
Message.canParse,
Message.fromJson,
);
Message({
this.clientRequestTime,
required this.jsonrpc,
});
static Message fromJson(Map<String, Object?> json) {
if (RequestMessage.canParse(json, nullLspJsonReporter)) {
return RequestMessage.fromJson(json);
}
if (NotificationMessage.canParse(json, nullLspJsonReporter)) {
return NotificationMessage.fromJson(json);
}
if (ResponseMessage.canParse(json, nullLspJsonReporter)) {
return ResponseMessage.fromJson(json);
}
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
return Message(
clientRequestTime: clientRequestTime,
jsonrpc: jsonrpc,
);
}
final int? clientRequestTime;
final String jsonrpc;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['jsonrpc'] = jsonrpc;
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type Message');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is Message && other.runtimeType == Message) {
return clientRequestTime == other.clientRequestTime &&
jsonrpc == other.jsonrpc &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
jsonrpc,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class MessageActionItem implements ToJsonable {
static const jsonHandler = LspJsonHandler(
MessageActionItem.canParse,
@@ -27218,137 +27119,6 @@ class NotebookDocumentSyncRegistrationOptions
String toString() => jsonEncoder.convert(toJson());
}
class NotificationMessage implements Message, IncomingMessage, ToJsonable {
static const jsonHandler = LspJsonHandler(
NotificationMessage.canParse,
NotificationMessage.fromJson,
);
NotificationMessage({
this.clientRequestTime,
required this.jsonrpc,
required this.method,
this.params,
});
static NotificationMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final methodJson = json['method'];
final method = Method.fromJson(methodJson as String);
final paramsJson = json['params'];
final params = paramsJson;
return NotificationMessage(
clientRequestTime: clientRequestTime,
jsonrpc: jsonrpc,
method: method,
params: params,
);
}
final int? clientRequestTime;
final String jsonrpc;
/// The method to be invoked.
final Method method;
/// The notification's params.
final Object? params;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['jsonrpc'] = jsonrpc;
__result['method'] = method.toJson();
if (params != null) {
__result['params'] = params;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('method');
try {
if (!obj.containsKey('method')) {
reporter.reportError('must not be undefined');
return false;
}
final method = obj['method'];
if (method == null) {
reporter.reportError('must not be null');
return false;
}
if (!(Method.canParse(method, reporter))) {
reporter.reportError('must be of type Method');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type NotificationMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is NotificationMessage &&
other.runtimeType == NotificationMessage) {
return clientRequestTime == other.clientRequestTime &&
jsonrpc == other.jsonrpc &&
method == other.method &&
params == other.params &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
jsonrpc,
method,
params,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class OptionalVersionedTextDocumentIdentifier
implements TextDocumentIdentifier, ToJsonable {
static const jsonHandler = LspJsonHandler(
@@ -30843,168 +30613,6 @@ class RenameRegistrationOptions
String toString() => jsonEncoder.convert(toJson());
}
class RequestMessage implements Message, IncomingMessage, ToJsonable {
static const jsonHandler = LspJsonHandler(
RequestMessage.canParse,
RequestMessage.fromJson,
);
RequestMessage({
this.clientRequestTime,
required this.id,
required this.jsonrpc,
required this.method,
this.params,
});
static RequestMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final idJson = json['id'];
final id = idJson is int
? Either2<int, String>.t1(idJson)
: (idJson is String
? Either2<int, String>.t2(idJson)
: (throw '''$idJson was not one of (int, String)'''));
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final methodJson = json['method'];
final method = Method.fromJson(methodJson as String);
final paramsJson = json['params'];
final params = paramsJson;
return RequestMessage(
clientRequestTime: clientRequestTime,
id: id,
jsonrpc: jsonrpc,
method: method,
params: params,
);
}
final int? clientRequestTime;
/// The request id.
final Either2<int, String> id;
final String jsonrpc;
/// The method to be invoked.
final Method method;
/// The method's params.
final Object? params;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['id'] = id;
__result['jsonrpc'] = jsonrpc;
__result['method'] = method.toJson();
if (params != null) {
__result['params'] = params;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('id');
try {
if (!obj.containsKey('id')) {
reporter.reportError('must not be undefined');
return false;
}
final id = obj['id'];
if (id == null) {
reporter.reportError('must not be null');
return false;
}
if (!((id is int || id is String))) {
reporter.reportError('must be of type Either2<int, String>');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('method');
try {
if (!obj.containsKey('method')) {
reporter.reportError('must not be undefined');
return false;
}
final method = obj['method'];
if (method == null) {
reporter.reportError('must not be null');
return false;
}
if (!(Method.canParse(method, reporter))) {
reporter.reportError('must be of type Method');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type RequestMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is RequestMessage && other.runtimeType == RequestMessage) {
return clientRequestTime == other.clientRequestTime &&
id == other.id &&
jsonrpc == other.jsonrpc &&
method == other.method &&
params == other.params &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
id,
jsonrpc,
method,
params,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class ResourceOperationKind implements ToJsonable {
const ResourceOperationKind._(this._value);
const ResourceOperationKind.fromJson(this._value);
@@ -31042,286 +30650,6 @@ class ResourceOperationKind implements ToJsonable {
o is ResourceOperationKind && o._value == _value;
}
class ResponseError implements ToJsonable {
static const jsonHandler = LspJsonHandler(
ResponseError.canParse,
ResponseError.fromJson,
);
ResponseError({
required this.code,
this.data,
required this.message,
});
static ResponseError fromJson(Map<String, Object?> json) {
final codeJson = json['code'];
final code = ErrorCodes.fromJson(codeJson as int);
final dataJson = json['data'];
final data = dataJson as String?;
final messageJson = json['message'];
final message = messageJson as String;
return ResponseError(
code: code,
data: data,
message: message,
);
}
/// A number indicating the error type that occurred.
final ErrorCodes code;
/// A string that contains additional information about the error. Can be
/// omitted.
final String? data;
/// A string providing a short description of the error.
final String message;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
__result['code'] = code.toJson();
if (data != null) {
__result['data'] = data;
}
__result['message'] = message;
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('code');
try {
if (!obj.containsKey('code')) {
reporter.reportError('must not be undefined');
return false;
}
final code = obj['code'];
if (code == null) {
reporter.reportError('must not be null');
return false;
}
if (!(ErrorCodes.canParse(code, reporter))) {
reporter.reportError('must be of type ErrorCodes');
return false;
}
} finally {
reporter.pop();
}
reporter.push('data');
try {
final data = obj['data'];
if (data != null && !(data is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
reporter.push('message');
try {
if (!obj.containsKey('message')) {
reporter.reportError('must not be undefined');
return false;
}
final message = obj['message'];
if (message == null) {
reporter.reportError('must not be null');
return false;
}
if (!(message is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type ResponseError');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is ResponseError && other.runtimeType == ResponseError) {
return code == other.code &&
data == other.data &&
message == other.message &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
code,
data,
message,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class ResponseMessage implements Message, ToJsonable {
static const jsonHandler = LspJsonHandler(
ResponseMessage.canParse,
ResponseMessage.fromJson,
);
ResponseMessage({
this.clientRequestTime,
this.error,
this.id,
required this.jsonrpc,
this.result,
});
static ResponseMessage fromJson(Map<String, Object?> json) {
final clientRequestTimeJson = json['clientRequestTime'];
final clientRequestTime = clientRequestTimeJson as int?;
final errorJson = json['error'];
final error = errorJson != null
? ResponseError.fromJson(errorJson as Map<String, Object?>)
: null;
final idJson = json['id'];
final id = idJson == null
? null
: (idJson is int
? Either2<int, String>.t1(idJson)
: (idJson is String
? Either2<int, String>.t2(idJson)
: (throw '''$idJson was not one of (int, String)''')));
final jsonrpcJson = json['jsonrpc'];
final jsonrpc = jsonrpcJson as String;
final resultJson = json['result'];
final result = resultJson;
return ResponseMessage(
clientRequestTime: clientRequestTime,
error: error,
id: id,
jsonrpc: jsonrpc,
result: result,
);
}
final int? clientRequestTime;
/// The error object in case a request fails.
final ResponseError? error;
/// The request id.
final Either2<int, String>? id;
final String jsonrpc;
/// The result of a request. This member is REQUIRED on success. This member
/// MUST NOT exist if there was an error invoking the method.
final Object? result;
Map<String, Object?> toJson() {
var __result = <String, Object?>{};
if (clientRequestTime != null) {
__result['clientRequestTime'] = clientRequestTime;
}
__result['id'] = id;
__result['jsonrpc'] = jsonrpc;
if (error != null && result != null) {
throw 'result and error cannot both be set';
} else if (error != null) {
__result['error'] = error;
} else {
__result['result'] = result;
}
return __result;
}
static bool canParse(Object? obj, LspJsonReporter reporter) {
if (obj is Map<String, Object?>) {
reporter.push('clientRequestTime');
try {
final clientRequestTime = obj['clientRequestTime'];
if (clientRequestTime != null && !(clientRequestTime is int)) {
reporter.reportError('must be of type int');
return false;
}
} finally {
reporter.pop();
}
reporter.push('error');
try {
final error = obj['error'];
if (error != null && !(ResponseError.canParse(error, reporter))) {
reporter.reportError('must be of type ResponseError');
return false;
}
} finally {
reporter.pop();
}
reporter.push('id');
try {
if (!obj.containsKey('id')) {
reporter.reportError('must not be undefined');
return false;
}
final id = obj['id'];
if (id != null && !((id is int || id is String))) {
reporter.reportError('must be of type Either2<int, String>');
return false;
}
} finally {
reporter.pop();
}
reporter.push('jsonrpc');
try {
if (!obj.containsKey('jsonrpc')) {
reporter.reportError('must not be undefined');
return false;
}
final jsonrpc = obj['jsonrpc'];
if (jsonrpc == null) {
reporter.reportError('must not be null');
return false;
}
if (!(jsonrpc is String)) {
reporter.reportError('must be of type String');
return false;
}
} finally {
reporter.pop();
}
return true;
} else {
reporter.reportError('must be of type ResponseMessage');
return false;
}
}
@override
bool operator ==(Object other) {
if (other is ResponseMessage && other.runtimeType == ResponseMessage) {
return clientRequestTime == other.clientRequestTime &&
error == other.error &&
id == other.id &&
jsonrpc == other.jsonrpc &&
result == other.result &&
true;
}
return false;
}
@override
int get hashCode => Object.hash(
clientRequestTime,
error,
id,
jsonrpc,
result,
);
@override
String toString() => jsonEncoder.convert(toJson());
}
class SaveOptions implements ToJsonable {
static const jsonHandler = LspJsonHandler(
SaveOptions.canParse,
@@ -8,6 +8,8 @@ import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/src/lsp/json_parsing.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
import 'protocol_custom_generated.dart';
const jsonRpcVersion = '2.0';
const NullJsonHandler = LspJsonHandler<Null>(_alwaysTrue, _alwaysNull);
@@ -264,14 +266,6 @@ class ErrorOr<T> extends Either2<ResponseError, T> {
}
}
/// A base class containing the fields common to RequestMessage and
/// NotificationMessage to simplify handling.
abstract class IncomingMessage {
int? get clientRequestTime;
Method get method;
dynamic get params;
}
/// A helper to allow handlers to declare both a JSON validation function and
/// parse function.
class LspJsonHandler<T> {
@@ -350,21 +350,19 @@ class LspAnalysisServer extends AbstractAnalysisServer {
if (message is ResponseMessage) {
handleClientResponse(message);
} else if (message is IncomingMessage) {
final incomingMessage = message as IncomingMessage;
// Record performance information for the request.
final performance = OperationPerformanceImpl('<root>');
await performance.runAsync('request', (performance) async {
final requestPerformance = RequestPerformance(
operation: incomingMessage.method.toString(),
operation: message.method.toString(),
performance: performance,
requestLatency: incomingMessage.timeSinceRequest,
requestLatency: message.timeSinceRequest,
);
recentPerformance.requests.add(requestPerformance);
final messageInfo = MessageInfo(
performance: performance,
timeSinceRequest: incomingMessage.timeSinceRequest,
timeSinceRequest: message.timeSinceRequest,
);
if (message is RequestMessage) {
@@ -4,7 +4,6 @@
import 'package:dart_style/dart_style.dart';
import 'typescript.dart';
import 'typescript_parser.dart';
final formatter = DartFormatter();
@@ -786,7 +785,6 @@ void _writeInterface(IndentableStringBuffer buffer, Interface interface) {
buffer.writeIndented('class ${interface.nameWithTypeArgs} ');
final allBaseTypes =
interface.baseTypes.map((t) => t.dartTypeWithTypeArgs).toList();
allBaseTypes.addAll(getSpecialBaseTypes(interface));
allBaseTypes.add('ToJsonable');
if (allBaseTypes.isNotEmpty) {
buffer.writeIndented('implements ${allBaseTypes.join(', ')} ');
@@ -196,15 +196,23 @@ List<AstNode> getCustomClasses() {
Field field(
String name, {
String? comment,
required String type,
bool array = false,
bool canBeUndefined = false,
}) {
var fieldType =
final fieldType =
array ? ArrayType(Type.identifier(type)) : Type.identifier(type);
final commentNode =
comment != null ? Comment(Token(TokenType.COMMENT, comment)) : null;
return Field(null, Token.identifier(name), fieldType,
allowsNull: false, allowsUndefined: canBeUndefined);
return Field(
commentNode,
Token.identifier(name),
fieldType,
allowsNull: false,
allowsUndefined: canBeUndefined,
);
}
final customTypes = <AstNode>[
@@ -218,6 +226,72 @@ List<AstNode> getCustomClasses() {
Token.identifier('LSPObject'),
Type.Any,
),
interface('Message', [
field('jsonrpc', type: 'string'),
field('clientRequestTime', type: 'int', canBeUndefined: true),
]),
interface(
'IncomingMessage',
[
field('method', type: 'Method'),
field('params', type: 'LSPAny', canBeUndefined: true),
],
baseType: 'Message',
),
interface(
'RequestMessage',
[
Field(
null,
Token.identifier('id'),
UnionType([Type.identifier('int'), Type.identifier('string')]),
allowsNull: false,
allowsUndefined: false,
)
],
baseType: 'IncomingMessage',
),
interface(
'NotificationMessage',
[],
baseType: 'IncomingMessage',
),
interface(
'ResponseMessage',
[
Field(
null,
Token.identifier('id'),
UnionType([Type.identifier('int'), Type.identifier('string')]),
allowsNull: true,
allowsUndefined: false,
),
field('result', type: 'LSPAny', canBeUndefined: true),
field('error', type: 'ResponseError', canBeUndefined: true),
],
baseType: 'Message',
),
interface(
'ResponseError',
[
field('code', type: 'ErrorCodes'),
field('message', type: 'string'),
// This is Object? normally, but since this class can be serialised
// we will crash if it data is set to something that can't be converted to
// JSON (for ex. Uri) so this forces anyone setting this to convert to a
// String.
field(
'data',
type: 'string',
canBeUndefined: true,
comment:
'A string that contains additional information about the error. '
'Can be omitted.',
),
],
),
TypeAlias(null, Token.identifier('DocumentUri'), Type.identifier('string')),
interface('DartDiagnosticServer', [field('port', type: 'int')]),
interface('AnalyzerStatusParams', [field('isAnalyzing', type: 'boolean')]),
interface('PublishClosingLabelsParams', [
@@ -326,34 +400,6 @@ List<AstNode> getCustomClasses() {
return customTypes;
}
/// Gets additional custom fields to be added to LSP Spec classes.
///
/// Non-standard fields should generally be avoided and must always allow
/// undefined.
List<Field> getCustomFields(String interfaceName) {
final additionalFields = <String, List<Field>>{
// Allow clients to pass a "clientRequestTime" against any incomine message
// so that we can capture latency information for requests for performance
// measurements.
'Message': [
Field(
null,
Token.identifier('clientRequestTime'),
Type.identifier('int'),
allowsNull: false,
allowsUndefined: true,
),
],
};
final fields = additionalFields[interfaceName] ?? [];
assert(
fields.every((field) => field.allowsUndefined),
'Any additional non-standard LSP field must allow undefined',
);
return fields;
}
Future<List<AstNode>> getSpecClasses(ArgResults args) async {
var download = args[argDownload] as bool;
if (download) {
@@ -366,7 +412,6 @@ Future<List<AstNode>> getSpecClasses(ArgResults args) async {
.map(parseString)
.expand((f) => f)
.where(includeTypeDefinitionInOutput)
.map(withCustomFields)
.toList();
// Generate an enum for all of the request methods to avoid strings.
@@ -417,26 +462,6 @@ bool shouldIncludeScriptBlock(String input) {
return true;
}
/// Returns [node] with any additional custom fields.
AstNode withCustomFields(AstNode node) {
if (node is! Interface) {
return node;
}
final customFields = getCustomFields(node.name);
if (customFields.isEmpty) {
return node;
}
return Interface(
node.commentNode,
node.nameToken,
node.typeArgs,
node.baseTypes,
[...node.members, ...customFields],
);
}
/// Fetches and in-lines any includes that appear in [spec] in the form
/// `{% include_relative types/uri.md %}`.
Future<String> _fetchIncludes(String spec, Uri baseUri) async {
@@ -43,21 +43,6 @@ String cleanComment(String comment) {
return comment.trim();
}
/// Improves comments in generated code to support where types may have been
/// altered (for ex. with [getImprovedType] above).
String? getImprovedComment(String interfaceName, String fieldName) {
const improvedComments = <String, Map<String, String>>{
'ResponseError': {
'data':
'// A string that contains additional information about the error. Can be omitted.',
},
};
final interface = improvedComments[interfaceName];
return interface != null ? interface[fieldName] : null;
}
/// Improves types in generated code, including:
///
/// - Fixes up some enum types that are not as specific as they could be in the
@@ -96,22 +81,6 @@ String? getImprovedType(String interfaceName, String? fieldName) {
'FoldingRange': {
'kind': 'FoldingRangeKind',
},
'ResponseError': {
'code': 'ErrorCodes',
// This is Object? normally, but since this class can be serialised
// we will crash if it data is set to something that can't be converted to
// JSON (for ex. Uri) so this forces anyone setting this to convert to a
// String.
'data': 'String',
},
'NotificationMessage': {
'method': 'Method',
'params': 'object',
},
'RequestMessage': {
'method': 'Method',
'params': 'object',
},
'SymbolInformation': {
'kind': 'SymbolKind',
},
@@ -134,26 +103,30 @@ String? getImprovedType(String interfaceName, String? fieldName) {
return interface != null ? interface[fieldName] : null;
}
List<String> getSpecialBaseTypes(Interface interface) {
if (interface.name == 'RequestMessage' ||
interface.name == 'NotificationMessage') {
return ['IncomingMessage'];
} else {
return [];
}
}
/// Removes types that are in the spec that we don't want to emit.
bool includeTypeDefinitionInOutput(AstNode node) {
// InitializeError is not used for v3.0 (Feb 2017) and by dropping it we don't
// have to handle any cases where both a namespace and interfaces are declared
// with the same name.
return node.name != 'InitializeError' &&
// We don't use `InitializeErrorCodes` as it contains only one error code
// that has been deprecated and we've never used.
node.name != 'InitializeErrorCodes' &&
// We don't emit MarkedString because it gets mapped to a simple String
// when getting the .dartType for it.
// .startsWith() because there are inline types that will be generated.
!node.name.startsWith('MarkedString');
const ignoredTypes = {
// InitializeError is not used for v3.0 (Feb 2017) and by dropping it we don't
// have to handle any cases where both a namespace and interfaces are declared
// with the same name.
'InitializeError',
// We don't use `InitializeErrorCodes` as it contains only one error code
// that has been deprecated and we've never used.
'InitializeErrorCodes',
// Handled in custom classes now in preperation for JSON meta model which
// does not specify them.
'Message',
'RequestMessage',
'NotificationMessage',
'ResponseMessage',
'ResponseError',
};
const ignoredPrefixes = {
// We don't emit MarkedString because it gets mapped to a simple String
// when getting the .dartType for it.
'MarkedString'
};
final shouldIgnore = ignoredTypes.contains(node.name) ||
ignoredPrefixes.any((ignore) => node.name.startsWith(ignore));
return !shouldIgnore;
}
@@ -378,12 +378,6 @@ class Parser {
type = _type(containerName, name.lexeme,
includeUndefined: canBeUndefined, improveTypes: true);
// Overwrite comment if we have an improved one.
final improvedComment = getImprovedComment(containerName, name.lexeme);
leadingComment = improvedComment != null
? Comment(Token(TokenType.COMMENT, improvedComment))
: leadingComment;
// Some fields have weird comments like this in the spec:
// {@link MessageType}
// These seem to be the correct type of the field, while the field is