Unverified Commit 88f38110 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Turn on avoid_dynamic_calls lint, except packages/flutter tests, make appropriate changes. (#84476)

This adds avoid_dynamic_calls to the list of lints, and fixes all instances where it was violated.

Importantly, this lint is NOT turned on for flutter/packages/test, because those changes are happening in another PR: #84478
parent acd68cf4
......@@ -61,7 +61,7 @@ linter:
# - avoid_catching_errors # we do this commonly
- avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime
# - avoid_dynamic_calls # not yet tested
- avoid_dynamic_calls
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
- avoid_escaping_inner_quotes
......
......@@ -595,7 +595,7 @@ class ArchivePublisher {
if (!jsonData.containsKey('current_release')) {
jsonData['current_release'] = <String, String>{};
}
jsonData['current_release'][branchName] = revision;
(jsonData['current_release'] as Map<String, dynamic>)[branchName] = revision;
if (!jsonData.containsKey('releases')) {
jsonData['releases'] = <Map<String, dynamic>>[];
}
......
......@@ -1059,7 +1059,7 @@ Future<void> _ensureChromeDriverIsRunning() async {
final HttpClientResponse response = await request.close();
final Map<String, dynamic> webDriverStatus = json.decode(await response.transform(utf8.decoder).join('')) as Map<String, dynamic>;
client.close();
final bool webDriverReady = webDriverStatus['value']['ready'] as bool;
final bool webDriverReady = (webDriverStatus['value'] as Map<String, dynamic>)['ready'] as bool;
if (!webDriverReady) {
throw Exception('WebDriver not available.');
}
......
......@@ -394,7 +394,7 @@ void main() {
// Make sure the new entry is first (and hopefully it takes less than a
// minute to go from publishArchive above to this line!).
expect(
DateTime.now().difference(DateTime.parse(releases[0]['release_date'] as String)),
DateTime.now().difference(DateTime.parse((releases[0] as Map<String, dynamic>)['release_date'] as String)),
lessThan(const Duration(minutes: 1)),
);
const JsonEncoder encoder = JsonEncoder.withIndent(' ');
......
......@@ -255,7 +255,7 @@ class ArchiveUnpublisher {
});
jsonData['releases'] = releases;
for (final Channel channel in channels) {
if (!revisionsBeingRemoved.contains(jsonData['current_release'][getChannelName(channel)])) {
if (!revisionsBeingRemoved.contains((jsonData['current_release'] as Map<String, dynamic>)[getChannelName(channel)])) {
// Don't replace the current release if it's not one of the revisions we're removing.
continue;
}
......@@ -263,7 +263,7 @@ class ArchiveUnpublisher {
if (replacementRelease == null) {
throw UnpublishException('Unable to find previous release for channel ${getChannelName(channel)}.');
}
jsonData['current_release'][getChannelName(channel)] = replacementRelease['hash'];
(jsonData['current_release'] as Map<String, dynamic>)[getChannelName(channel)] = replacementRelease['hash'];
print(
'${confirmed ? 'Reverting' : 'Would revert'} current ${getChannelName(channel)} '
'${getPublishedPlatform(platform)} release to ${replacementRelease['hash']} (version ${replacementRelease['version']}).'
......
......@@ -31,7 +31,7 @@ Future<void> main() async {
final Map<String, dynamic> data = <String, dynamic>{};
for (final String key in withSemantics.benchmarkScoreKeys) {
final String deltaKey = 'delta_$key';
data[deltaKey] = withSemantics.data[key] - withoutSemantics.data[key];
data[deltaKey] = (withSemantics.data[key] as num) - (withoutSemantics.data[key] as num);
data['semantics_$key'] = withSemantics.data[key];
data[key] = withoutSemantics.data[key];
benchmarkScoreKeys.add(deltaKey);
......
......@@ -273,7 +273,7 @@ Future<Uri> _getRemoteDebuggerUrl(Uri base) async {
if (jsonObject == null || jsonObject.isEmpty) {
return base;
}
return base.resolve(jsonObject.first['webSocketDebuggerUrl'] as String);
return base.resolve((jsonObject.first as Map<String, dynamic>)['webSocketDebuggerUrl'] as String);
}
/// Summarizes a Blink trace down to a few interesting values.
......
......@@ -104,11 +104,12 @@ Manifest _validateAndParseManifest(YamlMap manifestYaml) {
List<ManifestTask> _validateAndParseTasks(dynamic tasksYaml) {
_checkType(tasksYaml is YamlMap, tasksYaml, 'Value of "tasks"', 'dictionary');
final List<dynamic> sortedKeys = (tasksYaml as YamlMap).keys.toList()..sort();
return sortedKeys.map<ManifestTask>((dynamic taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList();
final List<String> sortedKeys = (tasksYaml as YamlMap).keys.toList().cast<String>()..sort();
// ignore: avoid_dynamic_calls
return sortedKeys.map<ManifestTask>((String taskName) => _validateAndParseTask(taskName, tasksYaml[taskName])).toList();
}
ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
ManifestTask _validateAndParseTask(String taskName, dynamic taskYaml) {
_checkType(taskName is String, taskName, 'Task name', 'string');
_checkType(taskYaml is YamlMap, taskYaml, 'Value of task "$taskName"', 'dictionary');
_checkKeys(taskYaml as YamlMap, 'Value of task "$taskName"', const <String>[
......@@ -119,27 +120,32 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
'timeout_in_minutes',
'on_luci',
]);
// ignore: avoid_dynamic_calls
final dynamic isFlaky = taskYaml['flaky'];
if (isFlaky != null) {
_checkType(isFlaky is bool, isFlaky, 'flaky', 'boolean');
}
// ignore: avoid_dynamic_calls
final dynamic timeoutInMinutes = taskYaml['timeout_in_minutes'];
if (timeoutInMinutes != null) {
_checkType(timeoutInMinutes is int, timeoutInMinutes, 'timeout_in_minutes', 'integer');
}
final List<dynamic> capabilities = _validateAndParseCapabilities(taskName as String, taskYaml['required_agent_capabilities']);
// ignore: avoid_dynamic_calls
final List<dynamic> capabilities = _validateAndParseCapabilities(taskName, taskYaml['required_agent_capabilities']);
// ignore: avoid_dynamic_calls
final dynamic onLuci = taskYaml['on_luci'];
if (onLuci != null) {
_checkType(onLuci is bool, onLuci, 'on_luci', 'boolean');
}
return ManifestTask._(
name: taskName as String,
name: taskName,
// ignore: avoid_dynamic_calls
description: taskYaml['description'] as String,
// ignore: avoid_dynamic_calls
stage: taskYaml['stage'] as String,
requiredAgentCapabilities: capabilities as List<String>,
isFlaky: isFlaky as bool ?? false,
......@@ -150,8 +156,9 @@ ManifestTask _validateAndParseTask(dynamic taskName, dynamic taskYaml) {
List<String> _validateAndParseCapabilities(String taskName, dynamic capabilitiesYaml) {
_checkType(capabilitiesYaml is List, capabilitiesYaml, 'required_agent_capabilities', 'list');
for (int i = 0; i < (capabilitiesYaml as List<dynamic>).length; i++) {
final dynamic capability = capabilitiesYaml[i];
final List<dynamic> capabilities = capabilitiesYaml as List<dynamic>;
for (int i = 0; i < capabilities.length; i++) {
final dynamic capability = capabilities[i];
_checkType(capability is String, capability, 'required_agent_capabilities[$i]', 'string');
}
return (capabilitiesYaml as List<dynamic>).cast<String>();
......
......@@ -31,7 +31,7 @@ class TaskResult {
'result data ${prettyJson.convert(data)}';
} else if (data[key] is! num) {
throw 'Invalid benchmark score for key "$key". It is expected to be a num '
'but was ${data[key].runtimeType}: ${prettyJson.convert(data[key])}';
'but was ${(data[key] as Object).runtimeType}: ${prettyJson.convert(data[key])}';
}
}
}
......
......@@ -151,24 +151,43 @@ TaskFunction createHotModeTest({String deviceIdOverride, Map<String, String> env
return TaskResult.success(
<String, dynamic> {
// ignore: avoid_dynamic_calls
'hotReloadInitialDevFSSyncMilliseconds': smallReloadData['hotReloadInitialDevFSSyncMilliseconds'][0],
// ignore: avoid_dynamic_calls
'hotRestartMillisecondsToFrame': smallReloadData['hotRestartMillisecondsToFrame'][0],
// ignore: avoid_dynamic_calls
'hotReloadMillisecondsToFrame' : smallReloadData['hotReloadMillisecondsToFrame'][0],
// ignore: avoid_dynamic_calls
'hotReloadDevFSSyncMilliseconds': smallReloadData['hotReloadDevFSSyncMilliseconds'][0],
// ignore: avoid_dynamic_calls
'hotReloadFlutterReassembleMilliseconds': smallReloadData['hotReloadFlutterReassembleMilliseconds'][0],
// ignore: avoid_dynamic_calls
'hotReloadVMReloadMilliseconds': smallReloadData['hotReloadVMReloadMilliseconds'][0],
// ignore: avoid_dynamic_calls
'hotReloadMillisecondsToFrameAfterChange' : smallReloadData['hotReloadMillisecondsToFrame'][1],
// ignore: avoid_dynamic_calls
'hotReloadDevFSSyncMillisecondsAfterChange': smallReloadData['hotReloadDevFSSyncMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadFlutterReassembleMillisecondsAfterChange': smallReloadData['hotReloadFlutterReassembleMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadVMReloadMillisecondsAfterChange': smallReloadData['hotReloadVMReloadMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadInitialDevFSSyncAfterRelaunchMilliseconds' : freshRestartReloadsData['hotReloadInitialDevFSSyncMilliseconds'][0],
// ignore: avoid_dynamic_calls
'hotReloadMillisecondsToFrameAfterMediumChange' : mediumReloadData['hotReloadMillisecondsToFrame'][1],
// ignore: avoid_dynamic_calls
'hotReloadDevFSSyncMillisecondsAfterMediumChange': mediumReloadData['hotReloadDevFSSyncMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadFlutterReassembleMillisecondsAfterMediumChange': mediumReloadData['hotReloadFlutterReassembleMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadVMReloadMillisecondsAfterMediumChange': mediumReloadData['hotReloadVMReloadMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadMillisecondsToFrameAfterLargeChange' : largeReloadData['hotReloadMillisecondsToFrame'][1],
// ignore: avoid_dynamic_calls
'hotReloadDevFSSyncMillisecondsAfterLargeChange': largeReloadData['hotReloadDevFSSyncMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadFlutterReassembleMillisecondsAfterLargeChange': largeReloadData['hotReloadFlutterReassembleMilliseconds'][1],
// ignore: avoid_dynamic_calls
'hotReloadVMReloadMillisecondsAfterLargeChange': largeReloadData['hotReloadVMReloadMilliseconds'][1],
},
benchmarkScoreKeys: <String>[
......
......@@ -421,13 +421,15 @@ TaskFunction createsScrollSmoothnessPerfTest() {
final Map<String, dynamic> result = <String, dynamic>{};
void addResult(dynamic data, String suffix) {
assert(data is Map<String, dynamic>);
if (data is Map<String, dynamic>) {
const List<String> metricKeys = <String>[
'janky_count',
'average_abs_jerk',
'dropped_frame_count',
];
for (final String key in metricKeys) {
result[key+suffix] = data[key];
result[key + suffix] = data[key];
}
}
}
addResult(data['resample on with 90Hz input'], '_with_resampler_90Hz');
......@@ -1472,15 +1474,15 @@ class DevToolsMemoryTest {
final Map<String, dynamic> data = json.decode(
file('$project/$_kJsonFileName').readAsStringSync(),
) as Map<String, dynamic>;
final List<dynamic> samples = data['samples']['data'] as List<dynamic>;
final List<Map<String, dynamic>> samples = (data['samples'] as Map<String, dynamic>)['data'] as List<Map<String, dynamic>>;
int maxRss = 0;
int maxAdbTotal = 0;
for (final dynamic sample in samples) {
for (final Map<String, dynamic> sample in samples) {
if (sample['rss'] != null) {
maxRss = math.max(maxRss, sample['rss'] as int);
}
if (sample['adb_memoryInfo'] != null) {
maxAdbTotal = math.max(maxAdbTotal, sample['adb_memoryInfo']['Total'] as int);
maxAdbTotal = math.max(maxAdbTotal, (sample['adb_memoryInfo'] as Map<String, dynamic>)['Total'] as int);
}
}
......
......@@ -69,7 +69,7 @@ Future<TaskResult> runWebBenchmark({ @required bool useCanvasKit }) async {
final BlinkTraceSummary traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace);
profile['totalUiFrame.average'] = traceSummary.averageTotalUIFrameTime.inMicroseconds;
profile['scoreKeys'] ??= <dynamic>[]; // using dynamic for consistency with JSON
profile['scoreKeys'].add('totalUiFrame.average');
(profile['scoreKeys'] as List<dynamic>).add('totalUiFrame.average');
latestPerformanceTrace = null;
}
collectedProfiles.add(profile);
......
......@@ -46,7 +46,7 @@ class _ColorPickerSwatch extends StatelessWidget {
final Color color;
final bool selected;
final Function? onTap;
final VoidCallback? onTap;
@override
Widget build (BuildContext context) {
......
......@@ -42,7 +42,7 @@ Future<void> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
frameStart = timestamp;
} else {
assert(phase == 'E');
final String routeName = startEvent['args']['to'] as String;
final String routeName = (startEvent['args'] as Map<String, dynamic>)['to'] as String;
durations[routeName] ??= <int>[];
durations[routeName]!.add(timestamp - frameStart!);
startEvent = null;
......@@ -79,7 +79,7 @@ Future<void> saveDurationsHistogram(List<Map<String, dynamic>> events, String ou
continue;
final String routeName = eventName == 'Start Transition'
? eventIter.current['args']['to'] as String
? (eventIter.current['args'] as Map<String, dynamic>)['to'] as String
: '';
if (eventName == lastEventName && routeName == lastRouteName) {
......
......@@ -440,18 +440,18 @@ class LogicalKeyEntry {
LogicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map)
: value = map['value'] as int,
name = map['name'] as String,
webNames = _toNonEmptyArray<String>(map['names']['web']),
macOSKeyCodeNames = _toNonEmptyArray<String>(map['names']['macos']),
macOSKeyCodeValues = _toNonEmptyArray<int>(map['values']?['macos']),
iOSKeyCodeNames = _toNonEmptyArray<String>(map['names']['ios']),
iOSKeyCodeValues = _toNonEmptyArray<int>(map['values']?['ios']),
gtkNames = _toNonEmptyArray<String>(map['names']['gtk']),
gtkValues = _toNonEmptyArray<int>(map['values']?['gtk']),
windowsNames = _toNonEmptyArray<String>(map['names']['windows']),
windowsValues = _toNonEmptyArray<int>(map['values']?['windows']),
androidNames = _toNonEmptyArray<String>(map['names']['android']),
androidValues = _toNonEmptyArray<int>(map['values']?['android']),
fuchsiaValues = _toNonEmptyArray<int>(map['values']?['fuchsia']),
webNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['web']),
macOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['macos']),
macOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['macos']),
iOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['ios']),
iOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['ios']),
gtkNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['gtk']),
gtkValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['gtk']),
windowsNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['windows']),
windowsValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['windows']),
androidNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['android']),
androidValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['android']),
fuchsiaValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['fuchsia']),
keyLabel = map['keyLabel'] as String?;
final int value;
......
......@@ -275,17 +275,20 @@ class PhysicalKeyEntry {
/// Populates the key from a JSON map.
factory PhysicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map) {
final Map<String, dynamic> names = map['names'] as Map<String, dynamic>;
final Map<String, dynamic> scanCodes = map['scanCodes'] as Map<String, dynamic>;
final Map<String, dynamic>? keyCodes = map['keyCodes'] as Map<String, dynamic>?;
return PhysicalKeyEntry(
name: map['names']['name'] as String,
chromiumCode: map['names']['chromium'] as String?,
usbHidCode: map['scanCodes']['usb'] as int,
androidScanCodes: (map['scanCodes']['android'] as List<dynamic>?)?.cast<int>() ?? <int>[],
linuxScanCode: map['scanCodes']['linux'] as int?,
xKbScanCode: map['scanCodes']['xkb'] as int?,
windowsScanCode: map['scanCodes']['windows'] as int?,
macOSScanCode: map['scanCodes']['macos'] as int?,
iOSScanCode: map['scanCodes']['ios'] as int?,
glfwKeyCodes: (map['keyCodes']?['glfw'] as List<dynamic>?)?.cast<int>() ?? <int>[],
name: names['name'] as String,
chromiumCode: names['chromium'] as String?,
usbHidCode: scanCodes['usb'] as int,
androidScanCodes: (scanCodes['android'] as List<dynamic>?)?.cast<int>() ?? <int>[],
linuxScanCode: scanCodes['linux'] as int?,
xKbScanCode: scanCodes['xkb'] as int?,
windowsScanCode: scanCodes['windows'] as int?,
macOSScanCode: scanCodes['macos'] as int?,
iOSScanCode: scanCodes['ios'] as int?,
glfwKeyCodes: (keyCodes?['glfw'] as List<dynamic>?)?.cast<int>() ?? <int>[],
);
}
......
......@@ -221,7 +221,7 @@ class _ChainedEvaluation<T> extends Animatable<T> {
/// If `T` is not nullable, then [begin] and [end] must both be set to
/// non-null values before using [lerp] or [transform], otherwise they
/// will throw.
class Tween<T extends dynamic> extends Animatable<T> {
class Tween<T extends Object?> extends Animatable<T> {
/// Creates a tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
......@@ -261,7 +261,8 @@ class Tween<T extends dynamic> extends Animatable<T> {
// that do not conform to the Tween requirements.
dynamic result;
try {
result = begin + (end - begin) * t;
// ignore: avoid_dynamic_calls
result = (begin as dynamic) + ((end as dynamic) - (begin as dynamic)) * t;
result as T;
return true;
} on NoSuchMethodError {
......@@ -301,7 +302,8 @@ class Tween<T extends dynamic> extends Animatable<T> {
]);
}
}());
return begin + (end - begin) * t as T;
// ignore: avoid_dynamic_calls
return (begin as dynamic) + ((end as dynamic) - (begin as dynamic)) * t as T;
}
/// Returns the interpolated value for the current value of the given animation.
......@@ -330,7 +332,7 @@ class Tween<T extends dynamic> extends Animatable<T> {
}
/// A [Tween] that evaluates its [parent] in reverse.
class ReverseTween<T> extends Tween<T> {
class ReverseTween<T extends Object?> extends Tween<T> {
/// Construct a [Tween] that evaluates its [parent] in reverse.
ReverseTween(this.parent)
: assert(parent != null),
......
......@@ -35,6 +35,7 @@ Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { St
final Completer<R> result = Completer<R>();
errorPort.listen((dynamic errorData) {
assert(errorData is List<dynamic>);
if (errorData is List<dynamic>) {
assert(errorData.length == 2);
final Exception exception = Exception(errorData[0]);
final StackTrace stack = StackTrace.fromString(errorData[1] as String);
......@@ -43,6 +44,7 @@ Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { St
} else {
result.completeError(exception, stack);
}
}
});
exitPort.listen((dynamic exitData) {
if (!result.isCompleted) {
......
......@@ -86,7 +86,7 @@ class NetworkImage
final Uri resolved = Uri.base.resolve(key.url);
// This API only exists in the web engine implementation and is not
// contained in the analyzer summary for Flutter.
return ui.webOnlyInstantiateImageCodecFromUrl(// ignore: undefined_function
return ui.webOnlyInstantiateImageCodecFromUrl(// ignore: undefined_function, avoid_dynamic_calls
resolved,
chunkCallback: (int bytes, int total) {
chunkEvents.add(ImageChunkEvent(cumulativeBytesLoaded: bytes, expectedTotalBytes: total));
......
......@@ -517,7 +517,7 @@ class ImageCache {
image.dispose();
_cache.remove(key);
if (!kReleaseMode) {
finishArgs['evictedKeys'].add(key.toString());
(finishArgs['evictedKeys'] as List<String>).add(key.toString());
}
}
if (!kReleaseMode) {
......
......@@ -1369,8 +1369,10 @@ class TextInput {
_currentConnection!._client.performAction(_toTextInputAction(args[1] as String));
break;
case 'TextInputClient.performPrivateCommand':
final Map<String, dynamic> firstArg = args[1] as Map<String, dynamic>;
_currentConnection!._client.performPrivateCommand(
args[1]['action'] as String, args[1]['data'] as Map<String, dynamic>,
firstArg['action'] as String,
firstArg['data'] as Map<String, dynamic>,
);
break;
case 'TextInputClient.updateFloatingCursor':
......
......@@ -6395,7 +6395,7 @@ FlutterErrorDetails _debugReportException(
/// * [RenderObjectElement.updateChildren], which discusses why this class is
/// used as slot values for the children of a [MultiChildRenderObjectElement].
@immutable
class IndexedSlot<T> {
class IndexedSlot<T extends Element?> {
/// Creates an [IndexedSlot] with the provided [index] and slot [value].
const IndexedSlot(this.index, this.value);
......
......@@ -306,6 +306,9 @@ class _GlowingOverscrollIndicatorState extends State<GlowingOverscrollIndicator>
}
}
} else if (notification is ScrollEndNotification || notification is ScrollUpdateNotification) {
// Using dynamic here to avoid layer violations of importing
// drag_details.dart from gestures.
// ignore: avoid_dynamic_calls
if ((notification as dynamic).dragDetails != null) {
_leadingController!.scrollEnd();
_trailingController!.scrollEnd();
......
include: ../analysis_options.yaml
linter:
rules:
# Turn off for tests, since we often use dynamic as a method to obtain a
# reference to a private state object or renderer in tests.
avoid_dynamic_calls: false
......@@ -209,7 +209,9 @@ class FakeAndroidPlatformViewsController {
Future<dynamic> _dispose(MethodCall call) {
assert(call.arguments is Map);
// ignore: avoid_dynamic_calls
final int id = call.arguments['id'] as int;
// ignore: avoid_dynamic_calls
final bool hybrid = call.arguments['hybrid'] as bool;
if (hybrid && !_views[id]!.hybrid!) {
......
......@@ -156,12 +156,12 @@ class WebFlutterDriver extends FlutterDriver {
final List<Map<String, dynamic>> events = <Map<String, dynamic>>[];
for (final async_io.LogEntry entry in await _connection.logs.toList()) {
if (_startTime.isBefore(entry.timestamp)) {
final Map<String, dynamic> data = jsonDecode(entry.message!)['message'] as Map<String, dynamic>;
final Map<String, dynamic> data = (jsonDecode(entry.message!) as Map<String, dynamic>)['message'] as Map<String, dynamic>;
if (data['method'] == 'Tracing.dataCollected') {
// 'ts' data collected from Chrome is in double format, conversion needed
try {
data['params']['ts'] =
double.parse(data['params']['ts'].toString()).toInt();
final Map<String, dynamic> params = data['params'] as Map<String, dynamic>;
params['ts'] = double.parse(params['ts'].toString()).toInt();
} on FormatException catch (_) {
// data is corrupted, skip
continue;
......
......@@ -968,16 +968,16 @@ void main() {
});
}
/// This function will verify the format of the script
/// and return the actual script.
/// script will be in the following format:
// This function will verify the format of the script and return the actual
// script. The script will be in the following format:
// window.flutterDriver('[actual script]')
String? _checkAndEncode(dynamic script) {
String _checkAndEncode(dynamic script) {
expect(script, isA<String>());
expect(script.startsWith(_kWebScriptPrefix), isTrue);
expect(script.endsWith(_kWebScriptSuffix), isTrue);
final String scriptString = script as String;
expect(scriptString.startsWith(_kWebScriptPrefix), isTrue);
expect(scriptString.endsWith(_kWebScriptSuffix), isTrue);
// Strip prefix and suffix
return script.substring(_kWebScriptPrefix.length, script.length - 2) as String?;
return scriptString.substring(_kWebScriptPrefix.length, script.length - 2);
}
vms.Response? makeFakeResponse(
......@@ -999,7 +999,7 @@ class FakeFlutterWebConnection extends Fake implements FlutterWebConnection {
@override
Future<dynamic> sendCommand(String script, Duration? duration) async {
commandLog.add('$script $duration');
final Map<String, dynamic> decoded = jsonDecode(_checkAndEncode(script)!) as Map<String, dynamic>;
final Map<String, dynamic> decoded = jsonDecode(_checkAndEncode(script)) as Map<String, dynamic>;
final dynamic response = responses[decoded['command']];
assert(response != null, 'Missing ${decoded['command']} in responses.');
return response;
......
......@@ -345,14 +345,18 @@ void main() {
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
final dynamic dialPainter = dialPaint.painter;
// ignore: avoid_dynamic_calls
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels12To11,
);
// ignore: avoid_dynamic_calls
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels12To11,
);
......@@ -363,14 +367,18 @@ void main() {
final CustomPaint dialPaint = tester.widget(find.byKey(const ValueKey<String>('time-picker-dial')));
final dynamic dialPainter = dialPaint.painter;
// ignore: avoid_dynamic_calls
final List<dynamic> primaryLabels = dialPainter.primaryLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
primaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels00To22TwoDigit,
);
// ignore: avoid_dynamic_calls
final List<dynamic> secondaryLabels = dialPainter.secondaryLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
secondaryLabels.map<String>((dynamic tp) => ((tp.painter as TextPainter).text! as TextSpan).text!),
labels00To22TwoDigit,
);
......
......@@ -866,7 +866,7 @@ class _HasGoodToStringDeep extends Matcher {
@override
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
final List<String> issues = <String>[];
String description = object.toStringDeep() as String;
String description = object.toStringDeep() as String; // ignore: avoid_dynamic_calls
if (description.endsWith('\n')) {
// Trim off trailing \n as the remaining calculations assume
// the description does not end with a trailing \n.
......@@ -904,7 +904,7 @@ class _HasGoodToStringDeep extends Matcher {
const String prefixOtherLines = 'PREFIX_OTHER_LINES_';
final List<String> prefixIssues = <String>[];
String descriptionWithPrefixes =
object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String;
object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines) as String; // ignore: avoid_dynamic_calls
if (descriptionWithPrefixes.endsWith('\n')) {
// Trim off trailing \n as the remaining calculations assume
// the description does not end with a trailing \n.
......@@ -1875,7 +1875,7 @@ class _MatchesSemanticsData extends Matcher {
bool allMatched = true;
if (children != null) {
int i = 0;
node.visitChildren((SemanticsNode child) {
(node as SemanticsNode).visitChildren((SemanticsNode child) {
allMatched = children![i].matches(child, matchState) && allMatched;
i += 1;
return allMatched;
......
......@@ -119,8 +119,9 @@ class TestTextInput {
log.add(methodCall);
switch (methodCall.method) {
case 'TextInput.setClient':
_client = methodCall.arguments[0] as int;
setClientArgs = methodCall.arguments[1] as Map<String, dynamic>;
final List<dynamic> arguments = methodCall.arguments as List<dynamic>;
_client = arguments[0] as int;
setClientArgs = arguments[1] as Map<String, dynamic>;
break;
case 'TextInput.updateConfig':
setClientArgs = methodCall.arguments as Map<String, dynamic>;
......
......@@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
test('TestWindow can handle new methods without breaking', () {
final dynamic testWindow = TestWindow(window: ui.window);
// ignore: avoid_dynamic_calls
expect(testWindow.someNewProperty, null);
});
......
......@@ -126,7 +126,7 @@ class MultiRootFileSystem extends ForwardingFileSystem {
} else if (path is FileSystemEntity) {
uri = path.uri;
} else {
throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
throw ArgumentError('Invalid type for "path": ${(path as Object?)?.runtimeType}');
}
if (!uri.hasScheme || uri.scheme != _scheme) {
......
......@@ -15,6 +15,7 @@ import '../../base/file_system.dart';
import '../../base/io.dart';
import '../../build_info.dart';
import '../../cache.dart';
import '../../convert.dart';
import '../../dart/language_version.dart';
import '../../dart/package_map.dart';
import '../../globals_null_migrated.dart' as globals;
......@@ -198,6 +199,16 @@ class Dart2JSTarget extends Target {
'dart2js.d',
];
String _collectOutput(ProcessResult result) {
final String stdout = result.stdout is List<int>
? utf8.decode(result.stdout as List<int>)
: result.stdout as String;
final String stderr = result.stderr is List<int>
? utf8.decode(result.stderr as List<int>)
: result.stderr as String;
return stdout + stderr;
}
@override
Future<void> build(Environment environment) async {
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
......@@ -233,7 +244,7 @@ class Dart2JSTarget extends Target {
environment.buildDir.childFile('main.dart').path, // dartfile
]);
if (kernelResult.exitCode != 0) {
throw Exception(kernelResult.stdout + kernelResult.stderr);
throw Exception(_collectOutput(kernelResult));
}
final String dart2jsOptimization = environment.defines[kDart2jsOptimization];
......@@ -250,7 +261,7 @@ class Dart2JSTarget extends Target {
environment.buildDir.childFile('app.dill').path, // dartfile
]);
if (javaScriptResult.exitCode != 0) {
throw Exception(javaScriptResult.stdout + javaScriptResult.stderr);
throw Exception(_collectOutput(javaScriptResult));
}
final File dart2jsDeps = environment.buildDir
.childFile('app.dill.deps');
......
......@@ -150,7 +150,7 @@ class AnalysisServer {
void _handleStatus(Map<String, dynamic> statusInfo) {
// {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
if (statusInfo['analysis'] != null && !_analyzingController.isClosed) {
final bool isAnalyzing = statusInfo['analysis']['isAnalyzing'] as bool;
final bool isAnalyzing = (statusInfo['analysis'] as Map<String, dynamic>)['isAnalyzing'] as bool;
_analyzingController.add(isAnalyzing);
}
}
......@@ -293,15 +293,16 @@ class WrittenError {
/// "hasFix":false
/// }
static WrittenError fromJson(Map<String, dynamic> json) {
final Map<String, dynamic> location = json['location'] as Map<String, dynamic>;
return WrittenError._(
severity: json['severity'] as String,
type: json['type'] as String,
message: json['message'] as String,
code: json['code'] as String,
file: json['location']['file'] as String,
startLine: json['location']['startLine'] as int,
startColumn: json['location']['startColumn'] as int,
offset: json['location']['offset'] as int,
file: location['file'] as String,
startLine: location['startLine'] as int,
startColumn: location['startColumn'] as int,
offset: location['offset'] as int,
);
}
......
......@@ -496,10 +496,10 @@ class _DefaultPub implements Pub {
// Because [loadPackageConfigWithLogging] succeeded [packageConfigFile]
// we can rely on the file to exist and be correctly formatted.
final dynamic jsonContents =
json.decode(packageConfigFile.readAsStringSync());
final Map<String, dynamic> jsonContents =
json.decode(packageConfigFile.readAsStringSync()) as Map<String, dynamic>;
jsonContents['packages'].add(<String, dynamic>{
(jsonContents['packages'] as List<dynamic>).add(<String, dynamic>{
'name': 'flutter_gen',
'rootUri': 'flutter_gen',
'languageVersion': '2.12',
......
......@@ -247,7 +247,7 @@ class FlutterManifest {
DeferredComponent(
name: component['name'] as String,
libraries: component['libraries'] == null ?
<String>[] : component['libraries'].cast<String>() as List<String>,
<String>[] : (component['libraries'] as List<dynamic>).cast<String>(),
assets: assetsUri,
)
);
......@@ -571,6 +571,7 @@ void _validateFlutter(YamlMap? yaml, List<String> errors) {
void _validateListType<T>(YamlList yamlList, List<String> errors, String context, String typeAlias) {
for (int i = 0; i < yamlList.length; i++) {
if (yamlList[i] is! T) {
// ignore: avoid_dynamic_calls
errors.add('Expected $context to be a list of $typeAlias, but element $i was a ${yamlList[i].runtimeType}');
}
}
......@@ -584,6 +585,7 @@ void _validateDeferredComponents(MapEntry<Object?, Object?> kvp, List<String> er
for (int i = 0; i < yamlList.length; i++) {
final Object? valueMap = yamlList[i];
if (valueMap is! YamlMap) {
// ignore: avoid_dynamic_calls
errors.add('Expected the $i element in "${kvp.key}" to be a map, but got ${yamlList[i]} (${yamlList[i].runtimeType}).');
continue;
}
......
......@@ -130,7 +130,7 @@ class SimControl {
return <String, Map<String, dynamic>>{};
}
try {
final Object decodeResult = json.decode(results.stdout)[section.name];
final Object decodeResult = (json.decode(results.stdout) as Map<String, dynamic>)[section.name];
if (decodeResult is Map<String, dynamic>) {
return decodeResult;
}
......
......@@ -269,17 +269,13 @@ class XCDevice {
final List<IOSDevice> devices = <IOSDevice>[];
for (final dynamic device in allAvailableDevices) {
if (device is! Map) {
continue;
}
final Map<String, dynamic> deviceProperties = device as Map<String, dynamic>;
if (device is Map<String, dynamic>) {
// Only include iPhone, iPad, iPod, or other iOS devices.
if (!_isIPhoneOSDevice(deviceProperties)) {
if (!_isIPhoneOSDevice(device)) {
continue;
}
final Map<String, dynamic> errorProperties = _errorProperties(deviceProperties);
final Map<String, dynamic> errorProperties = _errorProperties(device);
if (errorProperties != null) {
final String errorMessage = _parseErrorMessage(errorProperties);
if (errorMessage.contains('not paired')) {
......@@ -297,7 +293,7 @@ class XCDevice {
}
}
final IOSDeviceInterface interface = _interfaceType(deviceProperties);
final IOSDeviceInterface interface = _interfaceType(device);
// Only support USB devices, skip "network" interface (Xcode > Window > Devices and Simulators > Connect via network).
// TODO(jmagman): Remove this check once wirelessly detected devices can be observed and attached, https://github.com/flutter/flutter/issues/15072.
......@@ -308,9 +304,9 @@ class XCDevice {
devices.add(IOSDevice(
device['identifier'] as String,
name: device['name'] as String,
cpuArchitecture: _cpuArchitecture(deviceProperties),
cpuArchitecture: _cpuArchitecture(device),
interfaceType: interface,
sdkVersion: _sdkVersion(deviceProperties),
sdkVersion: _sdkVersion(device),
iProxy: _iProxy,
fileSystem: globals.fs,
logger: _logger,
......@@ -319,6 +315,7 @@ class XCDevice {
platform: globals.platform,
));
}
}
return devices;
}
......
......@@ -89,13 +89,12 @@ class Plugin {
factory Plugin._fromMultiPlatformYaml(
String name,
String path,
dynamic pluginYaml,
YamlMap pluginYaml,
List<String> dependencies,
FileSystem fileSystem,
bool isDirectDependency,
) {
assert (pluginYaml != null && pluginYaml['platforms'] != null,
'Invalid multi-platform plugin specification $name.');
assert (pluginYaml['platforms'] != null, 'Invalid multi-platform plugin specification $name.');
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
assert (_validateMultiPlatformYaml(platformsYaml).isEmpty,
......@@ -190,7 +189,7 @@ class Plugin {
bool isDirectDependency,
) {
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
final String pluginClass = pluginYaml['pluginClass'] as String;
final String pluginClass = (pluginYaml as Map<dynamic, dynamic>)['pluginClass'] as String;
if (pluginYaml != null && pluginClass != null) {
final String androidPackage = pluginYaml['androidPackage'] as String;
if (androidPackage != null) {
......
......@@ -177,8 +177,8 @@ class _BufferedStreamController<T> {
_streamControllerInstance.add(event);
} else {
_streamControllerInstance.addError(
event.first as Object,
event.last as StackTrace,
(event as Iterable<dynamic>).first as Object,
(event as Iterable<dynamic>).last as StackTrace,
);
}
}
......
......@@ -1118,8 +1118,9 @@ Future<OperationResult> _defaultReloadSourcesHelper(
// refactored, we'll probably need to send one hot reload/restart event
// per device to analytics.
firstReloadDetails.addAll(castStringKeyedMap(reloadReport.json['details']));
final int loadedLibraryCount = reloadReport.json['details']['loadedLibraryCount'] as int;
final int finalLibraryCount = reloadReport.json['details']['finalLibraryCount'] as int;
final Map<String, dynamic> details = reloadReport.json['details'] as Map<String, dynamic>;
final int loadedLibraryCount = details['loadedLibraryCount'] as int;
final int finalLibraryCount = details['finalLibraryCount'] as int;
globals.printTrace('reloaded $loadedLibraryCount of $finalLibraryCount libraries');
// reloadMessage = 'Reloaded $loadedLibraryCount of $finalLibraryCount libraries';
// Record time it took for the VM to reload the sources.
......
......@@ -737,6 +737,8 @@ class BrowserManager {
/// The callback for handling messages received from the host page.
void _onMessage(dynamic message) {
assert(message is Map<String, dynamic>);
if (message is Map<String, dynamic>) {
switch (message['command'] as String) {
case 'ping':
break;
......@@ -754,6 +756,7 @@ class BrowserManager {
break;
}
}
}
/// Closes the manager and releases any resources it owns, including closing
/// the browser.
......
......@@ -56,7 +56,7 @@ class VisualStudio {
if (_bestVisualStudioDetails[_catalogKey] == null) {
return null;
}
return _bestVisualStudioDetails[_catalogKey][_catalogDisplayVersionKey] as String?;
return (_bestVisualStudioDetails[_catalogKey] as Map<String, dynamic>)[_catalogDisplayVersionKey] as String?;
}
/// The directory where Visual Studio is installed.
......
......@@ -52,13 +52,14 @@ void main() {
expect(testLogger.statusText, isNotEmpty);
final dynamic jsonObject = json.decode(testLogger.statusText);
expect(jsonObject, isMap);
expect(jsonObject, const TypeMatcher<Map<String, dynamic>>());
if (jsonObject is Map<String, dynamic>) {
expect(jsonObject.containsKey('android-studio-dir'), true);
expect(jsonObject['android-studio-dir'], isNotNull);
expect(jsonObject.containsKey('android-sdk'), true);
expect(jsonObject['android-sdk'], isNotNull);
}
verifyNoAnalytics();
}, overrides: <Type, Generator>{
AndroidStudio: () => fakeAndroidStudio,
......
......@@ -93,7 +93,7 @@ void main() {
expect(response['id'], 0);
expect(response['result'], isNotEmpty);
expect(response['result']['platforms'], <String>{'macos'});
expect((response['result'] as Map<String, dynamic>)['platforms'], <String>{'macos'});
await responses.close();
await commands.close();
}, overrides: <Type, Generator>{
......@@ -111,7 +111,7 @@ void main() {
);
globals.printError('daemon.logMessage test');
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> map) {
return map['event'] == 'daemon.logMessage' && map['params']['level'] == 'error';
return map['event'] == 'daemon.logMessage' && (map['params'] as Map<String, dynamic>)['level'] == 'error';
});
expect(response['id'], isNull);
expect(response['event'], 'daemon.logMessage');
......@@ -347,7 +347,7 @@ void main() {
unawaited(output.stream
.firstWhere((Map<String, dynamic> request) => request['method'] == 'app.exposeUrl')
.then((Map<String, dynamic> request) {
expect(request['params']['url'], equals(originalUrl));
expect((request['params'] as Map<String, dynamic>)['url'], equals(originalUrl));
input.add(<String, dynamic>{'id': request['id'], 'result': <String, dynamic>{'url': mappedUrl}});
})
);
......@@ -370,9 +370,10 @@ void main() {
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
expect(response['result'], isNotEmpty);
expect(response['result']['host'], '127.0.0.1');
expect(response['result']['port'], 1234);
final Map<String, dynamic> result = response['result'] as Map<String, dynamic>;
expect(result, isNotEmpty);
expect(result['host'], '127.0.0.1');
expect(result['port'], 1234);
await responses.close();
await commands.close();
}, overrides: <Type, Generator>{
......@@ -390,9 +391,10 @@ void main() {
commands.add(<String, dynamic>{'id': 0, 'method': 'devtools.serve'});
final Map<String, dynamic> response = await responses.stream.firstWhere((Map<String, dynamic> response) => response['id'] == 0);
expect(response['result'], isNotEmpty);
expect(response['result']['host'], null);
expect(response['result']['port'], null);
final Map<String, dynamic> result = response['result'] as Map<String, dynamic>;
expect(result, isNotEmpty);
expect(result['host'], null);
expect(result['port'], null);
await responses.close();
await commands.close();
}, overrides: <Type, Generator>{
......
......@@ -28,6 +28,7 @@ import 'package:process/process.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:uuid/uuid.dart';
import 'package:yaml/yaml.dart';
import '../../src/common.dart';
import '../../src/context.dart';
......@@ -482,8 +483,9 @@ void main() {
// Expect the dependency on flutter_web_plugins exists
expect(pubspec.dependencies, contains('flutter_web_plugins'));
// The platform is correctly registered
expect(pubspec.flutter['plugin']['platforms']['web']['pluginClass'], 'FlutterProjectWeb');
expect(pubspec.flutter['plugin']['platforms']['web']['fileName'], 'flutter_project_web.dart');
final YamlMap web = ((pubspec.flutter['plugin'] as YamlMap)['platforms'] as YamlMap)['web'] as YamlMap;
expect(web['pluginClass'], 'FlutterProjectWeb');
expect(web['fileName'], 'flutter_project_web.dart');
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWebEnabled: true),
......
......@@ -90,47 +90,54 @@ void main() {
);
expect(result['type'], 'apk');
final Map<String, dynamic> androidManifestMap = result['children'][0] as Map<String, dynamic>;
final List<dynamic> resultChildren = result['children'] as List<dynamic>;
final Map<String, dynamic> androidManifestMap = resultChildren[0] as Map<String, dynamic>;
expect(androidManifestMap['n'], 'AndroidManifest.xml');
expect(androidManifestMap['value'], 6);
final Map<String, dynamic> metaInfMap = result['children'][1] as Map<String, dynamic>;
final Map<String, Object?> metaInfMap = resultChildren[1] as Map<String, Object?>;
final List<Map<String, Object?>> metaInfMapChildren = metaInfMap['children']! as List<Map<String, Object?>>;
expect(metaInfMap['n'], 'META-INF');
expect(metaInfMap['value'], 10);
final Map<String, dynamic> certRsaMap = metaInfMap['children'][0] as Map<String, dynamic>;
final Map<String, dynamic> certRsaMap = metaInfMapChildren[0];
expect(certRsaMap['n'], 'CERT.RSA');
expect(certRsaMap['value'], 5);
final Map<String, dynamic> certSfMap = metaInfMap['children'][1] as Map<String, dynamic>;
final Map<String, dynamic> certSfMap = metaInfMapChildren[1];
expect(certSfMap['n'], 'CERT.SF');
expect(certSfMap['value'], 5);
final Map<String, dynamic> libMap = result['children'][2] as Map<String, dynamic>;
final Map<String, Object?> libMap = resultChildren[2] as Map<String, Object?>;
final List<Map<String, Object?>> libMapChildren = libMap['children']! as List<Map<String, Object?>>;
expect(libMap['n'], 'lib');
expect(libMap['value'], 12);
final Map<String, dynamic> arm64Map = libMap['children'][0] as Map<String, dynamic>;
final Map<String, Object?> arm64Map = libMapChildren[0];
final List<Map<String, Object?>> arn64MapChildren = arm64Map['children']! as List<Map<String, Object?>>;
expect(arm64Map['n'], 'arm64-v8a');
expect(arm64Map['value'], 12);
final Map<String, dynamic> libAppMap = arm64Map['children'][0] as Map<String, dynamic>;
final Map<String, Object?> libAppMap = arn64MapChildren[0];
final List<dynamic> libAppMapChildren = libAppMap['children']! as List<dynamic>;
expect(libAppMap['n'], 'libxyzzyapp.so (Dart AOT)');
expect(libAppMap['value'], 6);
expect(libAppMap['children'].length, 3);
final Map<String, dynamic> internalMap = libAppMap['children'][0] as Map<String, dynamic>;
final Map<String, dynamic> skipMap = internalMap['children'][0] as Map<String, dynamic>;
expect(libAppMapChildren.length, 3);
final Map<String, Object?> internalMap = libAppMapChildren[0] as Map<String, Object?>;
final List<dynamic> internalMapChildren = internalMap['children']! as List<dynamic>;
final Map<String, Object?> skipMap = internalMapChildren[0] as Map<String, Object?>;
expect(skipMap['n'], 'skip');
expect(skipMap['value'], 2400);
final Map<String, dynamic> subListIterableMap = internalMap['children'][1] as Map<String, dynamic>;
final Map<String, Object?> subListIterableMap = internalMapChildren[1] as Map<String, Object?>;
expect(subListIterableMap['n'], 'new SubListIterable.');
expect(subListIterableMap['value'], 3560);
final Map<String, dynamic> coreMap = libAppMap['children'][1] as Map<String, dynamic>;
final Map<String, dynamic> rangeErrorMap = coreMap['children'][0] as Map<String, dynamic>;
final Map<String, Object?> coreMap = libAppMapChildren[1] as Map<String, Object?>;
final List<dynamic> coreMapChildren = coreMap['children']! as List<dynamic>;
final Map<String, Object?> rangeErrorMap = coreMapChildren[0] as Map<String, Object?>;
expect(rangeErrorMap['n'], 'new RangeError.range');
expect(rangeErrorMap['value'], 3920);
final Map<String, dynamic> stubsMap = libAppMap['children'][2] as Map<String, dynamic>;
final Map<String, dynamic> allocateMap = stubsMap['children'][0] as Map<String, dynamic>;
final Map<String, Object?> stubsMap = libAppMapChildren[2] as Map<String, Object?>;
final List<dynamic> stubsMapChildren = stubsMap['children']! as List<dynamic>;
final Map<String, Object?> allocateMap = stubsMapChildren[0] as Map<String, Object?>;
expect(allocateMap['n'], 'Allocate ArgumentError');
expect(allocateMap['value'], 4650);
final Map<String, dynamic> libFlutterMap = arm64Map['children'][1] as Map<String, dynamic>;
final Map<String, Object?> libFlutterMap = arn64MapChildren[1];
expect(libFlutterMap['n'], 'libflutter.so (Flutter Engine)');
expect(libFlutterMap['value'], 6);
......
......@@ -104,9 +104,10 @@ void main() {
final Fingerprint fingerprint = Fingerprint.fromBuildInputs(const <String>['a.dart', 'b.dart'], fileSystem);
final Map<String, dynamic>? jsonObject = castStringKeyedMap(json.decode(fingerprint.toJson()));
expect(jsonObject!['files'], hasLength(2));
expect(jsonObject['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
expect(jsonObject['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
final Map<String, dynamic> files = jsonObject!['files'] as Map<String, dynamic>;
expect(files, hasLength(2));
expect(files['a.dart'], '8a21a15fad560b799f6731d436c1b698');
expect(files['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
});
});
......@@ -124,10 +125,11 @@ void main() {
});
final Fingerprint fingerprint = Fingerprint.fromJson(jsonString);
final Map<String, dynamic>? content = castStringKeyedMap(json.decode(fingerprint.toJson()));
final Map<String, dynamic> files = content!['files'] as Map<String, dynamic>;
expect(content, hasLength(1));
expect(content!['files'], hasLength(2));
expect(content['files']['a.dart'], '8a21a15fad560b799f6731d436c1b698');
expect(content['files']['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
expect(files, hasLength(2));
expect(files['a.dart'], '8a21a15fad560b799f6731d436c1b698');
expect(files['b.dart'], '6f144e08b58cd0925328610fad7ac07c');
});
testWithoutContext('treats missing properties and files entries as if empty', () {
final String jsonString = json.encode(<String, dynamic>{});
......
......@@ -284,7 +284,7 @@ void main() {
version: 1.0.0+3
''', logger: BufferLogger.test());
final FlutterProject project = FlutterProject(fileSystem.systemTempDirectory,manifest,manifest);
final dynamic versionInfo = jsonDecode(project.getVersionInfo());
final Map<String, dynamic> versionInfo = jsonDecode(project.getVersionInfo()) as Map<String, dynamic>;
expect(versionInfo['app_name'],'test');
expect(versionInfo['version'],'1.0.0');
expect(versionInfo['build_number'],'3');
......
......@@ -81,7 +81,7 @@ void main() {
]);
// contains all of the experiments in features.dart
expect(result.stdout.split('\n'), containsAll(<Matcher>[
expect((result.stdout as String).split('\n'), containsAll(<Matcher>[
for (final Feature feature in allFeatures)
contains(feature.configSetting),
]));
......
......@@ -35,8 +35,8 @@ void main() {
.childDirectory('.dart_tool')
.childFile('package_config.json')
.readAsStringSync());
final dynamic collection = jsonContent['packages']
.firstWhere((dynamic e) => e['name'] == 'collection');
final Map<String, dynamic> collection = ((jsonContent as Map<String, dynamic>)['packages'] as Iterable<dynamic>)
.firstWhere((dynamic entry) => (entry as Map<String, dynamic>)['name'] == 'collection') as Map<String, dynamic>;
expect(
Uri.parse(collection['rootUri'] as String).isAbsolute,
isTrue,
......
......@@ -190,6 +190,6 @@ bool _isHotReloadCompletionEvent(Map<String, dynamic> event) {
return event != null &&
event['event'] == 'app.progress' &&
event['params'] != null &&
event['params']['progressId'] == 'hot.reload' &&
event['params']['finished'] == true;
(event['params'] as Map<String, dynamic>)['progressId'] == 'hot.reload' &&
(event['params'] as Map<String, dynamic>)['finished'] == true;
}
......@@ -387,11 +387,14 @@ abstract class FlutterTestDriver {
await subscription.cancel();
final StringBuffer error = StringBuffer();
error.write('Received app.stop event while waiting for $interestingOccurrence\n\n$_errorBuffer');
if (json['params'] != null && json['params']['error'] != null) {
error.write('${json['params']['error']}\n\n');
if (json['params'] != null) {
final Map<String, dynamic> params = json['params'] as Map<String, dynamic>;
if (params['error'] != null) {
error.write('${params['error']}\n\n');
}
if (json['params'] != null && params['trace'] != null) {
error.write('${params['trace']}\n\n');
}
if (json['params'] != null && json['params']['trace'] != null) {
error.write('${json['params']['trace']}\n\n');
}
response.completeError(Exception(error.toString()));
}
......@@ -563,7 +566,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
// _process.kill() (`flutter` is a shell script so _process itself is a
// shell, not the flutter tool's Dart process).
final Map<String, dynamic> connected = await _waitFor(event: 'daemon.connected');
_processPid = connected['params']['pid'] as int;
_processPid = (connected['params'] as Map<String, dynamic>)['pid'] as int;
// Set this up now, but we don't wait it yet. We want to make sure we don't
// miss it while waiting for debugPort below.
......@@ -571,7 +574,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
if (withDebugger) {
final Map<String, dynamic> debugPort = await _waitFor(event: 'app.debugPort', timeout: appStartTimeout);
final String wsUriString = debugPort['params']['wsUri'] as String;
final String wsUriString = (debugPort['params'] as Map<String, dynamic>)['wsUri'] as String;
_vmServiceWsUri = Uri.parse(wsUriString);
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
if (!startPaused) {
......@@ -588,7 +591,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
// Now await the started event; if it had already happened the future will
// have already completed.
_currentRunningAppId = (await started)['params']['appId'] as String;
_currentRunningAppId = ((await started)['params'] as Map<String, dynamic>)['appId'] as String;
prematureExitGuard.complete();
} on Exception catch (error, stackTrace) {
prematureExitGuard.completeError(Exception(error.toString()), stackTrace);
......@@ -618,10 +621,10 @@ class FlutterRunTestDriver extends FlutterTestDriver {
}
_debugPrint('Performing ${ pause ? "paused " : "" }${ fullRestart ? "hot restart" : "hot reload" }...');
final dynamic hotReloadResponse = await _sendRequest(
final Map<String, dynamic> hotReloadResponse = await _sendRequest(
'app.restart',
<String, dynamic>{'appId': _currentRunningAppId, 'fullRestart': fullRestart, 'pause': pause, 'debounce': debounce, 'debounceDurationOverrideMs': debounceDurationOverrideMs},
);
) as Map<String, dynamic>;
_debugPrint('${fullRestart ? "Hot restart" : "Hot reload"} complete.');
if (hotReloadResponse == null || hotReloadResponse['code'] != 0) {
......@@ -760,8 +763,9 @@ class FlutterTestTestDriver extends FlutterTestDriver {
_processPid = version['pid'] as int;
if (withDebugger) {
final Map<String, dynamic> startedProcess = await _waitFor(event: 'test.startedProcess', timeout: appStartTimeout);
final String vmServiceHttpString = startedProcess['params']['observatoryUri'] as String;
final Map<String, dynamic> startedProcessParams =
(await _waitFor(event: 'test.startedProcess', timeout: appStartTimeout))['params'] as Map<String, dynamic>;
final String vmServiceHttpString = startedProcessParams['observatoryUri'] as String;
_vmServiceWsUri = Uri.parse(vmServiceHttpString).replace(scheme: 'ws', path: '/ws');
await connectToVmService(pauseOnExceptions: pauseOnExceptions);
// Allow us to run code before we start, eg. to set up breakpoints.
......@@ -824,7 +828,7 @@ Stream<String> transformToLines(Stream<List<int>> byteStream) {
Map<String, dynamic> parseFlutterResponse(String line) {
if (line.startsWith('[') && line.endsWith(']') && line.length > 2) {
try {
final Map<String, dynamic> response = castStringKeyedMap(json.decode(line)[0]);
final Map<String, dynamic> response = castStringKeyedMap((json.decode(line) as List<dynamic>)[0]);
return response;
} on FormatException {
// Not valid JSON, so likely some other output that was surrounded by [brackets]
......
......@@ -19,18 +19,19 @@ void validatePubspecForPlugin({
}) {
final FlutterManifest manifest =
FlutterManifest.createFromPath('$projectDir/pubspec.yaml', fileSystem: globals.fs, logger: globals.logger)!;
final YamlMap platformsMap = YamlMap.wrap(manifest.supportedPlatforms!);
final YamlMap platformMaps = YamlMap.wrap(manifest.supportedPlatforms!);
for (final String platform in expectedPlatforms) {
expect(platformsMap[platform], isNotNull);
expect(platformsMap[platform]['pluginClass'], pluginClass);
expect(platformMaps[platform], isNotNull);
final YamlMap platformMap = platformMaps[platform]! as YamlMap;
expect(platformMap['pluginClass'], pluginClass);
if (platform == 'android') {
expect(platformsMap[platform]['package'], androidIdentifier);
expect(platformMap['package'], androidIdentifier);
}
if (platform == 'web') {
expect(platformsMap[platform]['fileName'], webFileName);
expect(platformMap['fileName'], webFileName);
}
}
for (final String platform in unexpectedPlatforms) {
expect(platformsMap[platform], isNull);
expect(platformMaps[platform], isNull);
}
}
......@@ -62,7 +62,7 @@ class Registrar extends BinaryMessenger {
/// compiling for the web.
void registerMessageHandler() {
// The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui.
// ignore: undefined_function
// ignore: undefined_function, avoid_dynamic_calls
ui.webOnlySetPluginHandler(handleFrameworkMessage);
}
......
......@@ -9,10 +9,13 @@ import 'package:flutter_driver/flutter_driver.dart';
import 'common.dart';
/// A callback to use with [integrationDriver].
typedef ScreenshotCallback = Future<bool> Function(String name, List<int> image);
/// Example Integration Test which can also run WebDriver command depending on
/// the requests coming from the test methods.
Future<void> integrationDriver(
{FlutterDriver? driver, Function? onScreenshot}) async {
{FlutterDriver? driver, ScreenshotCallback? onScreenshot}) async {
driver ??= await FlutterDriver.connect();
// Test states that it's waiting on web driver commands.
// [DriverTestMessage] is converted to string since json format causes an
......@@ -28,11 +31,12 @@ Future<void> integrationDriver(
response.data!['web_driver_command'] != '${WebDriverCommandType.noop}') {
final String? webDriverCommand = response.data!['web_driver_command'] as String?;
if (webDriverCommand == '${WebDriverCommandType.screenshot}') {
assert(onScreenshot != null, 'screenshot command requires an onScreenshot callback');
// Use `driver.screenshot()` method to get a screenshot of the web page.
final List<int> screenshotImage = await driver.screenshot();
final String? screenshotName = response.data!['screenshot_name'] as String?;
final String screenshotName = response.data!['screenshot_name']! as String;
final bool screenshotSuccess = await onScreenshot!(screenshotName, screenshotImage) as bool;
final bool screenshotSuccess = await onScreenshot!(screenshotName, screenshotImage);
if (screenshotSuccess) {
jsonResponse = await driver.requestData(DriverTestMessage.complete().toString());
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment