Reland "Use dap package in dds, dds_service_extensions"

This is a reland of commit 59bb1fce82

Original change's description:
> Use dap package in dds, dds_service_extensions
>
> Change-Id: I678c810e02a5989ee1b4edebaf9d741e2fc7d026
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302849
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Helin Shiah <helinx@google.com>

Change-Id: Ib5b9cad1d0c19dac79c73e65c5de8721d1768285
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304105
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Helin Shiah <helinx@google.com>
This commit is contained in:
Helin Shiah 2023-05-18 19:25:28 +00:00 committed by Commit Queue
parent cc8b3f792e
commit a48d2cf02c
31 changed files with 50 additions and 9108 deletions

View file

@ -4,11 +4,8 @@
export 'src/dap/adapters/dart.dart';
export 'src/dap/adapters/mixins.dart';
export 'src/dap/exceptions.dart';
export 'src/dap/logging.dart';
export 'src/dap/progress_reporter.dart';
export 'src/dap/protocol_common.dart';
export 'src/dap/protocol_generated.dart';
export 'src/dap/protocol_stream.dart';
export 'src/dap/server.dart' show DapServer;
export 'src/dap/stream_transformers.dart';

View file

@ -259,8 +259,8 @@ class DartDevelopmentServiceClient {
);
_clientPeer.registerMethod(
'handleDap',
(parameters) => dds.dapHandler.handle(adapter, parameters),
'sendDapRequest',
(parameters) => dds.dapHandler.sendRequest(adapter, parameters),
);
// When invoked within a fallback, the next fallback will start executing.

View file

@ -7,6 +7,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:dap/dap.dart';
import 'package:json_rpc_2/error_code.dart' as json_rpc_errors;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
@ -15,13 +16,10 @@ import 'package:vm_service/vm_service.dart' as vm;
import '../../../dds.dart';
import '../../rpc_error_codes.dart';
import '../base_debug_adapter.dart';
import '../exceptions.dart';
import '../isolate_manager.dart';
import '../logging.dart';
import '../progress_reporter.dart';
import '../protocol_common.dart';
import '../protocol_converter.dart';
import '../protocol_generated.dart';
import '../protocol_stream.dart';
import '../utils.dart';
import '../variables.dart';

View file

@ -7,11 +7,11 @@ import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
import 'package:dap/dap.dart';
import 'package:path/path.dart' as path;
import 'package:vm_service/vm_service.dart' as vm;
import '../logging.dart';
import '../protocol_generated.dart';
import '../protocol_stream.dart';
import 'dart.dart';
import 'mixins.dart';

View file

@ -7,10 +7,9 @@ import 'dart:convert';
import 'dart:io';
import 'package:async/async.dart';
import 'package:dap/dap.dart';
import 'package:vm_service/vm_service.dart' as vm;
import '../exceptions.dart';
import '../protocol_generated.dart';
import '../protocol_stream.dart';
import 'dart.dart';
import 'mixins.dart';

View file

@ -6,10 +6,10 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dap/dap.dart';
import 'package:path/path.dart' as path;
import '../logging.dart';
import '../protocol_common.dart';
/// A mixin providing some utility functions for locating/working with
/// package_config.json files.

View file

@ -4,12 +4,10 @@
import 'dart:async';
import 'package:dap/dap.dart';
import 'package:meta/meta.dart';
import 'constants.dart';
import 'exceptions.dart';
import 'protocol_common.dart';
import 'protocol_generated.dart';
import 'protocol_stream.dart';
typedef _FromJsonHandler<T> = T Function(Map<String, Object?>);

View file

@ -1,55 +0,0 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/// Exception thrown by a debug adapter when a request is not valid, either
/// because the inputs are not correct or the adapter is not in the correct
/// state.
class DebugAdapterException implements Exception {
final String message;
DebugAdapterException(this.message);
@override
String toString() => 'DebugAdapterException: $message';
}
/// Exception thrown when failing to read arguments supplied by the user because
/// they are not the correct type.
///
/// This is usually because a user customised their launch configuration (for
/// example in `.vscode/launch.json` for VS Code) with values that are not
/// valid, such as putting a `String` in a field intended to be a `Map`:
///
/// ```
/// // Bad.
/// "env": "foo"
///
/// // Good.
/// "env": {
/// "FLUTTER_ROOT": "foo",
/// }
/// ```
class DebugAdapterInvalidArgumentException implements DebugAdapterException {
final String requestName;
final String argumentName;
final Type expectedType;
final Type actualType;
final Object? actualValue;
DebugAdapterInvalidArgumentException({
required this.requestName,
required this.argumentName,
required this.expectedType,
required this.actualType,
required this.actualValue,
});
@override
String get message =>
'"$argumentName" argument in $requestName configuration must be a '
'$expectedType but provided value was a $actualType ($actualValue)';
@override
String toString() => 'DebugAdapterInvalidArgumentException: $message';
}

View file

@ -6,12 +6,11 @@ import 'dart:async';
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:dap/dap.dart';
import 'package:vm_service/vm_service.dart' as vm;
import '../rpc_error_codes.dart';
import 'adapters/dart.dart';
import 'exceptions.dart';
import 'protocol_generated.dart';
import 'utils.dart';
import 'variables.dart';

View file

@ -2,8 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dap/dap.dart';
import 'adapters/dart.dart';
import 'protocol_generated.dart';
/// A reporter that can send progress notifications to the client.
abstract class DapProgressReporter {

View file

@ -1,131 +0,0 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'exceptions.dart';
/// A base class for (spec-generated) classes that represent the `body` of a an
/// event.
abstract class EventBody {
static bool canParse(Object? obj) => obj is Map<String, Object?>?;
}
/// A generic event body class that just supplies an object directly.
///
/// Used to support custom events sent by the debug adapter such as 'dart.log'.
///
/// The supplied [body] must be convertible to JSON.
class RawEventBody extends EventBody {
final Object body;
RawEventBody(this.body)
: assert(() {
try {
jsonEncode(body);
return true;
} catch (e) {
return false;
}
}(), 'body should be JSON encodable');
Object toJson() => body;
}
/// A generic arguments class that just supplies the arguments map directly.
///
/// Used to support custom requests that may be provided by other implementing
/// adapters that are not known at compile time by DDS/base DAP.
class RawRequestArguments extends RequestArguments {
final Map<String, Object?> args;
RawRequestArguments.fromMap(this.args);
static RawRequestArguments fromJson(Map<String, Object?> obj) =>
RawRequestArguments.fromMap(obj);
}
/// A base class for (spec-generated) classes that represent the `arguments` of
/// a request.
abstract class RequestArguments {
static bool canParse(Object? obj) => obj is Map<String, Object?>?;
}
/// A helper for reading arguments for DAP requests from the client.
class DebugAdapterArgumentReader {
final String request;
DebugAdapterArgumentReader(this.request);
/// Reads a value of type [T] from [field] in [obj].
T read<T>(
Map<String, Object?> obj,
String field,
) {
final value = obj[field];
if (value is! T) {
throw DebugAdapterInvalidArgumentException(
requestName: request,
argumentName: field,
expectedType: T,
actualType: value.runtimeType,
actualValue: value,
);
}
return obj[field] as T;
}
/// Reads a List of values of type [T] from [field] in [obj].
List<T> readList<T>(
Map<String, Object?> obj,
String field,
) {
final value = obj[field];
if (value is! List || !value.every((element) => element is T)) {
throw DebugAdapterInvalidArgumentException(
requestName: request,
argumentName: field,
expectedType: List<T>,
actualType: value.runtimeType,
actualValue: value,
);
}
return (obj[field] as List<Object?>).cast<T>();
}
/// Reads an optional List of values of type [T] from [field] in [obj].
List<T>? readOptionalList<T>(
Map<String, Object?> obj,
String field,
) {
return obj.containsKey(field) ? readList<T>(obj, field) : null;
}
/// Reads an optional Map of types [K],[V] from [field] in [obj].
Map<K, V>? readOptionalMap<K, V>(
Map<String, Object?> obj,
String field,
) {
return obj.containsKey(field) ? readMap<K, V>(obj, field) : null;
}
/// Reads a Map of types [K],[V] from [field] in [obj].
Map<K, V> readMap<K, V>(
Map<String, Object?> obj,
String field,
) {
final value = obj[field];
if (value is! Map ||
!value.entries.every((entry) => entry.key is K && entry.value is V)) {
throw DebugAdapterInvalidArgumentException(
requestName: request,
argumentName: field,
expectedType: Map<K, V>,
actualType: value.runtimeType,
actualValue: value,
);
}
return (obj[field] as Map<Object?, Object?>).cast<K, V>();
}
}

View file

@ -7,12 +7,12 @@ import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:dap/dap.dart' as dap;
import 'package:path/path.dart' as path;
import 'package:vm_service/vm_service.dart' as vm;
import '../../dap.dart';
import 'isolate_manager.dart';
import 'protocol_generated.dart' as dap;
import 'variables.dart';
/// A helper that handlers converting to/from DAP and VM Service types and to
@ -398,7 +398,7 @@ class ProtocolConverter {
format: format,
);
} else {
return Variable(
return dap.Variable(
name: fieldRef.name ?? '<unnamed field>',
value: '<unavailable>',
variablesReference: 0,

File diff suppressed because it is too large Load diff

View file

@ -1,53 +0,0 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// TODO(dantup): Consolidate this with the equiv file in analysis_server (most
// likely by having analysis_server reference this one).
Object? specToJson(Object? obj) {
if (obj is ToJsonable) {
return obj.toJson();
} else {
return obj;
}
}
/// Represents either a [T1] or [T2].
///
/// This class is used for fields generated from the LSP/DAP specs that are
/// defined as unions in TypeScript (for example `String | number`) that cannot
/// directly be represented as Dart types.
///
/// Use the [map] function to access the element, providing a handler for each
/// of the possible types.
class Either2<T1, T2> extends ToJsonable {
final int _which;
final T1? _t1;
final T2? _t2;
Either2.t1(T1 this._t1)
: _t2 = null,
_which = 1;
Either2.t2(T2 this._t2)
: _t1 = null,
_which = 2;
T map<T>(T Function(T1) f1, T Function(T2) f2) {
return _which == 1 ? f1(_t1 as T1) : f2(_t2 as T2);
}
@override
Object? toJson() => map(specToJson, specToJson);
@override
String toString() => map((t) => t.toString(), (t) => t.toString());
/// Checks whether the value of the union equals the supplied value.
bool valueEquals(o) => map((t) => t == o, (t) => t == o);
}
/// An object from the LSP/DAP specs that can be converted to JSON.
abstract class ToJsonable {
Object? toJson();
}

View file

@ -5,9 +5,9 @@
import 'dart:async';
import 'dart:convert';
import 'exceptions.dart';
import 'package:dap/dap.dart';
import 'logging.dart';
import 'protocol_generated.dart';
import 'protocol_stream_transformers.dart';
// TODO(dantup): This class should mostly be shareable with the LSP version,

View file

@ -5,7 +5,7 @@
import 'dart:async';
import 'dart:convert';
import 'exceptions.dart';
import 'package:dap/dap.dart';
class InvalidEncodingException extends InvalidHeadersException {
InvalidEncodingException(String headers)

View file

@ -2,10 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dap/dap.dart';
import 'package:vm_service/vm_service.dart';
import 'protocol_generated.dart';
/// A wrapper around variables for use in `variablesRequest` that can hold
/// additional data, such as a formatting information supplied in an evaluation
/// request.

View file

@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:dap/dap.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import '../dap.dart';
@ -14,7 +15,7 @@ import 'dds_impl.dart';
class DapHandler {
DapHandler(this.dds);
Future<Map<String, dynamic>> handle(
Future<Map<String, dynamic>> sendRequest(
DdsHostedAdapter adapter,
json_rpc.Parameters parameters,
) async {
@ -37,7 +38,7 @@ class DapHandler {
return <String, dynamic>{
'type': 'DapResponse',
'message': result.toJson(),
'dapResponse': result,
};
}

View file

@ -14,6 +14,7 @@ dependencies:
browser_launcher: ^1.0.0
collection: ^1.15.0
dds_service_extensions: ^1.3.0
dap: ^1.0.0
devtools_shared: ^2.14.1
http_multi_server: ^3.0.0
json_rpc_2: ^3.0.0

View file

@ -4,7 +4,7 @@
import 'dart:io';
import 'package:dds/dap.dart';
import 'package:dap/dap.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

View file

@ -2,8 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dap/dap.dart';
import 'package:dds/src/dap/adapters/dart.dart';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:test/test.dart';
import 'test_client.dart';

View file

@ -5,7 +5,7 @@
import 'dart:async';
import 'dart:io';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:dap/dap.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

View file

@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:dap/dap.dart';
import 'package:test/test.dart';
import 'test_client.dart';

View file

@ -4,7 +4,7 @@
import 'dart:io';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:dap/dap.dart';
import 'package:test/test.dart';
import 'test_client.dart';

View file

@ -6,9 +6,9 @@ import 'dart:async';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:dap/dap.dart';
import 'package:dds/src/dap/adapters/dart.dart';
import 'package:dds/src/dap/logging.dart';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:dds/src/dap/protocol_stream.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart' as vm;

View file

@ -6,8 +6,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dap/dap.dart';
import 'package:dds/src/dap/logging.dart';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

View file

@ -4,6 +4,7 @@
import 'dart:async';
import 'package:dap/dap.dart' as dap;
import 'package:dds/dap.dart';
import 'package:dds/src/dap/adapters/dart_cli_adapter.dart';
import 'package:dds/src/dap/adapters/dart_test_adapter.dart';
@ -118,7 +119,7 @@ class MockDartTestDebugAdapter extends DartTestDebugAdapter {
}
}
class MockRequest extends Request {
class MockRequest extends dap.Request {
static var _requestId = 1;
MockRequest()
: super.fromMap({

View file

@ -5,8 +5,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:dap/dap.dart';
import 'package:dds/dds.dart';
import 'package:dds/src/dap/protocol_generated.dart';
import 'package:dds_service_extensions/src/dap.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service_io.dart';
@ -54,11 +54,12 @@ void main() {
);
// TODO(helinx): Check result format after using better typing from JSON.
final result = await service.handleDap(jsonEncode(setBreakpointsRequest));
expect(result.message, isNotNull);
expect(result.message['type'], 'response');
expect(result.message['success'], true);
expect(result.message['command'], 'setBreakpoints');
expect(result.message['body'], isNotNull);
final result =
await service.sendDapRequest(jsonEncode(setBreakpointsRequest));
expect(result.dapResponse, isNotNull);
expect(result.dapResponse.type, 'response');
expect(result.dapResponse.success, true);
expect(result.dapResponse.command, 'setBreakpoints');
expect(result.dapResponse.body, isNotNull);
});
}

View file

@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:dds/src/dap/protocol_special.dart';
import 'package:dap/dap.dart';
class JsonSchema {
late final Uri dollarSchema;

View file

@ -1,11 +1,12 @@
import 'package:dap/dap.dart' as dap;
// ignore: implementation_imports
import 'package:vm_service/src/vm_service.dart';
import 'package:vm_service/src/vm_service.dart' as vm;
extension DapExtension on VmService {
extension DapExtension on vm.VmService {
static bool _factoriesRegistered = false;
Future<DapResponse> handleDap(String message) async {
Future<DapResponse> sendDapRequest(String message) async {
return _callHelper<DapResponse>(
'handleDap',
'sendDapRequest',
args: {'message': message},
);
}
@ -25,20 +26,21 @@ extension DapExtension on VmService {
}
static void _registerFactories() {
addTypeFactory('DapResponse', DapResponse.parse);
vm.addTypeFactory('DapResponse', DapResponse.parse);
_factoriesRegistered = true;
}
}
class DapResponse extends Response {
class DapResponse extends vm.Response {
static DapResponse? parse(Map<String, dynamic>? json) =>
json == null ? null : DapResponse._fromJson(json);
DapResponse({
required this.message,
required this.dapResponse,
});
DapResponse._fromJson(Map<String, dynamic> json) : message = json['message'];
DapResponse._fromJson(Map<String, dynamic> json)
: dapResponse = dap.Response.fromJson(json['dapResponse']);
@override
String get type => 'DapResponse';
@ -46,5 +48,5 @@ class DapResponse extends Response {
@override
String toString() => '[DapResponse]';
final Map<String, Object?> message;
final dap.Response dapResponse;
}

View file

@ -10,6 +10,7 @@ environment:
dependencies:
async: ^2.4.1
dap: ^1.0.0
vm_service: ^11.0.0
# We use 'any' version constraints here as we get our package versions from