migrate vm service to null safety (#88320)

This commit is contained in:
Christopher Fujino 2021-10-02 10:18:03 -07:00 committed by GitHub
parent 0e78416737
commit 91dd3276fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 380 additions and 380 deletions

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.8
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
@ -48,12 +46,12 @@ const List<Map<String, Object>> kMaterialFonts = <Map<String, Object>>[
/// Injected factory class for spawning [AssetBundle] instances.
abstract class AssetBundleFactory {
/// The singleton instance, pulled from the [AppContext].
static AssetBundleFactory get instance => context.get<AssetBundleFactory>();
static AssetBundleFactory get instance => context.get<AssetBundleFactory>()!;
static AssetBundleFactory defaultInstance({
@required Logger logger,
@required FileSystem fileSystem,
@required Platform platform,
required Logger logger,
required FileSystem fileSystem,
required Platform platform,
bool splitDeferredAssets = false,
}) => _ManifestAssetBundleFactory(logger: logger, fileSystem: fileSystem, platform: platform, splitDeferredAssets: splitDeferredAssets);
@ -82,18 +80,18 @@ abstract class AssetBundle {
/// Returns 0 for success; non-zero for failure.
Future<int> build({
String manifestPath = defaultManifestPath,
String assetDirPath,
@required String packagesPath,
String? assetDirPath,
required String packagesPath,
bool deferredComponentsEnabled = false,
TargetPlatform targetPlatform,
TargetPlatform? targetPlatform,
});
}
class _ManifestAssetBundleFactory implements AssetBundleFactory {
_ManifestAssetBundleFactory({
@required Logger logger,
@required FileSystem fileSystem,
@required Platform platform,
required Logger logger,
required FileSystem fileSystem,
required Platform platform,
bool splitDeferredAssets = false,
}) : _logger = logger,
_fileSystem = fileSystem,
@ -114,9 +112,9 @@ class ManifestAssetBundle implements AssetBundle {
/// Constructs an [ManifestAssetBundle] that gathers the set of assets from the
/// pubspec.yaml manifest.
ManifestAssetBundle({
@required Logger logger,
@required FileSystem fileSystem,
@required Platform platform,
required Logger logger,
required FileSystem fileSystem,
required Platform platform,
bool splitDeferredAssets = false,
}) : _logger = logger,
_fileSystem = fileSystem,
@ -144,7 +142,7 @@ class ManifestAssetBundle implements AssetBundle {
// the current project.
final Map<Uri, Directory> _wildcardDirectories = <Uri, Directory>{};
DateTime _lastBuildTimestamp;
DateTime? _lastBuildTimestamp;
static const String _kAssetManifestJson = 'AssetManifest.json';
static const String _kNoticeFile = 'NOTICES';
@ -161,7 +159,7 @@ class ManifestAssetBundle implements AssetBundle {
@override
bool needsBuild({ String manifestPath = defaultManifestPath }) {
final DateTime lastBuildTimestamp = _lastBuildTimestamp;
final DateTime? lastBuildTimestamp = _lastBuildTimestamp;
if (lastBuildTimestamp == null) {
return true;
}
@ -192,10 +190,10 @@ class ManifestAssetBundle implements AssetBundle {
@override
Future<int> build({
String manifestPath = defaultManifestPath,
String assetDirPath,
@required String packagesPath,
String? assetDirPath,
required String packagesPath,
bool deferredComponentsEnabled = false,
TargetPlatform targetPlatform,
TargetPlatform? targetPlatform,
}) async {
assetDirPath ??= getAssetBuildDirectory();
FlutterProject flutterProject;
@ -244,7 +242,7 @@ class ManifestAssetBundle implements AssetBundle {
if (flutterProject.linux.existsSync())
flutterProject.linux.managedDirectory.path,
];
final Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
final Map<_Asset, List<_Asset>>? assetVariants = _parseAssets(
packageConfig,
flutterManifest,
wildcardDirectories,
@ -274,7 +272,7 @@ class ManifestAssetBundle implements AssetBundle {
}
final bool includesMaterialFonts = flutterManifest.usesMaterialDesign;
final List<Map<String, dynamic>> fonts = _parseFonts(
final List<Map<String, Object?>> fonts = _parseFonts(
flutterManifest,
packageConfig,
primary: true,
@ -287,7 +285,7 @@ class ManifestAssetBundle implements AssetBundle {
if (packageUri != null && packageUri.scheme == 'file') {
final String packageManifestPath = _fileSystem.path.fromUri(packageUri.resolve('../pubspec.yaml'));
inputFiles.add(_fileSystem.file(packageManifestPath));
final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath(
final FlutterManifest? packageFlutterManifest = FlutterManifest.createFromPath(
packageManifestPath,
logger: _logger,
fileSystem: _fileSystem,
@ -309,7 +307,7 @@ class ManifestAssetBundle implements AssetBundle {
}
final String packageBasePath = _fileSystem.path.dirname(packageManifestPath);
final Map<_Asset, List<_Asset>> packageAssets = _parseAssets(
final Map<_Asset, List<_Asset>>? packageAssets = _parseAssets(
packageConfig,
packageFlutterManifest,
// Do not track wildcard directories for dependencies.
@ -344,11 +342,12 @@ class ManifestAssetBundle implements AssetBundle {
// asset in entries.
for (final _Asset asset in assetVariants.keys) {
final File assetFile = asset.lookupAssetFile(_fileSystem);
if (!assetFile.existsSync() && assetVariants[asset].isEmpty) {
final List<_Asset> variants = assetVariants[asset]!;
if (!assetFile.existsSync() && variants.isEmpty) {
_logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
_logger.printError('No file or variants found for $asset.\n');
if (asset.package != null) {
_logger.printError('This asset was included from package ${asset.package.name}.');
_logger.printError('This asset was included from package ${asset.package?.name}.');
}
return 1;
}
@ -359,10 +358,10 @@ class ManifestAssetBundle implements AssetBundle {
// "1x" resolution variant and if both exist then the explicit 1x
// variant is preferred.
if (assetFile.existsSync()) {
assert(!assetVariants[asset].contains(asset));
assetVariants[asset].insert(0, asset);
assert(!variants.contains(asset));
variants.insert(0, asset);
}
for (final _Asset variant in assetVariants[asset]) {
for (final _Asset variant in variants) {
final File variantFile = variant.lookupAssetFile(_fileSystem);
inputFiles.add(variantFile);
assert(variantFile.existsSync());
@ -374,13 +373,14 @@ class ManifestAssetBundle implements AssetBundle {
if (deferredComponentsAssetVariants != null) {
for (final String componentName in deferredComponentsAssetVariants.keys) {
deferredComponentsEntries[componentName] = <String, DevFSContent>{};
for (final _Asset asset in deferredComponentsAssetVariants[componentName].keys) {
final Map<_Asset, List<_Asset>> assetsMap = deferredComponentsAssetVariants[componentName]!;
for (final _Asset asset in assetsMap.keys) {
final File assetFile = asset.lookupAssetFile(_fileSystem);
if (!assetFile.existsSync() && deferredComponentsAssetVariants[componentName][asset].isEmpty) {
if (!assetFile.existsSync() && assetsMap[asset]!.isEmpty) {
_logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
_logger.printError('No file or variants found for $asset.\n');
if (asset.package != null) {
_logger.printError('This asset was included from package ${asset.package.name}.');
_logger.printError('This asset was included from package ${asset.package?.name}.');
}
return 1;
}
@ -391,13 +391,13 @@ class ManifestAssetBundle implements AssetBundle {
// "1x" resolution variant and if both exist then the explicit 1x
// variant is preferred.
if (assetFile.existsSync()) {
assert(!deferredComponentsAssetVariants[componentName][asset].contains(asset));
deferredComponentsAssetVariants[componentName][asset].insert(0, asset);
assert(!assetsMap[asset]!.contains(asset));
assetsMap[asset]!.insert(0, asset);
}
for (final _Asset variant in deferredComponentsAssetVariants[componentName][asset]) {
for (final _Asset variant in assetsMap[asset]!) {
final File variantFile = variant.lookupAssetFile(_fileSystem);
assert(variantFile.existsSync());
deferredComponentsEntries[componentName][variant.entryUri.path] ??= DevFSFileContent(variantFile);
deferredComponentsEntries[componentName]![variant.entryUri.path] ??= DevFSFileContent(variantFile);
}
}
}
@ -455,7 +455,7 @@ class ManifestAssetBundle implements AssetBundle {
entries[key] = content;
return;
}
final DevFSStringContent oldContent = entries[key] as DevFSStringContent;
final DevFSStringContent? oldContent = entries[key] as DevFSStringContent?;
if (oldContent?.string != content.string) {
entries[key] = content;
}
@ -463,7 +463,7 @@ class ManifestAssetBundle implements AssetBundle {
void _setLicenseIfChanged(
String combinedLicenses,
TargetPlatform targetPlatform,
TargetPlatform? targetPlatform,
) {
// On the web, don't compress the NOTICES file since the client doesn't have
// dart:io to decompress it. So use the standard _setIfChanged to check if
@ -478,7 +478,7 @@ class ManifestAssetBundle implements AssetBundle {
// the uncompressed strings to not incur decompression/decoding while making
// the comparison.
if (!entries.containsKey(_kNoticeZippedFile) ||
(entries[_kNoticeZippedFile] as DevFSStringCompressingBytesContent)
(entries[_kNoticeZippedFile] as DevFSStringCompressingBytesContent?)
?.equals(combinedLicenses) != true) {
entries[_kNoticeZippedFile] = DevFSStringCompressingBytesContent(
combinedLicenses,
@ -493,18 +493,18 @@ class ManifestAssetBundle implements AssetBundle {
List<_Asset> _getMaterialAssets() {
final List<_Asset> result = <_Asset>[];
for (final Map<String, Object> family in kMaterialFonts) {
final Object fonts = family['fonts'];
final Object? fonts = family['fonts'];
if (fonts == null) {
continue;
}
for (final Map<String, Object> font in fonts as List<Map<String, String>>) {
final String asset = font['asset'] as String;
final String? asset = font['asset'] as String?;
if (asset == null) {
continue;
}
final Uri entryUri = _fileSystem.path.toUri(asset);
result.add(_Asset(
baseDir: _fileSystem.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
baseDir: _fileSystem.path.join(Cache.flutterRoot!, 'bin', 'cache', 'artifacts', 'material_fonts'),
relativeUri: Uri(path: entryUri.pathSegments.last),
entryUri: entryUri,
package: null,
@ -515,13 +515,13 @@ class ManifestAssetBundle implements AssetBundle {
return result;
}
List<Map<String, dynamic>> _parseFonts(
List<Map<String, Object?>> _parseFonts(
FlutterManifest manifest,
PackageConfig packageConfig, {
String packageName,
@required bool primary,
String? packageName,
required bool primary,
}) {
return <Map<String, dynamic>>[
return <Map<String, Object?>>[
if (primary && manifest.usesMaterialDesign)
...kMaterialFonts,
if (packageName == null)
@ -543,7 +543,7 @@ class ManifestAssetBundle implements AssetBundle {
Directory projectDirectory, {
List<String> excludeDirs = const <String>[],
}) {
final List<DeferredComponent> components = flutterManifest.deferredComponents;
final List<DeferredComponent>? components = flutterManifest.deferredComponents;
final Map<String, Map<_Asset, List<_Asset>>> deferredComponentsAssetVariants = <String, Map<_Asset, List<_Asset>>>{};
if (components == null) {
return deferredComponentsAssetVariants;
@ -559,7 +559,7 @@ class ManifestAssetBundle implements AssetBundle {
flutterManifest,
assetBasePath,
cache,
deferredComponentsAssetVariants[component.name],
deferredComponentsAssetVariants[component.name]!,
assetUri,
excludeDirs: excludeDirs,
);
@ -569,7 +569,7 @@ class ManifestAssetBundle implements AssetBundle {
flutterManifest,
assetBasePath,
cache,
deferredComponentsAssetVariants[component.name],
deferredComponentsAssetVariants[component.name]!,
assetUri,
excludeDirs: excludeDirs,
);
@ -604,7 +604,7 @@ class ManifestAssetBundle implements AssetBundle {
final List<_Asset> sortedKeys = jsonEntries.keys.toList()
..sort((_Asset left, _Asset right) => left.entryUri.path.compareTo(right.entryUri.path));
for (final _Asset main in sortedKeys) {
jsonObject[main.entryUri.path] = jsonEntries[main];
jsonObject[main.entryUri.path] = jsonEntries[main]!;
}
return DevFSStringContent(json.encode(jsonObject));
}
@ -623,7 +623,7 @@ class ManifestAssetBundle implements AssetBundle {
final Uri assetUri = fontAsset.assetUri;
if (assetUri.pathSegments.first == 'packages' &&
!_fileSystem.isFileSync(_fileSystem.path.fromUri(
packageConfig[packageName]?.packageUriRoot?.resolve('../${assetUri.path}')))) {
packageConfig[packageName]?.packageUriRoot.resolve('../${assetUri.path}')))) {
packageFontAssets.add(FontAsset(
fontAsset.assetUri,
weight: fontAsset.weight,
@ -667,14 +667,14 @@ class ManifestAssetBundle implements AssetBundle {
/// ],
/// }
/// ```
Map<_Asset, List<_Asset>> _parseAssets(
Map<_Asset, List<_Asset>>? _parseAssets(
PackageConfig packageConfig,
FlutterManifest flutterManifest,
List<Uri> wildcardDirectories,
String assetBase, {
List<String> excludeDirs = const <String>[],
String packageName,
Package attributedPackage,
String? packageName,
Package? attributedPackage,
}) {
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
@ -737,8 +737,8 @@ class ManifestAssetBundle implements AssetBundle {
Map<_Asset, List<_Asset>> result,
Uri assetUri, {
List<String> excludeDirs = const <String>[],
String packageName,
Package attributedPackage,
String? packageName,
Package? attributedPackage,
}) {
final String directoryPath = _fileSystem.path.join(
assetBase, assetUri.toFilePath(windows: _platform.isWindows));
@ -777,8 +777,8 @@ class ManifestAssetBundle implements AssetBundle {
Map<_Asset, List<_Asset>> result,
Uri assetUri, {
List<String> excludeDirs = const <String>[],
String packageName,
Package attributedPackage,
String? packageName,
Package? attributedPackage,
}) {
final _Asset asset = _resolveAsset(
packageConfig,
@ -792,7 +792,7 @@ class ManifestAssetBundle implements AssetBundle {
for (final String path in cache.variantsFor(assetFile.path)) {
final String relativePath = _fileSystem.path.relative(path, from: asset.baseDir);
final Uri relativeUri = _fileSystem.path.toUri(relativePath);
final Uri entryUri = asset.symbolicPrefixUri == null
final Uri? entryUri = asset.symbolicPrefixUri == null
? relativeUri
: asset.symbolicPrefixUri?.resolveUri(relativeUri);
if (entryUri != null) {
@ -814,15 +814,15 @@ class ManifestAssetBundle implements AssetBundle {
PackageConfig packageConfig,
String assetsBaseDir,
Uri assetUri,
String packageName,
Package attributedPackage,
String? packageName,
Package? attributedPackage,
) {
final String assetPath = _fileSystem.path.fromUri(assetUri);
if (assetUri.pathSegments.first == 'packages'
&& !_fileSystem.isFileSync(_fileSystem.path.join(assetsBaseDir, assetPath))) {
// The asset is referenced in the pubspec.yaml as
// 'packages/PACKAGE_NAME/PATH/TO/ASSET .
final _Asset packageAsset = _resolvePackageAsset(
final _Asset? packageAsset = _resolvePackageAsset(
assetUri,
packageConfig,
attributedPackage,
@ -842,12 +842,12 @@ class ManifestAssetBundle implements AssetBundle {
);
}
_Asset _resolvePackageAsset(Uri assetUri, PackageConfig packageConfig, Package attributedPackage) {
_Asset? _resolvePackageAsset(Uri assetUri, PackageConfig packageConfig, Package? attributedPackage) {
assert(assetUri.pathSegments.first == 'packages');
if (assetUri.pathSegments.length > 1) {
final String packageName = assetUri.pathSegments[1];
final Package package = packageConfig[packageName];
final Uri packageUri = package?.packageUriRoot;
final Package? package = packageConfig[packageName];
final Uri? packageUri = package?.packageUriRoot;
if (packageUri != null && packageUri.scheme == 'file') {
return _Asset(
baseDir: _fileSystem.path.fromUri(packageUri),
@ -869,15 +869,15 @@ class ManifestAssetBundle implements AssetBundle {
@immutable
class _Asset {
const _Asset({
@required this.baseDir,
@required this.relativeUri,
@required this.entryUri,
@required this.package,
required this.baseDir,
required this.relativeUri,
required this.entryUri,
required this.package,
});
final String baseDir;
final Package package;
final Package? package;
/// A platform-independent URL where this asset can be found on disk on the
/// host system relative to [baseDir].
@ -892,7 +892,7 @@ class _Asset {
/// The delta between what the entryUri is and the relativeUri (e.g.,
/// packages/flutter_gallery).
Uri get symbolicPrefixUri {
Uri? get symbolicPrefixUri {
if (entryUri == relativeUri) {
return null;
}
@ -966,11 +966,11 @@ class _AssetDirectoryCache {
continue;
}
variants[variantName] ??= <String>[];
variants[variantName].add(path);
variants[variantName]!.add(path);
}
_cache[directory] = variants;
}
return _cache[directory][assetName] ?? const <String>[];
return _cache[directory]![assetName] ?? const <String>[];
}
}

View file

@ -471,8 +471,8 @@ abstract class ResidentCompiler {
List<Uri>? invalidatedFiles, {
required String outputPath,
required PackageConfig packageConfig,
required String projectRootPath,
required FileSystem fs,
String? projectRootPath,
bool suppressErrors = false,
bool checkDartPluginRegistry = false,
});

View file

@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
@ -29,7 +26,7 @@ class DevFSConfig {
bool noDirectorySymlinks = false;
}
DevFSConfig get devFSConfig => context.get<DevFSConfig>();
DevFSConfig? get devFSConfig => context.get<DevFSConfig>();
/// Common superclass for content copied to the device.
abstract class DevFSContent {
@ -60,11 +57,11 @@ class DevFSFileContent extends DevFSContent {
DevFSFileContent(this.file);
final FileSystemEntity file;
File _linkTarget;
FileStat _fileStat;
File? _linkTarget;
FileStat? _fileStat;
File _getFile() {
final File linkTarget = _linkTarget;
final File? linkTarget = _linkTarget;
if (linkTarget != null) {
return linkTarget;
}
@ -76,7 +73,7 @@ class DevFSFileContent extends DevFSContent {
}
void _stat() {
final File linkTarget = _linkTarget;
final File? linkTarget = _linkTarget;
if (linkTarget != null) {
// Stat the cached symlink target.
final FileStat fileStat = linkTarget.statSync();
@ -106,9 +103,9 @@ class DevFSFileContent extends DevFSContent {
@override
bool get isModified {
final FileStat oldFileStat = _fileStat;
final FileStat? oldFileStat = _fileStat;
_stat();
final FileStat newFileStat = _fileStat;
final FileStat? newFileStat = _fileStat;
if (oldFileStat == null && newFileStat == null) {
return false;
}
@ -117,9 +114,9 @@ class DevFSFileContent extends DevFSContent {
@override
bool isModifiedAfter(DateTime time) {
final FileStat oldFileStat = _fileStat;
final FileStat? oldFileStat = _fileStat;
_stat();
final FileStat newFileStat = _fileStat;
final FileStat? newFileStat = _fileStat;
if (oldFileStat == null && newFileStat == null) {
return false;
}
@ -218,7 +215,7 @@ class DevFSStringContent extends DevFSByteContent {
/// The `hintString` parameter is a zlib dictionary hinting mechanism to suggest
/// the most common string occurrences to potentially assist with compression.
class DevFSStringCompressingBytesContent extends DevFSContent {
DevFSStringCompressingBytesContent(this._string, { String hintString })
DevFSStringCompressingBytesContent(this._string, { String? hintString })
: _compressor = ZLibEncoder(
dictionary: hintString == null
? null
@ -231,10 +228,9 @@ class DevFSStringCompressingBytesContent extends DevFSContent {
final ZLibEncoder _compressor;
final DateTime _modificationTime = DateTime.now();
List<int> _bytes;
bool _isModified = true;
List<int> get bytes => _bytes ??= _compressor.convert(utf8.encode(_string));
late final List<int> bytes = _compressor.convert(utf8.encode(_string));
/// Return true only once so that the content is written to the device only once.
@override
@ -266,7 +262,7 @@ class DevFSException implements Exception {
DevFSException(this.message, [this.error, this.stackTrace]);
final String message;
final dynamic error;
final StackTrace stackTrace;
final StackTrace? stackTrace;
@override
String toString() => 'DevFSException($message, $error, $stackTrace)';
@ -286,10 +282,10 @@ class _DevFSHttpWriter implements DevFSWriter {
_DevFSHttpWriter(
this.fsName,
FlutterVmService serviceProtocol, {
@required OperatingSystemUtils osUtils,
@required HttpClient httpClient,
@required Logger logger,
Duration uploadRetryThrottle,
required OperatingSystemUtils osUtils,
required HttpClient httpClient,
required Logger logger,
Duration? uploadRetryThrottle,
})
: httpAddress = serviceProtocol.httpAddress,
_client = httpClient,
@ -300,10 +296,10 @@ class _DevFSHttpWriter implements DevFSWriter {
final HttpClient _client;
final OperatingSystemUtils _osUtils;
final Logger _logger;
final Duration _uploadRetryThrottle;
final Duration? _uploadRetryThrottle;
final String fsName;
final Uri httpAddress;
final Uri? httpAddress;
// 3 was chosen to try to limit the variance in the time it takes to execute
// `await request.close()` since there is a known bug in Dart where it doesn't
@ -312,11 +308,11 @@ class _DevFSHttpWriter implements DevFSWriter {
static const int kMaxInFlight = 3;
int _inFlight = 0;
Map<Uri, DevFSContent> _outstanding = <Uri, DevFSContent>{};
Completer<void> _completer = Completer<void>();
late Map<Uri, DevFSContent> _outstanding;
late Completer<void> _completer;
@override
Future<void> write(Map<Uri, DevFSContent> entries, Uri devFSBase, [DevFSWriter parent]) async {
Future<void> write(Map<Uri, DevFSContent> entries, Uri devFSBase, [DevFSWriter? parent]) async {
try {
_client.maxConnectionsPerHost = kMaxInFlight;
_completer = Completer<void>();
@ -335,7 +331,7 @@ class _DevFSHttpWriter implements DevFSWriter {
void _scheduleWrites() {
while ((_inFlight < kMaxInFlight) && (!_completer.isCompleted) && _outstanding.isNotEmpty) {
final Uri deviceUri = _outstanding.keys.first;
final DevFSContent content = _outstanding.remove(deviceUri);
final DevFSContent content = _outstanding.remove(deviceUri)!;
_startWrite(deviceUri, content, retry: 10);
_inFlight += 1;
}
@ -351,7 +347,7 @@ class _DevFSHttpWriter implements DevFSWriter {
}) async {
while(true) {
try {
final HttpClientRequest request = await _client.putUrl(httpAddress);
final HttpClientRequest request = await _client.putUrl(httpAddress!);
request.headers.removeAll(HttpHeaders.acceptEncodingHeader);
request.headers.add('dev_fs_name', fsName);
request.headers.add('dev_fs_uri_b64', base64.encode(utf8.encode('$deviceUri')));
@ -424,7 +420,7 @@ class UpdateFSReport {
Duration get findInvalidatedDuration => _findInvalidatedDuration;
bool _success;
String fastReassembleClassName;
String? fastReassembleClassName;
int _invalidatedSourcesCount;
int _syncedBytes;
int _scannedSourcesCount;
@ -454,11 +450,11 @@ class DevFS {
FlutterVmService serviceProtocol,
this.fsName,
this.rootDirectory, {
@required OperatingSystemUtils osUtils,
@required Logger logger,
@required FileSystem fileSystem,
HttpClient httpClient,
Duration uploadRetryThrottle,
required OperatingSystemUtils osUtils,
required Logger logger,
required FileSystem fileSystem,
HttpClient? httpClient,
Duration? uploadRetryThrottle,
StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) : _vmService = serviceProtocol,
_logger = logger,
@ -471,7 +467,7 @@ class DevFS {
uploadRetryThrottle: uploadRetryThrottle,
httpClient: httpClient ?? ((context.get<HttpClientFactory>() == null)
? HttpClient()
: context.get<HttpClientFactory>()())),
: context.get<HttpClientFactory>()!())),
_stopwatchFactory = stopwatchFactory;
final FlutterVmService _vmService;
@ -488,13 +484,13 @@ class DevFS {
bool hasSetAssetDirectory = false;
List<Uri> sources = <Uri>[];
DateTime lastCompiled;
DateTime _previousCompiled;
PackageConfig lastPackageConfig;
File _widgetCacheOutputFile;
DateTime? lastCompiled;
DateTime? _previousCompiled;
PackageConfig? lastPackageConfig;
File? _widgetCacheOutputFile;
Uri _baseUri;
Uri get baseUri => _baseUri;
Uri? _baseUri;
Uri? get baseUri => _baseUri;
Uri deviceUriToHostUri(Uri deviceUri) {
final String deviceUriString = deviceUri.toString();
@ -510,7 +506,7 @@ class DevFS {
_logger.printTrace('DevFS: Creating new filesystem on the device ($_baseUri)');
try {
final vm_service.Response response = await _vmService.createDevFS(fsName);
_baseUri = Uri.parse(response.json['uri'] as String);
_baseUri = Uri.parse(response.json!['uri'] as String);
} on vm_service.RPCError catch (rpcException) {
if (rpcException.code == RPCErrorCodes.kServiceDisappeared) {
// This can happen if the device has been disconnected, so translate to
@ -526,10 +522,10 @@ class DevFS {
_logger.printTrace('DevFS: Creating failed. Destroying and trying again');
await destroy();
final vm_service.Response response = await _vmService.createDevFS(fsName);
_baseUri = Uri.parse(response.json['uri'] as String);
_baseUri = Uri.parse(response.json!['uri'] as String);
}
_logger.printTrace('DevFS: Created new filesystem on the device ($_baseUri)');
return _baseUri;
return _baseUri!;
}
Future<void> destroy() async {
@ -556,8 +552,8 @@ class DevFS {
///
/// If any other changes were made, or there is an error scanning the file,
/// return `null`.
String _checkIfSingleWidgetReloadApplied() {
final File widgetCacheOutputFile = _widgetCacheOutputFile;
String? _checkIfSingleWidgetReloadApplied() {
final File? widgetCacheOutputFile = _widgetCacheOutputFile;
if (widgetCacheOutputFile != null && widgetCacheOutputFile.existsSync()) {
final String widget = widgetCacheOutputFile.readAsStringSync().trim();
if (widget.isNotEmpty) {
@ -571,20 +567,20 @@ class DevFS {
///
/// Returns the number of bytes synced.
Future<UpdateFSReport> update({
@required Uri mainUri,
@required ResidentCompiler generator,
@required bool trackWidgetCreation,
@required String pathToReload,
@required List<Uri> invalidatedFiles,
@required PackageConfig packageConfig,
@required String dillOutputPath,
DevFSWriter devFSWriter,
String target,
AssetBundle bundle,
DateTime firstBuildTime,
required Uri mainUri,
required ResidentCompiler generator,
required bool trackWidgetCreation,
required String pathToReload,
required List<Uri> invalidatedFiles,
required PackageConfig packageConfig,
required String dillOutputPath,
DevFSWriter? devFSWriter,
String? target,
AssetBundle? bundle,
DateTime? firstBuildTime,
bool bundleFirstUpload = false,
bool fullRestart = false,
String projectRootPath,
String? projectRootPath,
}) async {
assert(trackWidgetCreation != null);
assert(generator != null);
@ -606,7 +602,7 @@ class DevFS {
// Await the compiler response after checking if the bundle is updated. This allows the file
// stating to be done while waiting for the frontend_server response.
final Stopwatch compileTimer = _stopwatchFactory.createStopwatch('compile')..start();
final Future<CompilerOutput> pendingCompilerOutput = generator.recompile(
final Future<CompilerOutput?> pendingCompilerOutput = generator.recompile(
mainUri,
invalidatedFiles,
outputPath: dillOutputPath,
@ -614,7 +610,7 @@ class DevFS {
projectRootPath: projectRootPath,
packageConfig: packageConfig,
checkDartPluginRegistry: true, // The entry point is assumed not to have changed.
).then((CompilerOutput result) {
).then((CompilerOutput? result) {
compileTimer.stop();
return result;
});
@ -641,7 +637,7 @@ class DevFS {
}
});
}
final CompilerOutput compilerOutput = await pendingCompilerOutput;
final CompilerOutput? compilerOutput = await pendingCompilerOutput;
if (compilerOutput == null || compilerOutput.errorCount > 0) {
return UpdateFSReport(success: false);
}
@ -654,8 +650,8 @@ class DevFS {
// Don't send full kernel file that would overwrite what VM already
// started loading from.
if (!bundleFirstUpload) {
final String compiledBinary = compilerOutput?.outputFilename;
if (compiledBinary != null && compiledBinary.isNotEmpty) {
final String compiledBinary = compilerOutput.outputFilename;
if (compiledBinary.isNotEmpty) {
final Uri entryUri = _fileSystem.path.toUri(pathToReload);
final DevFSFileContent content = DevFSFileContent(_fileSystem.file(compiledBinary));
syncedBytes += content.size;
@ -665,7 +661,7 @@ class DevFS {
_logger.printTrace('Updating files.');
final Stopwatch transferTimer = _stopwatchFactory.createStopwatch('transfer')..start();
if (dirtyEntries.isNotEmpty) {
await (devFSWriter ?? _httpWriter).write(dirtyEntries, _baseUri, _httpWriter);
await (devFSWriter ?? _httpWriter).write(dirtyEntries, _baseUri!, _httpWriter);
}
transferTimer.stop();
_logger.printTrace('DevFS: Sync finished');
@ -693,16 +689,17 @@ class DevFS {
/// Requires that the file system is the same for both the tool and application.
class LocalDevFSWriter implements DevFSWriter {
LocalDevFSWriter({
@required FileSystem fileSystem,
required FileSystem fileSystem,
}) : _fileSystem = fileSystem;
final FileSystem _fileSystem;
@override
Future<void> write(Map<Uri, DevFSContent> entries, Uri baseUri, [DevFSWriter parent]) async {
Future<void> write(Map<Uri, DevFSContent> entries, Uri baseUri, [DevFSWriter? parent]) async {
try {
for (final Uri uri in entries.keys) {
final DevFSContent devFSContent = entries[uri];
for (final MapEntry<Uri, DevFSContent> entry in entries.entries) {
final Uri uri = entry.key;
final DevFSContent devFSContent = entry.value;
final File destination = _fileSystem.file(baseUri.resolveUri(uri));
if (!destination.parent.existsSync()) {
destination.parent.createSync(recursive: true);

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.8
import 'dart:async';
import 'dart:math' as math;
@ -25,7 +23,7 @@ import 'device_port_forwarder.dart';
import 'project.dart';
import 'vmservice.dart';
DeviceManager get deviceManager => context.get<DeviceManager>();
DeviceManager? get deviceManager => context.get<DeviceManager>();
/// A description of the kind of workflow the device supports.
class Category {
@ -63,9 +61,9 @@ class PlatformType {
/// A discovery mechanism for flutter-supported development devices.
abstract class DeviceManager {
DeviceManager({
@required Logger logger,
@required Terminal terminal,
@required UserMessages userMessages,
required Logger logger,
required Terminal terminal,
required UserMessages userMessages,
}) : _logger = logger,
_terminal = terminal,
_userMessages = userMessages;
@ -78,17 +76,17 @@ abstract class DeviceManager {
/// of their methods are called.
List<DeviceDiscovery> get deviceDiscoverers;
String _specifiedDeviceId;
String? _specifiedDeviceId;
/// A user-specified device ID.
String get specifiedDeviceId {
String? get specifiedDeviceId {
if (_specifiedDeviceId == null || _specifiedDeviceId == 'all') {
return null;
}
return _specifiedDeviceId;
}
set specifiedDeviceId(String id) {
set specifiedDeviceId(String? id) {
_specifiedDeviceId = id;
}
@ -120,7 +118,7 @@ abstract class DeviceManager {
// found quickly, we don't wait for all the discoverers to complete.
final List<Device> prefixMatches = <Device>[];
final Completer<Device> exactMatchCompleter = Completer<Device>();
final List<Future<List<Device>>> futureDevices = <Future<List<Device>>>[
final List<Future<List<Device>?>> futureDevices = <Future<List<Device>?>>[
for (final DeviceDiscovery discoverer in _platformDiscoverers)
if (!hasWellKnownId || discoverer.wellKnownIds.contains(specifiedDeviceId))
discoverer
@ -143,9 +141,9 @@ abstract class DeviceManager {
];
// Wait for an exact match, or for all discoverers to return results.
await Future.any<dynamic>(<Future<dynamic>>[
await Future.any<Object>(<Future<Object>>[
exactMatchCompleter.future,
Future.wait<List<Device>>(futureDevices),
Future.wait<List<Device>?>(futureDevices),
]);
if (exactMatchCompleter.isCompleted) {
@ -156,9 +154,11 @@ abstract class DeviceManager {
/// Returns the list of connected devices, filtered by any user-specified device id.
Future<List<Device>> getDevices() {
return hasSpecifiedDeviceId
? getDevicesById(specifiedDeviceId)
: getAllConnectedDevices();
final String? id = specifiedDeviceId;
if (id == null) {
return getAllConnectedDevices();
}
return getDevicesById(id);
}
Iterable<DeviceDiscovery> get _platformDiscoverers {
@ -176,7 +176,7 @@ abstract class DeviceManager {
}
/// Returns the list of all connected devices. Discards existing cache of devices.
Future<List<Device>> refreshAllConnectedDevices({ Duration timeout }) async {
Future<List<Device>> refreshAllConnectedDevices({ Duration? timeout }) async {
final List<List<Device>> devices = await Future.wait<List<Device>>(<Future<List<Device>>>[
for (final DeviceDiscovery discoverer in _platformDiscoverers)
discoverer.discoverDevices(timeout: timeout),
@ -214,7 +214,7 @@ abstract class DeviceManager {
///
/// * If [flutterProject] is null, then assume the project supports all
/// device types.
Future<List<Device>> findTargetDevices(FlutterProject flutterProject, { Duration timeout }) async {
Future<List<Device>> findTargetDevices(FlutterProject flutterProject, { Duration? timeout }) async {
if (timeout != null) {
// Reset the cache with the specified timeout.
await refreshAllConnectedDevices(timeout: timeout);
@ -338,7 +338,7 @@ abstract class DeviceDiscovery {
Future<List<Device>> get devices;
/// Return all connected devices. Discards existing cache of devices.
Future<List<Device>> discoverDevices({ Duration timeout });
Future<List<Device>> discoverDevices({ Duration? timeout });
/// Gets a list of diagnostic messages pertaining to issues with any connected
/// devices (will be an empty list if there are no issues).
@ -366,11 +366,11 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
@protected
@visibleForTesting
ItemListNotifier<Device> deviceNotifier;
ItemListNotifier<Device>? deviceNotifier;
Timer _timer;
Timer? _timer;
Future<List<Device>> pollingGetDevices({ Duration timeout });
Future<List<Device>> pollingGetDevices({ Duration? timeout });
void startPolling() {
if (_timer == null) {
@ -380,11 +380,11 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
}
}
Timer _initTimer(Duration pollingTimeout) {
Timer _initTimer(Duration? pollingTimeout) {
return Timer(_pollingInterval, () async {
try {
final List<Device> devices = await pollingGetDevices(timeout: pollingTimeout);
deviceNotifier.updateWithNewList(devices);
deviceNotifier!.updateWithNewList(devices);
} on TimeoutException {
// Do nothing on a timeout.
}
@ -404,24 +404,24 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
}
@override
Future<List<Device>> discoverDevices({ Duration timeout }) {
Future<List<Device>> discoverDevices({ Duration? timeout }) {
deviceNotifier = null;
return _populateDevices(timeout: timeout);
}
Future<List<Device>> _populateDevices({ Duration timeout }) async {
Future<List<Device>> _populateDevices({ Duration? timeout }) async {
deviceNotifier ??= ItemListNotifier<Device>.from(await pollingGetDevices(timeout: timeout));
return deviceNotifier.items;
return deviceNotifier!.items;
}
Stream<Device> get onAdded {
deviceNotifier ??= ItemListNotifier<Device>();
return deviceNotifier.onAdded;
return deviceNotifier!.onAdded;
}
Stream<Device> get onRemoved {
deviceNotifier ??= ItemListNotifier<Device>();
return deviceNotifier.onRemoved;
return deviceNotifier!.onRemoved;
}
void dispose() => stopPolling();
@ -436,9 +436,9 @@ abstract class PollingDeviceDiscovery extends DeviceDiscovery {
/// the host operating system in the case of Flutter Desktop.
abstract class Device {
Device(this.id, {
@required this.category,
@required this.platformType,
@required this.ephemeral,
required this.category,
required this.platformType,
required this.ephemeral,
});
final String id;
@ -534,7 +534,7 @@ abstract class Device {
///
/// For example, the desktop device classes can use a writer which
/// copies the files across the local file system.
DevFSWriter createDevFSWriter(
DevFSWriter? createDevFSWriter(
covariant ApplicationPackage app,
String userIdentifier,
) {
@ -564,7 +564,7 @@ abstract class Device {
void clearLogs();
/// Optional device-specific artifact overrides.
OverrideArtifacts get artifactOverrides => null;
OverrideArtifacts? get artifactOverrides => null;
/// Start an app package on the current device.
///
@ -575,7 +575,7 @@ abstract class Device {
String mainPath,
String route,
DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs,
Map<String, Object?> platformArgs,
bool prebuiltApplication = false,
bool ipv6 = false,
String userIdentifier,
@ -817,8 +817,8 @@ class DebuggingOptions {
final bool enableSoftwareRendering;
final bool skiaDeterministicRendering;
final bool traceSkia;
final String traceAllowlist;
final String traceSkiaAllowlist;
final String? traceAllowlist;
final String? traceSkiaAllowlist;
final bool traceSystrace;
final bool endlessTraceBuffer;
final bool dumpSkpOnShaderCompilation;
@ -826,14 +826,14 @@ class DebuggingOptions {
final bool purgePersistentCache;
final bool useTestFonts;
final bool verboseSystemLogs;
final int hostVmServicePort;
final int deviceVmServicePort;
final int? hostVmServicePort;
final int? deviceVmServicePort;
final bool disablePortPublication;
final int ddsPort;
final Uri devToolsServerAddress;
final String port;
final String hostname;
final bool webEnableExposeUrl;
final int? ddsPort;
final Uri? devToolsServerAddress;
final String? port;
final String? hostname;
final bool? webEnableExposeUrl;
final bool webUseSseForDebugProxy;
final bool webUseSseForDebugBackend;
final bool webUseSseForInjectedClient;
@ -846,13 +846,13 @@ class DebuggingOptions {
final bool webRunHeadless;
/// The port the browser should use for its debugging protocol.
final int webBrowserDebugPort;
final int? webBrowserDebugPort;
/// Enable expression evaluation for web target.
final bool webEnableExpressionEvaluation;
/// A file where the VM Service URL should be written after the application is started.
final String vmserviceOutFile;
final String? vmserviceOutFile;
final bool fastStart;
final bool nullAssertions;
@ -875,7 +875,7 @@ class LaunchResult {
bool get hasObservatory => observatoryUri != null;
final bool started;
final Uri observatoryUri;
final Uri? observatoryUri;
@override
String toString() {
@ -896,13 +896,13 @@ abstract class DeviceLogReader {
/// Some logs can be obtained from a VM service stream.
/// Set this after the VM services are connected.
FlutterVmService connectedVMService;
FlutterVmService? connectedVMService;
@override
String toString() => name;
/// Process ID of the app on the device.
int appPid;
int? appPid;
// Clean up resources allocated by log reader e.g. subprocesses
void dispose();
@ -923,10 +923,10 @@ class NoOpDeviceLogReader implements DeviceLogReader {
final String name;
@override
int appPid;
int? appPid;
@override
FlutterVmService connectedVMService;
FlutterVmService? connectedVMService;
@override
Stream<String> get logLines => const Stream<String>.empty();
@ -939,7 +939,7 @@ class NoOpDeviceLogReader implements DeviceLogReader {
/// [debuggingOptions.nullAssertions] is true.
String computeDartVmFlags(DebuggingOptions debuggingOptions) {
return <String>[
if (debuggingOptions.dartFlags?.isNotEmpty ?? false)
if (debuggingOptions.dartFlags.isNotEmpty)
debuggingOptions.dartFlags,
if (debuggingOptions.nullAssertions)
'--null_assertions',

View file

@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'package:meta/meta.dart' show required, visibleForTesting;
import 'package:meta/meta.dart' show visibleForTesting;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'base/common.dart';
@ -31,7 +29,7 @@ const int kIsolateReloadBarred = 1005;
/// Override `WebSocketConnector` in [context] to use a different constructor
/// for [WebSocket]s (used by tests).
typedef WebSocketConnector = Future<io.WebSocket> Function(String url, {io.CompressionOptions compression, @required Logger logger});
typedef WebSocketConnector = Future<io.WebSocket> Function(String url, {io.CompressionOptions compression, required Logger logger});
typedef PrintStructuredErrorLogMethod = void Function(vm_service.Event);
@ -41,7 +39,7 @@ WebSocketConnector _openChannel = _defaultOpenChannel;
///
/// Provide a `null` value to restore the original connector.
@visibleForTesting
set openChannelForTesting(WebSocketConnector connector) {
set openChannelForTesting(WebSocketConnector? connector) {
_openChannel = connector ?? _defaultOpenChannel;
}
@ -93,7 +91,7 @@ typedef CompileExpression = Future<String> Function(
List<String> definitions,
List<String> typeDefinitions,
String libraryUri,
String klass,
String? klass,
bool isStatic,
);
@ -104,13 +102,13 @@ typedef GetSkSLMethod = Future<String> Function();
Future<io.WebSocket> _defaultOpenChannel(String url, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
@required Logger logger,
required Logger logger,
}) async {
Duration delay = const Duration(milliseconds: 100);
int attempts = 0;
io.WebSocket socket;
io.WebSocket? socket;
Future<void> handleError(dynamic e) async {
Future<void> handleError(Object? e) async {
void Function(String) printVisibleTrace = logger.printTrace;
if (attempts == 10) {
logger.printStatus('Connecting to the VM Service is taking longer than expected...');
@ -142,7 +140,7 @@ Future<io.WebSocket> _defaultOpenChannel(String url, {
final WebSocketConnector constructor = context.get<WebSocketConnector>() ?? (String url, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
@required Logger logger,
Logger? logger,
}) => io.WebSocket.connect(url, compression: compression);
while (socket == null) {
@ -161,14 +159,14 @@ Future<io.WebSocket> _defaultOpenChannel(String url, {
/// Override `VMServiceConnector` in [context] to return a different VMService
/// from [VMService.connect] (used by tests).
typedef VMServiceConnector = Future<FlutterVmService> Function(Uri httpUri, {
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression,
Device device,
@required Logger logger,
Device? device,
required Logger logger,
});
/// Set up the VM Service client by attaching services for each of the provided
@ -176,12 +174,12 @@ typedef VMServiceConnector = Future<FlutterVmService> Function(Uri httpUri, {
///
/// All parameters besides [vmService] may be null.
Future<vm_service.VmService> setUpVmService(
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
Device device,
GetSkSLMethod skSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
Device? device,
GetSkSLMethod? skSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
vm_service.VmService vmService
) async {
// Each service registration requires a request to the attached VM service. Since the
@ -189,14 +187,14 @@ Future<vm_service.VmService> setUpVmService(
// all at the end of this method.
final List<Future<vm_service.Success>> registrationRequests = <Future<vm_service.Success>>[];
if (reloadSources != null) {
vmService.registerServiceCallback('reloadSources', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('reloadSources', (Map<String, Object?> params) async {
final String isolateId = _validateRpcStringParam('reloadSources', params, 'isolateId');
final bool force = _validateRpcBoolParam('reloadSources', params, 'force');
final bool pause = _validateRpcBoolParam('reloadSources', params, 'pause');
await reloadSources(isolateId, force: force, pause: pause);
return <String, dynamic>{
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
}
@ -206,10 +204,10 @@ Future<vm_service.VmService> setUpVmService(
}
if (restart != null) {
vmService.registerServiceCallback('hotRestart', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('hotRestart', (Map<String, Object?> params) async {
final bool pause = _validateRpcBoolParam('compileExpression', params, 'pause');
await restart(pause: pause);
return <String, dynamic>{
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
}
@ -218,12 +216,12 @@ Future<vm_service.VmService> setUpVmService(
registrationRequests.add(vmService.registerService('hotRestart', 'Flutter Tools'));
}
vmService.registerServiceCallback('flutterVersion', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('flutterVersion', (Map<String, Object?> params) async {
final FlutterVersion version = context.get<FlutterVersion>() ?? FlutterVersion();
final Map<String, Object> versionJson = version.toJson();
versionJson['frameworkRevisionShort'] = version.frameworkRevisionShort;
versionJson['engineRevisionShort'] = version.engineRevisionShort;
return <String, dynamic>{
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
...versionJson,
@ -233,29 +231,29 @@ Future<vm_service.VmService> setUpVmService(
registrationRequests.add(vmService.registerService('flutterVersion', 'Flutter Tools'));
if (compileExpression != null) {
vmService.registerServiceCallback('compileExpression', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('compileExpression', (Map<String, Object?> params) async {
final String isolateId = _validateRpcStringParam('compileExpression', params, 'isolateId');
final String expression = _validateRpcStringParam('compileExpression', params, 'expression');
final List<String> definitions = List<String>.from(params['definitions'] as List<dynamic>);
final List<String> typeDefinitions = List<String>.from(params['typeDefinitions'] as List<dynamic>);
final String libraryUri = params['libraryUri'] as String;
final String klass = params['klass'] as String;
final List<String> definitions = List<String>.from(params['definitions']! as List<Object?>);
final List<String> typeDefinitions = List<String>.from(params['typeDefinitions']! as List<Object?>);
final String libraryUri = params['libraryUri']! as String;
final String? klass = params['klass'] as String?;
final bool isStatic = _validateRpcBoolParam('compileExpression', params, 'isStatic');
final String kernelBytesBase64 = await compileExpression(isolateId,
expression, definitions, typeDefinitions, libraryUri, klass,
isStatic);
return <String, dynamic>{
return <String, Object>{
'type': 'Success',
'result': <String, dynamic>{'kernelBytes': kernelBytesBase64},
'result': <String, String>{'kernelBytes': kernelBytesBase64},
};
});
registrationRequests.add(vmService.registerService('compileExpression', 'Flutter Tools'));
}
if (device != null) {
vmService.registerServiceCallback('flutterMemoryInfo', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('flutterMemoryInfo', (Map<String, Object?> params) async {
final MemoryInfo result = await device.queryMemoryInfo();
return <String, dynamic>{
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
...result.toJson(),
@ -265,9 +263,9 @@ Future<vm_service.VmService> setUpVmService(
registrationRequests.add(vmService.registerService('flutterMemoryInfo', 'Flutter Tools'));
}
if (skSLMethod != null) {
vmService.registerServiceCallback('flutterGetSkSL', (Map<String, dynamic> params) async {
vmService.registerServiceCallback('flutterGetSkSL', (Map<String, Object?> params) async {
final String filename = await skSLMethod();
return <String, dynamic>{
return <String, Object>{
'result': <String, Object>{
'type': 'Success',
'filename': filename,
@ -282,7 +280,7 @@ Future<vm_service.VmService> setUpVmService(
// thrown if we're already subscribed.
registrationRequests.add(vmService
.streamListen(vm_service.EventStreams.kExtension)
.catchError((dynamic error) {}, test: (dynamic error) => error is vm_service.RPCError)
.catchError((Object? error) {}, test: (Object? error) => error is vm_service.RPCError)
);
}
@ -304,14 +302,14 @@ Future<vm_service.VmService> setUpVmService(
/// See: https://github.com/dart-lang/sdk/commit/df8bf384eb815cf38450cb50a0f4b62230fba217
Future<FlutterVmService> connectToVmService(
Uri httpUri, {
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
@required Logger logger,
Device? device,
required Logger logger,
}) async {
final VMServiceConnector connector = context.get<VMServiceConnector>() ?? _connect;
return connector(httpUri,
@ -329,7 +327,7 @@ Future<FlutterVmService> connectToVmService(
Future<vm_service.VmService> createVmServiceDelegate(
Uri wsUri, {
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
@required Logger logger,
required Logger logger,
}) async {
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
return vm_service.VmService(
@ -344,14 +342,14 @@ Future<vm_service.VmService> createVmServiceDelegate(
Future<FlutterVmService> _connect(
Uri httpUri, {
ReloadSources reloadSources,
Restart restart,
CompileExpression compileExpression,
GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
Device device,
@required Logger logger,
Device? device,
required Logger logger,
}) async {
final Uri wsUri = httpUri.replace(scheme: 'ws', path: urlContext.join(httpUri.path, 'ws'));
final vm_service.VmService delegateService = await createVmServiceDelegate(
@ -374,20 +372,20 @@ Future<FlutterVmService> _connect(
return FlutterVmService(service, httpAddress: httpUri, wsAddress: wsUri);
}
String _validateRpcStringParam(String methodName, Map<String, dynamic> params, String paramName) {
final dynamic value = params[paramName];
if (value is! String || (value as String).isEmpty) {
String _validateRpcStringParam(String methodName, Map<String, Object?> params, String paramName) {
final Object? value = params[paramName];
if (value is! String || value.isEmpty) {
throw vm_service.RPCError(
methodName,
RPCErrorCodes.kInvalidParams,
"Invalid '$paramName': $value",
);
}
return value as String;
return value;
}
bool _validateRpcBoolParam(String methodName, Map<String, dynamic> params, String paramName) {
final dynamic value = params[paramName];
bool _validateRpcBoolParam(String methodName, Map<String, Object?> params, String paramName) {
final Object? value = params[paramName];
if (value != null && value is! bool) {
throw vm_service.RPCError(
methodName,
@ -395,30 +393,30 @@ bool _validateRpcBoolParam(String methodName, Map<String, dynamic> params, Strin
"Invalid '$paramName': $value",
);
}
return (value as bool) ?? false;
return (value as bool?) ?? false;
}
/// Peered to an Android/iOS FlutterView widget on a device.
class FlutterView {
FlutterView({
@required this.id,
@required this.uiIsolate,
required this.id,
required this.uiIsolate,
});
factory FlutterView.parse(Map<String, Object> json) {
final Map<String, Object> rawIsolate = json['isolate'] as Map<String, Object>;
vm_service.IsolateRef isolate;
final Map<String, Object?>? rawIsolate = json['isolate'] as Map<String, Object?>?;
vm_service.IsolateRef? isolate;
if (rawIsolate != null) {
rawIsolate['number'] = rawIsolate['number']?.toString();
isolate = vm_service.IsolateRef.parse(rawIsolate);
}
return FlutterView(
id: json['id'] as String,
id: json['id']! as String,
uiIsolate: isolate,
);
}
final vm_service.IsolateRef uiIsolate;
final vm_service.IsolateRef? uiIsolate;
final String id;
bool get hasIsolate => uiIsolate != null;
@ -426,8 +424,8 @@ class FlutterView {
@override
String toString() => id;
Map<String, Object> toJson() {
return <String, Object>{
Map<String, Object?> toJson() {
return <String, Object?>{
'id': id,
'isolate': uiIsolate?.toJson(),
};
@ -436,16 +434,20 @@ class FlutterView {
/// Flutter specific VM Service functionality.
class FlutterVmService {
FlutterVmService(this.service, {this.wsAddress, this.httpAddress});
FlutterVmService(
this.service, {
this.wsAddress,
this.httpAddress,
});
final vm_service.VmService service;
final Uri wsAddress;
final Uri httpAddress;
final Uri? wsAddress;
final Uri? httpAddress;
Future<vm_service.Response> callMethodWrapper(
Future<vm_service.Response?> callMethodWrapper(
String method, {
String isolateId,
Map<String, dynamic> args
String? isolateId,
Map<String, Object?>? args
}) async {
try {
return await service.callMethod(method, isolateId: isolateId, args: args);
@ -463,14 +465,13 @@ class FlutterVmService {
/// Set the asset directory for the an attached Flutter view.
Future<void> setAssetDirectory({
@required Uri assetsDirectory,
@required String viewId,
@required String uiIsolateId,
required Uri assetsDirectory,
required String? viewId,
required String? uiIsolateId,
}) async {
assert(assetsDirectory != null);
await callMethodWrapper(kSetAssetBundlePathMethod,
isolateId: uiIsolateId,
args: <String, dynamic>{
args: <String, Object?>{
'viewId': viewId,
'assetDirectory': assetsDirectory.toFilePath(windows: false),
});
@ -480,10 +481,10 @@ class FlutterVmService {
///
/// This method will only return data if `--cache-sksl` was provided as a
/// flutter run argument, and only then on physical devices.
Future<Map<String, Object>> getSkSLs({
@required String viewId,
Future<Map<String, Object>?> getSkSLs({
required String viewId,
}) async {
final vm_service.Response response = await callMethodWrapper(
final vm_service.Response? response = await callMethodWrapper(
kGetSkSLsMethod,
args: <String, String>{
'viewId': viewId,
@ -492,14 +493,14 @@ class FlutterVmService {
if (response == null) {
return null;
}
return response.json['SkSLs'] as Map<String, Object>;
return response.json?['SkSLs'] as Map<String, Object>?;
}
/// Flush all tasks on the UI thread for an attached Flutter view.
///
/// This method is currently used only for benchmarking.
Future<void> flushUIThreadTasks({
@required String uiIsolateId,
required String uiIsolateId,
}) async {
await callMethodWrapper(
kFlushUIThreadTasksMethod,
@ -515,9 +516,9 @@ class FlutterVmService {
/// This method is used by the tool to hot restart an already running Flutter
/// engine.
Future<void> runInView({
@required String viewId,
@required Uri main,
@required Uri assetsDirectory,
required String viewId,
required Uri main,
required Uri assetsDirectory,
}) async {
try {
await service.streamListen(vm_service.EventStreams.kIsolate);
@ -539,60 +540,63 @@ class FlutterVmService {
}
Future<String> flutterDebugDumpApp({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, Object> response = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? response = await invokeFlutterExtensionRpcRaw(
'ext.flutter.debugDumpApp',
isolateId: isolateId,
);
return response != null ? response['data']?.toString() : '';
return response?['data']?.toString() ?? '';
}
Future<String> flutterDebugDumpRenderTree({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, Object> response = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? response = await invokeFlutterExtensionRpcRaw(
'ext.flutter.debugDumpRenderTree',
isolateId: isolateId,
args: <String, Object>{}
);
return response != null ? response['data']?.toString() : '';
return response?['data']?.toString() ?? '';
}
Future<String> flutterDebugDumpLayerTree({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, Object> response = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? response = await invokeFlutterExtensionRpcRaw(
'ext.flutter.debugDumpLayerTree',
isolateId: isolateId,
);
return response != null ? response['data']?.toString() : '';
return response?['data']?.toString() ?? '';
}
Future<String> flutterDebugDumpSemanticsTreeInTraversalOrder({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, Object> response = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? response = await invokeFlutterExtensionRpcRaw(
'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
isolateId: isolateId,
);
return response != null ? response['data']?.toString() : '';
return response?['data']?.toString() ?? '';
}
Future<String> flutterDebugDumpSemanticsTreeInInverseHitTestOrder({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, Object> response = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? response = await invokeFlutterExtensionRpcRaw(
'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
isolateId: isolateId,
);
return response != null ? response['data']?.toString() : '';
if (response != null) {
return response['data']?.toString() ?? '';
}
return '';
}
Future<Map<String, dynamic>> _flutterToggle(String name, {
@required String isolateId,
Future<Map<String, Object?>?> _flutterToggle(String name, {
required String isolateId,
}) async {
Map<String, dynamic> state = await invokeFlutterExtensionRpcRaw(
Map<String, Object?>? state = await invokeFlutterExtensionRpcRaw(
'ext.flutter.$name',
isolateId: isolateId,
);
@ -600,7 +604,7 @@ class FlutterVmService {
state = await invokeFlutterExtensionRpcRaw(
'ext.flutter.$name',
isolateId: isolateId,
args: <String, dynamic>{
args: <String, Object>{
'enabled': state['enabled'] == 'true' ? 'false' : 'true',
},
);
@ -609,38 +613,38 @@ class FlutterVmService {
return state;
}
Future<Map<String, dynamic>> flutterToggleDebugPaintSizeEnabled({
@required String isolateId,
Future<Map<String, Object?>?> flutterToggleDebugPaintSizeEnabled({
required String isolateId,
}) => _flutterToggle('debugPaint', isolateId: isolateId);
Future<Map<String, dynamic>> flutterTogglePerformanceOverlayOverride({
@required String isolateId,
Future<Map<String, Object?>?> flutterTogglePerformanceOverlayOverride({
required String isolateId,
}) => _flutterToggle('showPerformanceOverlay', isolateId: isolateId);
Future<Map<String, dynamic>> flutterToggleWidgetInspector({
@required String isolateId,
Future<Map<String, Object?>?> flutterToggleWidgetInspector({
required String isolateId,
}) => _flutterToggle('inspector.show', isolateId: isolateId);
Future<Map<String,dynamic>> flutterToggleInvertOversizedImages({
@required String isolateId,
Future<Map<String, Object?>?> flutterToggleInvertOversizedImages({
required String isolateId,
}) => _flutterToggle('invertOversizedImages', isolateId: isolateId);
Future<Map<String, dynamic>> flutterToggleProfileWidgetBuilds({
@required String isolateId,
Future<Map<String, Object?>?> flutterToggleProfileWidgetBuilds({
required String isolateId,
}) => _flutterToggle('profileWidgetBuilds', isolateId: isolateId);
Future<Map<String, dynamic>> flutterDebugAllowBanner(bool show, {
@required String isolateId,
Future<Map<String, Object?>?> flutterDebugAllowBanner(bool show, {
required String isolateId,
}) {
return invokeFlutterExtensionRpcRaw(
'ext.flutter.debugAllowBanner',
isolateId: isolateId,
args: <String, dynamic>{'enabled': show ? 'true' : 'false'},
args: <String, Object>{'enabled': show ? 'true' : 'false'},
);
}
Future<Map<String, dynamic>> flutterReassemble({
@required String isolateId,
Future<Map<String, Object?>?> flutterReassemble({
required String isolateId,
}) {
return invokeFlutterExtensionRpcRaw(
'ext.flutter.reassemble',
@ -648,9 +652,9 @@ class FlutterVmService {
);
}
Future<Map<String, dynamic>> flutterFastReassemble({
@required String isolateId,
@required String className,
Future<Map<String, Object?>?> flutterFastReassemble({
required String isolateId,
required String className,
}) {
return invokeFlutterExtensionRpcRaw(
'ext.flutter.fastReassemble',
@ -662,18 +666,18 @@ class FlutterVmService {
}
Future<bool> flutterAlreadyPaintedFirstUsefulFrame({
@required String isolateId,
required String isolateId,
}) async {
final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? result = await invokeFlutterExtensionRpcRaw(
'ext.flutter.didSendFirstFrameRasterizedEvent',
isolateId: isolateId,
);
// result might be null when the service extension is not initialized
return result != null && result['enabled'] == 'true';
return result?['enabled'] == 'true';
}
Future<Map<String, dynamic>> uiWindowScheduleFrame({
@required String isolateId,
Future<Map<String, Object?>?> uiWindowScheduleFrame({
required String isolateId,
}) {
return invokeFlutterExtensionRpcRaw(
'ext.ui.window.scheduleFrame',
@ -681,13 +685,13 @@ class FlutterVmService {
);
}
Future<Map<String, dynamic>> flutterEvictAsset(String assetPath, {
@required String isolateId,
Future<Map<String, Object?>?> flutterEvictAsset(String assetPath, {
required String isolateId,
}) {
return invokeFlutterExtensionRpcRaw(
'ext.flutter.evict',
isolateId: isolateId,
args: <String, dynamic>{
args: <String, Object?>{
'value': assetPath,
},
);
@ -698,10 +702,10 @@ class FlutterVmService {
/// This method is only supported by certain embedders. This is
/// described by [Device.supportsFlutterExit].
Future<bool> flutterExit({
@required String isolateId,
required String isolateId,
}) async {
try {
final Map<String, Object> result = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? result = await invokeFlutterExtensionRpcRaw(
'ext.flutter.exit',
isolateId: isolateId,
);
@ -725,18 +729,18 @@ class FlutterVmService {
/// If a non-null value is provided for [platform], the platform override
/// is updated with this value.
Future<String> flutterPlatformOverride({
String platform,
@required String isolateId,
String? platform,
required String isolateId,
}) async {
final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? result = await invokeFlutterExtensionRpcRaw(
'ext.flutter.platformOverride',
isolateId: isolateId,
args: platform != null
? <String, dynamic>{'value': platform}
? <String, Object>{'value': platform}
: <String, String>{},
);
if (result != null && result['value'] is String) {
return result['value'] as String;
return result['value']! as String;
}
return 'unknown';
}
@ -746,15 +750,15 @@ class FlutterVmService {
///
/// If a non-null value is provided for [brightness], the brightness override
/// is updated with this value.
Future<Brightness> flutterBrightnessOverride({
Brightness brightness,
@required String isolateId,
Future<Brightness?> flutterBrightnessOverride({
Brightness? brightness,
required String isolateId,
}) async {
final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw(
final Map<String, Object?>? result = await invokeFlutterExtensionRpcRaw(
'ext.flutter.brightnessOverride',
isolateId: isolateId,
args: brightness != null
? <String, dynamic>{'value': brightness.toString()}
? <String, String>{'value': brightness.toString()}
: <String, String>{},
);
if (result != null && result['value'] is String) {
@ -765,9 +769,9 @@ class FlutterVmService {
return null;
}
Future<vm_service.Response> _checkedCallServiceExtension(
Future<vm_service.Response?> _checkedCallServiceExtension(
String method, {
Map<String, dynamic> args,
Map<String, Object?>? args,
}) async {
try {
return await service.callServiceExtension(method, args: args);
@ -784,14 +788,14 @@ class FlutterVmService {
/// Invoke a flutter extension method, if the flutter extension is not
/// available, returns null.
Future<Map<String, dynamic>> invokeFlutterExtensionRpcRaw(
Future<Map<String, Object?>?> invokeFlutterExtensionRpcRaw(
String method, {
@required String isolateId,
Map<String, dynamic> args,
required String isolateId,
Map<String, Object?>? args,
}) async {
final vm_service.Response response = await _checkedCallServiceExtension(
final vm_service.Response? response = await _checkedCallServiceExtension(
method,
args: <String, Object>{
args: <String, Object?>{
'isolateId': isolateId,
...?args,
},
@ -810,7 +814,7 @@ class FlutterVmService {
Duration delay = const Duration(milliseconds: 50),
}) async {
while (true) {
final vm_service.Response response = await callMethodWrapper(
final vm_service.Response? response = await callMethodWrapper(
kListViewsMethod,
);
if (response == null) {
@ -819,7 +823,7 @@ class FlutterVmService {
// with cleaning up.
return <FlutterView>[];
}
final List<Object> rawViews = response.json['views'] as List<Object>;
final List<Object>? rawViews = response.json?['views'] as List<Object>?;
final List<FlutterView> views = <FlutterView>[
if (rawViews != null)
for (final Object rawView in rawViews)
@ -850,11 +854,11 @@ class FlutterVmService {
}
final Completer<vm_service.IsolateRef> extensionAdded = Completer<vm_service.IsolateRef>();
StreamSubscription<vm_service.Event> isolateEvents;
late final StreamSubscription<vm_service.Event> isolateEvents;
isolateEvents = service.onIsolateEvent.listen((vm_service.Event event) {
if (event.kind == vm_service.EventKind.kServiceExtensionAdded
&& event.extensionRPC == extensionName) {
isolateEvents?.cancel();
isolateEvents.cancel();
extensionAdded.complete(event.isolate);
}
});
@ -862,7 +866,7 @@ class FlutterVmService {
try {
final List<vm_service.IsolateRef> refs = await _getIsolateRefs();
for (final vm_service.IsolateRef ref in refs) {
final vm_service.Isolate isolate = await getIsolateOrNull(ref.id);
final vm_service.Isolate? isolate = await getIsolateOrNull(ref.id!);
if (isolate != null && isolate.extensionRPCs?.contains(extensionName) == true) {
return ref;
}
@ -886,7 +890,7 @@ class FlutterVmService {
final List<vm_service.IsolateRef> refs = <vm_service.IsolateRef>[];
for (final FlutterView flutterView in flutterViews) {
final vm_service.IsolateRef uiIsolate = flutterView.uiIsolate;
final vm_service.IsolateRef? uiIsolate = flutterView.uiIsolate;
if (uiIsolate != null) {
refs.add(uiIsolate);
}
@ -896,11 +900,13 @@ class FlutterVmService {
/// Attempt to retrieve the isolate with id [isolateId], or `null` if it has
/// been collected.
Future<vm_service.Isolate> getIsolateOrNull(String isolateId) async {
Future<vm_service.Isolate?> getIsolateOrNull(String isolateId) async {
return service.getIsolate(isolateId)
.catchError((dynamic error, StackTrace stackTrace) {
// The .then() call is required to cast from Future<Isolate> to Future<Isolate?>
.then<vm_service.Isolate?>((vm_service.Isolate isolate) => isolate)
.catchError((Object? error, StackTrace stackTrace) {
return null;
}, test: (dynamic error) {
}, test: (Object? error) {
return (error is vm_service.SentinelException) ||
(error is vm_service.RPCError && error.code == RPCErrorCodes.kServiceDisappeared);
});
@ -912,7 +918,7 @@ class FlutterVmService {
// has custom handling of certain RPCErrors.
return service.callServiceExtension(
'_createDevFS',
args: <String, dynamic>{'fsName': fsName},
args: <String, Object?>{'fsName': fsName},
);
}
@ -920,15 +926,15 @@ class FlutterVmService {
Future<void> deleteDevFS(String fsName) async {
await _checkedCallServiceExtension(
'_deleteDevFS',
args: <String, dynamic>{'fsName': fsName},
args: <String, Object?>{'fsName': fsName},
);
}
Future<vm_service.Response> screenshot() {
Future<vm_service.Response?> screenshot() {
return _checkedCallServiceExtension(kScreenshotMethod);
}
Future<vm_service.Response> screenshotSkp() {
Future<vm_service.Response?> screenshotSkp() {
return _checkedCallServiceExtension(kScreenshotSkpMethod);
}
@ -937,13 +943,13 @@ class FlutterVmService {
assert(recordedStreams != null);
await _checkedCallServiceExtension(
'setVMTimelineFlags',
args: <String, dynamic>{
args: <String, Object?>{
'recordedStreams': recordedStreams,
},
);
}
Future<vm_service.Response> getTimeline() {
Future<vm_service.Response?> getTimeline() {
return _checkedCallServiceExtension('getVMTimeline');
}
@ -985,7 +991,7 @@ enum Brightness {
/// Process a VM service log event into a string message.
String processVmServiceMessage(vm_service.Event event) {
final String message = utf8.decode(base64.decode(event.bytes));
final String message = utf8.decode(base64.decode(event.bytes!));
// Remove extra trailing newlines appended by the vm service.
if (message.endsWith('\n')) {
return message.substring(0, message.length - 1);

View file

@ -481,7 +481,7 @@ void main() {
});
testWithoutContext('computeDartVmFlags handles various combinations of Dart VM flags and null_assertions', () {
expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: null)), '');
expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug)), '');
expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo')), '--foo');
expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '', nullAssertions: true)), '--null_assertions');
expect(computeDartVmFlags(DebuggingOptions.enabled(BuildInfo.debug, dartFlags: '--foo', nullAssertions: true)), '--foo,--null_assertions');

View file

@ -796,7 +796,7 @@ void main() {
},
),
]);
final FakeDelegateFlutterDevice flutterDevice = FakeDelegateFlutterDevice(
final FakeDelegateFlutterDevice flutterDevice = FakeDelegateFlutterDevice(
device,
BuildInfo.debug,
FakeResidentCompiler(),

View file

@ -2,14 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:meta/meta.dart';
import 'package:test_api/test_api.dart' hide test; // ignore: deprecated_member_use
import 'package:vm_service/vm_service.dart' as vm_service;
@ -19,9 +16,9 @@ export 'package:test_api/test_api.dart' hide test, isInstanceOf; // ignore: depr
/// and response structure.
class FakeVmServiceHost {
FakeVmServiceHost({
@required List<VmServiceExpectation> requests,
Uri httpAddress,
Uri wsAddress,
required List<VmServiceExpectation> requests,
Uri? httpAddress,
Uri? wsAddress,
}) : _requests = requests {
_vmService = FlutterVmService(vm_service.VmService(
_input.stream,
@ -44,16 +41,16 @@ class FakeVmServiceHost {
return;
}
if (fakeRequest.errorCode == null) {
_input.add(json.encode(<String, Object>{
_input.add(json.encode(<String, Object?>{
'jsonrpc': '2.0',
'id': request['id'],
'result': fakeRequest.jsonResponse ?? <String, Object>{'type': 'Success'},
}));
} else {
_input.add(json.encode(<String, Object>{
_input.add(json.encode(<String, Object?>{
'jsonrpc': '2.0',
'id': request['id'],
'error': <String, Object>{
'error': <String, Object?>{
'code': fakeRequest.errorCode,
}
}));
@ -67,7 +64,7 @@ class FakeVmServiceHost {
final StreamController<String> _output = StreamController<String>();
FlutterVmService get vmService => _vmService;
FlutterVmService _vmService;
late final FlutterVmService _vmService;
bool get hasRemainingExpectations => _requests.isNotEmpty;
@ -95,7 +92,7 @@ abstract class VmServiceExpectation {
class FakeVmServiceRequest implements VmServiceExpectation {
const FakeVmServiceRequest({
@required this.method,
required this.method,
this.args = const <String, Object>{},
this.jsonResponse,
this.errorCode,
@ -109,9 +106,9 @@ class FakeVmServiceRequest implements VmServiceExpectation {
/// If non-null, the error code for a [vm_service.RPCError] in place of a
/// standard response.
final int errorCode;
final Map<String, Object> args;
final Map<String, Object> jsonResponse;
final int? errorCode;
final Map<String, Object>? args;
final Map<String, Object>? jsonResponse;
@override
bool get isRequest => true;
@ -119,8 +116,8 @@ class FakeVmServiceRequest implements VmServiceExpectation {
class FakeVmServiceStreamResponse implements VmServiceExpectation {
const FakeVmServiceStreamResponse({
@required this.event,
@required this.streamId,
required this.event,
required this.streamId,
});
final vm_service.Event event;