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

This reverts commit b8c5ecd5aa.

TEST=N/A

Change-Id: I38bbebe1e38bc9dbfdde764eff847aafb3e39353
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200926
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Ben Konyi 2021-05-24 16:59:23 +00:00
parent 3db3b937f2
commit 7250fd6379
43 changed files with 298 additions and 348 deletions

View file

@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
"generated": "2021-05-21T16:08:02.444059",
"generated": "2021-05-24T09:58:37.618570",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@ -252,17 +252,11 @@
"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.3"
"languageVersion": "2.12"
},
{
"name": "diagnostic",

2
DEPS
View file

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

View file

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

View file

@ -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.10
import 'package:dds/dds.dart';
import 'package:vm_service/vm_service_io.dart';

View file

@ -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.10
/// A library used to spawn the Dart Developer Service, used to communicate
/// with a Dart VM Service instance.
library dds;
@ -41,15 +39,12 @@ abstract class DartDevelopmentService {
/// default.
static Future<DartDevelopmentService> startDartDevelopmentService(
Uri remoteVmServiceUri, {
Uri serviceUri,
Uri? serviceUri,
bool enableAuthCodes = true,
bool ipv6 = false,
DevToolsConfiguration devToolsConfiguration = const DevToolsConfiguration(),
DevToolsConfiguration? 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}',
@ -65,12 +60,15 @@ 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);
final address = addresses.firstWhere(
(a) => (a.type ==
(ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4)),
orElse: () => null,
);
if (address == null) {
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.
throw ArgumentError(
"serviceUri '$serviceUri' is not an IPv${ipv6 ? "6" : "4"} address.",
);
@ -115,24 +113,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.
@ -180,8 +178,8 @@ class DartDevelopmentServiceException implements Exception {
class DevToolsConfiguration {
const DevToolsConfiguration({
required this.customBuildDirectoryPath,
this.enable = false,
this.customBuildDirectoryPath,
});
final bool enable;

View file

@ -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.10
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

View file

@ -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.10
import 'dart:async';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -26,7 +24,7 @@ class DartDevelopmentServiceClient {
WebSocketChannel ws,
json_rpc.Peer vmServicePeer,
) : this._(
dds,
dds as DartDevelopmentServiceImpl,
ws,
vmServicePeer,
);
@ -36,7 +34,7 @@ class DartDevelopmentServiceClient {
SseConnection sse,
json_rpc.Peer vmServicePeer,
) : this._(
dds,
dds as DartDevelopmentServiceImpl,
sse,
vmServicePeer,
);
@ -167,7 +165,8 @@ class DartDevelopmentServiceClient {
(parameters) => {
'type': 'Size',
'size': StreamManager
.loggingRepositories[StreamManager.kLoggingStream].bufferSize,
.loggingRepositories[StreamManager.kLoggingStream]!
.bufferSize,
});
_clientPeer.registerMethod('setLogHistorySize', (parameters) {
@ -177,7 +176,7 @@ class DartDevelopmentServiceClient {
"'size' must be greater or equal to zero",
);
}
StreamManager.loggingRepositories[StreamManager.kLoggingStream]
StreamManager.loggingRepositories[StreamManager.kLoggingStream]!
.resize(size);
return RPCResponses.success;
});
@ -193,8 +192,8 @@ class DartDevelopmentServiceClient {
});
_clientPeer.registerMethod('getSupportedProtocols', (parameters) async {
final Map<String, dynamic> supportedProtocols =
await _vmServicePeer.sendRequest('getSupportedProtocols');
final Map<String, dynamic> supportedProtocols = (await _vmServicePeer
.sendRequest('getSupportedProtocols')) as Map<String, dynamic>;
final ddsVersion = DartDevelopmentService.protocolVersion.split('.');
final ddsProtocol = {
'protocolName': 'DDS',
@ -289,17 +288,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;
json_rpc.Peer _clientPeer;
late json_rpc.Peer _clientPeer;
}

View file

@ -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.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'client.dart';
@ -98,7 +96,7 @@ class ClientManager {
pauseTypeMask |= PauseTypeMasks.pauseOnExitMask;
}
clientResumePermissions[client.name].permissionsMask = pauseTypeMask;
clientResumePermissions[client.name!]!.permissionsMask = pauseTypeMask;
return RPCResponses.success;
}
@ -111,10 +109,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
@ -155,7 +153,7 @@ class ClientManager {
}
}
DartDevelopmentServiceClient findFirstClientThatHandlesService(
DartDevelopmentServiceClient? findFirstClientThatHandlesService(
String service) {
for (final client in clients) {
if (client.services.containsKey(service)) {
@ -173,7 +171,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,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.10
abstract class RPCResponses {
static const success = <String, dynamic>{
'type': 'Success',

View file

@ -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.10
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -172,13 +170,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();
}
@ -267,16 +265,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 buildDir =
_devToolsConfiguration.customBuildDirectoryPath?.toFilePath();
final String buildDir =
_devToolsConfiguration!.customBuildDirectoryPath.toFilePath();
return devtoolsHandler(
dds: this,
buildDir: buildDir,
notFoundHandler: proxyHandler(remoteVmServiceUri),
);
) as FutureOr<Response> Function(Request);
}
return proxyHandler(remoteVmServiceUri);
}
@ -294,7 +292,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
return pathSegments;
}
Uri _toWebSocket(Uri uri) {
Uri? _toWebSocket(Uri? uri) {
if (uri == null) {
return null;
}
@ -303,7 +301,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;
}
@ -312,7 +310,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.
@ -325,7 +323,7 @@ class DartDevelopmentServiceImpl implements DartDevelopmentService {
).query;
return Uri(
scheme: 'http',
host: uri.host,
host: uri!.host,
port: uri.port,
pathSegments: [
...uri.pathSegments.where(
@ -338,56 +336,61 @@ 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;
Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri);
@override
Uri get remoteVmServiceWsUri => _toWebSocket(_remoteVmServiceUri)!;
Uri _remoteVmServiceUri;
Uri get uri => _uri;
Uri _uri;
@override
Uri? get uri => _uri;
Uri? _uri;
Uri get sseUri => _toSse(_uri);
@override
Uri? get sseUri => _toSse(_uri);
Uri get wsUri => _toWebSocket(_uri);
@override
Uri? get wsUri => _toWebSocket(_uri);
Uri get devToolsUri =>
_devToolsConfiguration.enable ? _toDevTools(_uri) : null;
@override
Uri? get devToolsUri =>
_devToolsConfiguration?.enable ?? false ? _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;
ClientManager _clientManager;
late ClientManager _clientManager;
ExpressionEvaluator get expressionEvaluator => _expressionEvaluator;
ExpressionEvaluator _expressionEvaluator;
late ExpressionEvaluator _expressionEvaluator;
IsolateManager get isolateManager => _isolateManager;
IsolateManager _isolateManager;
late IsolateManager _isolateManager;
StreamManager get streamManager => _streamManager;
StreamManager _streamManager;
late StreamManager _streamManager;
static const _kSseHandlerPath = '\$debugHandler';
json_rpc.Peer vmServiceClient;
WebSocketChannel _vmServiceSocket;
HttpServer _server;
late json_rpc.Peer vmServiceClient;
late WebSocketChannel _vmServiceSocket;
late HttpServer _server;
}

View file

@ -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 'package:json_rpc_2/src/server.dart' as json_rpc;
@ -22,7 +20,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);
}
@ -59,7 +57,7 @@ class DevToolsClient {
}
_server = json_rpc.Server(
StreamChannel(stream, sink),
StreamChannel(stream, sink as StreamSink<String>),
strictProtocolChecks: false,
);
_registerJsonRpcMethods();
@ -92,5 +90,5 @@ class DevToolsClient {
});
}
json_rpc.Server _server;
late json_rpc.Server _server;
}

View file

@ -2,12 +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.
// @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';
@ -24,9 +21,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,8 +2,6 @@
// 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.
@ -18,7 +16,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;
}
@ -46,7 +44,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.
@ -63,7 +61,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,8 +2,6 @@
// 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.
@ -33,7 +31,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) {
@ -42,7 +40,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
@ -50,7 +48,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,
@ -76,7 +74,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));
@ -92,7 +90,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;
@ -125,7 +123,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,
@ -157,7 +155,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.');
@ -170,7 +168,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.');
@ -188,7 +186,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
@ -215,7 +213,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,8 +2,6 @@
// 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.
@ -21,13 +19,13 @@ class FlutterUsage {
/// used for testing.
FlutterUsage({
String settingsName = 'flutter',
String versionOverride,
String configDirOverride,
String? versionOverride,
String? configDirOverride,
}) {
_analytics = AnalyticsIO('', settingsName, '');
}
Analytics _analytics;
late Analytics _analytics;
/// Does the .flutter store exist?
static bool get doesStoreExist {
@ -48,8 +46,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(
@ -70,9 +68,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;
IOPersistentProperties properties;
late IOPersistentProperties properties;
static const _surveyActionTaken = 'surveyActionTaken';
static const _surveyShownCount = 'surveyShownCount';
@ -95,23 +93,21 @@ 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) {
assert(activeSurvey != null);
void _addSurvey(String? surveyName) {
assert(activeSurvey == surveyName);
rewriteActiveSurvey(false, 0);
}
String get activeSurvey => _activeSurvey;
String? get activeSurvey => _activeSurvey;
set activeSurvey(String surveyName) {
assert(surveyName != null);
set activeSurvey(String? surveyName) {
_activeSurvey = surveyName;
if (!surveyNameExists(activeSurvey)) {
@ -121,16 +117,14 @@ class DevToolsUsage {
}
/// Need to rewrite the entire survey structure for property to be persisted.
void rewriteActiveSurvey(bool actionTaken, int shownCount) {
assert(activeSurvey != null);
void rewriteActiveSurvey(bool? actionTaken, int? shownCount) {
properties[activeSurvey] = {
_surveyActionTaken: actionTaken,
_surveyShownCount: shownCount,
};
}
int get surveyShownCount {
assert(activeSurvey != null);
int? get surveyShownCount {
final prop = properties[activeSurvey];
if (prop[_surveyShownCount] == null) {
rewriteActiveSurvey(prop[_surveyActionTaken], 0);
@ -139,19 +133,16 @@ 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) {
assert(activeSurvey != null);
set surveyActionTaken(bool? value) {
final prop = properties[activeSurvey];
rewriteActiveSurvey(value, prop[_surveyShownCount]);
}
@ -177,7 +168,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();
@ -196,22 +187,22 @@ class IOPersistentProperties extends PersistentProperties {
syncSettings();
}
File _file;
late 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 {
@ -231,6 +222,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.
// @dart=2.10
import 'dart:async';
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(null) != null) {
if (parameters['scope'].asMapOr({}).isNotEmpty) {
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(null) != null) {
if (parameters['scope'].asMapOr({}).isNotEmpty) {
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,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.10
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'client.dart';
@ -56,7 +54,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);
@ -75,7 +73,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);
@ -85,9 +83,9 @@ class _RunningIsolate {
isolateManager.dds.clientManager.clientResumePermissions;
// Determine which clients require approval for this pause type.
permissions.forEach((name, clientNamePermissions) {
permissions.forEach((clientName, clientNamePermissions) {
if (clientNamePermissions.permissionsMask & _isolateStateMask != 0) {
requiredClientApprovals.add(name);
requiredClientApprovals.add(clientName!);
}
});
@ -116,8 +114,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 {
@ -152,16 +150,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;
@ -237,12 +235,13 @@ class IsolateManager {
String isolateId,
json_rpc.Parameters parameters,
) async {
final step = parameters['step'].asStringOr(null);
final frameIndex = parameters['frameIndex'].asIntOr(null);
const invalidFrameIndex = -1;
final step = parameters['step'].asStringOr('');
final frameIndex = parameters['frameIndex'].asIntOr(invalidFrameIndex);
final resumeResult = await dds.vmServiceClient.sendRequest('resume', {
'isolateId': isolateId,
if (step != null) 'step': step,
if (frameIndex != null) 'frameIndex': frameIndex,
if (step.isNotEmpty) 'step': step,
if (frameIndex != invalidFrameIndex) 'frameIndex': frameIndex,
});
return resumeResult;
}

View file

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

View file

@ -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.10
// Originally pulled from dart:_vmservice.
import 'dart:collection';
@ -25,14 +23,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,15 +2,13 @@
// 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,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.10
import 'dart:typed_data';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
@ -27,10 +25,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) {
@ -64,7 +62,7 @@ class StreamManager {
String service,
String alias,
) {
final namespace = dds.getNamespace(client);
final namespace = dds.getNamespace(client)!;
streamNotify(
kServiceStream,
_buildStreamRegisteredEvent(namespace, service, alias),
@ -86,7 +84,7 @@ class StreamManager {
'kind': 'ServiceUnregistered',
'timestamp': DateTime.now().millisecondsSinceEpoch,
'service': service,
'method': namespace + '.' + service,
'method': namespace! + '.' + service,
},
},
excludedClient: client,
@ -120,7 +118,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);
},
@ -132,10 +130,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 != null && stream.isNotEmpty);
assert(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
@ -152,13 +150,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.
@ -171,9 +169,9 @@ class StreamManager {
client.sendNotification(
'streamNotify',
_buildStreamRegisteredEvent(
namespace,
namespace!,
service,
c.services[service],
c.services[service]!,
),
);
}
@ -182,12 +180,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'],
];
}
@ -196,13 +194,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 != null && stream.isNotEmpty);
assert(stream.isNotEmpty);
final listeners = streamListeners[stream];
if (client != null && (listeners == null || !listeners.contains(client))) {
if (listeners == null || client != null && !listeners.contains(client)) {
throw kStreamNotSubscribedException;
}
listeners.remove(client);

View file

@ -2,19 +2,16 @@
// 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.
@ -25,7 +22,7 @@ extension DdsExtension on VmService {
_ddsVersion =
await _callHelper<Version>('getDartDevelopmentServiceVersion');
}
return _ddsVersion;
return _ddsVersion!;
}
/// Retrieve the event history for `stream`.
@ -47,19 +44,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) {
StreamController<Event> controller;
StreamQueue<Event> streamEvents;
late StreamController<Event> controller;
late 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);
@ -109,12 +106,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();
}
@ -135,10 +132,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: 1.8.0
version: 2.0.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds

View file

@ -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.10
import 'dart:convert';
import 'dart:io';
@ -15,18 +13,16 @@ import 'common/test_helper.dart';
void main() {
group('DDS', () {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
test('Bad Auth Code', () async {
@ -38,8 +34,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,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.10
import 'dart:async';
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;

View file

@ -2,12 +2,13 @@
// 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';
Uri remoteVmServiceUri;
import 'package:vm_service/vm_service.dart';
late Uri remoteVmServiceUri;
Future<Process> spawnDartProcess(
String script, {
@ -41,3 +42,20 @@ 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,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.10
import 'dart:developer';
main() {

View file

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

View file

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

View file

@ -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.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -13,19 +11,18 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('get_stream_history_script.dart',
pauseOnStart: false);
process = await spawnDartProcess(
'get_stream_history_script.dart',
);
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
test('getStreamHistory returns log history', () async {
@ -34,6 +31,10 @@ 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,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.10
import 'dart:async';
import 'package:dds/dds.dart';
@ -11,6 +9,7 @@ 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';
@ -43,15 +42,28 @@ 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 _) => null;
webSocketBuilder = (Uri _) => FakeWebSocketChannel();
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>());
@ -78,7 +90,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,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.10
import 'dart:async';
import 'dart:io';
@ -18,7 +16,7 @@ import 'package:test/test.dart';
Future<Uri> startTestServer() async {
final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
server.listen((Socket request) async {
await request.destroy();
request.destroy();
await server.close();
});
return Uri(scheme: 'http', host: server.address.host, port: server.port);

View file

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

View file

@ -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.10
import 'dart:async';
import 'dart:io';
@ -14,19 +12,18 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('on_event_with_history_script.dart',
pauseOnStart: false);
process = await spawnDartProcess(
'on_event_with_history_script.dart',
);
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
test('onEventWithHistory returns stream including log history', () async {
@ -36,6 +33,9 @@ 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,16 +43,15 @@ 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,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.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -12,8 +10,8 @@ import 'package:vm_service/vm_service_io.dart';
import 'common/test_helper.dart';
void main() {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
// We don't care what's actually running in the target process for this
@ -25,10 +23,8 @@ void main() {
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
test('Ensure streamListen and streamCancel calls are handled atomically',

View file

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

View file

@ -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.10
import 'dart:convert';
import 'dart:io';
@ -15,18 +13,16 @@ import 'common/test_helper.dart';
void main() {
group('DDS', () {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
void createSmokeTest(bool useAuthCodes, bool ipv6) {
@ -43,7 +39,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);
@ -52,11 +48,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,
);
@ -73,7 +69,7 @@ void main() {
final Map<String, dynamic> jsonResponse = (await response
.transform(utf8.decoder)
.transform(json.decoder)
.single);
.single) as Map<String, dynamic>;
expect(jsonResponse['result']['type'], 'Version');
expect(jsonResponse['result']['major'] > 0, true);
expect(jsonResponse['result']['minor'] >= 0, true);
@ -87,12 +83,6 @@ 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,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.10
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -23,12 +21,12 @@ import 'common/test_helper.dart';
// environment variables.
void main() {
Process chromeDriver;
DartDevelopmentService dds;
SseHandler handler;
Process process;
HttpServer server;
WebDriver webdriver;
late Process chromeDriver;
late DartDevelopmentService dds;
late SseHandler handler;
Process? process;
late HttpServer server;
late WebDriver webdriver;
setUpAll(() async {
final chromedriverUri = Platform.script.resolveUri(
@ -74,11 +72,10 @@ void main() {
});
tearDown(() async {
await dds?.shutdown();
await dds.shutdown();
process?.kill();
await webdriver.quit();
await server.close();
dds = null;
process = null;
});
@ -97,11 +94,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,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.10
import 'dart:io';
import 'package:dds/dds.dart';
@ -12,17 +10,15 @@ import 'package:test/test.dart';
import 'common/test_helper.dart';
void main() {
Process process;
DartDevelopmentService dds;
late Process process;
late DartDevelopmentService dds;
setUp(() async {
process = await spawnDartProcess('smoke.dart');
});
tearDown(() async {
await dds?.shutdown();
process?.kill();
dds = null;
process = null;
await dds.shutdown();
process.kill();
});
Future<int> getAvailablePort() async {
@ -71,8 +67,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,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.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,7 +57,6 @@ 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('third_party/pkg/webdev/frontend_server_client'),