Implementing control flow collections (#146601)

This pull request aims for improved readability, based on issue #146600.

```dart
// before
Set<Color> _distinctVisibleColors() {
  final Set<Color> distinctVisibleColors = <Color>{};
  if (top.style != BorderStyle.none) {
    distinctVisibleColors.add(top.color);
  }
  if (right.style != BorderStyle.none) {
    distinctVisibleColors.add(right.color);
  }
  if (bottom.style != BorderStyle.none) {
    distinctVisibleColors.add(bottom.color);
  }
  if (left.style != BorderStyle.none) {
    distinctVisibleColors.add(left.color);
  }
  return distinctVisibleColors;
}

// after
Set<Color> _distinctVisibleColors() {
  return <Color>{
    if (top.style != BorderStyle.none) top.color,
    if (right.style != BorderStyle.none) right.color,
    if (bottom.style != BorderStyle.none) bottom.color,
    if (left.style != BorderStyle.none) left.color,
  };
}
```

Most of the repo should be covered in this PR (aside from `flutter_tools/`, since there was a lot going on in there).
This commit is contained in:
Nate 2024-04-15 11:06:07 -05:00 committed by GitHub
parent 600787891a
commit 2e748e8598
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 276 additions and 494 deletions

View File

@ -11,30 +11,20 @@ import 'package:flutter/services.dart';
import 'package:microbenchmarks/common.dart'; import 'package:microbenchmarks/common.dart';
List<Object?> _makeTestBuffer(int size) { List<Object?> _makeTestBuffer(int size) {
final List<Object?> answer = <Object?>[]; return <Object?>[
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; i++)
switch (i % 9) { switch (i % 9) {
case 0: 0 => 1,
answer.add(1); 1 => math.pow(2, 65),
case 1: 2 => 1234.0,
answer.add(math.pow(2, 65)); 3 => null,
case 2: 4 => <int>[1234],
answer.add(1234.0); 5 => <String, int>{'hello': 1234},
case 3: 6 => 'this is a test',
answer.add(null); 7 => true,
case 4: _ => Uint8List(64),
answer.add(<int>[1234]); },
case 5: ];
answer.add(<String, int>{'hello': 1234});
case 6:
answer.add('this is a test');
case 7:
answer.add(true);
case 8:
answer.add(Uint8List(64));
}
}
return answer;
} }
Future<double> _runBasicStandardSmall( Future<double> _runBasicStandardSmall(

View File

@ -139,28 +139,21 @@ Future<void> verifyExist(
String flutterRoot, String flutterRoot,
{@visibleForTesting ProcessManager processManager = const LocalProcessManager() {@visibleForTesting ProcessManager processManager = const LocalProcessManager()
}) async { }) async {
final Set<String> foundFiles = <String>{}; final List<String> binaryPaths = await findBinaryPaths(
final String cacheDirectory = path.join(flutterRoot, 'bin', 'cache'); path.join(flutterRoot, 'bin', 'cache'),
processManager: processManager,
for (final String binaryPath );
in await findBinaryPaths(cacheDirectory, processManager: processManager)) {
if (binariesWithEntitlements(flutterRoot).contains(binaryPath)) {
foundFiles.add(binaryPath);
} else if (binariesWithoutEntitlements(flutterRoot).contains(binaryPath)) {
foundFiles.add(binaryPath);
} else {
throw Exception(
'Found unexpected binary in cache: $binaryPath');
}
}
final List<String> allExpectedFiles = binariesWithEntitlements(flutterRoot) + binariesWithoutEntitlements(flutterRoot); final List<String> allExpectedFiles = binariesWithEntitlements(flutterRoot) + binariesWithoutEntitlements(flutterRoot);
final Set<String> foundFiles = <String>{
for (final String binaryPath in binaryPaths)
if (allExpectedFiles.contains(binaryPath)) binaryPath
else throw Exception('Found unexpected binary in cache: $binaryPath'),
};
if (foundFiles.length < allExpectedFiles.length) { if (foundFiles.length < allExpectedFiles.length) {
final List<String> unfoundFiles = allExpectedFiles final List<String> unfoundFiles = <String>[
.where( for (final String file in allExpectedFiles) if (!foundFiles.contains(file)) file,
(String file) => !foundFiles.contains(file), ];
)
.toList();
print( print(
'Expected binaries not found in cache:\n\n${unfoundFiles.join('\n')}\n\n' 'Expected binaries not found in cache:\n\n${unfoundFiles.join('\n')}\n\n'
'If this commit is removing binaries from the cache, this test should be fixed by\n' 'If this commit is removing binaries from the cache, this test should be fixed by\n'

View File

@ -913,18 +913,14 @@ Future<void> _runFrameworkTests() async {
final Uint8List libappBytes = libapp.content as Uint8List; // bytes decompressed here final Uint8List libappBytes = libapp.content as Uint8List; // bytes decompressed here
final String libappStrings = utf8.decode(libappBytes, allowMalformed: true); final String libappStrings = utf8.decode(libappBytes, allowMalformed: true);
await runCommand(flutter, <String>['clean'], workingDirectory: tracingDirectory); await runCommand(flutter, <String>['clean'], workingDirectory: tracingDirectory);
final List<String> results = <String>[]; return <String>[
for (final String pattern in allowed) { for (final String pattern in allowed)
if (!libappStrings.contains(pattern)) { if (!libappStrings.contains(pattern))
results.add('When building with --$modeArgument, expected to find "$pattern" in libapp.so but could not find it.'); 'When building with --$modeArgument, expected to find "$pattern" in libapp.so but could not find it.',
} for (final String pattern in disallowed)
} if (libappStrings.contains(pattern))
for (final String pattern in disallowed) { 'When building with --$modeArgument, expected to not find "$pattern" in libapp.so but did find it.',
if (libappStrings.contains(pattern)) { ];
results.add('When building with --$modeArgument, expected to not find "$pattern" in libapp.so but did find it.');
}
}
return results;
} catch (error, stackTrace) { } catch (error, stackTrace) {
return <String>[ return <String>[
error.toString(), error.toString(),
@ -1332,11 +1328,9 @@ Future<void> _runDartTest(String workingDirectory, {
if (collectMetrics) { if (collectMetrics) {
try { try {
final List<String> testList = <String>[]; final List<String> testList = <String>[
final Map<int, TestSpecs> allTestSpecs = test.allTestSpecs; for (final TestSpecs testSpecs in test.allTestSpecs.values) testSpecs.toJson(),
for (final TestSpecs testSpecs in allTestSpecs.values) { ];
testList.add(testSpecs.toJson());
}
if (testList.isNotEmpty) { if (testList.isNotEmpty) {
final String testJson = json.encode(testList); final String testJson = json.encode(testList);
final File testResults = fileSystem.file( final File testResults = fileSystem.file(

View File

@ -110,12 +110,10 @@ class NextContext extends Context {
break; break;
} }
final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[]; final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[
for (final pb.Cherrypick cherrypick in state.engine.cherrypicks) { for (final pb.Cherrypick cherrypick in state.engine.cherrypicks)
if (!finishedStates.contains(cherrypick.state)) { if (!finishedStates.contains(cherrypick.state)) cherrypick,
unappliedCherrypicks.add(cherrypick); ];
}
}
if (unappliedCherrypicks.isEmpty) { if (unappliedCherrypicks.isEmpty) {
stdio.printStatus('All engine cherrypicks have been auto-applied by the conductor.\n'); stdio.printStatus('All engine cherrypicks have been auto-applied by the conductor.\n');
@ -206,12 +204,10 @@ class NextContext extends Context {
); );
} }
final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[]; final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[
for (final pb.Cherrypick cherrypick in state.framework.cherrypicks) { for (final pb.Cherrypick cherrypick in state.framework.cherrypicks)
if (!finishedStates.contains(cherrypick.state)) { if (!finishedStates.contains(cherrypick.state)) cherrypick,
unappliedCherrypicks.add(cherrypick); ];
}
}
if (state.framework.cherrypicks.isEmpty) { if (state.framework.cherrypicks.isEmpty) {
stdio.printStatus( stdio.printStatus(

View File

@ -183,15 +183,11 @@ abstract class Repository {
workingDirectory: (await checkoutDirectory).path, workingDirectory: (await checkoutDirectory).path,
); );
final List<String> remoteBranches = <String>[]; return <String>[
for (final String line in output.split('\n')) { for (final String line in output.split('\n'))
final RegExpMatch? match = _lsRemotePattern.firstMatch(line); if (_lsRemotePattern.firstMatch(line) case final RegExpMatch match)
if (match != null) { match.group(1)!,
remoteBranches.add(match.group(1)!); ];
}
}
return remoteBranches;
} }
/// Ensure the repository is cloned to disk and initialized with proper state. /// Ensure the repository is cloned to disk and initialized with proper state.

View File

@ -39,8 +39,8 @@ TaskFunction createMicrobenchmarkTask({
if (enableImpeller != null && !enableImpeller) '--no-enable-impeller', if (enableImpeller != null && !enableImpeller) '--no-enable-impeller',
'-d', '-d',
device.deviceId, device.deviceId,
benchmarkPath,
]; ];
options.add(benchmarkPath);
return startFlutter( return startFlutter(
'run', 'run',
options: options, options: options,

View File

@ -154,14 +154,11 @@ class AndroidSemanticsNode {
if (actions == null) { if (actions == null) {
return const <AndroidSemanticsAction>[]; return const <AndroidSemanticsAction>[];
} }
final List<AndroidSemanticsAction> convertedActions = <AndroidSemanticsAction>[]; return <AndroidSemanticsAction>[
for (final int id in actions) { for (final int id in actions)
final AndroidSemanticsAction? action = AndroidSemanticsAction.deserialize(id); if (AndroidSemanticsAction.deserialize(id) case final AndroidSemanticsAction action)
if (action != null) { action,
convertedActions.add(action); ];
}
}
return convertedActions;
} }
@override @override

View File

@ -121,10 +121,8 @@ class CalcExpression {
: this(<ExpressionToken>[], ExpressionState.Start); : this(<ExpressionToken>[], ExpressionState.Start);
CalcExpression.result(FloatToken result) CalcExpression.result(FloatToken result)
: _list = <ExpressionToken?>[], : _list = <ExpressionToken?>[result],
state = ExpressionState.Result { state = ExpressionState.Result;
_list.add(result);
}
/// The tokens comprising the expression. /// The tokens comprising the expression.
final List<ExpressionToken?> _list; final List<ExpressionToken?> _list;

View File

@ -84,15 +84,11 @@ class _CupertinoSearchTextFieldDemoState
Widget _buildPlatformList() { Widget _buildPlatformList() {
if (_searchPlatform.isNotEmpty) { if (_searchPlatform.isNotEmpty) {
final List<String> tempList = <String>[]; final String search = _searchPlatform.toLowerCase();
for (int i = 0; i < filteredPlatforms.length; i++) { filteredPlatforms = <String>[
if (filteredPlatforms[i] for (final String platform in filteredPlatforms)
.toLowerCase() if (platform.toLowerCase().contains(search)) platform
.contains(_searchPlatform.toLowerCase())) { ];
tempList.add(filteredPlatforms[i]);
}
}
filteredPlatforms = tempList;
} }
return ListView.builder( return ListView.builder(
itemCount: filteredPlatforms.length, itemCount: filteredPlatforms.length,

View File

@ -26,14 +26,10 @@ class _RestorableDessertSelections extends RestorableProperty<Set<int>> {
/// Takes a list of [_Dessert]s and saves the row indices of selected rows /// Takes a list of [_Dessert]s and saves the row indices of selected rows
/// into a [Set]. /// into a [Set].
void setDessertSelections(List<_Dessert> desserts) { void setDessertSelections(List<_Dessert> desserts) {
final Set<int> updatedSet = <int>{}; _dessertSelections = <int>{
for (int i = 0; i < desserts.length; i += 1) { for (final (int i, _Dessert dessert) in desserts.indexed)
final _Dessert dessert = desserts[i]; if (dessert.selected) i,
if (dessert.selected) { };
updatedSet.add(i);
}
}
_dessertSelections = updatedSet;
notifyListeners(); notifyListeners();
} }

View File

@ -116,19 +116,18 @@ Future<File> generateTest(Directory apiDir) async {
}); });
// Collect the examples, and import them all as separate symbols. // Collect the examples, and import them all as separate symbols.
final List<String> imports = <String>[]; final List<ExampleInfo> infoList = <ExampleInfo>[
imports.add('''import 'package:flutter/widgets.dart';'''); for (final File example in examples) ExampleInfo(example, examplesLibDir),
imports.add('''import 'package:flutter/scheduler.dart';'''); ];
imports.add('''import 'package:flutter_test/flutter_test.dart';''');
imports.add('''import 'package:integration_test/integration_test.dart';''');
final List<ExampleInfo> infoList = <ExampleInfo>[];
for (final File example in examples) {
final ExampleInfo info = ExampleInfo(example, examplesLibDir);
infoList.add(info);
imports.add('''import 'package:flutter_api_samples/${info.importPath}' as ${info.importName};''');
}
imports.sort();
infoList.sort((ExampleInfo a, ExampleInfo b) => a.importPath.compareTo(b.importPath)); infoList.sort((ExampleInfo a, ExampleInfo b) => a.importPath.compareTo(b.importPath));
final List<String> imports = <String>[
"import 'package:flutter/widgets.dart';",
"import 'package:flutter/scheduler.dart';",
"import 'package:flutter_test/flutter_test.dart';",
"import 'package:integration_test/integration_test.dart';",
for (final ExampleInfo info in infoList)
"import 'package:flutter_api_samples/${info.importPath}' as ${info.importName};"
]..sort();
final StringBuffer buffer = StringBuffer(); final StringBuffer buffer = StringBuffer();
buffer.writeln('// Temporary generated file. Do not commit.'); buffer.writeln('// Temporary generated file. Do not commit.');

View File

@ -388,15 +388,10 @@ bool testIsSuperset(Map<String, String> newCodepoints, Map<String, String> oldCo
@visibleForTesting @visibleForTesting
bool testIsStable(Map<String, String> newCodepoints, Map<String, String> oldCodepoints) { bool testIsStable(Map<String, String> newCodepoints, Map<String, String> oldCodepoints) {
final int oldCodepointsCount = oldCodepoints.length; final int oldCodepointsCount = oldCodepoints.length;
final List<String> unstable = <String>[]; final List<String> unstable = <String>[
for (final MapEntry<String, String>(:String key, :String value) in oldCodepoints.entries)
oldCodepoints.forEach((String key, String value) { if (newCodepoints.containsKey(key) && value != newCodepoints[key]) key,
if (newCodepoints.containsKey(key)) { ];
if (value != newCodepoints[key]) {
unstable.add(key);
}
}
});
if (unstable.isNotEmpty) { if (unstable.isNotEmpty) {
stderr.writeln('❌ out of $oldCodepointsCount existing codepoints, ${unstable.length} were unstable: $unstable'); stderr.writeln('❌ out of $oldCodepointsCount existing codepoints, ${unstable.length} were unstable: $unstable');

View File

@ -1485,22 +1485,15 @@ class _CupertinoAlertActionSection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<Widget> interactiveButtons = <Widget>[];
for (int i = 0; i < children.length; i += 1) {
interactiveButtons.add(
_PressableActionButton(
child: children[i],
),
);
}
return CupertinoScrollbar( return CupertinoScrollbar(
controller: scrollController, controller: scrollController,
child: SingleChildScrollView( child: SingleChildScrollView(
controller: scrollController, controller: scrollController,
child: _CupertinoDialogActionsRenderWidget( child: _CupertinoDialogActionsRenderWidget(
actionButtons: interactiveButtons, actionButtons: <Widget>[
for (final Widget child in children)
_PressableActionButton(child: child),
],
dividerThickness: _kDividerThickness, dividerThickness: _kDividerThickness,
hasCancelButton: hasCancelButton, hasCancelButton: hasCancelButton,
isActionSheet: isActionSheet, isActionSheet: isActionSheet,

View File

@ -311,12 +311,10 @@ final class _Float64ListChain {
/// are read back, they do not affect the timings of the work being /// are read back, they do not affect the timings of the work being
/// benchmarked. /// benchmarked.
List<double> extractElements() { List<double> extractElements() {
final List<double> result = <double>[]; return <double>[
_chain.forEach(result.addAll); for (final Float64List list in _chain) ...list,
for (int i = 0; i < _pointer; i++) { for (int i = 0; i < _pointer; i++) _slice[i],
result.add(_slice[i]); ];
}
return result;
} }
} }
@ -349,16 +347,11 @@ final class _StringListChain {
/// are read back, they do not affect the timings of the work being /// are read back, they do not affect the timings of the work being
/// benchmarked. /// benchmarked.
List<String> extractElements() { List<String> extractElements() {
final List<String> result = <String>[]; return <String>[
for (final List<String?> slice in _chain) { for (final List<String?> slice in _chain)
for (final String? element in slice) { for (final String? value in slice) value!,
result.add(element!); for (int i = 0; i < _pointer; i++) _slice[i]!,
} ];
}
for (int i = 0; i < _pointer; i++) {
result.add(_slice[i]!);
}
return result;
} }
} }

View File

@ -2125,37 +2125,22 @@ class _LocalizedShortcutLabeler {
keySeparator = '+'; keySeparator = '+';
} }
if (serialized.trigger != null) { if (serialized.trigger != null) {
final List<String> modifiers = <String>[];
final LogicalKeyboardKey trigger = serialized.trigger!; final LogicalKeyboardKey trigger = serialized.trigger!;
if (_usesSymbolicModifiers) { final List<String> modifiers = <String>[
// macOS/iOS platform convention uses this ordering, with always last. if (_usesSymbolicModifiers) ...<String>[
if (serialized.control!) { // MacOS/iOS platform convention uses this ordering, with always last.
modifiers.add(_getModifierLabel(LogicalKeyboardKey.control, localizations)); if (serialized.control!) _getModifierLabel(LogicalKeyboardKey.control, localizations),
} if (serialized.alt!) _getModifierLabel(LogicalKeyboardKey.alt, localizations),
if (serialized.alt!) { if (serialized.shift!) _getModifierLabel(LogicalKeyboardKey.shift, localizations),
modifiers.add(_getModifierLabel(LogicalKeyboardKey.alt, localizations)); if (serialized.meta!) _getModifierLabel(LogicalKeyboardKey.meta, localizations),
} ] else ...<String>[
if (serialized.shift!) { // This order matches the LogicalKeySet version.
modifiers.add(_getModifierLabel(LogicalKeyboardKey.shift, localizations)); if (serialized.alt!) _getModifierLabel(LogicalKeyboardKey.alt, localizations),
} if (serialized.control!) _getModifierLabel(LogicalKeyboardKey.control, localizations),
if (serialized.meta!) { if (serialized.meta!) _getModifierLabel(LogicalKeyboardKey.meta, localizations),
modifiers.add(_getModifierLabel(LogicalKeyboardKey.meta, localizations)); if (serialized.shift!) _getModifierLabel(LogicalKeyboardKey.shift, localizations),
} ],
} else { ];
// These should be in this order, to match the LogicalKeySet version.
if (serialized.alt!) {
modifiers.add(_getModifierLabel(LogicalKeyboardKey.alt, localizations));
}
if (serialized.control!) {
modifiers.add(_getModifierLabel(LogicalKeyboardKey.control, localizations));
}
if (serialized.meta!) {
modifiers.add(_getModifierLabel(LogicalKeyboardKey.meta, localizations));
}
if (serialized.shift!) {
modifiers.add(_getModifierLabel(LogicalKeyboardKey.shift, localizations));
}
}
String? shortcutTrigger; String? shortcutTrigger;
final int logicalKeyId = trigger.keyId; final int logicalKeyId = trigger.keyId;
if (_shortcutGraphicEquivalents.containsKey(trigger)) { if (_shortcutGraphicEquivalents.containsKey(trigger)) {

View File

@ -141,7 +141,6 @@ class NavigationDrawer extends StatelessWidget {
children.whereType<NavigationDrawerDestination>().toList().length; children.whereType<NavigationDrawerDestination>().toList().length;
int destinationIndex = 0; int destinationIndex = 0;
final List<Widget> wrappedChildren = <Widget>[];
Widget wrapChild(Widget child, int index) => _SelectableAnimatedBuilder( Widget wrapChild(Widget child, int index) => _SelectableAnimatedBuilder(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
isSelected: index == selectedIndex, isSelected: index == selectedIndex,
@ -162,14 +161,11 @@ class NavigationDrawer extends StatelessWidget {
); );
}); });
for (int i = 0; i < children.length; i++) { final List<Widget> wrappedChildren = <Widget>[
if (children[i] is! NavigationDrawerDestination) { for (final Widget child in children)
wrappedChildren.add(children[i]); if (child is! NavigationDrawerDestination) child
} else { else wrapChild(child, destinationIndex++),
wrappedChildren.add(wrapChild(children[i], destinationIndex)); ];
destinationIndex += 1;
}
}
final NavigationDrawerThemeData navigationDrawerTheme = NavigationDrawerTheme.of(context); final NavigationDrawerThemeData navigationDrawerTheme = NavigationDrawerTheme.of(context);
return Drawer( return Drawer(

View File

@ -492,20 +492,12 @@ class Border extends BoxBorder {
} }
Set<Color> _distinctVisibleColors() { Set<Color> _distinctVisibleColors() {
final Set<Color> distinctVisibleColors = <Color>{}; return <Color>{
if (top.style != BorderStyle.none) { if (top.style != BorderStyle.none) top.color,
distinctVisibleColors.add(top.color); if (right.style != BorderStyle.none) right.color,
} if (bottom.style != BorderStyle.none) bottom.color,
if (right.style != BorderStyle.none) { if (left.style != BorderStyle.none) left.color,
distinctVisibleColors.add(right.color); };
}
if (bottom.style != BorderStyle.none) {
distinctVisibleColors.add(bottom.color);
}
if (left.style != BorderStyle.none) {
distinctVisibleColors.add(left.color);
}
return distinctVisibleColors;
} }
// [BoxBorder.paintNonUniformBorder] is about 20% faster than [paintBorder], // [BoxBorder.paintNonUniformBorder] is about 20% faster than [paintBorder],
@ -840,21 +832,12 @@ class BorderDirectional extends BoxBorder {
} }
Set<Color> _distinctVisibleColors() { Set<Color> _distinctVisibleColors() {
final Set<Color> distinctVisibleColors = <Color>{}; return <Color>{
if (top.style != BorderStyle.none) { if (top.style != BorderStyle.none) top.color,
distinctVisibleColors.add(top.color); if (end.style != BorderStyle.none) end.color,
} if (bottom.style != BorderStyle.none) bottom.color,
if (end.style != BorderStyle.none) { if (start.style != BorderStyle.none) start.color,
distinctVisibleColors.add(end.color); };
}
if (bottom.style != BorderStyle.none) {
distinctVisibleColors.add(bottom.color);
}
if (start.style != BorderStyle.none) {
distinctVisibleColors.add(start.color);
}
return distinctVisibleColors;
} }

View File

@ -1260,19 +1260,13 @@ class RenderTable extends RenderBox {
return <DiagnosticsNode>[DiagnosticsNode.message('table is empty')]; return <DiagnosticsNode>[DiagnosticsNode.message('table is empty')];
} }
final List<DiagnosticsNode> children = <DiagnosticsNode>[]; return <DiagnosticsNode>[
for (int y = 0; y < rows; y += 1) { for (int y = 0; y < rows; y += 1)
for (int x = 0; x < columns; x += 1) { for (int x = 0; x < columns; x += 1)
final int xy = x + y * columns; if (_children[x + y * columns] case final RenderBox child)
final RenderBox? child = _children[xy]; child.toDiagnosticsNode(name: 'child ($x, $y)')
final String name = 'child ($x, $y)'; else
if (child != null) { DiagnosticsProperty<Object>('child ($x, $y)', null, ifNull: 'is null', showSeparator: false),
children.add(child.toDiagnosticsNode(name: name)); ];
} else {
children.add(DiagnosticsProperty<Object>(name, null, ifNull: 'is null', showSeparator: false));
}
}
}
return children;
} }
} }

View File

@ -205,20 +205,15 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
// This is run in another isolate created by _addLicenses above. // This is run in another isolate created by _addLicenses above.
static List<LicenseEntry> _parseLicenses(String rawLicenses) { static List<LicenseEntry> _parseLicenses(String rawLicenses) {
final String licenseSeparator = '\n${'-' * 80}\n'; final String licenseSeparator = '\n${'-' * 80}\n';
final List<LicenseEntry> result = <LicenseEntry>[]; return <LicenseEntry>[
final List<String> licenses = rawLicenses.split(licenseSeparator); for (final String license in rawLicenses.split(licenseSeparator))
for (final String license in licenses) { if (license.indexOf('\n\n') case final int split when split >= 0)
final int split = license.indexOf('\n\n'); LicenseEntryWithLineBreaks(
if (split >= 0) { license.substring(0, split).split('\n'),
result.add(LicenseEntryWithLineBreaks( license.substring(split + 2),
license.substring(0, split).split('\n'), )
license.substring(split + 2), else LicenseEntryWithLineBreaks(const <String>[], license),
)); ];
} else {
result.add(LicenseEntryWithLineBreaks(const <String>[], license));
}
}
return result;
} }
@override @override

View File

@ -625,14 +625,13 @@ class HardwareKeyboard {
} }
List<String> _debugPressedKeysDetails() { List<String> _debugPressedKeysDetails() {
if (_pressedKeys.isEmpty) { return <String>[
return <String>['Empty']; if (_pressedKeys.isEmpty)
} 'Empty'
final List<String> details = <String>[]; else
for (final PhysicalKeyboardKey physicalKey in _pressedKeys.keys) { for (final PhysicalKeyboardKey physicalKey in _pressedKeys.keys)
details.add('$physicalKey: ${_pressedKeys[physicalKey]}'); '$physicalKey: ${_pressedKeys[physicalKey]}',
} ];
return details;
} }
/// Process a new [KeyEvent] by recording the state changes and dispatching /// Process a new [KeyEvent] by recording the state changes and dispatching

View File

@ -180,20 +180,13 @@ class DefaultSpellCheckService implements SpellCheckService {
return null; return null;
} }
List<SuggestionSpan> suggestionSpans = <SuggestionSpan>[]; List<SuggestionSpan> suggestionSpans = <SuggestionSpan>[
for (final Map<dynamic, dynamic> resultMap in rawResults.cast<Map<dynamic, dynamic>>())
for (final dynamic result in rawResults) {
final Map<String, dynamic> resultMap =
Map<String,dynamic>.from(result as Map<dynamic, dynamic>);
suggestionSpans.add(
SuggestionSpan( SuggestionSpan(
TextRange( TextRange(start: resultMap['startIndex'] as int, end: resultMap['endIndex'] as int),
start: resultMap['startIndex'] as int, (resultMap['suggestions'] as List<Object?>).cast<String>(),
end: resultMap['endIndex'] as int), ),
(resultMap['suggestions'] as List<dynamic>).cast<String>(), ];
)
);
}
if (lastSavedResults != null) { if (lastSavedResults != null) {
// Merge current and previous spell check results if between requests, // Merge current and previous spell check results if between requests,

View File

@ -1894,14 +1894,11 @@ class TextInput {
TextInput._instance._updateEditingValue(value, exclude: _PlatformTextInputControl.instance); TextInput._instance._updateEditingValue(value, exclude: _PlatformTextInputControl.instance);
case 'TextInputClient.updateEditingStateWithDeltas': case 'TextInputClient.updateEditingStateWithDeltas':
assert(_currentConnection!._client is DeltaTextInputClient, 'You must be using a DeltaTextInputClient if TextInputConfiguration.enableDeltaModel is set to true'); assert(_currentConnection!._client is DeltaTextInputClient, 'You must be using a DeltaTextInputClient if TextInputConfiguration.enableDeltaModel is set to true');
final List<TextEditingDelta> deltas = <TextEditingDelta>[];
final Map<String, dynamic> encoded = args[1] as Map<String, dynamic>; final Map<String, dynamic> encoded = args[1] as Map<String, dynamic>;
final List<TextEditingDelta> deltas = <TextEditingDelta>[
for (final dynamic encodedDelta in encoded['deltas'] as List<dynamic>) { for (final dynamic encodedDelta in encoded['deltas'] as List<dynamic>)
final TextEditingDelta delta = TextEditingDelta.fromJSON(encodedDelta as Map<String, dynamic>); TextEditingDelta.fromJSON(encodedDelta as Map<String, dynamic>)
deltas.add(delta); ];
}
(_currentConnection!._client as DeltaTextInputClient).updateEditingValueWithDeltas(deltas); (_currentConnection!._client as DeltaTextInputClient).updateEditingValueWithDeltas(deltas);
case 'TextInputClient.performAction': case 'TextInputClient.performAction':

View File

@ -6686,16 +6686,11 @@ class MouseRegion extends SingleChildRenderObjectWidget {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
final List<String> listeners = <String>[]; final List<String> listeners = <String>[
if (onEnter != null) { if (onEnter != null) 'enter',
listeners.add('enter'); if (onExit != null) 'exit',
} if (onHover != null) 'hover',
if (onExit != null) { ];
listeners.add('exit');
}
if (onHover != null) {
listeners.add('hover');
}
properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>')); properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>'));
properties.add(DiagnosticsProperty<MouseCursor>('cursor', cursor, defaultValue: null)); properties.add(DiagnosticsProperty<MouseCursor>('cursor', cursor, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('opaque', opaque, defaultValue: true)); properties.add(DiagnosticsProperty<bool>('opaque', opaque, defaultValue: true));
@ -7573,12 +7568,10 @@ class KeyedSubtree extends StatelessWidget {
return items; return items;
} }
final List<Widget> itemsWithUniqueKeys = <Widget>[]; final List<Widget> itemsWithUniqueKeys = <Widget>[
int itemIndex = baseIndex; for (final (int i, Widget item) in items.indexed)
for (final Widget item in items) { KeyedSubtree.wrap(item, baseIndex + i),
itemsWithUniqueKeys.add(KeyedSubtree.wrap(item, itemIndex)); ];
itemIndex += 1;
}
assert(!debugItemsHaveDuplicateKeys(itemsWithUniqueKeys)); assert(!debugItemsHaveDuplicateKeys(itemsWithUniqueKeys));
return itemsWithUniqueKeys; return itemsWithUniqueKeys;

View File

@ -909,17 +909,12 @@ class _DragAvatar<T extends Object> extends Drag {
Iterable<_DragTargetState<Object>> _getDragTargets(Iterable<HitTestEntry> path) { Iterable<_DragTargetState<Object>> _getDragTargets(Iterable<HitTestEntry> path) {
// Look for the RenderBoxes that corresponds to the hit target (the hit target // Look for the RenderBoxes that corresponds to the hit target (the hit target
// widgets build RenderMetaData boxes for us for this purpose). // widgets build RenderMetaData boxes for us for this purpose).
final List<_DragTargetState<Object>> targets = <_DragTargetState<Object>>[]; return <_DragTargetState<Object>>[
for (final HitTestEntry entry in path) { for (final HitTestEntry entry in path)
final HitTestTarget target = entry.target; if (entry.target case final RenderMetaData target)
if (target is RenderMetaData) { if (target.metaData case final _DragTargetState<Object> metaData)
final dynamic metaData = target.metaData; if (metaData.isExpectedDataType(data, T)) metaData,
if (metaData is _DragTargetState && metaData.isExpectedDataType(data, T)) { ];
targets.add(metaData);
}
}
}
return targets;
} }
void _leaveAllEntered() { void _leaveAllEntered() {

View File

@ -2035,15 +2035,11 @@ class _HighlightModeManager {
// Check to see if any of the early handlers handle the key. If so, then // Check to see if any of the early handlers handle the key. If so, then
// return early. // return early.
if (_earlyKeyEventHandlers.isNotEmpty) { if (_earlyKeyEventHandlers.isNotEmpty) {
final List<KeyEventResult> results = <KeyEventResult>[]; final List<KeyEventResult> results = <KeyEventResult>[
// Copy the list before iteration to prevent problems if the list gets // Make a copy to prevent problems if the list is modified during iteration.
// modified during iteration. for (final OnKeyEventCallback callback in _earlyKeyEventHandlers.toList())
final List<OnKeyEventCallback> iterationList = _earlyKeyEventHandlers.toList(); for (final KeyEvent event in message.events) callback(event),
for (final OnKeyEventCallback callback in iterationList) { ];
for (final KeyEvent event in message.events) {
results.add(callback(event));
}
}
final KeyEventResult result = combineKeyEventResults(results); final KeyEventResult result = combineKeyEventResults(results);
switch (result) { switch (result) {
case KeyEventResult.ignored: case KeyEventResult.ignored:
@ -2067,15 +2063,13 @@ class _HighlightModeManager {
FocusManager.instance.primaryFocus!, FocusManager.instance.primaryFocus!,
...FocusManager.instance.primaryFocus!.ancestors, ...FocusManager.instance.primaryFocus!.ancestors,
]) { ]) {
final List<KeyEventResult> results = <KeyEventResult>[]; final List<KeyEventResult> results = <KeyEventResult>[
if (node.onKeyEvent != null) { if (node.onKeyEvent != null)
for (final KeyEvent event in message.events) { for (final KeyEvent event in message.events)
results.add(node.onKeyEvent!(node, event)); node.onKeyEvent!(node, event),
} if (node.onKey != null && message.rawEvent != null)
} node.onKey!(node, message.rawEvent!),
if (node.onKey != null && message.rawEvent != null) { ];
results.add(node.onKey!(node, message.rawEvent!));
}
final KeyEventResult result = combineKeyEventResults(results); final KeyEventResult result = combineKeyEventResults(results);
switch (result) { switch (result) {
case KeyEventResult.ignored: case KeyEventResult.ignored:
@ -2095,15 +2089,11 @@ class _HighlightModeManager {
// Check to see if any late key event handlers want to handle the event. // Check to see if any late key event handlers want to handle the event.
if (!handled && _lateKeyEventHandlers.isNotEmpty) { if (!handled && _lateKeyEventHandlers.isNotEmpty) {
final List<KeyEventResult> results = <KeyEventResult>[]; final List<KeyEventResult> results = <KeyEventResult>[
// Copy the list before iteration to prevent problems if the list gets // Make a copy to prevent problems if the list is modified during iteration.
// modified during iteration. for (final OnKeyEventCallback callback in _lateKeyEventHandlers.toList())
final List<OnKeyEventCallback> iterationList = _lateKeyEventHandlers.toList(); for (final KeyEvent event in message.events) callback(event),
for (final OnKeyEventCallback callback in iterationList) { ];
for (final KeyEvent event in message.events) {
results.add(callback(event));
}
}
final KeyEventResult result = combineKeyEventResults(results); final KeyEventResult result = combineKeyEventResults(results);
switch (result) { switch (result) {
case KeyEventResult.ignored: case KeyEventResult.ignored:

View File

@ -3194,14 +3194,11 @@ class BuildOwner {
keyStringCount[key] = 1; keyStringCount[key] = 1;
} }
} }
final List<String> keyLabels = <String>[]; final List<String> keyLabels = <String>[
keyStringCount.forEach((String key, int count) { for (final MapEntry<String, int>(:String key, value: int count) in keyStringCount.entries)
if (count == 1) { if (count == 1) key
keyLabels.add(key); else '$key ($count different affected keys had this toString representation)',
} else { ];
keyLabels.add('$key ($count different affected keys had this toString representation)');
}
});
final Iterable<Element> elements = _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans!.keys; final Iterable<Element> elements = _debugElementsThatWillNeedToBeRebuiltDueToGlobalKeyShenanigans!.keys;
final Map<String, int> elementStringCount = HashMap<String, int>(); final Map<String, int> elementStringCount = HashMap<String, int>();
for (final String element in elements.map<String>((Element element) => element.toString())) { for (final String element in elements.map<String>((Element element) => element.toString())) {
@ -3211,14 +3208,11 @@ class BuildOwner {
elementStringCount[element] = 1; elementStringCount[element] = 1;
} }
} }
final List<String> elementLabels = <String>[]; final List<String> elementLabels = <String>[
elementStringCount.forEach((String element, int count) { for (final MapEntry<String, int>(key: String element, value: int count) in elementStringCount.entries)
if (count == 1) { if (count == 1) element
elementLabels.add(element); else '$element ($count different affected elements had this toString representation)',
} else { ];
elementLabels.add('$element ($count different affected elements had this toString representation)');
}
});
assert(keyLabels.isNotEmpty); assert(keyLabels.isNotEmpty);
final String the = keys.length == 1 ? ' the' : ''; final String the = keys.length == 1 ? ' the' : '';
final String s = keys.length == 1 ? '' : 's'; final String s = keys.length == 1 ? '' : 's';

View File

@ -666,22 +666,12 @@ class PlatformMenuItemGroup extends PlatformMenuItem {
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}) { }) {
final List<Map<String, Object?>> result = <Map<String, Object?>>[]; return <Map<String, Object?>>[
result.add(<String, Object?>{ <String, Object?>{_kIdKey: getId(group), _kIsDividerKey: true},
_kIdKey: getId(group), for (final PlatformMenuItem item in group.members)
_kIsDividerKey: true, ...item.toChannelRepresentation(delegate, getId: getId),
}); <String, Object?>{_kIdKey: getId(group), _kIsDividerKey: true},
for (final PlatformMenuItem item in group.members) { ];
result.addAll(item.toChannelRepresentation(
delegate,
getId: getId,
));
}
result.add(<String, Object?>{
_kIdKey: getId(group),
_kIsDividerKey: true,
});
return result;
} }
@override @override

View File

@ -729,13 +729,10 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
AxisDirection.right => (SemanticsAction.scrollLeft, SemanticsAction.scrollRight), AxisDirection.right => (SemanticsAction.scrollLeft, SemanticsAction.scrollRight),
}; };
final Set<SemanticsAction> actions = <SemanticsAction>{}; final Set<SemanticsAction> actions = <SemanticsAction>{
if (pixels > minScrollExtent) { if (pixels > minScrollExtent) backward,
actions.add(backward); if (pixels < maxScrollExtent) forward,
} };
if (pixels < maxScrollExtent) {
actions.add(forward);
}
if (setEquals<SemanticsAction>(actions, _semanticActions)) { if (setEquals<SemanticsAction>(actions, _semanticActions)) {
return; return;

View File

@ -2350,23 +2350,22 @@ class _HorizontalInnerDimensionState extends ScrollableState {
ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy.explicit, ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy.explicit,
RenderObject? targetRenderObject, RenderObject? targetRenderObject,
}) { }) {
final List<Future<void>> newFutures = <Future<void>>[]; final List<Future<void>> newFutures = <Future<void>>[
position.ensureVisible(
newFutures.add(position.ensureVisible( object,
object, alignment: alignment,
alignment: alignment, duration: duration,
duration: duration, curve: curve,
curve: curve, alignmentPolicy: alignmentPolicy,
alignmentPolicy: alignmentPolicy, ),
)); verticalScrollable.position.ensureVisible(
object,
newFutures.add(verticalScrollable.position.ensureVisible( alignment: alignment,
object, duration: duration,
alignment: alignment, curve: curve,
duration: duration, alignmentPolicy: alignmentPolicy,
curve: curve, ),
alignmentPolicy: alignmentPolicy, ];
));
return (newFutures, verticalScrollable); return (newFutures, verticalScrollable);
} }

View File

@ -2213,13 +2213,10 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai
/// Copies the selected contents of all [Selectable]s. /// Copies the selected contents of all [Selectable]s.
@override @override
SelectedContent? getSelectedContent() { SelectedContent? getSelectedContent() {
final List<SelectedContent> selections = <SelectedContent>[]; final List<SelectedContent> selections = <SelectedContent>[
for (final Selectable selectable in selectables) { for (final Selectable selectable in selectables)
final SelectedContent? data = selectable.getSelectedContent(); if (selectable.getSelectedContent() case final SelectedContent data) data,
if (data != null) { ];
selections.add(data);
}
}
if (selections.isEmpty) { if (selections.isEmpty) {
return null; return null;
} }

View File

@ -254,18 +254,14 @@ class RenderTapRegionSurface extends RenderProxyBoxWithHitTestBehavior implement
// groups of regions that were not hit. // groups of regions that were not hit.
final Set<RenderTapRegion> hitRegions = final Set<RenderTapRegion> hitRegions =
_getRegionsHit(_registeredRegions, result.path).cast<RenderTapRegion>().toSet(); _getRegionsHit(_registeredRegions, result.path).cast<RenderTapRegion>().toSet();
final Set<RenderTapRegion> insideRegions = <RenderTapRegion>{};
assert(_tapRegionDebug('Tap event hit ${hitRegions.length} descendants.')); assert(_tapRegionDebug('Tap event hit ${hitRegions.length} descendants.'));
for (final RenderTapRegion region in hitRegions) { final Set<RenderTapRegion> insideRegions = <RenderTapRegion>{
if (region.groupId == null) { for (final RenderTapRegion region in hitRegions)
insideRegions.add(region); if (region.groupId == null) region
continue; // Adding all grouped regions, so they act as a single region.
} else ..._groupIdToRegions[region.groupId]!,
// Add all grouped regions to the insideRegions so that groups act as a };
// single region.
insideRegions.addAll(_groupIdToRegions[region.groupId]!);
}
// If they're not inside, then they're outside. // If they're not inside, then they're outside.
final Set<RenderTapRegion> outsideRegions = _registeredRegions.difference(insideRegions); final Set<RenderTapRegion> outsideRegions = _registeredRegions.difference(insideRegions);
@ -292,15 +288,12 @@ class RenderTapRegionSurface extends RenderProxyBoxWithHitTestBehavior implement
} }
// Returns the registered regions that are in the hit path. // Returns the registered regions that are in the hit path.
Iterable<HitTestTarget> _getRegionsHit(Set<RenderTapRegion> detectors, Iterable<HitTestEntry> hitTestPath) { Set<HitTestTarget> _getRegionsHit(Set<RenderTapRegion> detectors, Iterable<HitTestEntry> hitTestPath) {
final Set<HitTestTarget> hitRegions = <HitTestTarget>{}; return <HitTestTarget>{
for (final HitTestEntry<HitTestTarget> entry in hitTestPath) { for (final HitTestEntry<HitTestTarget> entry in hitTestPath)
final HitTestTarget target = entry.target; if (entry.target case final HitTestTarget target)
if (_registeredRegions.contains(target)) { if (_registeredRegions.contains(target)) target,
hitRegions.add(target); };
}
}
return hitRegions;
} }
} }

View File

@ -699,17 +699,14 @@ class _MultiChildComponentElement extends Element {
@override @override
List<DiagnosticsNode> debugDescribeChildren() { List<DiagnosticsNode> debugDescribeChildren() {
final List<DiagnosticsNode> children = <DiagnosticsNode>[]; return <DiagnosticsNode>[
if (_childElement != null) { if (_childElement != null) _childElement!.toDiagnosticsNode(),
children.add(_childElement!.toDiagnosticsNode()); for (int i = 0; i < _viewElements.length; i++)
} _viewElements[i].toDiagnosticsNode(
for (int i = 0; i < _viewElements.length; i++) { name: 'view ${i + 1}',
children.add(_viewElements[i].toDiagnosticsNode( style: DiagnosticsTreeStyle.offstage,
name: 'view ${i + 1}', ),
style: DiagnosticsTreeStyle.offstage, ];
));
}
return children;
} }
} }

View File

@ -960,17 +960,11 @@ mixin WidgetInspectorService {
registerServiceExtension( registerServiceExtension(
name: name, name: name,
callback: (Map<String, String> parameters) async { callback: (Map<String, String> parameters) async {
final List<String> args = <String>[]; int index;
int index = 0; final List<String> args = <String>[
while (true) { for (index = 0; parameters['arg$index'] != null; index++)
final String name = 'arg$index'; parameters['arg$index']!,
if (parameters.containsKey(name)) { ];
args.add(parameters[name]!);
} else {
break;
}
index++;
}
// Verify that the only arguments other than perhaps 'isolateId' are // Verify that the only arguments other than perhaps 'isolateId' are
// arguments we have already handled. // arguments we have already handled.
assert(index == parameters.length || (index == parameters.length - 1 && parameters.containsKey('isolateId'))); assert(index == parameters.length || (index == parameters.length - 1 && parameters.containsKey('isolateId')));
@ -3408,27 +3402,16 @@ class _Location {
final String? name; final String? name;
Map<String, Object?> toJsonMap() { Map<String, Object?> toJsonMap() {
final Map<String, Object?> json = <String, Object?>{ return <String, Object?>{
'file': file, 'file': file,
'line': line, 'line': line,
'column': column, 'column': column,
if (name != null) 'name': name,
}; };
if (name != null) {
json['name'] = name;
}
return json;
} }
@override @override
String toString() { String toString() => <String>[if (name != null) name!, file, '$line', '$column'].join(':');
final List<String> parts = <String>[];
if (name != null) {
parts.add(name!);
}
parts.add(file);
parts..add('$line')..add('$column');
return parts.join(':');
}
} }
bool _isDebugCreator(DiagnosticsNode node) => node is DiagnosticsDebugCreator; bool _isDebugCreator(DiagnosticsNode node) => node is DiagnosticsDebugCreator;

View File

@ -204,12 +204,7 @@ void main() {
// Adding 7 more children overflows onto a third page. // Adding 7 more children overflows onto a third page.
setState(() { setState(() {
children.add(const TestBox()); children.addAll(List<TestBox>.filled(6, const TestBox()));
children.add(const TestBox());
children.add(const TestBox());
children.add(const TestBox());
children.add(const TestBox());
children.add(const TestBox());
}); });
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.byType(TestBox), findsNWidgets(7)); expect(find.byType(TestBox), findsNWidgets(7));

View File

@ -17,24 +17,15 @@ void main() {
/// Builds test button items for each of the suggestions provided. /// Builds test button items for each of the suggestions provided.
List<ContextMenuButtonItem> buildSuggestionButtons(List<String> suggestions) { List<ContextMenuButtonItem> buildSuggestionButtons(List<String> suggestions) {
final List<ContextMenuButtonItem> buttonItems = <ContextMenuButtonItem>[]; return <ContextMenuButtonItem>[
for (final String suggestion in suggestions)
for (final String suggestion in suggestions) { ContextMenuButtonItem(onPressed: () {}, label: suggestion),
buttonItems.add(ContextMenuButtonItem(
onPressed: () {},
label: suggestion,
));
}
final ContextMenuButtonItem deleteButton =
ContextMenuButtonItem( ContextMenuButtonItem(
onPressed: () {}, onPressed: () {},
type: ContextMenuButtonType.delete, type: ContextMenuButtonType.delete,
label: 'DELETE', label: 'DELETE',
); ),
buttonItems.add(deleteButton); ];
return buttonItems;
} }
/// Finds the container of the [SpellCheckSuggestionsToolbar] so that /// Finds the container of the [SpellCheckSuggestionsToolbar] so that

View File

@ -338,14 +338,10 @@ void main() {
testWidgets('SliverFixedExtentList handles underflow when its children changes', (WidgetTester tester) async { testWidgets('SliverFixedExtentList handles underflow when its children changes', (WidgetTester tester) async {
final List<String> items = <String>['1', '2', '3', '4', '5', '6']; final List<String> items = <String>['1', '2', '3', '4', '5', '6'];
final List<String> initializedChild = <String>[]; final List<String> initializedChild = <String>[];
List<Widget> children = <Widget>[]; List<Widget> children = <Widget>[
for (final String item in items) { for (final String item in items)
children.add( StateInitSpy(item, () => initializedChild.add(item), key: ValueKey<String>(item)),
StateInitSpy( ];
item, () => initializedChild.add(item), key: ValueKey<String>(item),
),
);
}
final ScrollController controller = ScrollController(initialScrollOffset: 5400); final ScrollController controller = ScrollController(initialScrollOffset: 5400);
addTearDown(controller.dispose); addTearDown(controller.dispose);

View File

@ -106,16 +106,10 @@ class Response {
/// Create a list of Strings from [_failureDetails]. /// Create a list of Strings from [_failureDetails].
List<String> _failureDetailsAsString() { List<String> _failureDetailsAsString() {
final List<String> list = <String>[]; return <String>[
if (_failureDetails == null || _failureDetails.isEmpty) { if (_failureDetails != null)
return list; for (final Failure failure in _failureDetails) failure.toJson(),
} ];
for (final Failure failure in _failureDetails) {
list.add(failure.toJson());
}
return list;
} }
/// Creates a [Failure] list using a json response. /// Creates a [Failure] list using a json response.