migrate to null safety (dart-lang/coverage#332)
I did not do large refactors for the most part here I left in existing assumptions which means a lot of `!` are added.
Note that the `_shouldIgnoreLine` private method was moved to a local method and the patterns around it changed a fair bit due to iterators changing with null safety (it previously relied on `current` being null and now uses the result of `moveNext`).
diff --git a/pkgs/coverage/CHANGELOG.md b/pkgs/coverage/CHANGELOG.md
index 9a63f96..0a0d86e 100644
--- a/pkgs/coverage/CHANGELOG.md
+++ b/pkgs/coverage/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.0 - 2021-02-25
+
+* Migrate to null safety.
+
## 0.15.2 - 2021-02-08
* Update `args`, `logging`, and `package_config` deps to allow the latest
diff --git a/pkgs/coverage/bin/collect_coverage.dart b/pkgs/coverage/bin/collect_coverage.dart
index e49e62f..ccead74 100644
--- a/pkgs/coverage/bin/collect_coverage.dart
+++ b/pkgs/coverage/bin/collect_coverage.dart
@@ -39,7 +39,7 @@
final Uri serviceUri;
final IOSink out;
- final Duration timeout;
+ final Duration? timeout;
final bool waitPaused;
final bool resume;
final bool includeDart;
@@ -81,7 +81,7 @@
print(parser.usage);
}
- void fail(String message) {
+ Never fail(String message) {
print('Error: $message\n');
printUsage();
exit(1);
@@ -105,8 +105,7 @@
}
}
- final scopedOutput = args['scope-output'] as List<String> ?? [];
-
+ final scopedOutput = args['scope-output'] as List<String>;
IOSink out;
if (args['out'] == 'stdout') {
out = stdout;
diff --git a/pkgs/coverage/bin/format_coverage.dart b/pkgs/coverage/bin/format_coverage.dart
index a0cdf50..ab643ed 100644
--- a/pkgs/coverage/bin/format_coverage.dart
+++ b/pkgs/coverage/bin/format_coverage.dart
@@ -10,20 +10,35 @@
/// [Environment] stores gathered arguments information.
class Environment {
- String sdkRoot;
- String packagesPath;
- String baseDirectory;
- String input;
- IOSink output;
- List<String> reportOn;
- String bazelWorkspace;
+ Environment({
+ required this.baseDirectory,
+ required this.bazel,
+ required this.bazelWorkspace,
+ required this.checkIgnore,
+ required this.input,
+ required this.lcov,
+ required this.output,
+ required this.packagesPath,
+ required this.prettyPrint,
+ required this.reportOn,
+ required this.sdkRoot,
+ required this.verbose,
+ required this.workers,
+ });
+
+ String? baseDirectory;
bool bazel;
- int workers;
- bool prettyPrint;
- bool lcov;
- bool expectMarkers;
+ String bazelWorkspace;
bool checkIgnore;
+ String input;
+ bool lcov;
+ IOSink output;
+ String? packagesPath;
+ bool prettyPrint;
+ List<String>? reportOn;
+ String? sdkRoot;
bool verbose;
+ int workers;
}
Future<Null> main(List<String> arguments) async {
@@ -55,9 +70,7 @@
String output;
final resolver = env.bazel
? BazelResolver(workspacePath: env.bazelWorkspace)
- : Resolver(
- packagesPath: env.packagesPath,
- sdkRoot: env.sdkRoot);
+ : Resolver(packagesPath: env.packagesPath, sdkRoot: env.sdkRoot);
final loader = Loader();
if (env.prettyPrint) {
output =
@@ -96,7 +109,6 @@
/// Checks the validity of the provided arguments. Does not initialize actual
/// processing.
Environment parseArgs(List<String> arguments) {
- final env = Environment();
final parser = ArgParser();
parser.addOption('sdk-root', abbr: 's', help: 'path to the SDK root');
@@ -141,7 +153,7 @@
print(parser.usage);
}
- void fail(String msg) {
+ Never fail(String msg) {
print('\n$msg\n');
printUsage();
exit(1);
@@ -152,66 +164,83 @@
exit(0);
}
- env.sdkRoot = args['sdk-root'] as String;
- if (env.sdkRoot != null) {
- env.sdkRoot = p.normalize(p.join(p.absolute(env.sdkRoot), 'lib'));
- if (!FileSystemEntity.isDirectorySync(env.sdkRoot)) {
+ var sdkRoot = args['sdk-root'] as String?;
+ if (sdkRoot != null) {
+ sdkRoot = p.normalize(p.join(p.absolute(sdkRoot), 'lib'));
+ if (!FileSystemEntity.isDirectorySync(sdkRoot)) {
fail('Provided SDK root "${args["sdk-root"]}" is not a valid SDK '
'top-level directory');
}
}
- env.packagesPath = args['packages'] as String;
- if (env.packagesPath != null) {
- if (!FileSystemEntity.isFileSync(env.packagesPath)) {
+ final packagesPath = args['packages'] as String?;
+ if (packagesPath != null) {
+ if (!FileSystemEntity.isFileSync(packagesPath)) {
fail('Package spec "${args["packages"]}" not found, or not a file.');
}
}
if (args['in'] == null) fail('No input files given.');
- env.input = p.absolute(p.normalize(args['in'] as String));
- if (!FileSystemEntity.isDirectorySync(env.input) &&
- !FileSystemEntity.isFileSync(env.input)) {
+ final input = p.absolute(p.normalize(args['in'] as String));
+ if (!FileSystemEntity.isDirectorySync(input) &&
+ !FileSystemEntity.isFileSync(input)) {
fail('Provided input "${args["in"]}" is neither a directory nor a file.');
}
+ IOSink output;
if (args['out'] == 'stdout') {
- env.output = stdout;
+ output = stdout;
} else {
final outpath = p.absolute(p.normalize(args['out'] as String));
final outfile = File(outpath)..createSync(recursive: true);
- env.output = outfile.openWrite();
+ output = outfile.openWrite();
}
- final reportOn = args['report-on'] as List<String>;
- env.reportOn = reportOn.isNotEmpty ? reportOn : null;
+ final reportOnRaw = args['report-on'] as List<String>;
+ final reportOn = reportOnRaw.isNotEmpty ? reportOnRaw : null;
- env.bazel = args['bazel'] as bool;
- env.bazelWorkspace = args['bazel-workspace'] as String;
- if (env.bazelWorkspace.isNotEmpty && !env.bazel) {
+ final bazel = args['bazel'] as bool;
+ final bazelWorkspace = args['bazel-workspace'] as String;
+ if (bazelWorkspace.isNotEmpty && !bazel) {
stderr.writeln('warning: ignoring --bazel-workspace: --bazel not set');
}
+ String? baseDirectory;
if (args['base-directory'] != null) {
- env.baseDirectory = p.absolute(args['base-directory'] as String);
+ baseDirectory = p.absolute(args['base-directory'] as String);
}
- env.lcov = args['lcov'] as bool;
- if (args['pretty-print'] as bool && env.lcov) {
+ final lcov = args['lcov'] as bool;
+ if (args['pretty-print'] as bool && lcov == true) {
fail('Choose one of pretty-print or lcov output');
}
- // Use pretty-print either explicitly or by default.
- env.prettyPrint = !env.lcov;
+ // Use pretty-print either explicitly or by default.
+ final prettyPrint = !lcov;
+
+ int workers;
try {
- env.workers = int.parse('${args["workers"]}');
+ workers = int.parse('${args["workers"]}');
} catch (e) {
fail('Invalid worker count: $e');
}
- env.checkIgnore = args['check-ignore'] as bool;
- env.verbose = args['verbose'] as bool;
- return env;
+ final checkIgnore = args['check-ignore'] as bool;
+ final verbose = args['verbose'] as bool;
+ return Environment(
+ baseDirectory: baseDirectory,
+ bazel: bazel,
+ bazelWorkspace: bazelWorkspace,
+ checkIgnore: checkIgnore,
+ input: input,
+ lcov: lcov,
+ output: output,
+ packagesPath: packagesPath,
+ prettyPrint: prettyPrint,
+ reportOn: reportOn,
+ sdkRoot: sdkRoot,
+ verbose: verbose,
+ workers: workers);
}
/// Given an absolute path absPath, this function returns a [List] of files
diff --git a/pkgs/coverage/lib/src/chrome.dart b/pkgs/coverage/lib/src/chrome.dart
index 5246c07..33a0e1e 100644
--- a/pkgs/coverage/lib/src/chrome.dart
+++ b/pkgs/coverage/lib/src/chrome.dart
@@ -21,8 +21,8 @@
/// content is null will be ignored.
Future<Map<String, dynamic>> parseChromeCoverage(
List<Map<String, dynamic>> preciseCoverage,
- Future<String> Function(String scriptId) sourceProvider,
- Future<String> Function(String scriptId) sourceMapProvider,
+ Future<String?> Function(String scriptId) sourceProvider,
+ Future<String?> Function(String scriptId) sourceMapProvider,
Future<Uri> Function(String sourceUrl, String scriptId) sourceUriProvider,
) async {
final coverageReport = <Uri, Map<int, bool>>{};
@@ -50,8 +50,9 @@
for (var lineEntry in mapping.lines) {
for (var columnEntry in lineEntry.entries) {
- if (columnEntry.sourceUrlId == null) continue;
- final sourceUrl = mapping.urls[columnEntry.sourceUrlId];
+ final sourceUrlId = columnEntry.sourceUrlId;
+ if (sourceUrlId == null) continue;
+ final sourceUrl = mapping.urls[sourceUrlId];
// Ignore coverage information for the SDK.
if (sourceUrl.startsWith('org-dartlang-sdk:')) continue;
@@ -59,8 +60,9 @@
final uri = await sourceUriProvider(sourceUrl, scriptId);
final coverage = coverageReport.putIfAbsent(uri, () => <int, bool>{});
- final current = coverage[columnEntry.sourceLine + 1] ?? false;
- coverage[columnEntry.sourceLine + 1] = current ||
+ final sourceLine = columnEntry.sourceLine!;
+ final current = coverage[sourceLine + 1] ?? false;
+ coverage[sourceLine + 1] = current ||
coveredPositions.contains(
_Position(lineEntry.line + 1, columnEntry.column + 1));
}
@@ -71,7 +73,7 @@
coverageReport.forEach((uri, coverage) {
final hitMap = <int, int>{};
for (var line in coverage.keys.toList()..sort()) {
- hitMap[line] = coverage[line] ? 1 : 0;
+ hitMap[line] = coverage[line]! ? 1 : 0;
}
coverageHitMaps[uri] = hitMap;
});
diff --git a/pkgs/coverage/lib/src/collect.dart b/pkgs/coverage/lib/src/collect.dart
index 24cdd8e..29be493 100644
--- a/pkgs/coverage/lib/src/collect.dart
+++ b/pkgs/coverage/lib/src/collect.dart
@@ -35,17 +35,16 @@
/// if [isolateIds] is set, the coverage gathering will be restricted to only
/// those VM isolates.
Future<Map<String, dynamic>> collect(Uri serviceUri, bool resume,
- bool waitPaused, bool includeDart, Set<String> scopedOutput,
- {Set<String> isolateIds, Duration timeout}) async {
+ bool waitPaused, bool includeDart, Set<String>? scopedOutput,
+ {Set<String>? isolateIds, Duration? timeout}) async {
scopedOutput ??= <String>{};
- if (serviceUri == null) throw ArgumentError('serviceUri must not be null');
// Create websocket URI. Handle any trailing slashes.
final pathSegments =
serviceUri.pathSegments.where((c) => c.isNotEmpty).toList()..add('ws');
final uri = serviceUri.replace(scheme: 'ws', pathSegments: pathSegments);
- VmService service;
+ late VmService service;
await retry(() async {
try {
final options = const CompressionOptions(enabled: false);
@@ -83,24 +82,27 @@
}
}
-Future<Map<String, dynamic>> _getAllCoverage(VmService service,
- bool includeDart, Set<String> scopedOutput, Set<String> isolateIds) async {
+Future<Map<String, dynamic>> _getAllCoverage(
+ VmService service,
+ bool includeDart,
+ Set<String>? scopedOutput,
+ Set<String>? isolateIds) async {
scopedOutput ??= <String>{};
final vm = await service.getVM();
final allCoverage = <Map<String, dynamic>>[];
- for (var isolateRef in vm.isolates) {
+ for (var isolateRef in vm.isolates!) {
if (isolateIds != null && !isolateIds.contains(isolateRef.id)) continue;
if (scopedOutput.isNotEmpty) {
- final scripts = await service.getScripts(isolateRef.id);
- for (var script in scripts.scripts) {
- final uri = Uri.parse(script.uri);
+ final scripts = await service.getScripts(isolateRef.id!);
+ for (var script in scripts.scripts!) {
+ final uri = Uri.parse(script.uri!);
if (uri.scheme != 'package') continue;
final scope = uri.path.split('/').first;
// Skip scripts which should not be included in the report.
if (!scopedOutput.contains(scope)) continue;
final scriptReport = await service.getSourceReport(
- isolateRef.id, <String>[SourceReportKind.kCoverage],
+ isolateRef.id!, <String>[SourceReportKind.kCoverage],
forceCompile: true, scriptId: script.id);
final coverage = await _getCoverageJson(
service, isolateRef, scriptReport, includeDart);
@@ -108,7 +110,7 @@
}
} else {
final isolateReport = await service.getSourceReport(
- isolateRef.id,
+ isolateRef.id!,
<String>[SourceReportKind.kCoverage],
forceCompile: true,
);
@@ -123,14 +125,14 @@
Future _resumeIsolates(VmService service) async {
final vm = await service.getVM();
final futures = <Future>[];
- for (var isolateRef in vm.isolates) {
+ for (var isolateRef in vm.isolates!) {
// Guard against sync as well as async errors: sync - when we are writing
// message to the socket, the socket might be closed; async - when we are
// waiting for the response, the socket again closes.
futures.add(Future.sync(() async {
- final isolate = await service.getIsolate(isolateRef.id);
- if (isolate.pauseEvent.kind != EventKind.kResume) {
- await service.resume(isolateRef.id);
+ final isolate = await service.getIsolate(isolateRef.id!);
+ if (isolate.pauseEvent!.kind != EventKind.kResume) {
+ await service.resume(isolateRef.id!);
}
}));
}
@@ -141,7 +143,7 @@
}
}
-Future _waitIsolatesPaused(VmService service, {Duration timeout}) async {
+Future _waitIsolatesPaused(VmService service, {Duration? timeout}) async {
final pauseEvents = <String>{
EventKind.kPauseStart,
EventKind.kPauseException,
@@ -152,10 +154,10 @@
Future allPaused() async {
final vm = await service.getVM();
- if (vm.isolates.isEmpty) throw 'No isolates.';
- for (var isolateRef in vm.isolates) {
- final isolate = await service.getIsolate(isolateRef.id);
- if (!pauseEvents.contains(isolate.pauseEvent.kind)) {
+ if (vm.isolates!.isEmpty) throw 'No isolates.';
+ for (var isolateRef in vm.isolates!) {
+ final isolate = await service.getIsolate(isolateRef.id!);
+ if (!pauseEvents.contains(isolate.pauseEvent!.kind)) {
throw 'Unpaused isolates remaining.';
}
}
@@ -168,14 +170,14 @@
///
/// Performs a binary search within the script's token position table to locate
/// the line in question.
-int _getLineFromTokenPos(Script script, int tokenPos) {
+int? _getLineFromTokenPos(Script script, int tokenPos) {
// TODO(cbracken): investigate whether caching this lookup results in
// significant performance gains.
var min = 0;
- var max = script.tokenPosTable.length;
+ var max = script.tokenPosTable!.length;
while (min < max) {
final mid = min + ((max - min) >> 1);
- final row = script.tokenPosTable[mid];
+ final row = script.tokenPosTable![mid];
if (row[1] > tokenPos) {
max = mid;
} else {
@@ -194,9 +196,9 @@
// script uri -> { line -> hit count }
final hitMaps = <Uri, Map<int, int>>{};
final scripts = <ScriptRef, Script>{};
- for (var range in report.ranges) {
- final scriptRef = report.scripts[range.scriptIndex];
- final scriptUri = Uri.parse(report.scripts[range.scriptIndex].uri);
+ for (var range in report.ranges!) {
+ final scriptRef = report.scripts![range.scriptIndex!];
+ final scriptUri = Uri.parse(report.scripts![range.scriptIndex!].uri!);
// Not returned in scripts section of source report.
if (scriptUri.scheme == 'evaluate') continue;
@@ -206,9 +208,10 @@
if (!scripts.containsKey(scriptRef)) {
scripts[scriptRef] =
- await service.getObject(isolateRef.id, scriptRef.id) as Script;
+ await service.getObject(isolateRef.id!, scriptRef.id!) as Script;
}
final script = scripts[scriptRef];
+ if (script == null) continue;
// Look up the hit map for this script (shared across isolates).
final hitMap = hitMaps.putIfAbsent(scriptUri, () => <int, int>{});
@@ -218,17 +221,19 @@
if (coverage == null) continue;
- for (final tokenPos in coverage.hits) {
+ for (final tokenPos in coverage.hits!) {
final line = _getLineFromTokenPos(script, tokenPos);
if (line == null) {
print('tokenPos $tokenPos has no line mapping for script $scriptUri');
+ continue;
}
- hitMap[line] = hitMap.containsKey(line) ? hitMap[line] + 1 : 1;
+ hitMap[line] = hitMap.containsKey(line) ? hitMap[line]! + 1 : 1;
}
- for (final tokenPos in coverage.misses) {
+ for (final tokenPos in coverage.misses!) {
final line = _getLineFromTokenPos(script, tokenPos);
if (line == null) {
print('tokenPos $tokenPos has no line mapping for script $scriptUri');
+ continue;
}
hitMap.putIfAbsent(line, () => 0);
}
diff --git a/pkgs/coverage/lib/src/formatter.dart b/pkgs/coverage/lib/src/formatter.dart
index e436033..679b8f3 100644
--- a/pkgs/coverage/lib/src/formatter.dart
+++ b/pkgs/coverage/lib/src/formatter.dart
@@ -25,15 +25,15 @@
LcovFormatter(this.resolver, {this.reportOn, this.basePath});
final Resolver resolver;
- final String basePath;
- final List<String> reportOn;
+ final String? basePath;
+ final List<String>? reportOn;
@override
Future<String> format(Map<String, Map<int, int>> hitmap) async {
final pathFilter = _getPathFilter(reportOn);
final buf = StringBuffer();
for (var key in hitmap.keys) {
- final v = hitmap[key];
+ final v = hitmap[key]!;
var source = resolver.resolve(key);
if (source == null) {
continue;
@@ -53,7 +53,7 @@
buf.write('DA:$k,${v[k]}\n');
}
buf.write('LF:${lines.length}\n');
- buf.write('LH:${lines.where((k) => v[k] > 0).length}\n');
+ buf.write('LH:${lines.where((k) => v[k]! > 0).length}\n');
buf.write('end_of_record\n');
}
@@ -75,7 +75,7 @@
final Resolver resolver;
final Loader loader;
- final List<String> reportOn;
+ final List<String>? reportOn;
@override
Future<String> format(Map<String, dynamic> hitmap) async {
@@ -114,7 +114,7 @@
typedef _PathFilter = bool Function(String path);
-_PathFilter _getPathFilter(List<String> reportOn) {
+_PathFilter _getPathFilter(List<String>? reportOn) {
if (reportOn == null) return (String path) => true;
final absolutePaths = reportOn.map(p.absolute).toList();
diff --git a/pkgs/coverage/lib/src/hitmap.dart b/pkgs/coverage/lib/src/hitmap.dart
index 68397a5..fa32a27 100644
--- a/pkgs/coverage/lib/src/hitmap.dart
+++ b/pkgs/coverage/lib/src/hitmap.dart
@@ -15,7 +15,7 @@
Future<Map<String, Map<int, int>>> createHitmap(
List<Map<String, dynamic>> jsonResult, {
bool checkIgnoredLines = false,
- String packagesPath,
+ String? packagesPath,
}) async {
final resolver = Resolver(packagesPath: packagesPath);
final loader = Loader();
@@ -29,7 +29,7 @@
}
for (var e in jsonResult) {
- final source = e['source'] as String;
+ final source = e['source'] as String?;
if (source == null) {
// Couldn't resolve import, so skip this entry.
continue;
@@ -38,20 +38,46 @@
var ignoredLinesList = <List<int>>[];
if (checkIgnoredLines) {
- final lines = await loader.load(resolver.resolve(source));
- ignoredLinesList = getIgnoredLines(lines);
+ final path = resolver.resolve(source);
+ if (path != null) {
+ final lines = await loader.load(path);
+ ignoredLinesList = getIgnoredLines(lines!);
- // Ignore the whole file.
- if (ignoredLinesList.length == 1 &&
- ignoredLinesList[0][0] == 0 &&
- ignoredLinesList[0][1] == lines.length) {
- continue;
+ // Ignore the whole file.
+ if (ignoredLinesList.length == 1 &&
+ ignoredLinesList[0][0] == 0 &&
+ ignoredLinesList[0][1] == lines.length) {
+ continue;
+ }
}
}
// Move to the first ignore range.
final ignoredLines = ignoredLinesList.iterator;
- ignoredLines.moveNext();
+ var hasCurrent = ignoredLines.moveNext();
+
+ bool _shouldIgnoreLine(Iterator<List<int>> ignoredRanges, int line) {
+ if (!hasCurrent || ignoredRanges.current.isEmpty) {
+ return false;
+ }
+
+ if (line < ignoredRanges.current[0]) return false;
+
+ while (hasCurrent &&
+ ignoredRanges.current.isNotEmpty &&
+ ignoredRanges.current[1] < line) {
+ hasCurrent = ignoredRanges.moveNext();
+ }
+
+ if (hasCurrent &&
+ ignoredRanges.current.isNotEmpty &&
+ ignoredRanges.current[0] <= line &&
+ line <= ignoredRanges.current[1]) {
+ return true;
+ }
+
+ return false;
+ }
final sourceHitMap = globalHitMap.putIfAbsent(source, () => <int, int>{});
final hits = e['hits'] as List;
@@ -84,39 +110,18 @@
return globalHitMap;
}
-bool _shouldIgnoreLine(Iterator<List<int>> ignoredRanges, int line) {
- if (ignoredRanges.current == null || ignoredRanges.current.isEmpty) {
- return false;
- }
-
- if (line < ignoredRanges.current[0]) return false;
-
- while (ignoredRanges.current != null &&
- ignoredRanges.current.isNotEmpty &&
- ignoredRanges.current[1] < line) {
- ignoredRanges.moveNext();
- }
-
- if (ignoredRanges.current != null &&
- ignoredRanges.current.isNotEmpty &&
- ignoredRanges.current[0] <= line &&
- line <= ignoredRanges.current[1]) {
- return true;
- }
-
- return false;
-}
-
/// Merges [newMap] into [result].
void mergeHitmaps(
Map<String, Map<int, int>> newMap, Map<String, Map<int, int>> result) {
newMap.forEach((String file, Map<int, int> v) {
- if (result.containsKey(file)) {
+ final fileResult = result[file];
+ if (fileResult != null) {
v.forEach((int line, int cnt) {
- if (result[file][line] == null) {
- result[file][line] = cnt;
+ final lineFileResult = fileResult[line];
+ if (lineFileResult == null) {
+ fileResult[line] = cnt;
} else {
- result[file][line] += cnt;
+ fileResult[line] = lineFileResult + cnt;
}
});
} else {
diff --git a/pkgs/coverage/lib/src/resolver.dart b/pkgs/coverage/lib/src/resolver.dart
index 751e57f..6415e6c 100644
--- a/pkgs/coverage/lib/src/resolver.dart
+++ b/pkgs/coverage/lib/src/resolver.dart
@@ -10,20 +10,21 @@
/// [Resolver] resolves imports with respect to a given environment.
class Resolver {
- Resolver({String packagesPath, this.sdkRoot})
+ Resolver({String? packagesPath, this.sdkRoot})
: packagesPath = packagesPath,
_packages = packagesPath != null ? _parsePackages(packagesPath) : null;
- final String packagesPath;
- final String sdkRoot;
+ final String? packagesPath;
+ final String? sdkRoot;
final List<String> failed = [];
- final Map<String, Uri> _packages;
+ final Map<String, Uri>? _packages;
/// Returns the absolute path wrt. to the given environment or null, if the
/// import could not be resolved.
- String resolve(String scriptUri) {
+ String? resolve(String scriptUri) {
final uri = Uri.parse(scriptUri);
if (uri.scheme == 'dart') {
+ final sdkRoot = this.sdkRoot;
if (sdkRoot == null) {
// No sdk-root given, do not resolve dart: URIs.
return null;
@@ -53,6 +54,7 @@
return resolveSymbolicLinks(filePath);
}
if (uri.scheme == 'package') {
+ final _packages = this._packages;
if (_packages == null) {
return null;
}
@@ -76,7 +78,7 @@
}
/// Returns a canonicalized path, or `null` if the path cannot be resolved.
- String resolveSymbolicLinks(String path) {
+ String? resolveSymbolicLinks(String path) {
final normalizedPath = p.normalize(path);
final type = FileSystemEntity.typeSync(normalizedPath, followLinks: true);
if (type == FileSystemEntityType.notFound) return null;
@@ -123,7 +125,7 @@
/// Returns the absolute path wrt. to the given environment or null, if the
/// import could not be resolved.
@override
- String resolve(String scriptUri) {
+ String? resolve(String scriptUri) {
final uri = Uri.parse(scriptUri);
if (uri.scheme == 'dart') {
// Ignore the SDK
@@ -177,7 +179,7 @@
/// Loads an imported resource and returns a [Future] with a [List] of lines.
/// Returns `null` if the resource could not be loaded.
- Future<List<String>> load(String path) async {
+ Future<List<String>?> load(String path) async {
try {
// Ensure `readAsLines` runs within the try block so errors are caught.
return await File(path).readAsLines();
diff --git a/pkgs/coverage/lib/src/run_and_collect.dart b/pkgs/coverage/lib/src/run_and_collect.dart
index 78573e7..6e52f4f 100644
--- a/pkgs/coverage/lib/src/run_and_collect.dart
+++ b/pkgs/coverage/lib/src/run_and_collect.dart
@@ -10,10 +10,10 @@
import 'util.dart';
Future<Map<String, dynamic>> runAndCollect(String scriptPath,
- {List<String> scriptArgs,
+ {List<String>? scriptArgs,
bool checked = false,
bool includeDart = false,
- Duration timeout}) async {
+ Duration? timeout}) async {
final dartArgs = [
'--enable-vm-service',
'--pause_isolates_on_exit',
@@ -47,7 +47,7 @@
coverage = await collect(serviceUri, true, true, includeDart, <String>{},
timeout: timeout);
} finally {
- await process.stderr.drain<List<int>>();
+ await process.stderr.drain();
}
final exitStatus = await process.exitCode;
if (exitStatus != 0) {
diff --git a/pkgs/coverage/lib/src/util.dart b/pkgs/coverage/lib/src/util.dart
index bd375ea..45b2b9c 100644
--- a/pkgs/coverage/lib/src/util.dart
+++ b/pkgs/coverage/lib/src/util.dart
@@ -8,10 +8,10 @@
/// Retries the specified function with the specified interval and returns
/// the result on successful completion.
Future<dynamic> retry(Future Function() f, Duration interval,
- {Duration timeout}) async {
+ {Duration? timeout}) async {
var keepGoing = true;
- Future<dynamic> _withTimeout(Future Function() f, {Duration duration}) {
+ Future<dynamic> _withTimeout(Future Function() f, {Duration? duration}) {
if (duration == null) {
return f();
}
@@ -41,7 +41,7 @@
/// Scrapes and returns the observatory URI from a string, or null if not found.
///
/// Potentially useful as a means to extract it from log statements.
-Uri extractObservatoryUri(String str) {
+Uri? extractObservatoryUri(String str) {
const kObservatoryListening = 'Observatory listening on ';
final msgPos = str.indexOf(kObservatoryListening);
if (msgPos == -1) return null;
@@ -135,7 +135,7 @@
/// ]
/// ```
///
-List<List<int>> getIgnoredLines(List<String> lines) {
+List<List<int>> getIgnoredLines(List<String>? lines) {
final ignoredLines = <List<int>>[];
if (lines == null) return ignoredLines;
diff --git a/pkgs/coverage/pubspec.yaml b/pkgs/coverage/pubspec.yaml
index 72e9602..63d7c4f 100644
--- a/pkgs/coverage/pubspec.yaml
+++ b/pkgs/coverage/pubspec.yaml
@@ -1,24 +1,27 @@
name: coverage
-version: 0.15.2
+version: 1.0.0
description: Coverage data manipulation and formatting
homepage: https://github.com/dart-lang/coverage
environment:
- sdk: '>=2.7.0 <3.0.0'
+ sdk: '>=2.12.0-0 <3.0.0'
dependencies:
- args: '>=1.4.0 <3.0.0'
- logging: '>=0.9.0 <2.0.0'
- package_config: '>=1.9.0 <3.0.0'
- path: '>=0.9.0 <2.0.0'
- source_maps: ^0.10.8
- stack_trace: ^1.3.0
- vm_service: '>=1.0.0 <7.0.0'
-
+ args: ^2.0.0
+ logging: ^1.0.0
+ package_config: ^2.0.0
+ path: ^1.8.0
+ source_maps: ^0.10.10
+ stack_trace: ^1.10.0
+ vm_service: ^6.1.0
dev_dependencies:
- pedantic: ^1.0.0
- test: ^1.16.0-nullsafety.4
- test_descriptor: ^2.0.0-nullsafety
+ pedantic: ^1.10.0
+ test: ^1.16.0
+ test_descriptor: ^2.0.0
executables:
collect_coverage:
format_coverage:
+
+dependency_overrides:
+ test: ^1.16.0
+ test_core: ^0.3.14
diff --git a/pkgs/coverage/test/chrome_test.dart b/pkgs/coverage/test/chrome_test.dart
index b9c6a0e..2c378e7 100644
--- a/pkgs/coverage/test/chrome_test.dart
+++ b/pkgs/coverage/test/chrome_test.dart
@@ -18,7 +18,7 @@
return File('test/test_files/main_test.js.map').readAsString();
}
-Future<String> sourceProvider(String scriptId) async {
+Future<String?> sourceProvider(String scriptId) async {
if (scriptId != mainScriptId) return null;
return File('test/test_files/main_test.js').readAsString();
}
diff --git a/pkgs/coverage/test/collect_coverage_api_test.dart b/pkgs/coverage/test/collect_coverage_api_test.dart
index e20374e..49d4efb 100644
--- a/pkgs/coverage/test/collect_coverage_api_test.dart
+++ b/pkgs/coverage/test/collect_coverage_api_test.dart
@@ -18,11 +18,6 @@
final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
void main() {
- test('collect throws when serviceUri is null', () {
- expect(() => collect(null, true, false, false, <String>{}),
- throwsArgumentError);
- });
-
test('collect_coverage_api', () async {
final json = await _collectCoverage();
expect(json.keys, unorderedEquals(<String>['type', 'coverage']));
@@ -38,11 +33,11 @@
return map;
});
- for (var sampleCoverageData in sources[_sampleAppFileUri]) {
+ for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
expect(sampleCoverageData['hits'], isNotNull);
}
- for (var sampleCoverageData in sources[_isolateLibFileUri]) {
+ for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
expect(sampleCoverageData['hits'], isNotEmpty);
}
});
@@ -77,13 +72,13 @@
final coverage = json['coverage'] as List<Map<String, dynamic>>;
expect(coverage, isNotEmpty);
- final testAppCoverage = _getScriptCoverage(coverage, 'test_app.dart');
+ final testAppCoverage = _getScriptCoverage(coverage, 'test_app.dart')!;
var hits = testAppCoverage['hits'] as List<int>;
_expectHitCount(hits, 44, 0);
_expectHitCount(hits, 48, 0);
final isolateCoverage =
- _getScriptCoverage(coverage, 'test_app_isolate.dart');
+ _getScriptCoverage(coverage, 'test_app_isolate.dart')!;
hits = isolateCoverage['hits'] as List<int>;
_expectHitCount(hits, 11, 1);
_expectHitCount(hits, 18, 1);
@@ -91,8 +86,7 @@
}
Future<Map<String, dynamic>> _collectCoverage(
- {Set<String> scopedOutput, bool isolateIds = false}) async {
- scopedOutput ??= <String>{};
+ {Set<String> scopedOutput = const {}, bool isolateIds = false}) async {
final openPort = await getOpenPort();
// run the sample app, with the right flags
@@ -126,7 +120,7 @@
// Returns the first coverage hitmap for the script with with the specified
// script filename, ignoring leading path.
-Map<String, dynamic> _getScriptCoverage(
+Map<String, dynamic>? _getScriptCoverage(
List<Map<String, dynamic>> coverage, String filename) {
for (var isolateCoverage in coverage) {
final script = Uri.parse(isolateCoverage['script']['uri'] as String);
diff --git a/pkgs/coverage/test/collect_coverage_test.dart b/pkgs/coverage/test/collect_coverage_test.dart
index bd2b234..0407389 100644
--- a/pkgs/coverage/test/collect_coverage_test.dart
+++ b/pkgs/coverage/test/collect_coverage_test.dart
@@ -111,7 +111,7 @@
});
}
-String _coverageData;
+String? _coverageData;
Future<String> _getCoverageResult() async =>
_coverageData ??= await _collectCoverage();
@@ -158,7 +158,7 @@
}
await sampleProcess.exitCode;
- await sampleProcess.stderr.drain<List<int>>();
+ await sampleProcess.stderr.drain();
return toolResult.stdout as String;
}
diff --git a/pkgs/coverage/test/format_coverage_test.dart b/pkgs/coverage/test/format_coverage_test.dart
index f791df3..dd834b6 100644
--- a/pkgs/coverage/test/format_coverage_test.dart
+++ b/pkgs/coverage/test/format_coverage_test.dart
@@ -6,7 +6,7 @@
import '../bin/format_coverage.dart';
void main() {
- Directory testDir;
+ late Directory testDir;
setUp(() {
testDir = Directory.systemTemp.createTempSync('coverage_test_temp');
});
diff --git a/pkgs/coverage/test/lcov_test.dart b/pkgs/coverage/test/lcov_test.dart
index b90ea99..1399820 100644
--- a/pkgs/coverage/test/lcov_test.dart
+++ b/pkgs/coverage/test/lcov_test.dart
@@ -111,7 +111,7 @@
final hitLineRegexp = RegExp(r'\s+(\d+)\| return a \+ b;');
final match = hitLineRegexp.allMatches(res).single;
- final hitCount = int.parse(match[1]);
+ final hitCount = int.parse(match[1]!);
expect(hitCount, greaterThanOrEqualTo(1));
});
@@ -186,6 +186,6 @@
throw ProcessException(
'dart', sampleAppArgs, 'Fatal error. Exit code: $exitCode', exitCode);
}
- await sampleProcess.stderr.drain<List<int>>();
+ await sampleProcess.stderr.drain();
return hitMap;
}
diff --git a/pkgs/coverage/test/test_files/test_app.dart b/pkgs/coverage/test/test_files/test_app.dart
index 1677fbe..79c5f2a 100644
--- a/pkgs/coverage/test/test_files/test_app.dart
+++ b/pkgs/coverage/test/test_files/test_app.dart
@@ -29,7 +29,7 @@
print('isolateId = $isolateID');
isolate.addOnExitListener(port.sendPort);
- isolate.resume(isolate.pauseCapability);
+ isolate.resume(isolate.pauseCapability!);
final value = await port.first as int;
if (value != 3) {