From 0417f6621eaae9ba482c8cc22e297d1cfd74f943 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Fri, 27 Jan 2023 09:30:46 -0800 Subject: [PATCH] Fix nullability of TableRow.children (#119285) * Fix nullablility of TableRow.children * fix test --- .../flutter/lib/src/material/data_table.dart | 8 ++--- packages/flutter/lib/src/widgets/table.dart | 33 +++++++------------ packages/flutter/test/widgets/table_test.dart | 4 +-- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/packages/flutter/lib/src/material/data_table.dart b/packages/flutter/lib/src/material/data_table.dart index 70a1a5697fc8..ceb5712f6109 100644 --- a/packages/flutter/lib/src/material/data_table.dart +++ b/packages/flutter/lib/src/material/data_table.dart @@ -967,7 +967,7 @@ class DataTable extends StatelessWidget { int displayColumnIndex = 0; if (displayCheckboxColumn) { tableColumns[0] = FixedColumnWidth(effectiveCheckboxHorizontalMarginStart + Checkbox.width + effectiveCheckboxHorizontalMarginEnd); - tableRows[0].children![0] = _buildCheckbox( + tableRows[0].children[0] = _buildCheckbox( context: context, checked: someChecked ? null : allChecked, onRowTap: null, @@ -977,7 +977,7 @@ class DataTable extends StatelessWidget { ); rowIndex = 1; for (final DataRow row in rows) { - tableRows[rowIndex].children![0] = _buildCheckbox( + tableRows[rowIndex].children[0] = _buildCheckbox( context: context, checked: row.selected, onRowTap: row.onSelectChanged == null ? null : () => row.onSelectChanged?.call(!row.selected), @@ -1020,7 +1020,7 @@ class DataTable extends StatelessWidget { } else { tableColumns[displayColumnIndex] = const IntrinsicColumnWidth(); } - tableRows[0].children![displayColumnIndex] = _buildHeadingCell( + tableRows[0].children[displayColumnIndex] = _buildHeadingCell( context: context, padding: padding, label: column.label, @@ -1034,7 +1034,7 @@ class DataTable extends StatelessWidget { rowIndex = 1; for (final DataRow row in rows) { final DataCell cell = row.cells[dataColumnIndex]; - tableRows[rowIndex].children![displayColumnIndex] = _buildDataCell( + tableRows[rowIndex].children[displayColumnIndex] = _buildDataCell( context: context, padding: padding, label: cell.child, diff --git a/packages/flutter/lib/src/widgets/table.dart b/packages/flutter/lib/src/widgets/table.dart index f153a29fd148..32d04da3c488 100644 --- a/packages/flutter/lib/src/widgets/table.dart +++ b/packages/flutter/lib/src/widgets/table.dart @@ -32,7 +32,7 @@ export 'package:flutter/rendering.dart' show @immutable class TableRow { /// Creates a row in a [Table]. - const TableRow({ this.key, this.decoration, this.children }); + const TableRow({ this.key, this.decoration, this.children = const []}); /// An identifier for the row. final LocalKey? key; @@ -49,7 +49,7 @@ class TableRow { /// Children may be wrapped in [TableCell] widgets to provide per-cell /// configuration to the [Table], but children are not required to be wrapped /// in [TableCell] widgets. - final List? children; + final List children; @override String toString() { @@ -61,9 +61,7 @@ class TableRow { if (decoration != null) { result.write('$decoration, '); } - if (children == null) { - result.write('child list is null'); - } else if (children!.isEmpty) { + if (children.isEmpty) { result.write('no children'); } else { result.write('$children'); @@ -127,15 +125,6 @@ class Table extends RenderObjectWidget { this.defaultVerticalAlignment = TableCellVerticalAlignment.top, this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be }) : assert(defaultVerticalAlignment != TableCellVerticalAlignment.baseline || textBaseline != null, 'textBaseline is required if you specify the defaultVerticalAlignment with TableCellVerticalAlignment.baseline'), - assert(() { - if (children.any((TableRow row) => row.children == null)) { - throw FlutterError( - 'One of the rows of the table had null children.\n' - 'The children property of TableRow must not be null.', - ); - } - return true; - }()), assert(() { if (children.any((TableRow row1) => row1.key != null && children.any((TableRow row2) => row1 != row2 && row1.key == row2.key))) { throw FlutterError( @@ -147,8 +136,8 @@ class Table extends RenderObjectWidget { }()), assert(() { if (children.isNotEmpty) { - final int cellCount = children.first.children!.length; - if (children.any((TableRow row) => row.children!.length != cellCount)) { + final int cellCount = children.first.children.length; + if (children.any((TableRow row) => row.children.length != cellCount)) { throw FlutterError( 'Table contains irregular row lengths.\n' 'Every TableRow in a Table must have the same number of children, so that every cell is filled. ' @@ -162,7 +151,7 @@ class Table extends RenderObjectWidget { ? children.map((TableRow row) => row.decoration).toList(growable: false) : null { assert(() { - final List flatChildren = children.expand((TableRow row) => row.children!).toList(growable: false); + final List flatChildren = children.expand((TableRow row) => row.children).toList(growable: false); return !debugChildrenHaveDuplicateKeys(this, flatChildren, message: 'Two or more cells in this Table contain widgets with the same key.\n' 'Every widget child of every TableRow in a Table must have different keys. The cells of a Table are ' @@ -238,7 +227,7 @@ class Table extends RenderObjectWidget { RenderTable createRenderObject(BuildContext context) { assert(debugCheckHasDirectionality(context)); return RenderTable( - columns: children.isNotEmpty ? children[0].children!.length : 0, + columns: children.isNotEmpty ? children[0].children.length : 0, rows: children.length, columnWidths: columnWidths, defaultColumnWidth: defaultColumnWidth, @@ -254,7 +243,7 @@ class Table extends RenderObjectWidget { @override void updateRenderObject(BuildContext context, RenderTable renderObject) { assert(debugCheckHasDirectionality(context)); - assert(renderObject.columns == (children.isNotEmpty ? children[0].children!.length : 0)); + assert(renderObject.columns == (children.isNotEmpty ? children[0].children.length : 0)); assert(renderObject.rows == children.length); renderObject ..columnWidths = columnWidths @@ -289,7 +278,7 @@ class _TableElement extends RenderObjectElement { rowIndex += 1; return _TableElementRow( key: row.key, - children: row.children!.map((Widget child) { + children: row.children.map((Widget child) { return inflateWidget(child, _TableSlot(columnIndex++, rowIndex)); }).toList(growable: false), ); @@ -347,12 +336,12 @@ class _TableElement extends RenderObjectElement { oldChildren = const []; } final List<_TableSlot> slots = List<_TableSlot>.generate( - row.children!.length, + row.children.length, (int columnIndex) => _TableSlot(columnIndex, rowIndex), ); newChildren.add(_TableElementRow( key: row.key, - children: updateChildren(oldChildren, row.children!, forgottenChildren: _forgottenChildren, slots: slots), + children: updateChildren(oldChildren, row.children, forgottenChildren: _forgottenChildren, slots: slots), )); } while (oldUnkeyedRows.moveNext()) { diff --git a/packages/flutter/test/widgets/table_test.dart b/packages/flutter/test/widgets/table_test.dart index ea9fc30ed933..ecf38d7ccd62 100644 --- a/packages/flutter/test/widgets/table_test.dart +++ b/packages/flutter/test/widgets/table_test.dart @@ -940,7 +940,7 @@ void main() { }); testWidgets( - 'Table widget requires all TableRows to have non-null children', + 'Table widget requires all TableRows to have same number of children', (WidgetTester tester) async { FlutterError? error; try { @@ -959,7 +959,7 @@ void main() { error = e; } finally { expect(error, isNotNull); - expect(error!.toStringDeep(), contains('The children property of TableRow must not be null.')); + expect(error!.toStringDeep(), contains('Table contains irregular row lengths.')); } }, );