Revert "[ package:dds ] Add null safety support"

This reverts commit a527411e51.

Reason for revert: depends on package 'devtools_shared' that is not yet migrated.

Original change's description:
> [ package:dds ] Add null safety support
>
> Fixes https://github.com/dart-lang/sdk/issues/45756
>
> TEST=service + DDS tests
>
> Change-Id: I6dd14d7f9fdee479a830c3b053dc3b00aa635202
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/199800
> Commit-Queue: Ben Konyi <bkonyi@google.com>
> Reviewed-by: Devon Carew <devoncarew@google.com>

# Not skipping CQ checks because original CL landed > 1 day ago.

Change-Id: Icdaef3ac55d7ef302acd3f9c2538a41e52e4253a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200180
Reviewed-by: David Morgan <davidmorgan@google.com>
Commit-Queue: David Morgan <davidmorgan@google.com>
This commit is contained in:
Emmanuel Pellereau 2021-05-17 08:12:20 +00:00 committed by commit-bot@chromium.org
parent 18483f395b
commit b8c5ecd5aa
43 changed files with 348 additions and 298 deletions

View file

@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
"generated": "2021-05-13T13:57:59.578937",
"generated": "2021-05-11T11:47:02.674706",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@ -252,11 +252,17 @@
"packageUri": "lib/",
"languageVersion": "2.3"
},
{
"name": "devtools_server",
"rootUri": "../third_party/devtools/devtools_server",
"packageUri": "lib/",
"languageVersion": "2.6"
},
{
"name": "devtools_shared",
"rootUri": "../third_party/devtools/devtools_shared",
"packageUri": "lib/",
"languageVersion": "2.12"
"languageVersion": "2.3"
},
{
"name": "diagnostic",

2
DEPS
View file

@ -107,7 +107,7 @@ vars = {
"chromedriver_tag": "83.0.4103.39",
"dartdoc_rev" : "e6a9b7c536a85e49233c97bb892bbb0ab778e425",
"devtools_rev" : "e138d55437a59838607415ef21f20bd6c4955dbc",
"devtools_rev" : "12ad5341ae0a275042c84a4e7be9a6c98db65612",
"jsshell_tag": "version:88.0",
"ffi_rev": "f3346299c55669cc0db48afae85b8110088bf8da",
"fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",

View file

@ -1,7 +1,3 @@
# 2.0.0
- **Breaking change:** add null safety support.
- **Breaking change:** minimum Dart SDK revision bumped to 2.12.0.
# 1.8.0
- Add support for launching DevTools from DDS.
- Fixed issue where two clients subscribing to the same stream in close succession

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:convert';
import 'dart:io';
@ -26,7 +28,7 @@ Future<void> main(List<String> args) async {
final remoteVmServiceUri = Uri.parse(args.first);
// Resolve the address which is potentially provided by the user.
late InternetAddress address;
InternetAddress address;
final addresses = await InternetAddress.lookup(args[1]);
// Prefer IPv4 addresses.
for (int i = 0; i < addresses.length; i++) {
@ -41,7 +43,7 @@ Future<void> main(List<String> args) async {
final disableServiceAuthCodes = args[3] == 'true';
final startDevTools = args[4] == 'true';
Uri? devToolsBuildDirectory;
Uri devToolsBuildDirectory;
if (args[5].isNotEmpty) {
devToolsBuildDirectory = Uri.file(args[5]);
}
@ -53,7 +55,7 @@ Future<void> main(List<String> args) async {
remoteVmServiceUri,
serviceUri: serviceUri,
enableAuthCodes: !disableServiceAuthCodes,
devToolsConfiguration: startDevTools && devToolsBuildDirectory != null
devToolsConfiguration: startDevTools
? DevToolsConfiguration(
enable: startDevTools,
customBuildDirectoryPath: devToolsBuildDirectory,

View file

@ -2,6 +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.
// @dart=2.10
import 'package:dds/dds.dart';
import 'package:vm_service/vm_service_io.dart';

View file

@ -2,6 +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.
// @dart=2.10
/// A library used to spawn the Dart Developer Service, used to communicate
/// with a Dart VM Service instance.
library dds;
@ -39,12 +41,15 @@ abstract class DartDevelopmentService {
/// default.
static Future<DartDevelopmentService> startDartDevelopmentService(
Uri remoteVmServiceUri, {
Uri? serviceUri,
Uri serviceUri,
bool enableAuthCodes = true,
bool ipv6 = false,
DevToolsConfiguration? devToolsConfiguration,
DevToolsConfiguration devToolsConfiguration = const DevToolsConfiguration(),
bool logRequests = false,
}) async {
if (remoteVmServiceUri == null) {
throw ArgumentError.notNull('remoteVmServiceUri');
}
if (remoteVmServiceUri.scheme != 'http') {
throw ArgumentError(
'remoteVmServiceUri must have an HTTP scheme. Actual: ${remoteVmServiceUri.scheme}',
@ -60,15 +65,12 @@ abstract class DartDevelopmentService {
// If provided an address to bind to, ensure it uses a protocol consistent
// with that used to spawn DDS.
final addresses = await InternetAddress.lookup(serviceUri.host);
try {
// Check to see if there's a valid address.
addresses.firstWhere(
(a) => (a.type ==
(ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4)),
);
} on StateError {
// Could not find a valid address.
final address = addresses.firstWhere(
(a) => (a.type ==
(ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4)),
orElse: () => null,
);
if (address == null) {
throw ArgumentError(
"serviceUri '$serviceUri' is not an IPv${ipv6 ? "6" : "4"} address.",
);
@ -113,24 +115,24 @@ abstract class DartDevelopmentService {
/// [DartDevelopmentService] via HTTP.
///
/// Returns `null` if the service is not running.
Uri? get uri;
Uri get uri;
/// The [Uri] VM service clients can use to communicate with this
/// [DartDevelopmentService] via server-sent events (SSE).
///
/// Returns `null` if the service is not running.
Uri? get sseUri;
Uri get sseUri;
/// The [Uri] VM service clients can use to communicate with this
/// [DartDevelopmentService] via a [WebSocket].
///
/// Returns `null` if the service is not running.
Uri? get wsUri;
Uri get wsUri;
/// The HTTP [Uri] of the hosted DevTools instance.
///
/// Returns `null` if DevTools is not running.
Uri? get devToolsUri;
Uri get devToolsUri;
/// Set to `true` if this instance of [DartDevelopmentService] is accepting
/// requests.
@ -178,8 +180,8 @@ class DartDevelopmentServiceException implements Exception {
class DevToolsConfiguration {
const DevToolsConfiguration({
required this.customBuildDirectoryPath,
this.enable = false,
this.customBuildDirectoryPath,
});
final bool enable;

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -24,7 +26,7 @@ class DartDevelopmentServiceClient {
WebSocketChannel ws,
json_rpc.Peer vmServicePeer,
) : this._(
dds as DartDevelopmentServiceImpl,
dds,
ws,
vmServicePeer,
);
@ -34,7 +36,7 @@ class DartDevelopmentServiceClient {
SseConnection sse,
json_rpc.Peer vmServicePeer,
) : this._(
dds as DartDevelopmentServiceImpl,
dds,
sse,
vmServicePeer,
);
@ -165,8 +167,7 @@ class DartDevelopmentServiceClient {
(parameters) => {
'type': 'Size',
'size': StreamManager
.loggingRepositories[StreamManager.kLoggingStream]!
.bufferSize,
.loggingRepositories[StreamManager.kLoggingStream].bufferSize,
});
_clientPeer.registerMethod('setLogHistorySize', (parameters) {
@ -176,7 +177,7 @@ class DartDevelopmentServiceClient {
"'size' must be greater or equal to zero",
);
}
StreamManager.loggingRepositories[StreamManager.kLoggingStream]!
StreamManager.loggingRepositories[StreamManager.kLoggingStream]
.resize(size);
return RPCResponses.success;
});
@ -192,8 +193,8 @@ class DartDevelopmentServiceClient {
});
_clientPeer.registerMethod('getSupportedProtocols', (parameters) async {
final Map<String, dynamic> supportedProtocols = (await _vmServicePeer
.sendRequest('getSupportedProtocols')) as Map<String, dynamic>;
final Map<String, dynamic> supportedProtocols =
await _vmServicePeer.sendRequest('getSupportedProtocols');
final ddsVersion = DartDevelopmentService.protocolVersion.split('.');
final ddsProtocol = {
'protocolName': 'DDS',
@ -288,17 +289,17 @@ class DartDevelopmentServiceClient {
String get defaultClientName => 'client$_id';
/// The current name associated with this client.
String? get name => _name;
String get name => _name;
// NOTE: this should not be called directly except from:
// - `ClientManager._clearClientName`
// - `ClientManager._setClientNameHelper`
set name(String? n) => _name = n ?? defaultClientName;
String? _name;
set name(String n) => _name = n ?? defaultClientName;
String _name;
final DartDevelopmentServiceImpl dds;
final StreamChannel connection;
final Map<String, String> services = {};
final json_rpc.Peer _vmServicePeer;
late json_rpc.Peer _clientPeer;
json_rpc.Peer _clientPeer;
}

View file

@ -2,6 +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.
// @dart=2.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'client.dart';
@ -96,7 +98,7 @@ class ClientManager {
pauseTypeMask |= PauseTypeMasks.pauseOnExitMask;
}
clientResumePermissions[client.name!]!.permissionsMask = pauseTypeMask;
clientResumePermissions[client.name].permissionsMask = pauseTypeMask;
return RPCResponses.success;
}
@ -109,10 +111,10 @@ class ClientManager {
_clearClientName(client);
client.name = name.isEmpty ? client.defaultClientName : name;
clientResumePermissions.putIfAbsent(
client.name!,
client.name,
() => _ClientResumePermissions(),
);
clientResumePermissions[client.name!]!.clients.add(client);
clientResumePermissions[client.name].clients.add(client);
}
/// Resets the client's name while also cleaning up resume permissions and
@ -153,7 +155,7 @@ class ClientManager {
}
}
DartDevelopmentServiceClient? findFirstClientThatHandlesService(
DartDevelopmentServiceClient findFirstClientThatHandlesService(
String service) {
for (final client in clients) {
if (client.services.containsKey(service)) {
@ -171,7 +173,7 @@ class ClientManager {
/// Mapping of client names to all clients of that name and their resume
/// permissions.
final Map<String?, _ClientResumePermissions> clientResumePermissions = {};
final Map<String, _ClientResumePermissions> clientResumePermissions = {};
final DartDevelopmentServiceImpl dds;
}

View file

@ -2,6 +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.
// @dart=2.10
abstract class RPCResponses {
static const success = <String, dynamic>{
'type': 'Success',

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -170,13 +172,13 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
}
_shuttingDown = true;
// Don't accept any more HTTP requests.
await _server.close();
await _server?.close();
// Close connections to clients.
await clientManager.shutdown();
// Close connection to VM service.
await _vmServiceSocket.sink.close();
await _vmServiceSocket?.sink?.close();
_done.complete();
}
@ -265,16 +267,16 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
}
Handler _httpHandler() {
if (_devToolsConfiguration != null && _devToolsConfiguration!.enable) {
if (_devToolsConfiguration != null && _devToolsConfiguration.enable) {
// Install the DevTools handlers and forward any unhandled HTTP requests to
// the VM service.
final String buildDir =
_devToolsConfiguration!.customBuildDirectoryPath.toFilePath();
final buildDir =
_devToolsConfiguration.customBuildDirectoryPath?.toFilePath();
return devtoolsHandler(
dds: this,
buildDir: buildDir,
notFoundHandler: proxyHandler(remoteVmServiceUri),
) as FutureOr<Response> Function(Request);
);
}
return proxyHandler(remoteVmServiceUri);
}
@ -292,7 +294,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
return pathSegments;
}
Uri? _toWebSocket(Uri? uri) {
Uri _toWebSocket(Uri uri) {
if (uri == null) {
return null;
}
@ -301,7 +303,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
return uri.replace(scheme: 'ws', pathSegments: pathSegments);
}
Uri? _toSse(Uri? uri) {
Uri _toSse(Uri uri) {
if (uri == null) {
return null;
}
@ -310,7 +312,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
return uri.replace(scheme: 'sse', pathSegments: pathSegments);
}
Uri? _toDevTools(Uri? uri) {
Uri _toDevTools(Uri uri) {
// The DevTools URI is a bit strange as the query parameters appear after
// the fragment. There's no nice way to encode the query parameters
// properly, so we create another Uri just to grab the formatted query.
@ -323,7 +325,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
).query;
return Uri(
scheme: 'http',
host: uri!.host,
host: uri.host,
port: uri.port,
pathSegments: [
...uri.pathSegments.where(
@ -336,61 +338,56 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
);
}
String? getNamespace(DartDevelopmentServiceClient client) =>
String getNamespace(DartDevelopmentServiceClient client) =>
clientManager.clients.keyOf(client);
bool get authCodesEnabled => _authCodesEnabled;
final bool _authCodesEnabled;
String? get authCode => _authCode;
String? _authCode;
String get authCode => _authCode;
String _authCode;
final bool shouldLogRequests;
Uri get remoteVmServiceUri => _remoteVmServiceUri;
@override
Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri)!;
Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri);
Uri _remoteVmServiceUri;
@override
Uri? get uri => _uri;
Uri? _uri;
Uri get uri => _uri;
Uri _uri;
@override
Uri? get sseUri => _toSse(_uri);
Uri get sseUri => _toSse(_uri);
@override
Uri? get wsUri => _toWebSocket(_uri);
Uri get wsUri => _toWebSocket(_uri);
@override
Uri? get devToolsUri =>
_devToolsConfiguration?.enable ?? false ? _toDevTools(_uri) : null;
Uri get devToolsUri =>
_devToolsConfiguration.enable ? _toDevTools(_uri) : null;
final bool _ipv6;
bool get isRunning => _uri != null;
final DevToolsConfiguration? _devToolsConfiguration;
final DevToolsConfiguration _devToolsConfiguration;
Future<void> get done => _done.future;
Completer _done = Completer<void>();
bool _shuttingDown = false;
ClientManager get clientManager => _clientManager;
late ClientManager _clientManager;
ClientManager _clientManager;
ExpressionEvaluator get expressionEvaluator => _expressionEvaluator;
late ExpressionEvaluator _expressionEvaluator;
ExpressionEvaluator _expressionEvaluator;
IsolateManager get isolateManager => _isolateManager;
late IsolateManager _isolateManager;
IsolateManager _isolateManager;
StreamManager get streamManager => _streamManager;
late StreamManager _streamManager;
StreamManager _streamManager;
static const _kSseHandlerPath = '\$debugHandler';
late json_rpc.Peer vmServiceClient;
late WebSocketChannel _vmServiceSocket;
late HttpServer _server;
json_rpc.Peer vmServiceClient;
WebSocketChannel _vmServiceSocket;
HttpServer _server;
}

View file

@ -2,6 +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.
// @dart=2.9
import 'dart:async';
import 'package:json_rpc_2/src/server.dart' as json_rpc;
@ -20,7 +22,7 @@ class LoggingMiddlewareSink<S> implements StreamSink<S> {
}
@override
void addError(Object error, [StackTrace? stackTrace]) {
void addError(Object error, [StackTrace stackTrace]) {
print('DevTools SSE error response: $error');
sink.addError(error);
}
@ -57,7 +59,7 @@ class DevToolsClient {
}
_server = json_rpc.Server(
StreamChannel(stream, sink as StreamSink<String>),
StreamChannel(stream, sink),
strictProtocolChecks: false,
);
_registerJsonRpcMethods();
@ -90,5 +92,5 @@ class DevToolsClient {
});
}
late json_rpc.Server _server;
json_rpc.Server _server;
}

View file

@ -2,9 +2,12 @@
// 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 'package:dds/src/constants.dart';
import 'package:meta/meta.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_static/shelf_static.dart';
import 'package:sse/server/sse_handler.dart';
@ -21,9 +24,9 @@ import 'server_api.dart';
/// [notFoundHandler] is a [Handler] to which requests that could not be handled
/// by the DevTools handler are forwarded (e.g., a proxy to the VM service).
FutureOr<Handler> devtoolsHandler({
required DartDevelopmentServiceImpl dds,
required String buildDir,
required Handler notFoundHandler,
@required DartDevelopmentServiceImpl dds,
@required String buildDir,
@required Handler notFoundHandler,
}) {
// Serves the web assets for DevTools.
final devtoolsAssetHandler = createStaticHandler(

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart=2.9
// TODO(bkonyi): remove once package:devtools_server_api is available
// See https://github.com/flutter/devtools/issues/2958.
@ -16,7 +18,7 @@ class LocalFileSystem {
static String _userHomeDir() {
final String envKey =
Platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
final String? value = Platform.environment[envKey];
final String value = Platform.environment[envKey];
return value == null ? '.' : value;
}
@ -44,7 +46,7 @@ class LocalFileSystem {
/// Returns a DevTools file from the given path.
///
/// Only files within ~/.flutter-devtools/ can be accessed.
static File? devToolsFileFromPath(String pathFromDevToolsDir) {
static File devToolsFileFromPath(String pathFromDevToolsDir) {
if (pathFromDevToolsDir.contains('..')) {
// The passed in path should not be able to walk up the directory tree
// outside of the ~/.flutter-devtools/ directory.
@ -61,7 +63,7 @@ class LocalFileSystem {
/// Returns a DevTools file from the given path as encoded json.
///
/// Only files within ~/.flutter-devtools/ can be accessed.
static String? devToolsFileAsJson(String pathFromDevToolsDir) {
static String devToolsFileAsJson(String pathFromDevToolsDir) {
final file = devToolsFileFromPath(pathFromDevToolsDir);
if (file == null) return null;

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart=2.9
// TODO(bkonyi): remove once package:devtools_server_api is available
// See https://github.com/flutter/devtools/issues/2958.
@ -31,7 +33,7 @@ class ServerApi {
/// To override an API call, pass in a subclass of [ServerApi].
static FutureOr<shelf.Response> handle(
shelf.Request request, [
ServerApi? api,
ServerApi api,
]) {
api ??= ServerApi();
switch (request.url.path) {
@ -40,7 +42,7 @@ class ServerApi {
// Is Analytics collection enabled?
return api.getCompleted(
request,
json.encode(FlutterUsage.doesStoreExist ? _usage!.enabled : null),
json.encode(FlutterUsage.doesStoreExist ? _usage.enabled : null),
);
case apiGetFlutterGAClientId:
// Flutter Tool GA clientId - ONLY get Flutter's clientId if enabled is
@ -48,7 +50,7 @@ class ServerApi {
return (FlutterUsage.doesStoreExist)
? api.getCompleted(
request,
json.encode(_usage!.enabled ? _usage!.clientId : null),
json.encode(_usage.enabled ? _usage.clientId : null),
)
: api.getCompleted(
request,
@ -74,7 +76,7 @@ class ServerApi {
final queryParams = request.requestedUri.queryParameters;
if (queryParams.containsKey(devToolsEnabledPropertyName)) {
_devToolsUsage.enabled =
json.decode(queryParams[devToolsEnabledPropertyName]!);
json.decode(queryParams[devToolsEnabledPropertyName]);
}
return api.setCompleted(request, json.encode(_devToolsUsage.enabled));
@ -90,7 +92,7 @@ class ServerApi {
final queryParams = request.requestedUri.queryParameters;
if (queryParams.keys.length == 1 &&
queryParams.containsKey(activeSurveyName)) {
final String theSurveyName = queryParams[activeSurveyName]!;
final String theSurveyName = queryParams[activeSurveyName];
// Set the current activeSurvey.
_devToolsUsage.activeSurvey = theSurveyName;
@ -123,7 +125,7 @@ class ServerApi {
final queryParams = request.requestedUri.queryParameters;
if (queryParams.containsKey(surveyActionTakenPropertyName)) {
_devToolsUsage.surveyActionTaken =
json.decode(queryParams[surveyActionTakenPropertyName]!);
json.decode(queryParams[surveyActionTakenPropertyName]);
}
return api.setCompleted(
request,
@ -155,7 +157,7 @@ class ServerApi {
case apiGetBaseAppSizeFile:
final queryParams = request.requestedUri.queryParameters;
if (queryParams.containsKey(baseAppSizeFilePropertyName)) {
final filePath = queryParams[baseAppSizeFilePropertyName]!;
final filePath = queryParams[baseAppSizeFilePropertyName];
final fileJson = LocalFileSystem.devToolsFileAsJson(filePath);
if (fileJson == null) {
return api.badRequest('No JSON file available at $filePath.');
@ -168,7 +170,7 @@ class ServerApi {
case apiGetTestAppSizeFile:
final queryParams = request.requestedUri.queryParameters;
if (queryParams.containsKey(testAppSizeFilePropertyName)) {
final filePath = queryParams[testAppSizeFilePropertyName]!;
final filePath = queryParams[testAppSizeFilePropertyName];
final fileJson = LocalFileSystem.devToolsFileAsJson(filePath);
if (fileJson == null) {
return api.badRequest('No JSON file available at $filePath.');
@ -186,7 +188,7 @@ class ServerApi {
// Accessing Flutter usage file e.g., ~/.flutter.
// NOTE: Only access the file if it exists otherwise Flutter Tool hasn't yet
// been run.
static final FlutterUsage? _usage =
static final FlutterUsage _usage =
FlutterUsage.doesStoreExist ? FlutterUsage() : null;
// Accessing DevTools usage file e.g., ~/.devtools
@ -213,7 +215,7 @@ class ServerApi {
/// setActiveSurvey not called.
///
/// This is a 400 Bad Request response.
FutureOr<shelf.Response> badRequest([String? logError]) {
FutureOr<shelf.Response> badRequest([String logError]) {
if (logError != null) print(logError);
return shelf.Response(HttpStatus.badRequest);
}

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart=2.9
// TODO(bkonyi): remove once package:devtools_server_api is available
// See https://github.com/flutter/devtools/issues/2958.
@ -19,13 +21,13 @@ class FlutterUsage {
/// used for testing.
FlutterUsage({
String settingsName = 'flutter',
String? versionOverride,
String? configDirOverride,
String versionOverride,
String configDirOverride,
}) {
_analytics = AnalyticsIO('', settingsName, '');
}
late Analytics _analytics;
Analytics _analytics;
/// Does the .flutter store exist?
static bool get doesStoreExist {
@ -46,8 +48,8 @@ class DevToolsUsage {
/// Create a new Usage instance; [versionOverride] and [configDirOverride] are
/// used for testing.
DevToolsUsage({
String? versionOverride,
String? configDirOverride,
String versionOverride,
String configDirOverride,
}) {
LocalFileSystem.maybeMoveLegacyDevToolsStore();
properties = IOPersistentProperties(
@ -68,9 +70,9 @@ class DevToolsUsage {
/// It is a requirement that the API apiSetActiveSurvey must be called before
/// calling any survey method on DevToolsUsage (addSurvey, rewriteActiveSurvey,
/// surveyShownCount, incrementSurveyShownCount, or surveyActionTaken).
String? _activeSurvey;
String _activeSurvey;
late IOPersistentProperties properties;
IOPersistentProperties properties;
static const _surveyActionTaken = 'surveyActionTaken';
static const _surveyShownCount = 'surveyShownCount';
@ -93,21 +95,23 @@ class DevToolsUsage {
return properties['enabled'];
}
set enabled(bool? value) {
set enabled(bool value) {
properties['enabled'] = value;
return properties['enabled'];
}
bool surveyNameExists(String? surveyName) => properties[surveyName] != null;
bool surveyNameExists(String surveyName) => properties[surveyName] != null;
void _addSurvey(String? surveyName) {
void _addSurvey(String surveyName) {
assert(activeSurvey != null);
assert(activeSurvey == surveyName);
rewriteActiveSurvey(false, 0);
}
String? get activeSurvey => _activeSurvey;
String get activeSurvey => _activeSurvey;
set activeSurvey(String? surveyName) {
set activeSurvey(String surveyName) {
assert(surveyName != null);
_activeSurvey = surveyName;
if (!surveyNameExists(activeSurvey)) {
@ -117,14 +121,16 @@ class DevToolsUsage {
}
/// Need to rewrite the entire survey structure for property to be persisted.
void rewriteActiveSurvey(bool? actionTaken, int? shownCount) {
void rewriteActiveSurvey(bool actionTaken, int shownCount) {
assert(activeSurvey != null);
properties[activeSurvey] = {
_surveyActionTaken: actionTaken,
_surveyShownCount: shownCount,
};
}
int? get surveyShownCount {
int get surveyShownCount {
assert(activeSurvey != null);
final prop = properties[activeSurvey];
if (prop[_surveyShownCount] == null) {
rewriteActiveSurvey(prop[_surveyActionTaken], 0);
@ -133,16 +139,19 @@ class DevToolsUsage {
}
void incrementSurveyShownCount() {
assert(activeSurvey != null);
surveyShownCount; // Ensure surveyShownCount has been initialized.
final prop = properties[activeSurvey];
rewriteActiveSurvey(prop[_surveyActionTaken], prop[_surveyShownCount] + 1);
}
bool get surveyActionTaken {
assert(activeSurvey != null);
return properties[activeSurvey][_surveyActionTaken] == true;
}
set surveyActionTaken(bool? value) {
set surveyActionTaken(bool value) {
assert(activeSurvey != null);
final prop = properties[activeSurvey];
rewriteActiveSurvey(value, prop[_surveyShownCount]);
}
@ -168,7 +177,7 @@ const JsonEncoder _jsonEncoder = JsonEncoder.withIndent(' ');
class IOPersistentProperties extends PersistentProperties {
IOPersistentProperties(
String name, {
String? documentDirPath,
String documentDirPath,
}) : super(name) {
final String fileName = name.replaceAll(' ', '_');
documentDirPath ??= LocalFileSystem.devToolsDir();
@ -187,22 +196,22 @@ class IOPersistentProperties extends PersistentProperties {
syncSettings();
}
late File _file;
File _file;
Map? _map;
Map _map;
@override
dynamic operator [](String? key) => _map![key];
dynamic operator [](String key) => _map[key];
@override
void operator []=(String? key, dynamic value) {
if (value == null && !_map!.containsKey(key)) return;
if (_map![key] == value) return;
void operator []=(String key, dynamic value) {
if (value == null && !_map.containsKey(key)) return;
if (_map[key] == value) return;
if (value == null) {
_map!.remove(key);
_map.remove(key);
} else {
_map![key] = value;
_map[key] = value;
}
try {
@ -222,6 +231,6 @@ class IOPersistentProperties extends PersistentProperties {
}
void remove(String propertyName) {
_map!.remove(propertyName);
_map.remove(propertyName);
}
}

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 'dart:async';
// @dart=2.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -17,16 +17,16 @@ class ExpressionEvaluator {
ExpressionEvaluator(this.dds);
Future<Map<String, dynamic>> execute(json_rpc.Parameters parameters) async {
DartDevelopmentServiceClient? externalClient =
DartDevelopmentServiceClient externalClient =
dds.clientManager.findFirstClientThatHandlesService(
'compileExpression',
);
// If no compilation service is registered, just forward to the VM service.
if (externalClient == null) {
return (await dds.vmServiceClient.sendRequest(
return await dds.vmServiceClient.sendRequest(
parameters.method,
parameters.value,
)) as Map<String, dynamic>;
);
}
final isolateId = parameters['isolateId'].asString;
@ -59,18 +59,18 @@ class ExpressionEvaluator {
json_rpc.Parameters parameters) async {
final params = _setupParams(parameters);
params['isolateId'] = parameters['isolateId'].asString;
if (parameters['scope'].asMapOr({}).isNotEmpty) {
if (parameters['scope'].asMapOr(null) != null) {
params['scope'] = parameters['scope'].asMap;
}
return (await dds.vmServiceClient.sendRequest(
return await dds.vmServiceClient.sendRequest(
'_buildExpressionEvaluationScope',
params,
)) as Map<String, dynamic>;
);
}
Future<String> _compileExpression(String isolateId, String expression,
Map<String, dynamic> buildScopeResponseResult) async {
DartDevelopmentServiceClient? externalClient =
DartDevelopmentServiceClient externalClient =
dds.clientManager.findFirstClientThatHandlesService(
'compileExpression',
);
@ -116,13 +116,13 @@ class ExpressionEvaluator {
params['kernelBytes'] = kernelBase64;
params['disableBreakpoints'] =
parameters['disableBreakpoints'].asBoolOr(false);
if (parameters['scope'].asMapOr({}).isNotEmpty) {
if (parameters['scope'].asMapOr(null) != null) {
params['scope'] = parameters['scope'].asMap;
}
return (await dds.vmServiceClient.sendRequest(
return await dds.vmServiceClient.sendRequest(
'_evaluateCompiledExpression',
params,
)) as Map<String, dynamic>;
);
}
Map<String, dynamic> _setupParams(json_rpc.Parameters parameters) {

View file

@ -2,6 +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.
// @dart=2.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'client.dart';
@ -54,7 +56,7 @@ class _RunningIsolate {
/// done so. Called when the last client of a given name disconnects or
/// changes name to ensure we don't deadlock waiting for approval to resume
/// from a disconnected client.
Future<void> maybeResumeAfterClientChange(String? clientName) async {
Future<void> maybeResumeAfterClientChange(String clientName) async {
// Remove approvals from the disconnected client.
_resumeApprovalsByName.remove(clientName);
@ -73,7 +75,7 @@ class _RunningIsolate {
/// which have provided approval to resume this isolate. If not provided,
/// the existing approvals state will be examined to see if the isolate
/// should resume due to a client disconnect or name change.
bool shouldResume({DartDevelopmentServiceClient? resumingClient}) {
bool shouldResume({DartDevelopmentServiceClient resumingClient}) {
if (resumingClient != null) {
// Mark approval by the client.
_resumeApprovalsByName.add(resumingClient.name);
@ -83,9 +85,9 @@ class _RunningIsolate {
isolateManager.dds.clientManager.clientResumePermissions;
// Determine which clients require approval for this pause type.
permissions.forEach((clientName, clientNamePermissions) {
permissions.forEach((name, clientNamePermissions) {
if (clientNamePermissions.permissionsMask & _isolateStateMask != 0) {
requiredClientApprovals.add(clientName!);
requiredClientApprovals.add(name);
}
});
@ -114,8 +116,8 @@ class _RunningIsolate {
final IsolateManager isolateManager;
final String name;
final String id;
final Set<String?> _resumeApprovalsByName = {};
_IsolateState? _state;
final Set<String> _resumeApprovalsByName = {};
_IsolateState _state;
}
class IsolateManager {
@ -150,16 +152,16 @@ class IsolateManager {
final isolate = isolates[id];
switch (eventKind) {
case ServiceEvents.pauseExit:
isolate!.pausedOnExit();
isolate.pausedOnExit();
break;
case ServiceEvents.pausePostRequest:
isolate!.pausedPostRequest();
isolate.pausedPostRequest();
break;
case ServiceEvents.pauseStart:
isolate!.pausedOnStart();
isolate.pausedOnStart();
break;
case ServiceEvents.resume:
isolate!.resumed();
isolate.resumed();
break;
default:
break;
@ -235,13 +237,12 @@ class IsolateManager {
String isolateId,
json_rpc.Parameters parameters,
) async {
const invalidFrameIndex = -1;
final step = parameters['step'].asStringOr('');
final frameIndex = parameters['frameIndex'].asIntOr(invalidFrameIndex);
final step = parameters['step'].asStringOr(null);
final frameIndex = parameters['frameIndex'].asIntOr(null);
final resumeResult = await dds.vmServiceClient.sendRequest('resume', {
'isolateId': isolateId,
if (step.isNotEmpty) 'step': step,
if (frameIndex != invalidFrameIndex) 'frameIndex': frameIndex,
if (step != null) 'step': step,
if (frameIndex != null) 'frameIndex': frameIndex,
});
return resumeResult;
}

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:math';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -48,8 +50,9 @@ class LoggingRepository extends _RingBuffer<Map<String, dynamic>> {
// TODO(bkonyi): move to standalone file if we decide to use this elsewhere.
class _RingBuffer<T> {
_RingBuffer(this._bufferSize) {
_buffer = List<T?>.filled(
_RingBuffer(int initialSize) {
_bufferSize = initialSize;
_buffer = List<T>.filled(
_bufferSize,
null,
);
@ -57,7 +60,7 @@ class _RingBuffer<T> {
Iterable<T> call() sync* {
for (int i = _size - 1; i >= 0; --i) {
yield _buffer[(_count - i - 1) % _bufferSize]!;
yield _buffer[(_count - i - 1) % _bufferSize];
}
}
@ -73,7 +76,7 @@ class _RingBuffer<T> {
if (size == _bufferSize) {
return;
}
final resized = List<T?>.filled(
final resized = List<T>.filled(
size,
null,
);
@ -94,5 +97,5 @@ class _RingBuffer<T> {
int _bufferSize;
int _count = 0;
late List<T?> _buffer;
List<T> _buffer;
}

View file

@ -2,6 +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.
// @dart=2.10
// Originally pulled from dart:_vmservice.
import 'dart:collection';
@ -23,14 +25,14 @@ class NamedLookup<E> with IterableMixin<E> {
}
void remove(E e) {
final id = _ids.remove(e)!;
final id = _ids.remove(e);
_elements.remove(id);
_generator.release(id);
}
E? operator [](String id) => _elements[id];
E operator [](String id) => _elements[id];
String? keyOf(E e) => _ids[e];
String keyOf(E e) => _ids[e];
Iterator<E> get iterator => _ids.keys.iterator;
}

View file

@ -2,13 +2,15 @@
// 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.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
abstract class RpcErrorCodes {
static json_rpc.RpcException buildRpcException(int code, {dynamic data}) {
return json_rpc.RpcException(
code,
errorMessages[code]!,
errorMessages[code],
data: data,
);
}

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:typed_data';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -25,10 +27,10 @@ class StreamManager {
void streamNotify(
String streamId,
data, {
DartDevelopmentServiceClient? excludedClient,
DartDevelopmentServiceClient excludedClient,
}) {
if (streamListeners.containsKey(streamId)) {
final listeners = streamListeners[streamId]!;
final listeners = streamListeners[streamId];
final isBinaryData = data is Uint8List;
for (final listener in listeners) {
if (listener == excludedClient) {
@ -62,7 +64,7 @@ class StreamManager {
String service,
String alias,
) {
final namespace = dds.getNamespace(client)!;
final namespace = dds.getNamespace(client);
streamNotify(
kServiceStream,
_buildStreamRegisteredEvent(namespace, service, alias),
@ -84,7 +86,7 @@ class StreamManager {
'kind': 'ServiceUnregistered',
'timestamp': DateTime.now().millisecondsSinceEpoch,
'service': service,
'method': namespace! + '.' + service,
'method': namespace + '.' + service,
},
},
excludedClient: client,
@ -118,7 +120,7 @@ class StreamManager {
// Keep a history of messages to send to clients when they first
// subscribe to a stream with an event history.
if (loggingRepositories.containsKey(streamId)) {
loggingRepositories[streamId]!.add(parameters.asMap);
loggingRepositories[streamId].add(parameters.asMap);
}
streamNotify(streamId, parameters.value);
},
@ -130,10 +132,10 @@ class StreamManager {
/// If `client` is the first client to listen to `stream`, DDS will send a
/// `streamListen` request for `stream` to the VM service.
Future<void> streamListen(
DartDevelopmentServiceClient? client,
DartDevelopmentServiceClient client,
String stream,
) async {
assert(stream.isNotEmpty);
assert(stream != null && stream.isNotEmpty);
if (!streamListeners.containsKey(stream)) {
// Initialize the list of clients for the new stream before we do
// anything else to ensure multiple clients registering for the same
@ -150,13 +152,13 @@ class StreamManager {
assert(result['type'] == 'Success');
}
}
if (streamListeners[stream]!.contains(client)) {
if (streamListeners[stream].contains(client)) {
throw kStreamAlreadySubscribedException;
}
if (client != null) {
streamListeners[stream]!.add(client);
streamListeners[stream].add(client);
if (loggingRepositories.containsKey(stream)) {
loggingRepositories[stream]!.sendHistoricalLogs(client);
loggingRepositories[stream].sendHistoricalLogs(client);
} else if (stream == kServiceStream) {
// Send all previously registered service extensions when a client
// subscribes to the Service stream.
@ -169,9 +171,9 @@ class StreamManager {
client.sendNotification(
'streamNotify',
_buildStreamRegisteredEvent(
namespace!,
namespace,
service,
c.services[service]!,
c.services[service],
),
);
}
@ -180,12 +182,12 @@ class StreamManager {
}
}
List<Map<String, dynamic>>? getStreamHistory(String stream) {
List<Map<String, dynamic>> getStreamHistory(String stream) {
if (!loggingRepositories.containsKey(stream)) {
return null;
}
return [
for (final event in loggingRepositories[stream]!()) event['event'],
for (final event in loggingRepositories[stream]()) event['event'],
];
}
@ -194,13 +196,13 @@ class StreamManager {
/// If `client` is the last client to unsubscribe from `stream`, DDS will
/// send a `streamCancel` request for `stream` to the VM service.
Future<void> streamCancel(
DartDevelopmentServiceClient? client,
DartDevelopmentServiceClient client,
String stream, {
bool cancelCoreStream = false,
}) async {
assert(stream.isNotEmpty);
assert(stream != null && stream.isNotEmpty);
final listeners = streamListeners[stream];
if (listeners == null || client != null && !listeners.contains(client)) {
if (client != null && (listeners == null || !listeners.contains(client))) {
throw kStreamNotSubscribedException;
}
listeners.remove(client);

View file

@ -2,16 +2,19 @@
// 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.10
import 'dart:async';
import 'dart:collection';
import 'package:async/async.dart';
import 'package:meta/meta.dart';
import 'package:pedantic/pedantic.dart';
import 'package:vm_service/src/vm_service.dart';
extension DdsExtension on VmService {
static bool _factoriesRegistered = false;
static Version? _ddsVersion;
static Version _ddsVersion;
/// The _getDartDevelopmentServiceVersion_ RPC is used to determine what version of
/// the Dart Development Service Protocol is served by a DDS instance.
@ -22,7 +25,7 @@ extension DdsExtension on VmService {
_ddsVersion =
await _callHelper<Version>('getDartDevelopmentServiceVersion');
}
return _ddsVersion!;
return _ddsVersion;
}
/// Retrieve the event history for `stream`.
@ -44,19 +47,19 @@ extension DdsExtension on VmService {
/// If `stream` does not have event history collected, a parameter error is
/// sent over the returned [Stream].
Stream<Event> onEventWithHistory(String stream) {
late StreamController<Event> controller;
late StreamQueue<Event> streamEvents;
StreamController<Event> controller;
StreamQueue<Event> streamEvents;
controller = StreamController<Event>(onListen: () async {
streamEvents = StreamQueue<Event>(onEvent(stream));
final history = (await getStreamHistory(stream)).history;
Event? firstStreamEvent;
Event firstStreamEvent;
unawaited(streamEvents.peek.then((e) {
firstStreamEvent = e;
}));
for (final event in history) {
if (firstStreamEvent != null &&
event.timestamp! > firstStreamEvent!.timestamp!) {
event.timestamp > firstStreamEvent.timestamp) {
break;
}
controller.sink.add(event);
@ -106,12 +109,12 @@ extension DdsExtension on VmService {
if (_ddsVersion == null) {
_ddsVersion = await getDartDevelopmentServiceVersion();
}
return ((_ddsVersion!.major == major && _ddsVersion!.minor! >= minor) ||
(_ddsVersion!.major! > major));
return ((_ddsVersion.major == major && _ddsVersion.minor >= minor) ||
(_ddsVersion.major > major));
}
Future<T> _callHelper<T>(String method,
{String? isolateId, Map args = const {}}) {
{String isolateId, Map args = const {}}) {
if (!_factoriesRegistered) {
_registerFactories();
}
@ -132,10 +135,10 @@ extension DdsExtension on VmService {
/// A collection of historical [Event]s from some stream.
class StreamHistory extends Response {
static StreamHistory? parse(Map<String, dynamic>? json) =>
static StreamHistory parse(Map<String, dynamic> json) =>
json == null ? null : StreamHistory._fromJson(json);
StreamHistory({required List<Event> history}) : _history = history;
StreamHistory({@required List<Event> history}) : _history = history;
StreamHistory._fromJson(Map<String, dynamic> json)
: _history = json['history']

View file

@ -3,7 +3,7 @@ description: >-
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
version: 2.0.0
version: 1.8.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:convert';
import 'dart:io';
@ -13,16 +15,18 @@ import 'common/test_helper.dart';
void main() {
group('DDS', () {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
test('Bad Auth Code', () async {
@ -34,8 +38,8 @@ void main() {
// Ensure basic websocket requests are forwarded correctly to the VM service.
final service = await vmServiceConnectUri(dds.wsUri.toString());
final version = await service.getVersion();
expect(version.major! > 0, true);
expect(version.minor! >= 0, true);
expect(version.major > 0, true);
expect(version.minor >= 0, true);
// Ensure we can still make requests of the VM service via HTTP.
HttpClient client = HttpClient();

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;

View file

@ -2,13 +2,12 @@
// 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:async';
// @dart=2.10
import 'dart:convert';
import 'dart:io';
import 'package:vm_service/vm_service.dart';
late Uri remoteVmServiceUri;
Uri remoteVmServiceUri;
Future<Process> spawnDartProcess(
String script, {
@ -42,20 +41,3 @@ Future<Process> spawnDartProcess(
remoteVmServiceUri = Uri.parse(infoJson['uri']);
return process;
}
Future<void> executeUntilNextPause(VmService service) async {
final vm = await service.getVM();
final isolate = await service.getIsolate(vm.isolates!.first.id!);
final completer = Completer<void>();
late StreamSubscription sub;
sub = service.onDebugEvent.listen((event) async {
if (event.kind == EventKind.kPauseBreakpoint) {
completer.complete();
await sub.cancel();
}
});
await service.streamListen(EventStreams.kDebug);
await service.resume(isolate.id!);
await completer.future;
}

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:developer';
main() {

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -11,8 +13,8 @@ import 'common/test_helper.dart';
void main() {
group('DDS', () {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process =
@ -20,8 +22,10 @@ void main() {
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
test('evaluate invokes client provided compileExpression RPC', () async {
@ -40,10 +44,9 @@ void main() {
throw 'error';
});
final vm = await service.getVM();
final isolate = await service.getIsolate(vm.isolates!.first.id!);
final isolate = await service.getIsolate(vm.isolates.first.id);
try {
await service.evaluate(
isolate.id!, isolate.libraries!.first.id!, '1 + 1');
await service.evaluate(isolate.id, isolate.libraries.first.id, '1 + 1');
} catch (_) {
// ignore error
}
@ -67,13 +70,11 @@ void main() {
throw 'error';
});
final vm = await service.getVM();
final isolate = await service.getIsolate(vm.isolates!.first.id!);
await service.resume(isolate.id!);
final isolate = await service.getIsolate(vm.isolates.first.id);
await service.resume(isolate.id);
try {
await service.evaluateInFrame(isolate.id!, 0, '1 + 1');
} catch (e, st) {
print(e);
print(st);
await service.evaluateInFrame(isolate.id, 0, '1 + 1');
} catch (_) {
// ignore error
}
expect(invokedCompileExpression, true);

View file

@ -1,6 +1,4 @@
// 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.
// @dart = 2.10
import 'dart:developer';

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -11,18 +13,19 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess(
'get_stream_history_script.dart',
);
process = await spawnDartProcess('get_stream_history_script.dart',
pauseOnStart: false);
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
test('getStreamHistory returns log history', () async {
@ -31,10 +34,6 @@ void main() {
);
expect(dds.isRunning, true);
final service = await vmServiceConnectUri(dds.wsUri.toString());
// Wait until the test script has finished writing logs.
await executeUntilNextPause(service);
final result = await service.getStreamHistory('Logging');
expect(result, isNotNull);
expect(result, isA<StreamHistory>());

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'package:dds/dds.dart';
@ -9,7 +11,6 @@ import 'package:dds/src/dds_impl.dart';
import 'package:dds/src/rpc_error_codes.dart';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'package:pedantic/pedantic.dart';
import 'package:test/fake.dart';
import 'package:test/test.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
@ -42,28 +43,15 @@ class StreamCancelDisconnectPeer extends FakePeer {
}
}
class FakeWebSocketSink extends Fake implements WebSocketSink {
@override
Future close([int? closeCode, String? closeReason]) {
// Do nothing.
return Future.value();
}
}
class FakeWebSocketChannel extends Fake implements WebSocketChannel {
@override
WebSocketSink get sink => FakeWebSocketSink();
}
void main() {
webSocketBuilder = (Uri _) => FakeWebSocketChannel();
webSocketBuilder = (Uri _) => null;
peerBuilder =
(WebSocketChannel _, dynamic __) async => StreamCancelDisconnectPeer();
test('StateError handled by _StreamManager.clientDisconnect', () async {
final dds = await DartDevelopmentService.startDartDevelopmentService(
Uri(scheme: 'http'));
final ws = await WebSocketChannel.connect(dds.uri!.replace(scheme: 'ws'));
final ws = await WebSocketChannel.connect(dds.uri.replace(scheme: 'ws'));
// Create a VM service client that connects to DDS.
final client = json_rpc.Client(ws.cast<String>());
@ -90,7 +78,7 @@ void main() {
() async {
final dds = await DartDevelopmentService.startDartDevelopmentService(
Uri(scheme: 'http'));
final ws = await WebSocketChannel.connect(dds.uri!.replace(scheme: 'ws'));
final ws = await WebSocketChannel.connect(dds.uri.replace(scheme: 'ws'));
// Create a VM service client that connects to DDS.
final client = json_rpc.Client(ws.cast<String>());

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'dart:io';
@ -16,7 +18,7 @@ import 'package:test/test.dart';
Future<Uri> startTestServer() async {
final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
server.listen((Socket request) async {
request.destroy();
await request.destroy();
await server.close();
});
return Uri(scheme: 'http', host: server.address.host, port: server.port);

View file

@ -1,3 +1,5 @@
// @dart=2.10
import 'dart:developer';
void main() {

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'dart:io';
@ -12,18 +14,19 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess(
'on_event_with_history_script.dart',
);
process = await spawnDartProcess('on_event_with_history_script.dart',
pauseOnStart: false);
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
test('onEventWithHistory returns stream including log history', () async {
@ -33,9 +36,6 @@ void main() {
expect(dds.isRunning, true);
final service = await vmServiceConnectUri(dds.wsUri.toString());
// Wait until the test script has finished writing its initial logs.
await executeUntilNextPause(service);
await service.streamListen('Logging');
final stream = service.onLoggingEventWithHistory;
@ -43,15 +43,16 @@ void main() {
int count = 0;
stream.listen((event) {
count++;
expect(event.logRecord!.message!.valueAsString, count.toString());
expect(event.logRecord.message.valueAsString, count.toString());
if (count % 10 == 0) {
completer.complete();
}
});
await completer.future;
completer = Completer<void>();
final isolateId = (await service.getVM()).isolates!.first.id!;
final isolateId = (await service.getVM()).isolates.first.id;
await service.resume(isolateId);
await completer.future;

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -10,8 +12,8 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
// We don't care what's actually running in the target process for this
@ -23,8 +25,10 @@ void main() {
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
test('Ensure streamListen and streamCancel calls are handled atomically',

View file

@ -1,3 +1,5 @@
// @dart=2.10
void main() {
print('Hello world!');
}

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:convert';
import 'dart:io';
@ -13,16 +15,18 @@ import 'common/test_helper.dart';
void main() {
group('DDS', () {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
void createSmokeTest(bool useAuthCodes, bool ipv6) {
@ -39,7 +43,7 @@ void main() {
expect(dds.isRunning, true);
try {
Uri.parseIPv6Address(dds.uri!.host);
Uri.parseIPv6Address(dds.uri.host);
expect(ipv6, true);
} on FormatException {
expect(ipv6, false);
@ -48,11 +52,11 @@ void main() {
// Ensure basic websocket requests are forwarded correctly to the VM service.
final service = await vmServiceConnectUri(dds.wsUri.toString());
final version = await service.getVersion();
expect(version.major! > 0, true);
expect(version.minor! >= 0, true);
expect(version.major > 0, true);
expect(version.minor >= 0, true);
expect(
dds.uri!.pathSegments,
dds.uri.pathSegments,
useAuthCodes ? isNotEmpty : isEmpty,
);
@ -69,7 +73,7 @@ void main() {
final Map<String, dynamic> jsonResponse = (await response
.transform(utf8.decoder)
.transform(json.decoder)
.single) as Map<String, dynamic>;
.single);
expect(jsonResponse['result']['type'], 'Version');
expect(jsonResponse['result']['major'] > 0, true);
expect(jsonResponse['result']['minor'] >= 0, true);
@ -83,6 +87,12 @@ void main() {
});
test('Invalid args test', () async {
// null VM Service URI
expect(
() async =>
await DartDevelopmentService.startDartDevelopmentService(null),
throwsA(TypeMatcher<ArgumentError>()));
// Non-HTTP VM Service URI scheme
expect(
() async => await DartDevelopmentService.startDartDevelopmentService(

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -21,12 +23,12 @@ import 'common/test_helper.dart';
// environment variables.
void main() {
late Process chromeDriver;
late DartDevelopmentService dds;
late SseHandler handler;
Process? process;
late HttpServer server;
late WebDriver webdriver;
Process chromeDriver;
DartDevelopmentService dds;
SseHandler handler;
Process process;
HttpServer server;
WebDriver webdriver;
setUpAll(() async {
final chromedriverUri = Platform.script.resolveUri(
@ -72,10 +74,11 @@ void main() {
});
tearDown(() async {
await dds.shutdown();
await dds?.shutdown();
process?.kill();
await webdriver.quit();
await server.close();
dds = null;
process = null;
});
@ -94,11 +97,11 @@ void main() {
// Replace the sse scheme with http as sse isn't supported for CORS.
testeeConnection.sink
.add(dds.sseUri!.replace(scheme: 'http').toString());
.add(dds.sseUri.replace(scheme: 'http').toString());
final response = json.decode(await testeeConnection.stream.first);
final version = service.Version.parse(response)!;
expect(version.major! > 0, isTrue);
expect(version.minor! >= 0, isTrue);
final version = service.Version.parse(response);
expect(version.major > 0, isTrue);
expect(version.minor >= 0, isTrue);
},
);
}

View file

@ -2,6 +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.
// @dart=2.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -10,15 +12,17 @@ import 'package:test/test.dart';
import 'common/test_helper.dart';
void main() {
late Process process;
late DartDevelopmentService dds;
Process process;
DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds.shutdown();
process.kill();
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
});
Future<int> getAvailablePort() async {
@ -67,8 +71,8 @@ void main() {
// just make sure that it's at the right address and port.
expect(dds.uri.toString().contains(serviceUri.toString()), isTrue);
expect(dds.uri!.pathSegments, isNotEmpty);
final authCode = dds.uri!.pathSegments.first;
expect(dds.uri.pathSegments, isNotEmpty);
final authCode = dds.uri.pathSegments.first;
expect(
dds.sseUri,
serviceUri.replace(

View file

@ -2,6 +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.
// @dart=2.10
// This file must be compiled for changes to be picked up.
//
// Run the following command from the root of this package if this file is

View file

@ -390,7 +390,7 @@ class _ServiceTesterRunner {
if (useDds) {
dds = await DartDevelopmentService.startDartDevelopmentService(
serverAddress);
setupAddresses(dds.uri!);
setupAddresses(dds.uri);
} else {
setupAddresses(serverAddress);
}

View file

@ -57,6 +57,7 @@ void main(List<String> args) {
packageDirectory(
'runtime/observatory_2/tests/service_2/observatory_test_package_2'),
packageDirectory('sdk/lib/_internal/sdk_library_metadata'),
packageDirectory('third_party/devtools/devtools_server'),
packageDirectory('third_party/devtools/devtools_shared'),
packageDirectory('third_party/pkg/protobuf/protobuf'),
packageDirectory('tools/package_deps'),