From 97852ba78bdb30a55b1c96aacd936b9abab7d047 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Wed, 13 Sep 2023 15:24:38 -0500 Subject: [PATCH] Enable 'strict-inference' language analysis mode --- analysis_options.yaml | 1 + lib/src/command.dart | 2 +- lib/src/command/dependency_services.dart | 6 +++--- lib/src/error_group.dart | 2 +- lib/src/lock_file.dart | 4 ++-- lib/src/oauth2.dart | 6 +++--- lib/src/source/hosted.dart | 2 +- lib/src/utils.dart | 4 ++-- test/cache/list_test.dart | 10 +++++++++- .../dependency_services_test.dart | 6 ++++-- test/embedding/ensure_pubspec_resolved.dart | 2 +- test/error_group_test.dart | 20 ++++++++++++------- ...d_storage_upload_doesnt_redirect_test.dart | 2 +- ...storage_upload_provides_an_error_test.dart | 2 +- test/lish/utils.dart | 2 +- ...efresh_token_authenticates_again_test.dart | 4 ++-- test/test_pub.dart | 6 +++--- test/token/remove_token_test.dart | 4 +++- .../when_receives_401_removes_token_test.dart | 4 +++- test/utils_test.dart | 6 +++--- tool/extract_all_pub_dev.dart | 3 ++- 21 files changed, 60 insertions(+), 38 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index f0bd15af3..156085cf5 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -11,6 +11,7 @@ analyzer: language: strict-casts: true + strict-inference: true linter: rules: diff --git a/lib/src/command.dart b/lib/src/command.dart index 49c69adff..b2c5fe372 100644 --- a/lib/src/command.dart +++ b/lib/src/command.dart @@ -147,7 +147,7 @@ abstract class PubCommand extends Command { @override String get invocation { PubCommand? command = this; - var names = []; + var names = []; do { names.add(command?.name); command = command?.parent as PubCommand?; diff --git a/lib/src/command/dependency_services.dart b/lib/src/command/dependency_services.dart index 8a0813a15..c16e8501e 100644 --- a/lib/src/command/dependency_services.dart +++ b/lib/src/command/dependency_services.dart @@ -166,7 +166,7 @@ class DependencyServicesReportCommand extends PubCommand { _UpgradeType.compatible, ), 'singleBreaking': kind != 'transitive' && singleBreakingVersion == null - ? [] + ? [] : await computeUpgradeSet( singleBreakingVersion, _UpgradeType.singleBreaking, @@ -176,7 +176,7 @@ class DependencyServicesReportCommand extends PubCommand { multiBreakingVersion, _UpgradeType.multiBreaking, ) - : [], + : [], if (smallestUpgrade != null) 'smallestUpdate': await computeUpgradeSet( smallestUpgrade, @@ -503,7 +503,7 @@ class DependencyServicesApplyCommand extends PubCommand { }, ); // Dummy message. - log.message(json.encode({'dependencies': []})); + log.message(json.encode({'dependencies': []})); } } diff --git a/lib/src/error_group.dart b/lib/src/error_group.dart index 8c0955264..27a065f6c 100644 --- a/lib/src/error_group.dart +++ b/lib/src/error_group.dart @@ -313,7 +313,7 @@ class _ErrorGroupStream extends Stream { if (_isDone) return; _subscription.cancel(); // Call these asynchronously to work around issue 7913. - Future.value().then((_) { + Future.value().then((_) { _controller.addError(e, stackTrace); _controller.close(); }); diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart index cecf4072f..4df8f5be7 100644 --- a/lib/src/lock_file.dart +++ b/lib/src/lock_file.dart @@ -420,7 +420,7 @@ class LockFile { /// serialized as absolute. String serialize(String? packageDir, SystemCache cache) { // Convert the dependencies to a simple object. - var packageMap = {}; + var packageMap = {}; for (final id in packages.values) { packageMap[id.name] = { 'version': id.version.toString(), @@ -432,7 +432,7 @@ class LockFile { } var data = { - 'sdks': mapMap( + 'sdks': mapMap( sdkConstraints, value: (_, constraint) => constraint.effectiveConstraint.toString(), ), diff --git a/lib/src/oauth2.dart b/lib/src/oauth2.dart index 8131ceb09..9c6e1ec7d 100644 --- a/lib/src/oauth2.dart +++ b/lib/src/oauth2.dart @@ -124,7 +124,7 @@ Future withClient(Future Function(http.Client) fn) { // Be sure to save the credentials even when an error happens. _saveCredentials(client.credentials); }); - }).catchError((error) { + }).catchError((Object error) { if (error is _ExpirationException) { log.error("Pub's authorization to upload packages has expired and " "can't be automatically refreshed."); @@ -139,7 +139,7 @@ Future withClient(Future Function(http.Client) fn) { return withClient(fn); } else { // ignore: only_throw_errors - throw error as Object; + throw error; } }); } @@ -970,7 +970,7 @@ class Credentials { /// /// Throws a [FormatException] if the JSON is incorrectly formatted. factory Credentials.fromJson(String json) { - void validate(bool condition, message) { + void validate(bool condition, String message) { if (condition) return; throw FormatException('Failed to load credentials: $message.\n\n$json'); } diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart index e99ee523a..b3062e2f4 100644 --- a/lib/src/source/hosted.dart +++ b/lib/src/source/hosted.dart @@ -308,7 +308,7 @@ class HostedSource extends CachedSource { /// this throws a descriptive FormatException. HostedDescription _parseDescription( String packageName, - description, + Object? description, LanguageVersion languageVersion, ) { if (description == null) { diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 31ca1d188..3320df01f 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -511,7 +511,7 @@ final _unquotableYamlString = RegExp(r'^[a-zA-Z_-][a-zA-Z_0-9-]*$'); String yamlToString(Object? data) { var buffer = StringBuffer(); - void stringify(bool isMapValue, String indent, data) { + void stringify(bool isMapValue, String indent, Object? data) { // TODO(nweiz): Serialize using the YAML library once it supports // serialization. @@ -757,7 +757,7 @@ Future retry( final rf = randomizationFactor * (random.nextDouble() * 2 - 1) + 1; final exp = math.min(attempt, 31); // prevent overflows. final delay = delayFactor * math.pow(2.0, exp) * rf; - await Future.delayed(delay < maxDelay ? delay : maxDelay); + await Future.delayed(delay < maxDelay ? delay : maxDelay); } } diff --git a/test/cache/list_test.dart b/test/cache/list_test.dart index 7b4e5f554..eea83bbb4 100644 --- a/test/cache/list_test.dart +++ b/test/cache/list_test.dart @@ -23,7 +23,15 @@ void main() { d.dir('hosted', [d.dir('pub.dev', [])]), ]).create(); - await runPub(args: ['cache', 'list'], outputJson: {'packages': {}}); + await runPub( + args: [ + 'cache', + 'list', + ], + outputJson: { + 'packages': {}, + }, + ); }); test('running pub cache list', () async { diff --git a/test/dependency_services/dependency_services_test.dart b/test/dependency_services/dependency_services_test.dart index 1e307fe17..33937b3f6 100644 --- a/test/dependency_services/dependency_services_test.dart +++ b/test/dependency_services/dependency_services_test.dart @@ -631,9 +631,11 @@ Future main() async { } dynamic findChangeVersion(dynamic json, String updateType, String name) { - final dep = json['dependencies'].firstWhere((p) => p['name'] == 'foo'); + final dep = + json['dependencies'].firstWhere((dynamic p) => p['name'] == 'foo'); if (dep == null) return null; - return dep[updateType].firstWhere((p) => p['name'] == name)['version']; + return dep[updateType] + .firstWhere((dynamic p) => p['name'] == name)['version']; } class _PackageVersion { diff --git a/test/embedding/ensure_pubspec_resolved.dart b/test/embedding/ensure_pubspec_resolved.dart index ba46efdaf..19654bedb 100644 --- a/test/embedding/ensure_pubspec_resolved.dart +++ b/test/embedding/ensure_pubspec_resolved.dart @@ -559,7 +559,7 @@ Future _noImplicitPubGet({ Future _touch(String path) async { // Delay a bit to make sure the modification times are noticeably different. // 1s seems to be the finest granularity that dart:io reports. - await Future.delayed(Duration(seconds: 1)); + await Future.delayed(Duration(seconds: 1)); path = p.join(d.sandbox, 'myapp', path); touch(path); diff --git a/test/error_group_test.dart b/test/error_group_test.dart index 15ffcf422..ec673bbbc 100644 --- a/test/error_group_test.dart +++ b/test/error_group_test.dart @@ -33,9 +33,13 @@ void main() { expect(errorGroup.done, throwsFormatException); errorGroup.signalError(FormatException()); - expect(() => errorGroup.registerFuture(Future.value()), throwsStateError); expect( - () => errorGroup.registerStream(StreamController(sync: true).stream), + () => errorGroup.registerFuture(Future.value()), + throwsStateError, + ); + expect( + () => errorGroup + .registerStream(StreamController(sync: true).stream), throwsStateError, ); }); @@ -63,12 +67,14 @@ void main() { completer.complete('value'); expect( - completer.future.then((_) => errorGroup.registerFuture(Future.value())), + completer.future + .then((_) => errorGroup.registerFuture(Future.value())), throwsStateError, ); expect( completer.future.then( - (_) => errorGroup.registerStream(StreamController(sync: true).stream), + (_) => errorGroup + .registerStream(StreamController(sync: true).stream), ), throwsStateError, ); @@ -401,7 +407,7 @@ void main() { test( "shouldn't throw a top-level exception if a stream receives an error " 'after the other listened stream completes', () { - var signal = Completer(); + var signal = Completer(); expect( stream1.toList().whenComplete(signal.complete), completion(equals(['value1', 'value2'])), @@ -423,7 +429,7 @@ void main() { test( "shouldn't throw a top-level exception if an error is signaled after " 'one listened stream completes', () { - var signal = Completer(); + var signal = Completer(); expect( stream1.toList().whenComplete(signal.complete), completion(equals(['value1', 'value2'])), @@ -505,7 +511,7 @@ void main() { test( "shouldn't throw a top-level exception if the future receives an " 'error after the listened stream completes', () { - var signal = Completer(); + var signal = Completer(); expect( stream.toList().whenComplete(signal.complete), completion(equals(['value1', 'value2'])), diff --git a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart index f95db5ed9..38f32cf6b 100644 --- a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart +++ b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart @@ -20,7 +20,7 @@ void main() { handleUploadForm(globalServer); globalServer.expect('POST', '/upload', (request) async { - await request.read().drain(); + await request.read().drain(); return shelf.Response(200); }); diff --git a/test/lish/cloud_storage_upload_provides_an_error_test.dart b/test/lish/cloud_storage_upload_provides_an_error_test.dart index bd14d84d0..a51b66462 100644 --- a/test/lish/cloud_storage_upload_provides_an_error_test.dart +++ b/test/lish/cloud_storage_upload_provides_an_error_test.dart @@ -20,7 +20,7 @@ void main() { handleUploadForm(globalServer); globalServer.expect('POST', '/upload', (request) { - return request.read().drain().then((_) { + return request.read().drain().then((_) { return shelf.Response.notFound( 'Your request sucked.', headers: {'content-type': 'application/xml'}, diff --git a/test/lish/utils.dart b/test/lish/utils.dart index eebdc3757..27df55f2e 100644 --- a/test/lish/utils.dart +++ b/test/lish/utils.dart @@ -34,7 +34,7 @@ void handleUpload(PackageServer server) { // that the request body is correctly formatted. See issue 6952. return request .read() - .drain() + .drain() .then((_) => server.url) .then((url) => shelf.Response.found(Uri.parse(url).resolve('/create'))); }); diff --git a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart index 419a81e60..0669cb6db 100644 --- a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart +++ b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart @@ -32,7 +32,7 @@ void main() { var pub = await startPublish(globalServer); globalServer.expect('POST', '/token', (request) { - return request.read().drain().then((_) { + return request.read().drain().then((_) { return shelf.Response( 400, body: jsonEncode({'error': 'invalid_request'}), @@ -46,7 +46,7 @@ void main() { await expectLater(pub.stdout, emits(startsWith('Uploading...'))); await authorizePub(pub, globalServer, 'new access token'); - var done = Completer(); + var done = Completer(); globalServer.expect('GET', '/api/packages/versions/new', (request) async { expect( request.headers, diff --git a/test/test_pub.dart b/test/test_pub.dart index 951ee21b1..cad7f3052 100644 --- a/test/test_pub.dart +++ b/test/test_pub.dart @@ -79,7 +79,7 @@ String packageConfigFilePath = Map packageSpec(String packageName) => json .decode(File(d.path(packageConfigFilePath)).readAsStringSync())['packages'] .firstWhere( - (e) => e['name'] == packageName, + (dynamic e) => e['name'] == packageName, orElse: () => null, ) as Map; @@ -796,7 +796,7 @@ String binStubName(String name) => Platform.isWindows ? '$name.bat' : name; void _validateOutput( List failures, String pipe, - expected, + Object? expected, String actual, ) { if (expected == null) return; @@ -884,7 +884,7 @@ void _validateOutputJson( // Remove dart2js's timing logs, which would otherwise cause tests to fail // flakily when compilation takes a long time. actual['log']?.removeWhere( - (entry) => + (dynamic entry) => entry['level'] == 'Fine' && (entry['message'] as String).startsWith('Not yet complete after'), ); diff --git a/test/token/remove_token_test.dart b/test/token/remove_token_test.dart index dd4f4c43e..e06459ea7 100644 --- a/test/token/remove_token_test.dart +++ b/test/token/remove_token_test.dart @@ -19,7 +19,9 @@ void main() { await runPub(args: ['token', 'remove', 'https://server.demo']); - await d.tokensFile({'version': 1, 'hosted': []}).validate(); + await d.tokensFile( + {'version': 1, 'hosted': >[]}, + ).validate(); }); test('without any matching schemes, does nothing', () async { diff --git a/test/token/when_receives_401_removes_token_test.dart b/test/token/when_receives_401_removes_token_test.dart index 13816ccd7..ad90b3386 100644 --- a/test/token/when_receives_401_removes_token_test.dart +++ b/test/token/when_receives_401_removes_token_test.dart @@ -27,6 +27,8 @@ void main() { await pub.shouldExit(65); - await d.tokensFile({'version': 1, 'hosted': []}).validate(); + await d.tokensFile( + {'version': 1, 'hosted': >[]}, + ).validate(); }); } diff --git a/test/utils_test.dart b/test/utils_test.dart index 173041d5c..1ce8869af 100644 --- a/test/utils_test.dart +++ b/test/utils_test.dart @@ -75,7 +75,7 @@ no: 1 }); test('handles non-string map keys', () { - var map = {}; + var map = {}; map[null] = 'null'; map[123] = 'num'; map[true] = 'bool'; @@ -92,7 +92,7 @@ true: bool'''), test('handles empty maps', () { expect(yamlToString({}), equals('{}')); expect( - yamlToString({'a': {}, 'b': {}}), + yamlToString({'a': {}, 'b': {}}), equals(''' a: {} b: {}'''), @@ -188,7 +188,7 @@ b: {}'''), expect(() => hexEncode([256, 0, 1]), throwsA(isA())); }); test('hexDecode', () { - expect(hexDecode(''), []); + expect(hexDecode(''), []); expect(hexDecode('ff0001f0abcdef'), [255, 0, 1, 240, 171, 205, 239]); expect(hexDecode('FF0001F0ABCDEF'), [255, 0, 1, 240, 171, 205, 239]); expect(() => hexDecode('F'), throwsA(isA())); diff --git a/tool/extract_all_pub_dev.dart b/tool/extract_all_pub_dev.dart index ffd08a2df..9525a1998 100644 --- a/tool/extract_all_pub_dev.dart +++ b/tool/extract_all_pub_dev.dart @@ -47,7 +47,8 @@ Future main() async { for (final packageName in json['packages'] as Iterable? ?? []) { alreadyDonePackages.add(packageName as String); } - for (final failure in (json['failures'] ?? []) as Iterable) { + for (final failure + in (json['failures'] ?? >[]) as Iterable) { failures.add(failure as Map); } }