mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Migrate analysis_server and analysis_server_client protocol.
Change-Id: Ie0912627733f0481de0d3239647a4978e5327f12 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193641 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
db6f65e661
commit
c2d660d161
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Support for client code that needs to interact with the requests, responses
|
||||
/// and notifications that are part of the analysis server's wire protocol.
|
||||
import 'dart:convert' hide JsonDecoder;
|
||||
|
@ -30,7 +28,7 @@ class Notification {
|
|||
|
||||
/// A table mapping the names of notification parameters to their values, or
|
||||
/// `null` if there are no notification parameters.
|
||||
final Map<String, Object> params;
|
||||
final Map<String, Object>? params;
|
||||
|
||||
/// Initialize a newly created [Notification] to have the given [event] name.
|
||||
/// If [params] is provided, it will be used as the params; otherwise no
|
||||
|
@ -40,7 +38,7 @@ class Notification {
|
|||
/// Initialize a newly created instance based on the given JSON data.
|
||||
factory Notification.fromJson(Map json) {
|
||||
return Notification(json[Notification.EVENT],
|
||||
json[Notification.PARAMS] as Map<String, Object>);
|
||||
json[Notification.PARAMS] as Map<String, Object>?);
|
||||
}
|
||||
|
||||
/// Return a table representing the structure of the Json object that will be
|
||||
|
@ -48,6 +46,7 @@ class Notification {
|
|||
Map<String, Object> toJson() {
|
||||
var jsonObject = <String, Object>{};
|
||||
jsonObject[EVENT] = event;
|
||||
var params = this.params;
|
||||
if (params != null) {
|
||||
jsonObject[PARAMS] = params;
|
||||
}
|
||||
|
@ -79,84 +78,18 @@ class Request {
|
|||
final String method;
|
||||
|
||||
/// A table mapping the names of request parameters to their values.
|
||||
final Map<String, Object> params;
|
||||
final Map<String, Object?> params;
|
||||
|
||||
/// The time (milliseconds since epoch) at which the client made the request
|
||||
/// or `null` if this information is not provided by the client.
|
||||
final int clientRequestTime;
|
||||
final int? clientRequestTime;
|
||||
|
||||
/// Initialize a newly created [Request] to have the given [id] and [method]
|
||||
/// name. If [params] is supplied, it is used as the "params" map for the
|
||||
/// request. Otherwise an empty "params" map is allocated.
|
||||
Request(this.id, this.method,
|
||||
[Map<String, Object> params, this.clientRequestTime])
|
||||
: params = params ?? <String, Object>{};
|
||||
|
||||
/// Return a request parsed from the given json, or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
factory Request.fromJson(Map<String, Object> result) {
|
||||
var id = result[Request.ID];
|
||||
var method = result[Request.METHOD];
|
||||
if (id is! String || method is! String) {
|
||||
return null;
|
||||
}
|
||||
var time = result[Request.CLIENT_REQUEST_TIME];
|
||||
if (time != null && time is! int) {
|
||||
return null;
|
||||
}
|
||||
var params = result[Request.PARAMS];
|
||||
if (params is Map || params == null) {
|
||||
return Request(id, method, params as Map<String, Object>, time);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given [data], or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
factory Request.fromString(String data) {
|
||||
try {
|
||||
var result = json.decode(data);
|
||||
if (result is Map) {
|
||||
return Request.fromJson(result as Map<String, dynamic>);
|
||||
}
|
||||
return null;
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
[Map<String, Object?>? params, this.clientRequestTime])
|
||||
: params = params ?? <String, Object?>{};
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
|
@ -181,13 +114,14 @@ class Request {
|
|||
if (params.isNotEmpty) {
|
||||
jsonObject[PARAMS] = params;
|
||||
}
|
||||
var clientRequestTime = this.clientRequestTime;
|
||||
if (clientRequestTime != null) {
|
||||
jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime;
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
bool _equalLists(List first, List second) {
|
||||
bool _equalLists(List? first, List? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -206,7 +140,7 @@ class Request {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool _equalMaps(Map first, Map second) {
|
||||
bool _equalMaps(Map? first, Map? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -227,7 +161,7 @@ class Request {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool _equalObjects(Object first, Object second) {
|
||||
bool _equalObjects(Object? first, Object? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -248,6 +182,72 @@ class Request {
|
|||
}
|
||||
return first == second;
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given json, or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
static Request? fromJson(Map<String, Object?> result) {
|
||||
var id = result[Request.ID];
|
||||
var method = result[Request.METHOD];
|
||||
if (id is! String || method is! String) {
|
||||
return null;
|
||||
}
|
||||
var time = result[Request.CLIENT_REQUEST_TIME];
|
||||
if (time is! int?) {
|
||||
return null;
|
||||
}
|
||||
var params = result[Request.PARAMS];
|
||||
if (params is Map<String, Object?>?) {
|
||||
return Request(id, method, params, time);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given [data], or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
static Request? fromString(String data) {
|
||||
try {
|
||||
var result = json.decode(data);
|
||||
if (result is Map<String, Object?>) {
|
||||
return Request.fromJson(result);
|
||||
}
|
||||
return null;
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An exception that occurred during the handling of a request that requires
|
||||
|
@ -297,11 +297,11 @@ class Response {
|
|||
|
||||
/// The error that was caused by attempting to handle the request, or `null`
|
||||
/// if there was no error.
|
||||
final RequestError error;
|
||||
final RequestError? error;
|
||||
|
||||
/// A table mapping the names of result fields to their values. Should be
|
||||
/// `null` if there is no result to send.
|
||||
Map<String, Object> result;
|
||||
Map<String, Object?>? result;
|
||||
|
||||
/// Initialize a newly created instance to represent a response to a request
|
||||
/// with the given [id]. If [_result] is provided, it will be used as the
|
||||
|
@ -336,30 +336,6 @@ class Response {
|
|||
error: RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
|
||||
'Error during `edit.format`: source contains syntax errors.'));
|
||||
|
||||
/// Initialize a newly created instance based on the given JSON data.
|
||||
factory Response.fromJson(Map json) {
|
||||
try {
|
||||
Object id = json[Response.ID];
|
||||
if (id is! String) {
|
||||
return null;
|
||||
}
|
||||
Object error = json[Response.ERROR];
|
||||
RequestError decodedError;
|
||||
if (error is Map) {
|
||||
decodedError =
|
||||
RequestError.fromJson(ResponseDecoder(null), '.error', error);
|
||||
}
|
||||
Object result = json[Response.RESULT];
|
||||
Map<String, Object> decodedResult;
|
||||
if (result is Map) {
|
||||
decodedResult = result as Map<String, Object>;
|
||||
}
|
||||
return Response(id, error: decodedError, result: decodedResult);
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize a newly created instance to represent the
|
||||
/// GET_ERRORS_INVALID_FILE error condition.
|
||||
Response.getErrorsInvalidFile(Request request)
|
||||
|
@ -529,12 +505,41 @@ class Response {
|
|||
Map<String, Object> toJson() {
|
||||
var jsonObject = <String, Object>{};
|
||||
jsonObject[ID] = id;
|
||||
var error = this.error;
|
||||
if (error != null) {
|
||||
jsonObject[ERROR] = error.toJson();
|
||||
}
|
||||
var result = this.result;
|
||||
if (result != null) {
|
||||
jsonObject[RESULT] = result;
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/// Initialize a newly created instance based on the given JSON data.
|
||||
static Response? fromJson(Map<String, Object?> json) {
|
||||
try {
|
||||
var id = json[Response.ID];
|
||||
if (id is! String) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RequestError? decodedError;
|
||||
var error = json[Response.ERROR];
|
||||
if (error is Map) {
|
||||
decodedError =
|
||||
RequestError.fromJson(ResponseDecoder(null), '.error', error);
|
||||
}
|
||||
|
||||
Map<String, Object?>? decodedResult;
|
||||
var result = json[Response.RESULT];
|
||||
if (result is Map<String, Object?>) {
|
||||
decodedResult = result;
|
||||
}
|
||||
|
||||
return Response(id, error: decodedError, result: decodedResult);
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
const String PROTOCOL_VERSION = '1.32.5';
|
||||
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:collection';
|
||||
import 'dart:convert' hide JsonDecoder;
|
||||
|
||||
|
@ -31,8 +29,8 @@ String applySequenceOfEdits(String code, Iterable<SourceEdit> edits) {
|
|||
|
||||
/// Compare the lists [listA] and [listB], using [itemEqual] to compare
|
||||
/// list elements.
|
||||
bool listEqual<T1, T2>(
|
||||
List<T1> listA, List<T2> listB, bool Function(T1 a, T2 b) itemEqual) {
|
||||
bool listEqual<T>(
|
||||
List<T>? listA, List<T>? listB, bool Function(T a, T b) itemEqual) {
|
||||
if (listA == null) {
|
||||
return listB == null;
|
||||
}
|
||||
|
@ -53,7 +51,7 @@ bool listEqual<T1, T2>(
|
|||
/// Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
|
||||
/// values.
|
||||
bool mapEqual<K, V>(
|
||||
Map<K, V> mapA, Map<K, V> mapB, bool Function(V a, V b) valueEqual) {
|
||||
Map<K, V>? mapA, Map<K, V>? mapB, bool Function(V a, V b) valueEqual) {
|
||||
if (mapA == null) {
|
||||
return mapB == null;
|
||||
}
|
||||
|
@ -63,11 +61,11 @@ bool mapEqual<K, V>(
|
|||
if (mapA.length != mapB.length) {
|
||||
return false;
|
||||
}
|
||||
for (var key in mapA.keys) {
|
||||
if (!mapB.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
if (!valueEqual(mapA[key], mapB[key])) {
|
||||
for (var entryA in mapA.entries) {
|
||||
var key = entryA.key;
|
||||
var valueA = entryA.value;
|
||||
var valueB = mapB[key];
|
||||
if (valueB == null || !valueEqual(valueA, valueB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +75,7 @@ bool mapEqual<K, V>(
|
|||
/// Translate the input [map], applying [keyCallback] to all its keys, and
|
||||
/// [valueCallback] to all its values.
|
||||
Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
|
||||
{KR Function(KP key) keyCallback, VR Function(VP value) valueCallback}) {
|
||||
{KR Function(KP key)? keyCallback, VR Function(VP value)? valueCallback}) {
|
||||
Map<KR, VR> result = HashMap<KR, VR>();
|
||||
map.forEach((key, value) {
|
||||
KR resultKey;
|
||||
|
@ -98,8 +96,8 @@ Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
|
|||
}
|
||||
|
||||
/// Create a [RefactoringFeedback] corresponding the given [kind].
|
||||
RefactoringFeedback refactoringFeedbackFromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) {
|
||||
RefactoringFeedback? refactoringFeedbackFromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object? json, Map feedbackJson) {
|
||||
var kind = jsonDecoder.refactoringKind;
|
||||
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
|
||||
return ExtractLocalVariableFeedback.fromJson(jsonDecoder, jsonPath, json);
|
||||
|
@ -123,8 +121,8 @@ RefactoringFeedback refactoringFeedbackFromJson(
|
|||
}
|
||||
|
||||
/// Create a [RefactoringOptions] corresponding the given [kind].
|
||||
RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
||||
String jsonPath, Object json, RefactoringKind kind) {
|
||||
RefactoringOptions? refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
||||
String jsonPath, Object? json, RefactoringKind kind) {
|
||||
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
|
||||
return ExtractLocalVariableOptions.fromJson(jsonDecoder, jsonPath, json);
|
||||
}
|
||||
|
@ -162,13 +160,13 @@ class RequestDecoder extends JsonDecoder {
|
|||
RequestDecoder(this._request);
|
||||
|
||||
@override
|
||||
RefactoringKind get refactoringKind {
|
||||
RefactoringKind? get refactoringKind {
|
||||
// Refactoring feedback objects should never appear in requests.
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic mismatch(String jsonPath, String expected, [Object actual]) {
|
||||
Object mismatch(String jsonPath, String expected, [Object? actual]) {
|
||||
var buffer = StringBuffer();
|
||||
buffer.write('Expected to be ');
|
||||
buffer.write(expected);
|
||||
|
@ -182,7 +180,7 @@ class RequestDecoder extends JsonDecoder {
|
|||
}
|
||||
|
||||
@override
|
||||
dynamic missingKey(String jsonPath, String key) {
|
||||
Object missingKey(String jsonPath, String key) {
|
||||
return RequestFailure(Response.invalidParameter(
|
||||
_request, jsonPath, 'Expected to contain key ${json.encode(key)}'));
|
||||
}
|
||||
|
@ -198,12 +196,12 @@ abstract class RequestParams implements HasToJson {
|
|||
/// used only for testing. Errors are reported using bare [Exception] objects.
|
||||
class ResponseDecoder extends JsonDecoder {
|
||||
@override
|
||||
final RefactoringKind refactoringKind;
|
||||
final RefactoringKind? refactoringKind;
|
||||
|
||||
ResponseDecoder(this.refactoringKind);
|
||||
|
||||
@override
|
||||
dynamic mismatch(String jsonPath, String expected, [Object actual]) {
|
||||
Object mismatch(String jsonPath, String expected, [Object? actual]) {
|
||||
var buffer = StringBuffer();
|
||||
buffer.write('Expected ');
|
||||
buffer.write(expected);
|
||||
|
@ -218,7 +216,7 @@ class ResponseDecoder extends JsonDecoder {
|
|||
}
|
||||
|
||||
@override
|
||||
dynamic missingKey(String jsonPath, String key) {
|
||||
Object missingKey(String jsonPath, String key) {
|
||||
return Exception('Missing key $key at $jsonPath');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
const String CODE = 'code';
|
||||
const String COMPLETION_RESULTS = 'completion.results';
|
||||
const String CONTEXT_MESSAGES = 'contextMessages';
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Convenience methods for running integration tests.
|
||||
import 'dart:async';
|
||||
|
||||
|
@ -81,10 +79,10 @@ abstract class IntegrationTestMixin {
|
|||
/// pid: int
|
||||
///
|
||||
/// The process id of the analysis server process.
|
||||
Stream<ServerConnectedParams> onServerConnected;
|
||||
late Stream<ServerConnectedParams> onServerConnected;
|
||||
|
||||
/// Stream controller for [onServerConnected].
|
||||
StreamController<ServerConnectedParams> _onServerConnected;
|
||||
late StreamController<ServerConnectedParams> _onServerConnected;
|
||||
|
||||
/// Reports that an unexpected error has occurred while executing the server.
|
||||
/// This notification is not used for problems with specific requests (which
|
||||
|
@ -109,20 +107,20 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// The stack trace associated with the generation of the error, used for
|
||||
/// debugging the server.
|
||||
Stream<ServerErrorParams> onServerError;
|
||||
late Stream<ServerErrorParams> onServerError;
|
||||
|
||||
/// Stream controller for [onServerError].
|
||||
StreamController<ServerErrorParams> _onServerError;
|
||||
late StreamController<ServerErrorParams> _onServerError;
|
||||
|
||||
/// The stream of entries describing events happened in the server.
|
||||
///
|
||||
/// Parameters
|
||||
///
|
||||
/// entry: ServerLogEntry
|
||||
Stream<ServerLogParams> onServerLog;
|
||||
late Stream<ServerLogParams> onServerLog;
|
||||
|
||||
/// Stream controller for [onServerLog].
|
||||
StreamController<ServerLogParams> _onServerLog;
|
||||
late StreamController<ServerLogParams> _onServerLog;
|
||||
|
||||
/// Reports the current status of the server. Parameters are omitted if there
|
||||
/// has been no change in the status represented by that parameter.
|
||||
|
@ -145,10 +143,10 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// Note: this status type is deprecated, and is no longer sent by the
|
||||
/// server.
|
||||
Stream<ServerStatusParams> onServerStatus;
|
||||
late Stream<ServerStatusParams> onServerStatus;
|
||||
|
||||
/// Stream controller for [onServerStatus].
|
||||
StreamController<ServerStatusParams> _onServerStatus;
|
||||
late StreamController<ServerStatusParams> _onServerStatus;
|
||||
|
||||
/// Return the errors associated with the given file. If the errors for the
|
||||
/// given file have not yet been computed, or the most recently computed
|
||||
|
@ -492,7 +490,7 @@ abstract class IntegrationTestMixin {
|
|||
/// that the normal pubspec.yaml mechanism should always be used.
|
||||
Future sendAnalysisSetAnalysisRoots(
|
||||
List<String> included, List<String> excluded,
|
||||
{Map<String, String> packageRoots}) async {
|
||||
{Map<String, String>? packageRoots}) async {
|
||||
var params = AnalysisSetAnalysisRootsParams(included, excluded,
|
||||
packageRoots: packageRoots)
|
||||
.toJson();
|
||||
|
@ -646,10 +644,10 @@ abstract class IntegrationTestMixin {
|
|||
/// directories: List<FilePath>
|
||||
///
|
||||
/// A list of the paths of the files that are being analyzed.
|
||||
Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles;
|
||||
late Stream<AnalysisAnalyzedFilesParams> onAnalysisAnalyzedFiles;
|
||||
|
||||
/// Stream controller for [onAnalysisAnalyzedFiles].
|
||||
StreamController<AnalysisAnalyzedFilesParams> _onAnalysisAnalyzedFiles;
|
||||
late StreamController<AnalysisAnalyzedFilesParams> _onAnalysisAnalyzedFiles;
|
||||
|
||||
/// Reports closing labels relevant to a given file.
|
||||
///
|
||||
|
@ -672,10 +670,10 @@ abstract class IntegrationTestMixin {
|
|||
/// constructor/method calls and List arguments that span multiple lines.
|
||||
/// Note that the ranges that are returned can overlap each other because
|
||||
/// they may be associated with constructs that can be nested.
|
||||
Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels;
|
||||
late Stream<AnalysisClosingLabelsParams> onAnalysisClosingLabels;
|
||||
|
||||
/// Stream controller for [onAnalysisClosingLabels].
|
||||
StreamController<AnalysisClosingLabelsParams> _onAnalysisClosingLabels;
|
||||
late StreamController<AnalysisClosingLabelsParams> _onAnalysisClosingLabels;
|
||||
|
||||
/// Reports the errors associated with a given file. The set of errors
|
||||
/// included in the notification is always a complete list that supersedes
|
||||
|
@ -690,10 +688,10 @@ abstract class IntegrationTestMixin {
|
|||
/// errors: List<AnalysisError>
|
||||
///
|
||||
/// The errors contained in the file.
|
||||
Stream<AnalysisErrorsParams> onAnalysisErrors;
|
||||
late Stream<AnalysisErrorsParams> onAnalysisErrors;
|
||||
|
||||
/// Stream controller for [onAnalysisErrors].
|
||||
StreamController<AnalysisErrorsParams> _onAnalysisErrors;
|
||||
late StreamController<AnalysisErrorsParams> _onAnalysisErrors;
|
||||
|
||||
/// Reports that any analysis results that were previously associated with
|
||||
/// the given files should be considered to be invalid because those files
|
||||
|
@ -713,10 +711,10 @@ abstract class IntegrationTestMixin {
|
|||
/// files: List<FilePath>
|
||||
///
|
||||
/// The files that are no longer being analyzed.
|
||||
Stream<AnalysisFlushResultsParams> onAnalysisFlushResults;
|
||||
late Stream<AnalysisFlushResultsParams> onAnalysisFlushResults;
|
||||
|
||||
/// Stream controller for [onAnalysisFlushResults].
|
||||
StreamController<AnalysisFlushResultsParams> _onAnalysisFlushResults;
|
||||
late StreamController<AnalysisFlushResultsParams> _onAnalysisFlushResults;
|
||||
|
||||
/// Reports the folding regions associated with a given file. Folding regions
|
||||
/// can be nested, but will not be overlapping. Nesting occurs when a
|
||||
|
@ -736,10 +734,10 @@ abstract class IntegrationTestMixin {
|
|||
/// regions: List<FoldingRegion>
|
||||
///
|
||||
/// The folding regions contained in the file.
|
||||
Stream<AnalysisFoldingParams> onAnalysisFolding;
|
||||
late Stream<AnalysisFoldingParams> onAnalysisFolding;
|
||||
|
||||
/// Stream controller for [onAnalysisFolding].
|
||||
StreamController<AnalysisFoldingParams> _onAnalysisFolding;
|
||||
late StreamController<AnalysisFoldingParams> _onAnalysisFolding;
|
||||
|
||||
/// Reports the highlight regions associated with a given file.
|
||||
///
|
||||
|
@ -760,10 +758,10 @@ abstract class IntegrationTestMixin {
|
|||
/// some range. Note that the highlight regions that are returned can
|
||||
/// overlap other highlight regions if there is more than one meaning
|
||||
/// associated with a particular region.
|
||||
Stream<AnalysisHighlightsParams> onAnalysisHighlights;
|
||||
late Stream<AnalysisHighlightsParams> onAnalysisHighlights;
|
||||
|
||||
/// Stream controller for [onAnalysisHighlights].
|
||||
StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
|
||||
late StreamController<AnalysisHighlightsParams> _onAnalysisHighlights;
|
||||
|
||||
/// Reports the classes that are implemented or extended and class members
|
||||
/// that are implemented or overridden in a file.
|
||||
|
@ -785,10 +783,10 @@ abstract class IntegrationTestMixin {
|
|||
/// members: List<ImplementedMember>
|
||||
///
|
||||
/// The member defined in the file that are implemented or overridden.
|
||||
Stream<AnalysisImplementedParams> onAnalysisImplemented;
|
||||
late Stream<AnalysisImplementedParams> onAnalysisImplemented;
|
||||
|
||||
/// Stream controller for [onAnalysisImplemented].
|
||||
StreamController<AnalysisImplementedParams> _onAnalysisImplemented;
|
||||
late StreamController<AnalysisImplementedParams> _onAnalysisImplemented;
|
||||
|
||||
/// Reports that the navigation information associated with a region of a
|
||||
/// single file has become invalid and should be re-requested.
|
||||
|
@ -816,10 +814,10 @@ abstract class IntegrationTestMixin {
|
|||
/// The delta to be applied to the offsets in information that follows the
|
||||
/// invalidated region in order to update it so that it doesn't need to be
|
||||
/// re-requested.
|
||||
Stream<AnalysisInvalidateParams> onAnalysisInvalidate;
|
||||
late Stream<AnalysisInvalidateParams> onAnalysisInvalidate;
|
||||
|
||||
/// Stream controller for [onAnalysisInvalidate].
|
||||
StreamController<AnalysisInvalidateParams> _onAnalysisInvalidate;
|
||||
late StreamController<AnalysisInvalidateParams> _onAnalysisInvalidate;
|
||||
|
||||
/// Reports the navigation targets associated with a given file.
|
||||
///
|
||||
|
@ -852,10 +850,10 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// The files containing navigation targets referenced in the file. They
|
||||
/// are referenced by NavigationTargets by their index in this array.
|
||||
Stream<AnalysisNavigationParams> onAnalysisNavigation;
|
||||
late Stream<AnalysisNavigationParams> onAnalysisNavigation;
|
||||
|
||||
/// Stream controller for [onAnalysisNavigation].
|
||||
StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
|
||||
late StreamController<AnalysisNavigationParams> _onAnalysisNavigation;
|
||||
|
||||
/// Reports the occurrences of references to elements within a single file.
|
||||
///
|
||||
|
@ -872,10 +870,10 @@ abstract class IntegrationTestMixin {
|
|||
/// occurrences: List<Occurrences>
|
||||
///
|
||||
/// The occurrences of references to elements within the file.
|
||||
Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
|
||||
late Stream<AnalysisOccurrencesParams> onAnalysisOccurrences;
|
||||
|
||||
/// Stream controller for [onAnalysisOccurrences].
|
||||
StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
|
||||
late StreamController<AnalysisOccurrencesParams> _onAnalysisOccurrences;
|
||||
|
||||
/// Reports the outline associated with a single file.
|
||||
///
|
||||
|
@ -904,10 +902,10 @@ abstract class IntegrationTestMixin {
|
|||
/// outline: Outline
|
||||
///
|
||||
/// The outline associated with the file.
|
||||
Stream<AnalysisOutlineParams> onAnalysisOutline;
|
||||
late Stream<AnalysisOutlineParams> onAnalysisOutline;
|
||||
|
||||
/// Stream controller for [onAnalysisOutline].
|
||||
StreamController<AnalysisOutlineParams> _onAnalysisOutline;
|
||||
late StreamController<AnalysisOutlineParams> _onAnalysisOutline;
|
||||
|
||||
/// Reports the overriding members in a file.
|
||||
///
|
||||
|
@ -924,10 +922,10 @@ abstract class IntegrationTestMixin {
|
|||
/// overrides: List<Override>
|
||||
///
|
||||
/// The overrides associated with the file.
|
||||
Stream<AnalysisOverridesParams> onAnalysisOverrides;
|
||||
late Stream<AnalysisOverridesParams> onAnalysisOverrides;
|
||||
|
||||
/// Stream controller for [onAnalysisOverrides].
|
||||
StreamController<AnalysisOverridesParams> _onAnalysisOverrides;
|
||||
late StreamController<AnalysisOverridesParams> _onAnalysisOverrides;
|
||||
|
||||
/// Request that completion suggestions for the given offset in the given
|
||||
/// file be returned.
|
||||
|
@ -1117,10 +1115,10 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// If an AvailableSuggestion has relevance tags that match more than one
|
||||
/// IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
|
||||
Stream<CompletionResultsParams> onCompletionResults;
|
||||
late Stream<CompletionResultsParams> onCompletionResults;
|
||||
|
||||
/// Stream controller for [onCompletionResults].
|
||||
StreamController<CompletionResultsParams> _onCompletionResults;
|
||||
late StreamController<CompletionResultsParams> _onCompletionResults;
|
||||
|
||||
/// Reports the pre-computed, candidate completions from symbols defined in a
|
||||
/// corresponding library. This notification may be sent multiple times. When
|
||||
|
@ -1140,10 +1138,11 @@ abstract class IntegrationTestMixin {
|
|||
/// removedLibraries: List<int> (optional)
|
||||
///
|
||||
/// A list of library ids that no longer apply.
|
||||
Stream<CompletionAvailableSuggestionsParams> onCompletionAvailableSuggestions;
|
||||
late Stream<CompletionAvailableSuggestionsParams>
|
||||
onCompletionAvailableSuggestions;
|
||||
|
||||
/// Stream controller for [onCompletionAvailableSuggestions].
|
||||
StreamController<CompletionAvailableSuggestionsParams>
|
||||
late StreamController<CompletionAvailableSuggestionsParams>
|
||||
_onCompletionAvailableSuggestions;
|
||||
|
||||
/// Reports existing imports in a library. This notification may be sent
|
||||
|
@ -1159,10 +1158,10 @@ abstract class IntegrationTestMixin {
|
|||
/// imports: ExistingImports
|
||||
///
|
||||
/// The existing imports in the library.
|
||||
Stream<CompletionExistingImportsParams> onCompletionExistingImports;
|
||||
late Stream<CompletionExistingImportsParams> onCompletionExistingImports;
|
||||
|
||||
/// Stream controller for [onCompletionExistingImports].
|
||||
StreamController<CompletionExistingImportsParams>
|
||||
late StreamController<CompletionExistingImportsParams>
|
||||
_onCompletionExistingImports;
|
||||
|
||||
/// Perform a search for references to the element defined or referenced at
|
||||
|
@ -1325,7 +1324,7 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// The list of the paths of files with declarations.
|
||||
Future<SearchGetElementDeclarationsResult> sendSearchGetElementDeclarations(
|
||||
{String file, String pattern, int maxResults}) async {
|
||||
{String? file, String? pattern, int? maxResults}) async {
|
||||
var params = SearchGetElementDeclarationsParams(
|
||||
file: file, pattern: pattern, maxResults: maxResults)
|
||||
.toJson();
|
||||
|
@ -1369,7 +1368,7 @@ abstract class IntegrationTestMixin {
|
|||
/// to allow a type hierarchy to be produced.
|
||||
Future<SearchGetTypeHierarchyResult> sendSearchGetTypeHierarchy(
|
||||
String file, int offset,
|
||||
{bool superOnly}) async {
|
||||
{bool? superOnly}) async {
|
||||
var params =
|
||||
SearchGetTypeHierarchyParams(file, offset, superOnly: superOnly)
|
||||
.toJson();
|
||||
|
@ -1397,10 +1396,10 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// True if this is that last set of results that will be returned for the
|
||||
/// indicated search.
|
||||
Stream<SearchResultsParams> onSearchResults;
|
||||
late Stream<SearchResultsParams> onSearchResults;
|
||||
|
||||
/// Stream controller for [onSearchResults].
|
||||
StreamController<SearchResultsParams> _onSearchResults;
|
||||
late StreamController<SearchResultsParams> _onSearchResults;
|
||||
|
||||
/// Format the contents of a single file. The currently selected region of
|
||||
/// text is passed in so that the selection can be preserved across the
|
||||
|
@ -1450,7 +1449,7 @@ abstract class IntegrationTestMixin {
|
|||
/// The length of the selection after formatting the code.
|
||||
Future<EditFormatResult> sendEditFormat(
|
||||
String file, int selectionOffset, int selectionLength,
|
||||
{int lineLength}) async {
|
||||
{int? lineLength}) async {
|
||||
var params = EditFormatParams(file, selectionOffset, selectionLength,
|
||||
lineLength: lineLength)
|
||||
.toJson();
|
||||
|
@ -1580,7 +1579,7 @@ abstract class IntegrationTestMixin {
|
|||
/// Details that summarize the fixes associated with the recommended
|
||||
/// changes.
|
||||
Future<EditBulkFixesResult> sendEditBulkFixes(List<String> included,
|
||||
{bool inTestMode}) async {
|
||||
{bool? inTestMode}) async {
|
||||
var params = EditBulkFixesParams(included, inTestMode: inTestMode).toJson();
|
||||
var result = await server.send('edit.bulkFixes', params);
|
||||
var decoder = ResponseDecoder(null);
|
||||
|
@ -1681,11 +1680,11 @@ abstract class IntegrationTestMixin {
|
|||
/// proposed changes. There is one URL for each of the included file paths.
|
||||
/// The field is omitted if a preview was not requested.
|
||||
Future<EditDartfixResult> sendEditDartfix(List<String> included,
|
||||
{List<String> includedFixes,
|
||||
bool includePedanticFixes,
|
||||
List<String> excludedFixes,
|
||||
int port,
|
||||
String outputDir}) async {
|
||||
{List<String>? includedFixes,
|
||||
bool? includePedanticFixes,
|
||||
List<String>? excludedFixes,
|
||||
int? port,
|
||||
String? outputDir}) async {
|
||||
var params = EditDartfixParams(included,
|
||||
includedFixes: includedFixes,
|
||||
includePedanticFixes: includePedanticFixes,
|
||||
|
@ -1841,7 +1840,7 @@ abstract class IntegrationTestMixin {
|
|||
/// the refactoring.
|
||||
Future<EditGetRefactoringResult> sendEditGetRefactoring(RefactoringKind kind,
|
||||
String file, int offset, int length, bool validateOnly,
|
||||
{RefactoringOptions options}) async {
|
||||
{RefactoringOptions? options}) async {
|
||||
var params = EditGetRefactoringParams(
|
||||
kind, file, offset, length, validateOnly,
|
||||
options: options)
|
||||
|
@ -1975,7 +1974,7 @@ abstract class IntegrationTestMixin {
|
|||
/// that need to be applied.
|
||||
Future<EditImportElementsResult> sendEditImportElements(
|
||||
String file, List<ImportedElements> elements,
|
||||
{int offset}) async {
|
||||
{int? offset}) async {
|
||||
var params =
|
||||
EditImportElementsParams(file, elements, offset: offset).toJson();
|
||||
var result = await server.send('edit.importElements', params);
|
||||
|
@ -2164,7 +2163,7 @@ abstract class IntegrationTestMixin {
|
|||
String contextFile,
|
||||
int contextOffset,
|
||||
List<RuntimeCompletionVariable> variables,
|
||||
{List<RuntimeCompletionExpression> expressions}) async {
|
||||
{List<RuntimeCompletionExpression>? expressions}) async {
|
||||
var params = ExecutionGetSuggestionsParams(
|
||||
code, offset, contextFile, contextOffset, variables,
|
||||
expressions: expressions)
|
||||
|
@ -2221,7 +2220,7 @@ abstract class IntegrationTestMixin {
|
|||
/// The URI to which the file path was mapped. This field is omitted if the
|
||||
/// file field was not given in the request.
|
||||
Future<ExecutionMapUriResult> sendExecutionMapUri(String id,
|
||||
{String file, String uri}) async {
|
||||
{String? file, String? uri}) async {
|
||||
var params = ExecutionMapUriParams(id, file: file, uri: uri).toJson();
|
||||
var result = await server.send('execution.mapUri', params);
|
||||
var decoder = ResponseDecoder(null);
|
||||
|
@ -2273,10 +2272,10 @@ abstract class IntegrationTestMixin {
|
|||
///
|
||||
/// A list of the Dart files that are referenced by the file. This field is
|
||||
/// omitted if the file is not an HTML file.
|
||||
Stream<ExecutionLaunchDataParams> onExecutionLaunchData;
|
||||
late Stream<ExecutionLaunchDataParams> onExecutionLaunchData;
|
||||
|
||||
/// Stream controller for [onExecutionLaunchData].
|
||||
StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
|
||||
late StreamController<ExecutionLaunchDataParams> _onExecutionLaunchData;
|
||||
|
||||
/// Return server diagnostics.
|
||||
///
|
||||
|
@ -2512,7 +2511,7 @@ abstract class IntegrationTestMixin {
|
|||
/// The change that should be applied.
|
||||
Future<FlutterSetWidgetPropertyValueResult> sendFlutterSetWidgetPropertyValue(
|
||||
int id,
|
||||
{FlutterWidgetPropertyValue value}) async {
|
||||
{FlutterWidgetPropertyValue? value}) async {
|
||||
var params = FlutterSetWidgetPropertyValueParams(id, value: value).toJson();
|
||||
var result = await server.send('flutter.setWidgetPropertyValue', params);
|
||||
var decoder = ResponseDecoder(null);
|
||||
|
@ -2573,10 +2572,10 @@ abstract class IntegrationTestMixin {
|
|||
/// outline: FlutterOutline
|
||||
///
|
||||
/// The outline associated with the file.
|
||||
Stream<FlutterOutlineParams> onFlutterOutline;
|
||||
late Stream<FlutterOutlineParams> onFlutterOutline;
|
||||
|
||||
/// Stream controller for [onFlutterOutline].
|
||||
StreamController<FlutterOutlineParams> _onFlutterOutline;
|
||||
late StreamController<FlutterOutlineParams> _onFlutterOutline;
|
||||
|
||||
/// Initialize the fields in InttestMixin, and ensure that notifications will
|
||||
/// be handled.
|
||||
|
@ -2762,7 +2761,6 @@ abstract class IntegrationTestMixin {
|
|||
break;
|
||||
default:
|
||||
fail('Unexpected notification: $event');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
|
@ -42,7 +40,7 @@ Matcher isOneOf(List<Matcher> choiceMatchers) => _OneOf(choiceMatchers);
|
|||
|
||||
/// Assert that [actual] matches [matcher].
|
||||
void outOfTestExpect(actual, Matcher matcher,
|
||||
{String reason, skip, bool verbose = false}) {
|
||||
{String? reason, skip, bool verbose = false}) {
|
||||
var matchState = {};
|
||||
try {
|
||||
if (matcher.matches(actual, matchState)) return;
|
||||
|
@ -53,7 +51,7 @@ void outOfTestExpect(actual, Matcher matcher,
|
|||
}
|
||||
|
||||
String _defaultFailFormatter(
|
||||
actual, Matcher matcher, String reason, Map matchState, bool verbose) {
|
||||
actual, Matcher matcher, String? reason, Map matchState, bool verbose) {
|
||||
var description = StringDescription();
|
||||
description.add('Expected: ').addDescriptionOf(matcher).add('\n');
|
||||
description.add(' Actual: ').addDescriptionOf(actual).add('\n');
|
||||
|
@ -90,7 +88,7 @@ abstract class AbstractAnalysisServerIntegrationTest
|
|||
final Server server = Server();
|
||||
|
||||
/// Temporary directory in which source files can be stored.
|
||||
Directory sourceDirectory;
|
||||
late Directory sourceDirectory;
|
||||
|
||||
/// Map from file path to the list of analysis errors which have most recently
|
||||
/// been received for the file.
|
||||
|
@ -98,7 +96,7 @@ abstract class AbstractAnalysisServerIntegrationTest
|
|||
HashMap<String, List<AnalysisError>>();
|
||||
|
||||
/// The last list of analyzed files received.
|
||||
List<String> lastAnalyzedFiles;
|
||||
late List<String> lastAnalyzedFiles;
|
||||
|
||||
/// True if the teardown process should skip sending a "server.shutdown"
|
||||
/// request (e.g. because the server is known to have already shutdown).
|
||||
|
@ -121,12 +119,13 @@ abstract class AbstractAnalysisServerIntegrationTest
|
|||
/// analysis to finish.
|
||||
Future<ServerStatusParams> get analysisFinished {
|
||||
var completer = Completer<ServerStatusParams>();
|
||||
StreamSubscription<ServerStatusParams> subscription;
|
||||
late StreamSubscription<ServerStatusParams> subscription;
|
||||
// This will only work if the caller has already subscribed to
|
||||
// SERVER_STATUS (e.g. using sendServerSetSubscriptions(['STATUS']))
|
||||
outOfTestExpect(_subscribedToServerStatus, isTrue);
|
||||
subscription = onServerStatus.listen((ServerStatusParams params) {
|
||||
if (params.analysis != null && !params.analysis.isAnalyzing) {
|
||||
var analysisStatus = params.analysis;
|
||||
if (analysisStatus != null && !analysisStatus.isAnalyzing) {
|
||||
completer.complete(params);
|
||||
subscription.cancel();
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ abstract class AbstractAnalysisServerIntegrationTest
|
|||
server.debugStdio();
|
||||
}
|
||||
|
||||
List<AnalysisError> getErrors(String pathname) =>
|
||||
List<AnalysisError>? getErrors(String pathname) =>
|
||||
currentAnalysisErrors[pathname];
|
||||
|
||||
/// Read a source file with the given absolute [pathname].
|
||||
|
@ -219,8 +218,8 @@ abstract class AbstractAnalysisServerIntegrationTest
|
|||
|
||||
/// Start [server].
|
||||
Future startServer({
|
||||
int diagnosticPort,
|
||||
int servicesPort,
|
||||
int? diagnosticPort,
|
||||
int? servicesPort,
|
||||
}) {
|
||||
return server.start(
|
||||
diagnosticPort: diagnosticPort, servicesPort: servicesPort);
|
||||
|
@ -259,33 +258,30 @@ class LazyMatcher implements Matcher {
|
|||
|
||||
/// The matcher returned by [_creator], if it has already been called.
|
||||
/// Otherwise null.
|
||||
Matcher _wrappedMatcher;
|
||||
Matcher? _wrappedMatcher;
|
||||
|
||||
LazyMatcher(this._creator);
|
||||
|
||||
/// Create the wrapped matcher object, if it hasn't been created already.
|
||||
Matcher get _matcher {
|
||||
return _wrappedMatcher ??= _creator();
|
||||
}
|
||||
|
||||
@override
|
||||
Description describe(Description description) {
|
||||
_createMatcher();
|
||||
return _wrappedMatcher.describe(description);
|
||||
return _matcher.describe(description);
|
||||
}
|
||||
|
||||
@override
|
||||
Description describeMismatch(
|
||||
item, Description mismatchDescription, Map matchState, bool verbose) {
|
||||
_createMatcher();
|
||||
return _wrappedMatcher.describeMismatch(
|
||||
return _matcher.describeMismatch(
|
||||
item, mismatchDescription, matchState, verbose);
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(item, Map matchState) {
|
||||
_createMatcher();
|
||||
return _wrappedMatcher.matches(item, matchState);
|
||||
}
|
||||
|
||||
/// Create the wrapped matcher object, if it hasn't been created already.
|
||||
void _createMatcher() {
|
||||
_wrappedMatcher ??= _creator();
|
||||
return _matcher.matches(item, matchState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,11 +313,11 @@ class MatchesJsonObject extends _RecursiveMatcher {
|
|||
|
||||
/// Fields that are required to be in the JSON object, and [Matcher]s
|
||||
/// describing their expected types.
|
||||
final Map<String, Matcher> requiredFields;
|
||||
final Map<String, Matcher>? requiredFields;
|
||||
|
||||
/// Fields that are optional in the JSON object, and [Matcher]s describing
|
||||
/// their expected types.
|
||||
final Map<String, Matcher> optionalFields;
|
||||
final Map<String, Matcher>? optionalFields;
|
||||
|
||||
const MatchesJsonObject(this.description, this.requiredFields,
|
||||
{this.optionalFields});
|
||||
|
@ -336,9 +332,11 @@ class MatchesJsonObject extends _RecursiveMatcher {
|
|||
mismatches.add(simpleDescription('is not a map'));
|
||||
return;
|
||||
}
|
||||
var requiredFields = this.requiredFields;
|
||||
var optionalFields = this.optionalFields;
|
||||
if (requiredFields != null) {
|
||||
requiredFields.forEach((String key, Matcher valueMatcher) {
|
||||
if (!(item as Map).containsKey(key)) {
|
||||
if (!item.containsKey(key)) {
|
||||
mismatches.add((Description mismatchDescription) =>
|
||||
mismatchDescription
|
||||
.add('is missing field ')
|
||||
|
@ -354,13 +352,18 @@ class MatchesJsonObject extends _RecursiveMatcher {
|
|||
item.forEach((key, value) {
|
||||
if (requiredFields != null && requiredFields.containsKey(key)) {
|
||||
// Already checked this field
|
||||
} else if (optionalFields != null && optionalFields.containsKey(key)) {
|
||||
_checkField(key, value, optionalFields[key], mismatches);
|
||||
} else {
|
||||
mismatches.add((Description mismatchDescription) => mismatchDescription
|
||||
.add('has unexpected field ')
|
||||
.addDescriptionOf(key));
|
||||
return;
|
||||
}
|
||||
if (optionalFields != null) {
|
||||
var optionalValue = optionalFields[key];
|
||||
if (optionalValue != null) {
|
||||
_checkField(key, value, optionalValue, mismatches);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mismatches.add((Description mismatchDescription) => mismatchDescription
|
||||
.add('has unexpected field ')
|
||||
.addDescriptionOf(key));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -382,7 +385,7 @@ class MatchesJsonObject extends _RecursiveMatcher {
|
|||
/// facilitate communication to and from the server.
|
||||
class Server {
|
||||
/// Server process object, or null if server hasn't been started yet.
|
||||
Process _process;
|
||||
late final Process _process;
|
||||
|
||||
/// Commands that have been sent to the server but not yet acknowledged, and
|
||||
/// the [Completer] objects which should be completed when acknowledgement is
|
||||
|
@ -411,7 +414,7 @@ class Server {
|
|||
|
||||
/// The [currentElapseTime] at which the last communication was received from
|
||||
/// the server or `null` if no communication has been received.
|
||||
double lastCommunicationTime;
|
||||
double? lastCommunicationTime;
|
||||
|
||||
/// The current elapse time (seconds) since the server was started.
|
||||
double get currentElapseTime => _time.elapsedTicks / _time.frequency;
|
||||
|
@ -536,7 +539,7 @@ class Server {
|
|||
/// 'result' field from the response. If the server acknowledges the command
|
||||
/// with an error response, the future will be completed with an error.
|
||||
Future<Map<String, dynamic>> send(
|
||||
String method, Map<String, dynamic> params) {
|
||||
String method, Map<String, dynamic>? params) {
|
||||
var id = '${_nextId++}';
|
||||
var command = <String, dynamic>{'id': id, 'method': method};
|
||||
if (params != null) {
|
||||
|
@ -554,16 +557,13 @@ class Server {
|
|||
/// with "--observe" and "--pause-isolates-on-exit", allowing the observatory
|
||||
/// to be used.
|
||||
Future start({
|
||||
int diagnosticPort,
|
||||
String instrumentationLogFile,
|
||||
int? diagnosticPort,
|
||||
String? instrumentationLogFile,
|
||||
bool profileServer = false,
|
||||
String sdkPath,
|
||||
int servicesPort,
|
||||
String? sdkPath,
|
||||
int? servicesPort,
|
||||
bool useAnalysisHighlight2 = false,
|
||||
}) async {
|
||||
if (_process != null) {
|
||||
throw Exception('Process already started');
|
||||
}
|
||||
_time.start();
|
||||
var dartBinary = Platform.executable;
|
||||
|
||||
|
@ -833,7 +833,7 @@ abstract class _RecursiveMatcher extends Matcher {
|
|||
@override
|
||||
Description describeMismatch(
|
||||
item, Description mismatchDescription, Map matchState, bool verbose) {
|
||||
var mismatches = matchState['mismatches'] as List<MismatchDescriber>;
|
||||
var mismatches = matchState['mismatches'] as List<MismatchDescriber>?;
|
||||
if (mismatches != null) {
|
||||
for (var i = 0; i < mismatches.length; i++) {
|
||||
var mismatch = mismatches[i];
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Matchers for data types defined in the analysis server API.
|
||||
import 'package:test/test.dart';
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:analysis_server/protocol/protocol.dart';
|
||||
|
@ -92,34 +90,34 @@ class RequestErrorTest {
|
|||
|
||||
@reflectiveTest
|
||||
class RequestTest {
|
||||
void test_fromJson() {
|
||||
void test_fromString() {
|
||||
var original = Request('one', 'aMethod');
|
||||
var jsonData = json.encode(original.toJson());
|
||||
var request = Request.fromString(jsonData);
|
||||
var request = Request.fromString(jsonData)!;
|
||||
expect(request.id, equals('one'));
|
||||
expect(request.method, equals('aMethod'));
|
||||
expect(request.clientRequestTime, isNull);
|
||||
}
|
||||
|
||||
void test_fromJson_invalidId() {
|
||||
void test_fromString_invalidId_notString() {
|
||||
var json = '{"id":{"one":"two"},"method":"aMethod","params":{"foo":"bar"}}';
|
||||
var request = Request.fromString(json);
|
||||
expect(request, isNull);
|
||||
}
|
||||
|
||||
void test_fromJson_invalidMethod() {
|
||||
void test_fromString_invalidMethod_notString() {
|
||||
var json = '{"id":"one","method":{"boo":"aMethod"},"params":{"foo":"bar"}}';
|
||||
var request = Request.fromString(json);
|
||||
expect(request, isNull);
|
||||
}
|
||||
|
||||
void test_fromJson_invalidParams() {
|
||||
void test_fromString_invalidParams_notMap() {
|
||||
var json = '{"id":"one","method":"aMethod","params":"foobar"}';
|
||||
var request = Request.fromString(json);
|
||||
expect(request, isNull);
|
||||
}
|
||||
|
||||
void test_fromJson_withBadClientTime() {
|
||||
void test_fromString_withBadClientTime() {
|
||||
var original = Request('one', 'aMethod', null, 347);
|
||||
var map = original.toJson();
|
||||
// Insert bad value - should be int but client sent string instead
|
||||
|
@ -129,19 +127,19 @@ class RequestTest {
|
|||
expect(request, isNull);
|
||||
}
|
||||
|
||||
void test_fromJson_withClientTime() {
|
||||
void test_fromString_withClientTime() {
|
||||
var original = Request('one', 'aMethod', null, 347);
|
||||
var jsonData = json.encode(original.toJson());
|
||||
var request = Request.fromString(jsonData);
|
||||
var request = Request.fromString(jsonData)!;
|
||||
expect(request.id, equals('one'));
|
||||
expect(request.method, equals('aMethod'));
|
||||
expect(request.clientRequestTime, 347);
|
||||
}
|
||||
|
||||
void test_fromJson_withParams() {
|
||||
void test_fromString_withParams() {
|
||||
var original = Request('one', 'aMethod', {'foo': 'bar'});
|
||||
var jsonData = json.encode(original.toJson());
|
||||
var request = Request.fromString(jsonData);
|
||||
var request = Request.fromString(jsonData)!;
|
||||
expect(request.id, equals('one'));
|
||||
expect(request.method, equals('aMethod'));
|
||||
expect(request.toJson()['params'], equals({'foo': 'bar'}));
|
||||
|
@ -199,25 +197,25 @@ class ResponseTest {
|
|||
|
||||
void test_fromJson() {
|
||||
var original = Response('myId');
|
||||
var response = Response.fromJson(original.toJson());
|
||||
var response = Response.fromJson(original.toJson())!;
|
||||
expect(response.id, equals('myId'));
|
||||
}
|
||||
|
||||
void test_fromJson_withError() {
|
||||
var original = Response.invalidRequestFormat();
|
||||
var response = Response.fromJson(original.toJson());
|
||||
var response = Response.fromJson(original.toJson())!;
|
||||
expect(response.id, equals(''));
|
||||
expect(response.error, isNotNull);
|
||||
var error = response.error;
|
||||
var error = response.error!;
|
||||
expect(error.code, equals(RequestErrorCode.INVALID_REQUEST));
|
||||
expect(error.message, equals('Invalid request'));
|
||||
}
|
||||
|
||||
void test_fromJson_withResult() {
|
||||
var original = Response('myId', result: {'foo': 'bar'});
|
||||
var response = Response.fromJson(original.toJson());
|
||||
var response = Response.fromJson(original.toJson())!;
|
||||
expect(response.id, equals('myId'));
|
||||
var result = response.toJson()['result'] as Map<String, Object>;
|
||||
var result = response.toJson()['result'] as Map<String, Object?>;
|
||||
expect(result.length, equals(1));
|
||||
expect(result['foo'], equals('bar'));
|
||||
}
|
||||
|
|
|
@ -246,8 +246,9 @@ void main() {
|
|||
''');
|
||||
var property = await getWidgetProperty('Text(', 'overflow');
|
||||
|
||||
var json = property.toJson().cast<String, dynamic>();
|
||||
expect(
|
||||
property.toJson()['editor']['enumItems'][0]['documentation'],
|
||||
json['editor']['enumItems'][0]['documentation'],
|
||||
startsWith('Clip the overflowing'),
|
||||
);
|
||||
|
||||
|
|
|
@ -42,4 +42,10 @@ class DartCodegenVisitor extends HierarchicalApiVisitor {
|
|||
throw Exception("Can't convert to a dart type");
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the Dart type for [field], nullable if the field is optional.
|
||||
String fieldDartType(TypeObjectField field) {
|
||||
var typeStr = dartType(field.type);
|
||||
return field.optional ? '$typeStr?' : typeStr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,8 +112,6 @@ mixin NotificationHandler {
|
|||
void visitApi() {
|
||||
outputHeader(year: '2018');
|
||||
writeln();
|
||||
writeln('// @dart = 2.9');
|
||||
writeln();
|
||||
emitImports();
|
||||
emitNotificationHandler();
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
/// Emit the toJson() code for an empty class.
|
||||
void emitEmptyToJsonMember() {
|
||||
writeln('@override');
|
||||
writeln('Map<String, dynamic> toJson() => <String, dynamic>{};');
|
||||
writeln('Map<String, Object> toJson() => <String, Object>{};');
|
||||
}
|
||||
|
||||
/// Emit a class to encapsulate an enum.
|
||||
|
@ -358,7 +358,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
void emitEnumFromJsonConstructor(
|
||||
String className, TypeEnum type, ImpliedType impliedType) {
|
||||
writeln(
|
||||
'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
|
||||
'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
|
||||
indent(() {
|
||||
writeln('if (json is String) {');
|
||||
indent(() {
|
||||
|
@ -435,13 +435,6 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
if (emitSpecialStaticMembers(className)) {
|
||||
writeln();
|
||||
}
|
||||
for (var field in type.fields) {
|
||||
if (field.value != null) {
|
||||
continue;
|
||||
}
|
||||
writeln('${dartType(field.type)} _${field.name};');
|
||||
writeln();
|
||||
}
|
||||
for (var field in type.fields) {
|
||||
if (field.value != null) {
|
||||
continue;
|
||||
|
@ -449,19 +442,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.translateHtml(field.html);
|
||||
}));
|
||||
writeln('${dartType(field.type)} get ${field.name} => _${field.name};');
|
||||
writeln();
|
||||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.translateHtml(field.html);
|
||||
}));
|
||||
writeln('set ${field.name}(${dartType(field.type)} value) {');
|
||||
indent(() {
|
||||
if (!field.optional) {
|
||||
writeln('assert(value != null);');
|
||||
}
|
||||
writeln('_${field.name} = value;');
|
||||
});
|
||||
writeln('}');
|
||||
writeln('${fieldDartType(field)} ${field.name};');
|
||||
writeln();
|
||||
}
|
||||
emitObjectConstructor(type, className);
|
||||
|
@ -505,61 +486,39 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
void emitObjectConstructor(TypeObject type, String className) {
|
||||
var args = <String>[];
|
||||
var optionalArgs = <String>[];
|
||||
var extraInitCode = <CodegenCallback>[];
|
||||
var initializers = <String>[];
|
||||
for (var field in type.fields) {
|
||||
if (field.value != null) {
|
||||
continue;
|
||||
}
|
||||
var arg = '${dartType(field.type)} ${field.name}';
|
||||
var setValueFromArg = 'this.${field.name} = ${field.name};';
|
||||
if (isOptionalConstructorArg(className, field)) {
|
||||
optionalArgs.add(arg);
|
||||
if (!field.optional) {
|
||||
// Optional constructor arg, but non-optional field. If no arg is
|
||||
optionalArgs.add('${dartType(field.type)}? ${field.name}');
|
||||
// Optional constructor arg, but non-optional field. If no arg is
|
||||
// given, the constructor should populate with the empty list.
|
||||
var fieldType = field.type;
|
||||
if (fieldType is TypeList) {
|
||||
extraInitCode.add(() {
|
||||
writeln('if (${field.name} == null) {');
|
||||
indent(() {
|
||||
writeln(
|
||||
'this.${field.name} = <${dartType(fieldType.itemType)}>[];');
|
||||
});
|
||||
writeln('} else {');
|
||||
indent(() {
|
||||
writeln(setValueFromArg);
|
||||
});
|
||||
writeln('}');
|
||||
});
|
||||
var defaultValue = '<${dartType(fieldType.itemType)}>[]';
|
||||
initializers.add('${field.name} = ${field.name} ?? $defaultValue');
|
||||
} else {
|
||||
throw Exception("Don't know how to create default field value.");
|
||||
}
|
||||
} else {
|
||||
extraInitCode.add(() {
|
||||
writeln(setValueFromArg);
|
||||
});
|
||||
optionalArgs.add('this.${field.name}');
|
||||
}
|
||||
} else {
|
||||
args.add(arg);
|
||||
extraInitCode.add(() {
|
||||
writeln(setValueFromArg);
|
||||
});
|
||||
args.add('this.${field.name}');
|
||||
}
|
||||
}
|
||||
if (optionalArgs.isNotEmpty) {
|
||||
args.add('{${optionalArgs.join(', ')}}');
|
||||
}
|
||||
write('$className(${args.join(', ')})');
|
||||
if (extraInitCode.isEmpty) {
|
||||
if (initializers.isEmpty) {
|
||||
writeln(';');
|
||||
} else {
|
||||
writeln(' {');
|
||||
indent(() {
|
||||
for (var callback in extraInitCode) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
writeln('}');
|
||||
writeln(' : ${initializers.join(', ')}');
|
||||
writeln(';');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,8 +557,8 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
String className, TypeObject type, ImpliedType impliedType) {
|
||||
var humanReadableNameString = literalString(impliedType.humanReadableName);
|
||||
if (className == 'RefactoringFeedback') {
|
||||
writeln('factory RefactoringFeedback.fromJson(JsonDecoder jsonDecoder, '
|
||||
'String jsonPath, Object json, Map responseJson) {');
|
||||
writeln('static RefactoringFeedback? fromJson(JsonDecoder jsonDecoder, '
|
||||
'String jsonPath, Object? json, Map responseJson) {');
|
||||
indent(() {
|
||||
writeln('return refactoringFeedbackFromJson(jsonDecoder, jsonPath, '
|
||||
'json, responseJson);');
|
||||
|
@ -608,8 +567,8 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
return;
|
||||
}
|
||||
if (className == 'RefactoringOptions') {
|
||||
writeln('factory RefactoringOptions.fromJson(JsonDecoder jsonDecoder, '
|
||||
'String jsonPath, Object json, RefactoringKind kind) {');
|
||||
writeln('static RefactoringOptions? fromJson(JsonDecoder jsonDecoder, '
|
||||
'String jsonPath, Object? json, RefactoringKind kind) {');
|
||||
indent(() {
|
||||
writeln('return refactoringOptionsFromJson(jsonDecoder, jsonPath, '
|
||||
'json, kind);');
|
||||
|
@ -618,7 +577,7 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
return;
|
||||
}
|
||||
writeln(
|
||||
'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {');
|
||||
'factory $className.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object? json) {');
|
||||
indent(() {
|
||||
writeln('json ??= {};');
|
||||
writeln('if (json is Map) {');
|
||||
|
@ -629,12 +588,13 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
var fieldNameString = literalString(field.name);
|
||||
var fieldAccessor = 'json[$fieldNameString]';
|
||||
var jsonPath = 'jsonPath + ${literalString('.${field.name}')}';
|
||||
if (field.value != null) {
|
||||
var valueString = literalString(field.value);
|
||||
var fieldValue = field.value;
|
||||
if (fieldValue is String) {
|
||||
var valueString = literalString(fieldValue);
|
||||
writeln('if ($fieldAccessor != $valueString) {');
|
||||
indent(() {
|
||||
writeln(
|
||||
"throw jsonDecoder.mismatch(jsonPath, 'equal ${field.value}', json);");
|
||||
"throw jsonDecoder.mismatch(jsonPath, 'equal $fieldValue', json);");
|
||||
});
|
||||
writeln('}');
|
||||
continue;
|
||||
|
@ -644,11 +604,11 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
} else {
|
||||
args.add(field.name);
|
||||
}
|
||||
var fieldType = field.type;
|
||||
var fieldDartType = dartType(fieldType);
|
||||
writeln('$fieldDartType ${field.name};');
|
||||
var typeStr = fieldDartType(field);
|
||||
writeln('$typeStr ${field.name};');
|
||||
writeln('if (json.containsKey($fieldNameString)) {');
|
||||
indent(() {
|
||||
var fieldType = field.type;
|
||||
var fromJson =
|
||||
fromJsonCode(fieldType).asSnippet(jsonPath, fieldAccessor);
|
||||
writeln('${field.name} = $fromJson;');
|
||||
|
@ -852,19 +812,23 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
/// Emit the toJson() code for an object class.
|
||||
void emitToJsonMember(TypeObject type) {
|
||||
writeln('@override');
|
||||
writeln('Map<String, dynamic> toJson() {');
|
||||
writeln('Map<String, Object> toJson() {');
|
||||
indent(() {
|
||||
writeln('var result = <String, dynamic>{};');
|
||||
writeln('var result = <String, Object>{};');
|
||||
for (var field in type.fields) {
|
||||
var fieldNameString = literalString(field.name);
|
||||
if (field.value != null) {
|
||||
writeln('result[$fieldNameString] = ${literalString(field.value)};');
|
||||
var fieldValue = field.value;
|
||||
if (fieldValue is String) {
|
||||
var valueString = literalString(fieldValue);
|
||||
writeln('result[$fieldNameString] = $valueString;');
|
||||
continue;
|
||||
}
|
||||
var fieldToJson = toJsonCode(field.type).asSnippet(field.name);
|
||||
var populateField = 'result[$fieldNameString] = $fieldToJson;';
|
||||
if (field.optional) {
|
||||
writeln('if (${field.name} != null) {');
|
||||
var name = field.name;
|
||||
writeln('var $name = this.$name;');
|
||||
writeln('if ($name != null) {');
|
||||
indent(() {
|
||||
writeln(populateField);
|
||||
});
|
||||
|
@ -1122,8 +1086,6 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
void visitApi() {
|
||||
outputHeader(year: '2017');
|
||||
writeln();
|
||||
writeln('// @dart = 2.9');
|
||||
writeln();
|
||||
emitImports();
|
||||
emitClasses(getClassesToEmit());
|
||||
}
|
||||
|
@ -1177,7 +1139,7 @@ class FromJsonSnippet extends FromJsonCode {
|
|||
|
||||
@override
|
||||
String get asClosure =>
|
||||
'(String jsonPath, Object json) => ${callback('jsonPath', 'json')}';
|
||||
'(String jsonPath, Object? json) => ${callback('jsonPath', 'json')}';
|
||||
|
||||
@override
|
||||
bool get isIdentity => false;
|
||||
|
|
|
@ -49,7 +49,7 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
|||
|
||||
/// Generate a function argument for the given parameter field.
|
||||
String formatArgument(TypeObjectField field) =>
|
||||
'${dartType(field.type)} ${field.name}';
|
||||
'${fieldDartType(field)} ${field.name}';
|
||||
|
||||
/// Figure out the appropriate Dart type for data having the given API
|
||||
/// protocol [type].
|
||||
|
@ -86,8 +86,6 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
|||
void visitApi() {
|
||||
outputHeader(year: '2017');
|
||||
writeln();
|
||||
writeln('// @dart = 2.9');
|
||||
writeln();
|
||||
writeln('/// Convenience methods for running integration tests.');
|
||||
writeln("import 'dart:async';");
|
||||
writeln();
|
||||
|
@ -134,7 +132,6 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
|||
writeln('default:');
|
||||
indent(() {
|
||||
writeln("fail('Unexpected notification: \$event');");
|
||||
writeln('break;');
|
||||
});
|
||||
});
|
||||
writeln('}');
|
||||
|
@ -156,12 +153,12 @@ class CodegenInttestMethodsVisitor extends DartCodegenVisitor
|
|||
toHtmlVisitor.translateHtml(notification.html);
|
||||
toHtmlVisitor.describePayload(notification.params, 'Parameters');
|
||||
}));
|
||||
writeln('Stream<$className> $streamName;');
|
||||
writeln('late Stream<$className> $streamName;');
|
||||
writeln();
|
||||
docComment(toHtmlVisitor.collectHtml(() {
|
||||
toHtmlVisitor.write('Stream controller for [$streamName].');
|
||||
}));
|
||||
writeln('StreamController<$className> _$streamName;');
|
||||
writeln('late StreamController<$className> _$streamName;');
|
||||
fieldInitializationCode.add(collectCode(() {
|
||||
writeln('_$streamName = StreamController<$className>(sync: true);');
|
||||
writeln('$streamName = _$streamName.stream.asBroadcastStream();');
|
||||
|
|
|
@ -91,8 +91,6 @@ class CodegenMatchersVisitor extends HierarchicalApiVisitor with CodeGenerator {
|
|||
void visitApi() {
|
||||
outputHeader(year: '2017');
|
||||
writeln();
|
||||
writeln('// @dart = 2.9');
|
||||
writeln();
|
||||
writeln('/// Matchers for data types defined in the analysis server API.');
|
||||
writeln("import 'package:test/test.dart';");
|
||||
writeln();
|
||||
|
|
|
@ -90,8 +90,6 @@ class CodegenVisitor extends DartCodegenVisitor with CodeGenerator {
|
|||
void visitApi() {
|
||||
outputHeader(year: '2017');
|
||||
writeln();
|
||||
writeln('// @dart = 2.9');
|
||||
writeln();
|
||||
generateConstants();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'package:analysis_server_client/protocol.dart';
|
||||
|
||||
/// [NotificationHandler] processes analysis server notifications
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
export 'package:analysis_server_client/src/protocol/protocol_base.dart';
|
||||
export 'package:analysis_server_client/src/protocol/protocol_common.dart';
|
||||
export 'package:analysis_server_client/src/protocol/protocol_constants.dart';
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Support for client code that needs to interact with the requests, responses
|
||||
/// and notifications that are part of the analysis server's wire protocol.
|
||||
import 'dart:convert' hide JsonDecoder;
|
||||
|
@ -36,7 +34,7 @@ class Notification {
|
|||
|
||||
/// A table mapping the names of notification parameters to their values, or
|
||||
/// `null` if there are no notification parameters.
|
||||
final Map<String, Object> params;
|
||||
final Map<String, Object>? params;
|
||||
|
||||
/// Initialize a newly created [Notification] to have the given [event] name.
|
||||
/// If [params] is provided, it will be used as the params; otherwise no
|
||||
|
@ -54,6 +52,7 @@ class Notification {
|
|||
Map<String, Object> toJson() {
|
||||
var jsonObject = <String, Object>{};
|
||||
jsonObject[EVENT] = event;
|
||||
var params = this.params;
|
||||
if (params != null) {
|
||||
jsonObject[PARAMS] = params;
|
||||
}
|
||||
|
@ -85,84 +84,18 @@ class Request {
|
|||
final String method;
|
||||
|
||||
/// A table mapping the names of request parameters to their values.
|
||||
final Map<String, Object> params;
|
||||
final Map<String, Object?> params;
|
||||
|
||||
/// The time (milliseconds since epoch) at which the client made the request
|
||||
/// or `null` if this information is not provided by the client.
|
||||
final int clientRequestTime;
|
||||
final int? clientRequestTime;
|
||||
|
||||
/// Initialize a newly created [Request] to have the given [id] and [method]
|
||||
/// name. If [params] is supplied, it is used as the "params" map for the
|
||||
/// request. Otherwise an empty "params" map is allocated.
|
||||
Request(this.id, this.method,
|
||||
[Map<String, Object> params, this.clientRequestTime])
|
||||
: params = params ?? <String, Object>{};
|
||||
|
||||
/// Return a request parsed from the given json, or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
factory Request.fromJson(Map<String, Object> result) {
|
||||
var id = result[Request.ID];
|
||||
var method = result[Request.METHOD];
|
||||
if (id is! String || method is! String) {
|
||||
return null;
|
||||
}
|
||||
var time = result[Request.CLIENT_REQUEST_TIME];
|
||||
if (time != null && time is! int) {
|
||||
return null;
|
||||
}
|
||||
var params = result[Request.PARAMS];
|
||||
if (params is Map || params == null) {
|
||||
return Request(id, method, params as Map<String, Object>, time);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given [data], or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
factory Request.fromString(String data) {
|
||||
try {
|
||||
var result = json.decode(data);
|
||||
if (result is Map) {
|
||||
return Request.fromJson(result as Map<String, dynamic>);
|
||||
}
|
||||
return null;
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
[Map<String, Object?>? params, this.clientRequestTime])
|
||||
: params = params ?? <String, Object?>{};
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
|
@ -187,13 +120,14 @@ class Request {
|
|||
if (params.isNotEmpty) {
|
||||
jsonObject[PARAMS] = params;
|
||||
}
|
||||
var clientRequestTime = this.clientRequestTime;
|
||||
if (clientRequestTime != null) {
|
||||
jsonObject[CLIENT_REQUEST_TIME] = clientRequestTime;
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
bool _equalLists(List first, List second) {
|
||||
bool _equalLists(List? first, List? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -212,7 +146,7 @@ class Request {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool _equalMaps(Map first, Map second) {
|
||||
bool _equalMaps(Map? first, Map? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -233,7 +167,7 @@ class Request {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool _equalObjects(Object first, Object second) {
|
||||
bool _equalObjects(Object? first, Object? second) {
|
||||
if (first == null) {
|
||||
return second == null;
|
||||
}
|
||||
|
@ -254,6 +188,72 @@ class Request {
|
|||
}
|
||||
return first == second;
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given json, or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
static Request? fromJson(Map<String, Object?> result) {
|
||||
var id = result[Request.ID];
|
||||
var method = result[Request.METHOD];
|
||||
if (id is! String || method is! String) {
|
||||
return null;
|
||||
}
|
||||
var time = result[Request.CLIENT_REQUEST_TIME];
|
||||
if (time is! int?) {
|
||||
return null;
|
||||
}
|
||||
var params = result[Request.PARAMS];
|
||||
if (params is Map<String, Object?>?) {
|
||||
return Request(id, method, params, time);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a request parsed from the given [data], or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
/// have the following format:
|
||||
///
|
||||
/// {
|
||||
/// 'clientRequestTime': millisecondsSinceEpoch
|
||||
/// 'id': String,
|
||||
/// 'method': methodName,
|
||||
/// 'params': {
|
||||
/// paramter_name: value
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// where both the parameters and clientRequestTime are optional.
|
||||
///
|
||||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
static Request? fromString(String data) {
|
||||
try {
|
||||
var result = json.decode(data);
|
||||
if (result is Map<String, Object?>) {
|
||||
return Request.fromJson(result);
|
||||
}
|
||||
return null;
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An exception that occurred during the handling of a request that requires
|
||||
|
@ -303,17 +303,17 @@ class Response {
|
|||
|
||||
/// The error that was caused by attempting to handle the request, or `null` if
|
||||
/// there was no error.
|
||||
final RequestError error;
|
||||
final RequestError? error;
|
||||
|
||||
/// A table mapping the names of result fields to their values. Should be
|
||||
/// `null` if there is no result to send.
|
||||
Map<String, Object> result;
|
||||
Map<String, Object?>? result;
|
||||
|
||||
/// Initialize a newly created instance to represent a response to a request
|
||||
/// with the given [id]. If [_result] is provided, it will be used as the
|
||||
/// with the given [id]. If [result] is provided, it will be used as the
|
||||
/// result; otherwise an empty result will be used. If an [error] is provided
|
||||
/// then the response will represent an error condition.
|
||||
Response(this.id, {Map<String, Object> result, this.error}) : result = result;
|
||||
Response(this.id, {this.result, this.error});
|
||||
|
||||
/// Create and return the `DEBUG_PORT_COULD_NOT_BE_OPENED` error response.
|
||||
Response.debugPortCouldNotBeOpened(Request request, dynamic error)
|
||||
|
@ -342,30 +342,6 @@ class Response {
|
|||
error: RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
|
||||
'Error during `edit.format`: source contains syntax errors.'));
|
||||
|
||||
/// Initialize a newly created instance based on the given JSON data.
|
||||
factory Response.fromJson(Map json) {
|
||||
try {
|
||||
Object id = json[Response.ID];
|
||||
if (id is! String) {
|
||||
return null;
|
||||
}
|
||||
Object error = json[Response.ERROR];
|
||||
RequestError decodedError;
|
||||
if (error is Map) {
|
||||
decodedError =
|
||||
RequestError.fromJson(ResponseDecoder(null), '.error', error);
|
||||
}
|
||||
Object result = json[Response.RESULT];
|
||||
Map<String, Object> decodedResult;
|
||||
if (result is Map) {
|
||||
decodedResult = result as Map<String, Object>;
|
||||
}
|
||||
return Response(id, error: decodedError, result: decodedResult);
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize a newly created instance to represent the
|
||||
/// GET_ERRORS_INVALID_FILE error condition.
|
||||
Response.getErrorsInvalidFile(Request request)
|
||||
|
@ -528,12 +504,41 @@ class Response {
|
|||
Map<String, Object> toJson() {
|
||||
var jsonObject = <String, Object>{};
|
||||
jsonObject[ID] = id;
|
||||
var error = this.error;
|
||||
if (error != null) {
|
||||
jsonObject[ERROR] = error.toJson();
|
||||
}
|
||||
var result = this.result;
|
||||
if (result != null) {
|
||||
jsonObject[RESULT] = result;
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/// Initialize a newly created instance based on the given JSON data.
|
||||
static Response? fromJson(Map<String, Object?> json) {
|
||||
try {
|
||||
var id = json[Response.ID];
|
||||
if (id is! String) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RequestError? decodedError;
|
||||
var error = json[Response.ERROR];
|
||||
if (error is Map) {
|
||||
decodedError =
|
||||
RequestError.fromJson(ResponseDecoder(null), '.error', error);
|
||||
}
|
||||
|
||||
Map<String, Object?>? decodedResult;
|
||||
var result = json[Response.RESULT];
|
||||
if (result is Map<String, Object?>) {
|
||||
decodedResult = result;
|
||||
}
|
||||
|
||||
return Response(id, error: decodedError, result: decodedResult);
|
||||
} catch (exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,8 +6,6 @@
|
|||
// To regenerate the file, use the script
|
||||
// "pkg/analysis_server/tool/spec/generate_files".
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
const String PROTOCOL_VERSION = '1.32.5';
|
||||
|
||||
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
import 'dart:collection';
|
||||
import 'dart:convert' hide JsonDecoder;
|
||||
|
||||
|
@ -61,7 +59,7 @@ String applySequenceOfEdits(String code, Iterable<SourceEdit> edits) {
|
|||
}
|
||||
|
||||
/// Returns the [FileEdit] for the given [file], maybe `null`.
|
||||
SourceFileEdit getChangeFileEdit(SourceChange change, String file) {
|
||||
SourceFileEdit? getChangeFileEdit(SourceChange change, String file) {
|
||||
for (var fileEdit in change.edits) {
|
||||
if (fileEdit.file == file) {
|
||||
return fileEdit;
|
||||
|
@ -72,8 +70,8 @@ SourceFileEdit getChangeFileEdit(SourceChange change, String file) {
|
|||
|
||||
/// Compare the lists [listA] and [listB], using [itemEqual] to compare
|
||||
/// list elements.
|
||||
bool listEqual<T1, T2>(
|
||||
List<T1> listA, List<T2> listB, bool Function(T1 a, T2 b) itemEqual) {
|
||||
bool listEqual<T>(
|
||||
List<T>? listA, List<T>? listB, bool Function(T a, T b) itemEqual) {
|
||||
if (listA == null) {
|
||||
return listB == null;
|
||||
}
|
||||
|
@ -94,7 +92,7 @@ bool listEqual<T1, T2>(
|
|||
/// Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
|
||||
/// values.
|
||||
bool mapEqual<K, V>(
|
||||
Map<K, V> mapA, Map<K, V> mapB, bool Function(V a, V b) valueEqual) {
|
||||
Map<K, V>? mapA, Map<K, V>? mapB, bool Function(V a, V b) valueEqual) {
|
||||
if (mapA == null) {
|
||||
return mapB == null;
|
||||
}
|
||||
|
@ -104,11 +102,11 @@ bool mapEqual<K, V>(
|
|||
if (mapA.length != mapB.length) {
|
||||
return false;
|
||||
}
|
||||
for (var key in mapA.keys) {
|
||||
if (!mapB.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
if (!valueEqual(mapA[key], mapB[key])) {
|
||||
for (var entryA in mapA.entries) {
|
||||
var key = entryA.key;
|
||||
var valueA = entryA.value;
|
||||
var valueB = mapB[key];
|
||||
if (valueB == null || !valueEqual(valueA, valueB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +116,7 @@ bool mapEqual<K, V>(
|
|||
/// Translate the input [map], applying [keyCallback] to all its keys, and
|
||||
/// [valueCallback] to all its values.
|
||||
Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
|
||||
{KR Function(KP key) keyCallback, VR Function(VP value) valueCallback}) {
|
||||
{KR Function(KP key)? keyCallback, VR Function(VP value)? valueCallback}) {
|
||||
Map<KR, VR> result = HashMap<KR, VR>();
|
||||
map.forEach((key, value) {
|
||||
KR resultKey;
|
||||
|
@ -138,8 +136,8 @@ Map<KR, VR> mapMap<KP, VP, KR, VR>(Map<KP, VP> map,
|
|||
return result;
|
||||
}
|
||||
|
||||
RefactoringProblemSeverity maxRefactoringProblemSeverity(
|
||||
RefactoringProblemSeverity a, RefactoringProblemSeverity b) {
|
||||
RefactoringProblemSeverity? maxRefactoringProblemSeverity(
|
||||
RefactoringProblemSeverity? a, RefactoringProblemSeverity? b) {
|
||||
if (b == null) {
|
||||
return a;
|
||||
}
|
||||
|
@ -161,8 +159,8 @@ RefactoringProblemSeverity maxRefactoringProblemSeverity(
|
|||
}
|
||||
|
||||
/// Create a [RefactoringFeedback] corresponding the given [kind].
|
||||
RefactoringFeedback refactoringFeedbackFromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object json, Map feedbackJson) {
|
||||
RefactoringFeedback? refactoringFeedbackFromJson(
|
||||
JsonDecoder jsonDecoder, String jsonPath, Object? json, Map feedbackJson) {
|
||||
var kind = jsonDecoder.refactoringKind;
|
||||
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
|
||||
return ExtractLocalVariableFeedback.fromJson(jsonDecoder, jsonPath, json);
|
||||
|
@ -186,8 +184,8 @@ RefactoringFeedback refactoringFeedbackFromJson(
|
|||
}
|
||||
|
||||
/// Create a [RefactoringOptions] corresponding the given [kind].
|
||||
RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
||||
String jsonPath, Object json, RefactoringKind kind) {
|
||||
RefactoringOptions? refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
||||
String jsonPath, Object? json, RefactoringKind kind) {
|
||||
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
|
||||
return ExtractLocalVariableOptions.fromJson(jsonDecoder, jsonPath, json);
|
||||
}
|
||||
|
@ -212,7 +210,8 @@ RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
|||
/// Type of callbacks used to decode parts of JSON objects. [jsonPath] is a
|
||||
/// string describing the part of the JSON object being decoded, and [value] is
|
||||
/// the part to decode.
|
||||
typedef JsonDecoderCallback<E> = E Function(String jsonPath, Object value);
|
||||
typedef JsonDecoderCallback<E extends Object> = E Function(
|
||||
String jsonPath, Object? value);
|
||||
|
||||
/// Instances of the class [HasToJson] implement [toJson] method that returns
|
||||
/// a JSON presentation.
|
||||
|
@ -227,7 +226,7 @@ abstract class JsonDecoder {
|
|||
/// Retrieve the RefactoringKind that should be assumed when decoding
|
||||
/// refactoring feedback objects, or null if no refactoring feedback object is
|
||||
/// expected to be encountered.
|
||||
RefactoringKind get refactoringKind;
|
||||
RefactoringKind? get refactoringKind;
|
||||
|
||||
/// Decode a JSON object that is expected to be a boolean. The strings "true"
|
||||
/// and "false" are also accepted.
|
||||
|
@ -261,7 +260,7 @@ abstract class JsonDecoder {
|
|||
|
||||
/// Decode a JSON object that is expected to be an integer. A string
|
||||
/// representation of an integer is also accepted.
|
||||
int decodeInt(String jsonPath, Object json) {
|
||||
int decodeInt(String jsonPath, Object? json) {
|
||||
if (json is int) {
|
||||
return json;
|
||||
} else if (json is String) {
|
||||
|
@ -278,8 +277,8 @@ abstract class JsonDecoder {
|
|||
/// to decode the items in the list.
|
||||
///
|
||||
/// The type parameter [E] is the expected type of the elements in the list.
|
||||
List<E> decodeList<E>(String jsonPath, Object json,
|
||||
[JsonDecoderCallback<E> decoder]) {
|
||||
List<E> decodeList<E extends Object>(
|
||||
String jsonPath, Object? json, JsonDecoderCallback<E> decoder) {
|
||||
if (json == null) {
|
||||
return <E>[];
|
||||
} else if (json is List) {
|
||||
|
@ -295,9 +294,10 @@ abstract class JsonDecoder {
|
|||
|
||||
/// Decode a JSON object that is expected to be a Map. [keyDecoder] is used
|
||||
/// to decode the keys, and [valueDecoder] is used to decode the values.
|
||||
Map<K, V> decodeMap<K, V>(String jsonPath, Object jsonData,
|
||||
{JsonDecoderCallback<K> keyDecoder,
|
||||
JsonDecoderCallback<V> valueDecoder}) {
|
||||
Map<K, V> decodeMap<K extends Object, V extends Object>(
|
||||
String jsonPath, Object? jsonData,
|
||||
{JsonDecoderCallback<K>? keyDecoder,
|
||||
JsonDecoderCallback<V>? valueDecoder}) {
|
||||
if (jsonData == null) {
|
||||
return {};
|
||||
} else if (jsonData is Map) {
|
||||
|
@ -321,7 +321,7 @@ abstract class JsonDecoder {
|
|||
}
|
||||
|
||||
/// Decode a JSON object that is expected to be a string.
|
||||
String decodeString(String jsonPath, Object json) {
|
||||
String decodeString(String jsonPath, Object? json) {
|
||||
if (json is String) {
|
||||
return json;
|
||||
} else {
|
||||
|
@ -333,7 +333,7 @@ abstract class JsonDecoder {
|
|||
/// where the choices are disambiguated by the contents of the field [field].
|
||||
/// [decoders] is a map from each possible string in the field to the decoder
|
||||
/// that should be used to decode the JSON object.
|
||||
Object decodeUnion(String jsonPath, Map jsonData, String field,
|
||||
Object decodeUnion(String jsonPath, Object? jsonData, String field,
|
||||
Map<String, JsonDecoderCallback> decoders) {
|
||||
if (jsonData is Map) {
|
||||
if (!jsonData.containsKey(field)) {
|
||||
|
@ -341,11 +341,12 @@ abstract class JsonDecoder {
|
|||
}
|
||||
var disambiguatorPath = '$jsonPath[${json.encode(field)}]';
|
||||
var disambiguator = decodeString(disambiguatorPath, jsonData[field]);
|
||||
if (!decoders.containsKey(disambiguator)) {
|
||||
var decoder = decoders[disambiguator];
|
||||
if (decoder == null) {
|
||||
throw mismatch(
|
||||
disambiguatorPath, 'One of: ${decoders.keys.toList()}', jsonData);
|
||||
}
|
||||
return decoders[disambiguator](jsonPath, jsonData);
|
||||
return decoder(jsonPath, jsonData);
|
||||
} else {
|
||||
throw mismatch(jsonPath, 'Map', jsonData);
|
||||
}
|
||||
|
@ -353,7 +354,7 @@ abstract class JsonDecoder {
|
|||
|
||||
/// Create an exception to throw if the JSON object at [jsonPath] fails to
|
||||
/// match the API definition of [expected].
|
||||
dynamic mismatch(String jsonPath, String expected, [Object actual]);
|
||||
dynamic mismatch(String jsonPath, String expected, [Object? actual]);
|
||||
|
||||
/// Create an exception to throw if the JSON object at [jsonPath] is missing
|
||||
/// the key [key].
|
||||
|
@ -369,13 +370,13 @@ class RequestDecoder extends JsonDecoder {
|
|||
RequestDecoder(this._request);
|
||||
|
||||
@override
|
||||
RefactoringKind get refactoringKind {
|
||||
RefactoringKind? get refactoringKind {
|
||||
// Refactoring feedback objects should never appear in requests.
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic mismatch(String jsonPath, String expected, [Object actual]) {
|
||||
dynamic mismatch(String jsonPath, String expected, [Object? actual]) {
|
||||
var buffer = StringBuffer();
|
||||
buffer.write('Expected to be ');
|
||||
buffer.write(expected);
|
||||
|
@ -405,12 +406,12 @@ abstract class RequestParams implements HasToJson {
|
|||
/// used only for testing. Errors are reported using bare [Exception] objects.
|
||||
class ResponseDecoder extends JsonDecoder {
|
||||
@override
|
||||
final RefactoringKind refactoringKind;
|
||||
final RefactoringKind? refactoringKind;
|
||||
|
||||
ResponseDecoder(this.refactoringKind);
|
||||
|
||||
@override
|
||||
dynamic mismatch(String jsonPath, String expected, [Object actual]) {
|
||||
dynamic mismatch(String jsonPath, String expected, [Object? actual]) {
|
||||
var buffer = StringBuffer();
|
||||
buffer.write('Expected ');
|
||||
buffer.write(expected);
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
/// Jenkins hash function, optimized for small integers.
|
||||
///
|
||||
/// Static methods borrowed from sdk/lib/math/jenkins_smi_hash.dart. Non-static
|
||||
|
|
|
@ -80,7 +80,7 @@ class Request {
|
|||
final String method;
|
||||
|
||||
/// A table mapping the names of request parameters to their values.
|
||||
final Map<String, Object> params;
|
||||
final Map<String, Object?> params;
|
||||
|
||||
/// The time (milliseconds since epoch) at which the server made the request,
|
||||
/// or `null` if this information is not provided by the server.
|
||||
|
@ -90,8 +90,8 @@ class Request {
|
|||
/// name. If [params] is supplied, it is used as the "params" map for the
|
||||
/// request. Otherwise an empty "params" map is allocated.
|
||||
Request(this.id, this.method,
|
||||
[Map<String, Object>? params, this.serverRequestTime])
|
||||
: params = params ?? <String, Object>{};
|
||||
[Map<String, Object?>? params, this.serverRequestTime])
|
||||
: params = params ?? <String, Object?>{};
|
||||
|
||||
/// Return a request parsed from the given json, or `null` if the [data] is
|
||||
/// not a valid json representation of a request. The [data] is expected to
|
||||
|
@ -111,19 +111,19 @@ class Request {
|
|||
/// The parameters can contain any number of name/value pairs. The
|
||||
/// clientRequestTime must be an int representing the time at which the client
|
||||
/// issued the request (milliseconds since epoch).
|
||||
factory Request.fromJson(Map<String, Object> result) {
|
||||
factory Request.fromJson(Map<String, Object?> result) {
|
||||
var id = result[Request.ID];
|
||||
var method = result[Request.METHOD];
|
||||
if (id is! String || method is! String) {
|
||||
throw StateError('Unexpected type for id or method');
|
||||
}
|
||||
var time = result[Request.SERVER_REQUEST_TIME];
|
||||
if (time != null && time is! int) {
|
||||
if (time is! int?) {
|
||||
throw StateError('Unexpected type for server request time');
|
||||
}
|
||||
var params = result[Request.PARAMS];
|
||||
if (params is Map || params == null) {
|
||||
return Request(id, method, params as Map<String, Object>?, time as int?);
|
||||
if (params is Map<String, Object?>?) {
|
||||
return Request(id, method, params, time);
|
||||
} else {
|
||||
throw StateError('Unexpected type for params');
|
||||
}
|
||||
|
@ -304,36 +304,39 @@ class Response {
|
|||
|
||||
/// A table mapping the names of result fields to their values. Should be
|
||||
/// `null` if there is no result to send.
|
||||
Map<String, Object>? result;
|
||||
Map<String, Object?>? result;
|
||||
|
||||
/// Initialize a newly created instance to represent a response to a request
|
||||
/// with the given [id]. If [_result] is provided, it will be used as the
|
||||
/// with the given [id]. If [result] is provided, it will be used as the
|
||||
/// result; otherwise an empty result will be used. If an [error] is provided
|
||||
/// then the response will represent an error condition.
|
||||
Response(this.id, this.requestTime, {this.error, Map<String, Object>? result})
|
||||
: result = result;
|
||||
Response(this.id, this.requestTime, {this.error, this.result});
|
||||
|
||||
/// Initialize a newly created instance based on the given JSON data.
|
||||
factory Response.fromJson(Map json) {
|
||||
factory Response.fromJson(Map<String, Object?> json) {
|
||||
var id = json[ID];
|
||||
if (id is! String) {
|
||||
throw StateError('Unexpected type for id');
|
||||
}
|
||||
var error = json[ERROR];
|
||||
|
||||
RequestError? decodedError;
|
||||
var error = json[ERROR];
|
||||
if (error is Map) {
|
||||
decodedError =
|
||||
RequestError.fromJson(ResponseDecoder(null), '.error', error);
|
||||
}
|
||||
|
||||
var requestTime = json[REQUEST_TIME];
|
||||
if (requestTime is! int) {
|
||||
throw StateError('Unexpected type for requestTime');
|
||||
}
|
||||
var result = json[RESULT];
|
||||
Map<String, Object>? decodedResult;
|
||||
if (result is Map) {
|
||||
decodedResult = result as Map<String, Object>;
|
||||
|
||||
Map<String, Object?>? decodedResult;
|
||||
var result = json[Response.RESULT];
|
||||
if (result is Map<String, Object?>) {
|
||||
decodedResult = result;
|
||||
}
|
||||
|
||||
return Response(id, requestTime,
|
||||
error: decodedError, result: decodedResult);
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ abstract class ServerIsolateChannel implements ServerCommunicationChannel {
|
|||
if (input is SendPort) {
|
||||
_sendPort = input;
|
||||
channelReady.complete(null);
|
||||
} else if (input is Map) {
|
||||
} else if (input is Map<String, Object?>) {
|
||||
if (input.containsKey('id')) {
|
||||
var encodedInput = json.encode(input);
|
||||
instrumentationService.logPluginResponse(pluginId, encodedInput);
|
||||
|
|
|
@ -136,11 +136,11 @@ bool mapEqual<K, V>(
|
|||
if (mapA.length != mapB.length) {
|
||||
return false;
|
||||
}
|
||||
for (var key in mapA.keys) {
|
||||
if (!mapB.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
if (!valueEqual(mapA[key]!, mapB[key]!)) {
|
||||
for (var entryA in mapA.entries) {
|
||||
var key = entryA.key;
|
||||
var valueA = entryA.value;
|
||||
var valueB = mapB[key];
|
||||
if (valueB == null || !valueEqual(valueA, valueB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ RefactoringOptions refactoringOptionsFromJson(JsonDecoder jsonDecoder,
|
|||
/// string describing the part of the JSON object being decoded, and [value] is
|
||||
/// the part to decode.
|
||||
typedef JsonDecoderCallback<E extends Object> = E Function(
|
||||
String jsonPath, dynamic value);
|
||||
String jsonPath, Object? value);
|
||||
|
||||
/// Instances of the class [HasToJson] implement [toJson] method that returns
|
||||
/// a JSON presentation.
|
||||
|
@ -361,7 +361,7 @@ abstract class JsonDecoder {
|
|||
/// where the choices are disambiguated by the contents of the field [field].
|
||||
/// [decoders] is a map from each possible string in the field to the decoder
|
||||
/// that should be used to decode the JSON object.
|
||||
Object decodeUnion(String jsonPath, Map jsonData, String field,
|
||||
Object decodeUnion(String jsonPath, Object? jsonData, String field,
|
||||
Map<String, JsonDecoderCallback> decoders) {
|
||||
if (jsonData is Map) {
|
||||
if (!jsonData.containsKey(field)) {
|
||||
|
|
|
@ -28,9 +28,7 @@ List<GeneratedContent> get allTargets {
|
|||
targets.add(codegen_inttest_methods.target);
|
||||
targets.add(codegen_matchers.target);
|
||||
targets.add(codegen_protocol_common.pluginTarget(true));
|
||||
// TODO(scheglov) Migrate analysis_server_client
|
||||
// https://github.com/dart-lang/sdk/issues/45500
|
||||
// targets.add(codegen_protocol_common.clientTarget(true));
|
||||
targets.add(codegen_protocol_common.clientTarget(true));
|
||||
targets.add(codegen_protocol_constants.target);
|
||||
targets.add(to_html.target);
|
||||
return targets;
|
||||
|
|
Loading…
Reference in a new issue