From 32c3b9b7cbe178a1b790e76324decead56cf5ee9 Mon Sep 17 00:00:00 2001 From: Yegor Date: Wed, 5 Jun 2024 19:16:55 -0700 Subject: [PATCH] [web] clean up dynamic calls, remove always_specify_types (#53228) Remove the `avoid_dynamic_calls` exception in `web_ui`, and clean up all dynamic calls. --- lib/web_ui/analysis_options.yaml | 2 -- lib/web_ui/dev/roll_fallback_fonts.dart | 7 ++++--- lib/web_ui/dev/steps/run_suite_step.dart | 10 +++++----- lib/web_ui/lib/src/engine/app_bootstrap.dart | 10 +++++----- lib/web_ui/lib/src/engine/clipboard.dart | 2 +- lib/web_ui/lib/src/engine/platform_dispatcher.dart | 2 +- lib/web_ui/lib/src/engine/services/message_codecs.dart | 10 ++++++---- .../lib/src/engine/text_editing/text_editing.dart | 5 +++-- .../canvaskit/initialization/services_vs_ui_test.dart | 2 +- lib/web_ui/test/engine/app_bootstrap_test.dart | 2 +- lib/web_ui/test/engine/routing_test.dart | 10 ++++++---- 11 files changed, 33 insertions(+), 29 deletions(-) diff --git a/lib/web_ui/analysis_options.yaml b/lib/web_ui/analysis_options.yaml index 0485498791305..0938119b50664 100644 --- a/lib/web_ui/analysis_options.yaml +++ b/lib/web_ui/analysis_options.yaml @@ -8,8 +8,6 @@ include: ../../analysis_options.yaml linter: rules: - always_specify_types: true # avoid_dynamic_calls needs to be cleaned up before we can start relying on type inference - avoid_dynamic_calls: false avoid_print: false avoid_setters_without_getters: false library_private_types_in_public_api: false diff --git a/lib/web_ui/dev/roll_fallback_fonts.dart b/lib/web_ui/dev/roll_fallback_fonts.dart index 623ef2be25a0f..bdec667f556eb 100644 --- a/lib/web_ui/dev/roll_fallback_fonts.dart +++ b/lib/web_ui/dev/roll_fallback_fonts.dart @@ -73,11 +73,12 @@ class RollFallbackFontsCommand extends Command (googleFontsResult['items'] as List) .cast>(); final Map urlForFamily = {}; - for (final Map fontData in fontDatas) { + for (final Map fontData in fontDatas) { if (fallbackFonts.contains(fontData['family'])) { - final Uri uri = Uri.parse(fontData['files']['regular'] as String) + final files = fontData['files']! as Map; + final Uri uri = Uri.parse(files['regular']! as String) .replace(scheme: 'https'); - urlForFamily[fontData['family'] as String] = uri; + urlForFamily[fontData['family']! as String] = uri; } } final Map charsetForFamily = {}; diff --git a/lib/web_ui/dev/steps/run_suite_step.dart b/lib/web_ui/dev/steps/run_suite_step.dart index 2944187a7f38b..e2992e23989a5 100644 --- a/lib/web_ui/dev/steps/run_suite_step.dart +++ b/lib/web_ui/dev/steps/run_suite_step.dart @@ -156,12 +156,12 @@ class RunSuiteStep implements PipelineStep { throw ToolExit('Could not find built bundle ${suite.testBundle.name.ansiMagenta} for suite ${suite.name.ansiCyan}.'); } final String jsonString = resultsJsonFile.readAsStringSync(); - final dynamic jsonContents = const JsonDecoder().convert(jsonString); - final dynamic results = jsonContents['results']; + final jsonContents = const JsonDecoder().convert(jsonString) as Map; + final results = jsonContents['results']! as Map; final List testPaths = []; - results.forEach((dynamic k, dynamic v) { - final String result = v as String; - final String testPath = k as String; + results.forEach((Object? k, Object? v) { + final String result = v! as String; + final String testPath = k! as String; if (testFiles != null) { if (!testFiles!.contains(FilePath.fromTestSet(suite.testBundle.testSet, testPath))) { return; diff --git a/lib/web_ui/lib/src/engine/app_bootstrap.dart b/lib/web_ui/lib/src/engine/app_bootstrap.dart index 686811314775f..3c101f95717cb 100644 --- a/lib/web_ui/lib/src/engine/app_bootstrap.dart +++ b/lib/web_ui/lib/src/engine/app_bootstrap.dart @@ -12,20 +12,20 @@ import 'view_embedder/flutter_view_manager.dart'; /// The type of a function that initializes an engine (in Dart). typedef InitEngineFn = Future Function([JsFlutterConfiguration? params]); +/// The signature of the `runApp` function passed to [AppBootstrap]. +typedef AppBootstrapRunAppFn = Future Function(); + /// A class that controls the coarse lifecycle of a Flutter app. class AppBootstrap { /// Construct an AppBootstrap. - AppBootstrap({required InitEngineFn initializeEngine, required Function runApp}) : + AppBootstrap({required InitEngineFn initializeEngine, required AppBootstrapRunAppFn runApp}) : _initializeEngine = initializeEngine, _runApp = runApp; // A function to initialize the engine. final InitEngineFn _initializeEngine; // A function to run the app. - // - // TODO(dit): Be more strict with the typedef of this function, so we can add - // typed params to the function. (See InitEngineFn). - final Function _runApp; + final AppBootstrapRunAppFn _runApp; /// Immediately bootstraps the app. /// diff --git a/lib/web_ui/lib/src/engine/clipboard.dart b/lib/web_ui/lib/src/engine/clipboard.dart index 54ab51eaa9c10..3e1b4f728ce5f 100644 --- a/lib/web_ui/lib/src/engine/clipboard.dart +++ b/lib/web_ui/lib/src/engine/clipboard.dart @@ -23,7 +23,7 @@ class ClipboardMessageHandler { const MethodCodec codec = JSONMethodCodec(); bool errorEnvelopeEncoded = false; _copyToClipboardStrategy - .setData(methodCall.arguments['text'] as String?) + .setData((methodCall.arguments as Map)['text'] as String?) .then((bool success) { if (success) { callback!(codec.encodeSuccessEnvelope(true)); diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index 8cdb6d19bddbc..63aa5cc65f1bd 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher.dart @@ -535,7 +535,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { if (renderer is CanvasKitRenderer) { assert( decoded.arguments is int, - 'Argument to Skia.setResourceCacheMaxBytes must be an int, but was ${decoded.arguments.runtimeType}', + 'Argument to Skia.setResourceCacheMaxBytes must be an int, but was ${(decoded.arguments as Object?).runtimeType}', ); final int cacheSizeInBytes = decoded.arguments as int; CanvasKitRenderer.instance.resourceCacheMaxBytes = diff --git a/lib/web_ui/lib/src/engine/services/message_codecs.dart b/lib/web_ui/lib/src/engine/services/message_codecs.dart index 26c01c141e3d0..5167563737dfb 100644 --- a/lib/web_ui/lib/src/engine/services/message_codecs.dart +++ b/lib/web_ui/lib/src/engine/services/message_codecs.dart @@ -412,16 +412,18 @@ class StandardMessageCodec implements MessageCodec { result = buffer.getFloat64List(length); case _valueList: final int length = readSize(buffer); - result = []; + final theResult = []; for (int i = 0; i < length; i++) { - result.add(readValue(buffer)); + theResult.add(readValue(buffer)); } + result = theResult; case _valueMap: final int length = readSize(buffer); - result = {}; + final theResult = {}; for (int i = 0; i < length; i++) { - result[readValue(buffer)] = readValue(buffer); + theResult[readValue(buffer)] = readValue(buffer); } + result = theResult; default: throw const FormatException('Message corrupted'); } diff --git a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart index 6f4ebdd7990dd..da49e877b2d7c 100644 --- a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart +++ b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart @@ -2184,9 +2184,10 @@ class TextEditingChannel { final TextInputCommand command; switch (call.method) { case 'TextInput.setClient': + final args = call.arguments! as List; command = TextInputSetClient( - clientId: call.arguments[0] as int, - configuration: InputConfiguration.fromFrameworkMessage(call.arguments[1] as Map), + clientId: args[0]! as int, + configuration: InputConfiguration.fromFrameworkMessage(args[1]! as Map), ); case 'TextInput.updateConfig': diff --git a/lib/web_ui/test/canvaskit/initialization/services_vs_ui_test.dart b/lib/web_ui/test/canvaskit/initialization/services_vs_ui_test.dart index 709b88aff9a92..d8960ad204237 100644 --- a/lib/web_ui/test/canvaskit/initialization/services_vs_ui_test.dart +++ b/lib/web_ui/test/canvaskit/initialization/services_vs_ui_test.dart @@ -54,7 +54,7 @@ Future bootstrapAndExtractConfig() { final Completer configCompleter = Completer(); final AppBootstrap bootstrap = AppBootstrap( initializeEngine: ([JsFlutterConfiguration? config]) async => configCompleter.complete(config), - runApp: () {} + runApp: () async {} ); final FlutterLoader? loader = flutter?.loader; if (loader == null || loader.isAutoStart) { diff --git a/lib/web_ui/test/engine/app_bootstrap_test.dart b/lib/web_ui/test/engine/app_bootstrap_test.dart index 683073ea02c18..d9f55f6f6029b 100644 --- a/lib/web_ui/test/engine/app_bootstrap_test.dart +++ b/lib/web_ui/test/engine/app_bootstrap_test.dart @@ -34,7 +34,7 @@ void testMain() { await Future.delayed(const Duration(milliseconds: 1)); } - void mockRunApp () { + Future mockRunApp () async { runCalled = callOrder++; } diff --git a/lib/web_ui/test/engine/routing_test.dart b/lib/web_ui/test/engine/routing_test.dart index e5713cd49b34e..5620868b0685a 100644 --- a/lib/web_ui/test/engine/routing_test.dart +++ b/lib/web_ui/test/engine/routing_test.dart @@ -279,13 +279,15 @@ void testMain() { await callback.future; expect(myWindow.browserHistory, isA()); expect(myWindow.browserHistory.urlStrategy!.getPath(), '/baz'); - final dynamic wrappedState = myWindow.browserHistory.urlStrategy!.getState(); - final dynamic actualState = wrappedState['state']; + final wrappedState = myWindow.browserHistory.urlStrategy!.getState()! as Map; + final actualState = wrappedState['state']! as Map; expect(actualState['state1'], true); expect(actualState['state2'], 1); expect(actualState['state3'], 'string'); - expect(actualState['state4']['substate1'], 1.0); - expect(actualState['state4']['substate2'], 'string2'); + + final state4 = actualState['state4']! as Map; + expect(state4['substate1'], 1.0); + expect(state4['substate2'], 'string2'); }); test('routeInformationUpdated can handle uri',