Commit 28366002 authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

enable lint prefer_foreach (#12674)

* enable lint prefer_foreach

* fix tests
parent 872d83a3
......@@ -119,7 +119,7 @@ linter:
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
- prefer_final_fields
- prefer_final_locals
# - prefer_foreach # not yet tested
- prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested
- prefer_initializing_formals
# - prefer_interpolation_to_compose_strings # not yet tested
......
......@@ -113,7 +113,7 @@ linter:
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
- prefer_final_fields
- prefer_final_locals
# - prefer_foreach # not yet tested
- prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested
- prefer_initializing_formals
# - prefer_interpolation_to_compose_strings # not yet tested
......
......@@ -293,8 +293,7 @@ abstract class MultiDragGestureRecognizer<T extends MultiDragPointerState> exten
@override
void dispose() {
for (int pointer in _pointers.keys.toList())
_removeState(pointer);
_pointers.keys.toList().forEach(_removeState);
assert(_pointers.isEmpty);
_pointers = null;
super.dispose();
......
......@@ -199,9 +199,7 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
}
void _clearTrackers() {
final List<_TapTracker> localTrackers = new List<_TapTracker>.from(_trackers.values);
for (_TapTracker tracker in localTrackers)
_reject(tracker);
_trackers.values.toList().forEach(_reject);
assert(_trackers.isEmpty);
}
......
......@@ -173,10 +173,10 @@ const String _kDefaultDebugLabel = 'unknown';
/// If the package internally uses the font it defines, it should still specify
/// the `package` argument when creating the text style as in the example above.
///
/// A package can also provide font files without declaring a font in its
/// `pubspec.yaml`. These files should then be in the `lib/` folder of the
/// package. The font files will not automatically be bundled in the app, instead
/// the app can use these selectively when declaring a font. Suppose a package
/// A package can also provide font files without declaring a font in its
/// `pubspec.yaml`. These files should then be in the `lib/` folder of the
/// package. The font files will not automatically be bundled in the app, instead
/// the app can use these selectively when declaring a font. Suppose a package
/// named `my_package` has:
///
/// ```
......@@ -197,7 +197,7 @@ const String _kDefaultDebugLabel = 'unknown';
///
/// The `lib/` is implied, so it should not be included in the asset path.
///
/// In this case, since the app locally defines the font, the TextStyle is
/// In this case, since the app locally defines the font, the TextStyle is
/// created without the `package` argument:
///
///```dart
......@@ -709,8 +709,7 @@ class TextStyle extends Diagnosticable {
final bool styleSpecified = styles.any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info));
properties.add(new DiagnosticsProperty<bool>('${prefix}inherit', inherit, level: (!styleSpecified && inherit) ? DiagnosticLevel.fine : DiagnosticLevel.info));
for (DiagnosticsNode style in styles)
properties.add(style);
styles.forEach(properties.add);
if (!styleSpecified)
properties.add(new FlagProperty('inherit', value: inherit, ifTrue: '$prefix<all styles inherited>', ifFalse: '$prefix<no style specified>'));
......
......@@ -2736,9 +2736,7 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
/// Add all the children to the end of this render object's child list.
void addAll(List<ChildType> children) {
if (children != null)
for (ChildType child in children)
add(child);
children?.forEach(add);
}
void _removeFromChildList(ChildType child) {
......@@ -2923,7 +2921,7 @@ class FlutterErrorDetailsForRendering extends FlutterErrorDetails {
/// Describes the semantics information a [RenderObject] wants to add to its
/// parent.
///
///
/// It has two notable subclasses:
/// * [_InterestingSemanticsFragment] describing actual semantic information to
/// be added to the parent.
......
......@@ -438,10 +438,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
@override
void redepthChildren() {
if (_children != null) {
for (SemanticsNode child in _children)
redepthChild(child);
}
_children?.forEach(redepthChild);
}
@override
......
......@@ -219,8 +219,7 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
@override
void removeAll() {
super.removeAll();
for (RenderBox child in _keepAliveBucket.values)
dropChild(child);
_keepAliveBucket.values.forEach(dropChild);
_keepAliveBucket.clear();
}
......@@ -274,15 +273,13 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
@override
void redepthChildren() {
super.redepthChildren();
for (RenderBox child in _keepAliveBucket.values)
redepthChild(child);
_keepAliveBucket.values.forEach(redepthChild);
}
@override
void visitChildren(RenderObjectVisitor visitor) {
super.visitChildren(visitor);
for (RenderBox child in _keepAliveBucket.values)
visitor(child);
_keepAliveBucket.values.forEach(visitor);
}
@override
......
......@@ -384,10 +384,7 @@ class RenderTable extends RenderBox {
_configuration = configuration;
_defaultVerticalAlignment = defaultVerticalAlignment;
_textBaseline = textBaseline;
if (children != null) {
for (List<RenderBox> row in children)
addRow(row);
}
children?.forEach(addRow);
}
// Children are stored in row-major order.
......@@ -628,8 +625,7 @@ class RenderTable extends RenderBox {
y += 1;
}
// drop all the lost children
for (RenderBox oldChild in lostChildren)
dropChild(oldChild);
lostChildren.forEach(dropChild);
// update our internal values
_columns = columns;
_rows = cells.length ~/ columns;
......@@ -652,8 +648,7 @@ class RenderTable extends RenderBox {
_children.clear();
_columns = cells.isNotEmpty ? cells.first.length : 0;
_rows = 0;
for (List<RenderBox> row in cells)
addRow(row);
cells.forEach(addRow);
assert(_children.length == rows * columns);
}
......
......@@ -1736,8 +1736,7 @@ class _InactiveElements {
final List<Element> elements = _elements.toList()..sort(Element._sort);
_elements.clear();
try {
for (Element element in elements.reversed)
_unmount(element);
elements.reversed.forEach(_unmount);
} finally {
assert(_elements.isEmpty);
_locked = false;
......
......@@ -791,8 +791,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
}());
push(_routeNamed(Navigator.defaultRouteName));
} else {
for (Route<dynamic> route in plannedInitialRoutes)
push(route);
plannedInitialRoutes.forEach(push);
}
} else {
Route<dynamic> route;
......@@ -1328,8 +1327,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
absorber?.absorbing = true;
});
}
for (int pointer in _activePointers.toList())
WidgetsBinding.instance.cancelPointer(pointer);
_activePointers.toList().forEach(WidgetsBinding.instance.cancelPointer);
}
@override
......
......@@ -36,8 +36,7 @@ class TestTree extends Object with DiagnosticableTreeMixin {
if (style != null)
properties.defaultDiagnosticsTreeStyle = style;
for (DiagnosticsNode property in this.properties)
properties.add(property);
this.properties.forEach(properties.add);
}
}
......
......@@ -28,8 +28,7 @@ void main() {
scheduler.scheduleTask(() { executedTasks.add(x); }, Priority.idle + x);
}
for (int x in input)
scheduleAddingTask(x);
input.forEach(scheduleAddingTask);
strategy.allowedPriority = 100;
for (int i = 0; i < 3; i += 1)
......
......@@ -26,13 +26,11 @@ class LinkedScrollController extends ScrollController {
void setParent(ScrollController newParent) {
if (_parent != null) {
for (ScrollPosition position in positions)
_parent.detach(position);
positions.forEach(_parent.detach);
}
_parent = newParent;
if (_parent != null) {
for (ScrollPosition position in positions)
_parent.attach(position);
positions.forEach(_parent.attach);
}
}
......@@ -54,8 +52,7 @@ class LinkedScrollController extends ScrollController {
@override
void dispose() {
if (_parent != null) {
for (ScrollPosition position in positions)
_parent.detach(position);
positions.forEach(_parent.detach);
}
super.dispose();
}
......
......@@ -194,9 +194,7 @@ class AssetBundle {
void dump() {
printTrace('Dumping AssetBundle:');
for (String archivePath in entries.keys.toList()..sort()) {
printTrace(archivePath);
}
(entries.keys.toList()..sort()).forEach(printTrace);
}
}
......
......@@ -55,8 +55,7 @@ Future<List<int>> _attempt(Uri url) async {
printTrace('Received response from server, collecting bytes...');
try {
final BytesBuilder responseBody = new BytesBuilder(copy: false);
await for (List<int> chunk in response)
responseBody.add(chunk);
await response.forEach(responseBody.add);
return responseBody.takeBytes();
} on IOException catch (error) {
printTrace('Download error: $error');
......
......@@ -142,10 +142,8 @@ class ItemListNotifier<T> {
_items = updatedSet;
for (T item in addedItems)
_addedController.add(item);
for (T item in removedItems)
_removedController.add(item);
addedItems.forEach(_addedController.add);
removedItems.forEach(_removedController.add);
}
/// Close the streams.
......
......@@ -131,8 +131,7 @@ class ResidentCompiler {
final String inputKey = new Uuid().generateV4();
_server.stdin.writeln('recompile $inputKey');
for (String invalidatedFile in invalidatedFiles)
_server.stdin.writeln(invalidatedFile);
invalidatedFiles.forEach(_server.stdin.writeln);
_server.stdin.writeln(inputKey);
return stdoutHandler.outputFilename.future;
......
......@@ -478,8 +478,7 @@ class DevFS {
}
// No need to send source files because all compilation is done on the
// host and result of compilation is single kernel file.
for (Uri fileUri in filesUris)
dirtyEntries.remove(fileUri);
filesUris.forEach(dirtyEntries.remove);
printTrace('Compiling dart to kernel with ${invalidatedFiles.length} updated files');
final String compiledBinary = fullRestart
? await compile(
......
......@@ -91,7 +91,7 @@ class MockHttpClientRequest implements io.HttpClientRequest {
}
}
class MockHttpClientResponse implements io.HttpClientResponse {
class MockHttpClientResponse extends Stream<List<int>> implements io.HttpClientResponse {
MockHttpClientResponse(this.statusCode);
@override
......
......@@ -45,7 +45,7 @@ void main() {
final String output = await compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart'
);
verifyNever(mockFrontendServerStdIn.writeln(any));
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
expect(logger.traceText, equals('compile debug message: line1\ncompile debug message: line2\n'));
expect(output, equals('/path/to/main.dart.dill'));
}, overrides: <Type, Generator>{
......@@ -64,7 +64,7 @@ void main() {
final String output = await compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart'
);
verifyNever(mockFrontendServerStdIn.writeln(any));
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
expect(logger.traceText, equals('compile debug message: line1\ncompile debug message: line2\n'));
expect(output, equals(null));
}, overrides: <Type, Generator>{
......@@ -110,7 +110,7 @@ void main() {
final String output = await generator.recompile(
'/path/to/main.dart', null /* invalidatedFiles */
);
verify(mockFrontendServerStdIn.writeln('compile /path/to/main.dart'));
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(logger.traceText, equals('compile debug message: line1\ncompile debug message: line2\n'));
expect(output, equals('/path/to/main.dart.dill'));
......@@ -125,12 +125,13 @@ void main() {
when(mockFrontendServer.stdout).thenReturn(streamController.stream);
streamController.add(UTF8.encode('result abc\nline0\nline1\nabc /path/to/main.dart.dill\n'));
await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
verify(mockFrontendServerStdIn.writeln('compile /path/to/main.dart'));
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
'result abc\nline1\nline2\nabc /path/to/main.dart.dill\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
expect(logger.traceText, equals(
'compile debug message: line0\ncompile debug message: line1\n'
'compile debug message: line1\ncompile debug message: line2\n'
......@@ -148,7 +149,7 @@ void main() {
'result abc\nline0\nline1\nabc /path/to/main.dart.dill\n'
));
await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
verify(mockFrontendServerStdIn.writeln('compile /path/to/main.dart'));
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
'result abc\nline1\nline2\nabc /path/to/main.dart.dill\n');
......@@ -156,6 +157,7 @@ void main() {
'result abc\nline2\nline3\nabc /path/to/main.dart.dill\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
expect(logger.traceText, equals(
'compile debug message: line0\ncompile debug message: line1\n'
'compile debug message: line1\ncompile debug message: line2\n'
......@@ -177,15 +179,33 @@ Future<Null> _recompile(StreamController<List<int>> streamController,
});
final String output = await generator.recompile(null /* mainPath */, <String>['/path/to/main.dart']);
expect(output, equals('/path/to/main.dart.dill'));
final String recompileCommand = verify(
mockFrontendServerStdIn.writeln(captureThat(startsWith('recompile ')))
).captured[0];
final String token1 = recompileCommand.split(' ')[1];
verify(mockFrontendServerStdIn.writeln('/path/to/main.dart'));
verify(mockFrontendServerStdIn.writeln(token1));
final String commands = mockFrontendServerStdIn.getAndClear();
final RegExp re = new RegExp(r'^recompile (.*)\n/path/to/main.dart\n(.*)\n$');
expect(commands, matches(re));
final Match match = re.firstMatch(commands);
expect(match[1] == match[2], isTrue);
mockFrontendServerStdIn._stdInWrites.clear();
}
class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {}
class MockStream extends Mock implements Stream<List<int>> {}
class MockStdIn extends Mock implements IOSink {}
class MockStdIn extends Mock implements IOSink {
final StringBuffer _stdInWrites = new StringBuffer();
String getAndClear() {
final String result = _stdInWrites.toString();
_stdInWrites.clear();
return result;
}
@override
void write([Object o = '']) {
_stdInWrites.write(o);
}
@override
void writeln([Object o = '']) {
_stdInWrites.writeln(o);
}
}
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