Unverified Commit 0417f662 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Fix nullability of TableRow.children (#119285)

* Fix nullablility of TableRow.children

* fix test
parent 0b575967
...@@ -967,7 +967,7 @@ class DataTable extends StatelessWidget { ...@@ -967,7 +967,7 @@ class DataTable extends StatelessWidget {
int displayColumnIndex = 0; int displayColumnIndex = 0;
if (displayCheckboxColumn) { if (displayCheckboxColumn) {
tableColumns[0] = FixedColumnWidth(effectiveCheckboxHorizontalMarginStart + Checkbox.width + effectiveCheckboxHorizontalMarginEnd); tableColumns[0] = FixedColumnWidth(effectiveCheckboxHorizontalMarginStart + Checkbox.width + effectiveCheckboxHorizontalMarginEnd);
tableRows[0].children![0] = _buildCheckbox( tableRows[0].children[0] = _buildCheckbox(
context: context, context: context,
checked: someChecked ? null : allChecked, checked: someChecked ? null : allChecked,
onRowTap: null, onRowTap: null,
...@@ -977,7 +977,7 @@ class DataTable extends StatelessWidget { ...@@ -977,7 +977,7 @@ class DataTable extends StatelessWidget {
); );
rowIndex = 1; rowIndex = 1;
for (final DataRow row in rows) { for (final DataRow row in rows) {
tableRows[rowIndex].children![0] = _buildCheckbox( tableRows[rowIndex].children[0] = _buildCheckbox(
context: context, context: context,
checked: row.selected, checked: row.selected,
onRowTap: row.onSelectChanged == null ? null : () => row.onSelectChanged?.call(!row.selected), onRowTap: row.onSelectChanged == null ? null : () => row.onSelectChanged?.call(!row.selected),
...@@ -1020,7 +1020,7 @@ class DataTable extends StatelessWidget { ...@@ -1020,7 +1020,7 @@ class DataTable extends StatelessWidget {
} else { } else {
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth(); tableColumns[displayColumnIndex] = const IntrinsicColumnWidth();
} }
tableRows[0].children![displayColumnIndex] = _buildHeadingCell( tableRows[0].children[displayColumnIndex] = _buildHeadingCell(
context: context, context: context,
padding: padding, padding: padding,
label: column.label, label: column.label,
...@@ -1034,7 +1034,7 @@ class DataTable extends StatelessWidget { ...@@ -1034,7 +1034,7 @@ class DataTable extends StatelessWidget {
rowIndex = 1; rowIndex = 1;
for (final DataRow row in rows) { for (final DataRow row in rows) {
final DataCell cell = row.cells[dataColumnIndex]; final DataCell cell = row.cells[dataColumnIndex];
tableRows[rowIndex].children![displayColumnIndex] = _buildDataCell( tableRows[rowIndex].children[displayColumnIndex] = _buildDataCell(
context: context, context: context,
padding: padding, padding: padding,
label: cell.child, label: cell.child,
......
...@@ -32,7 +32,7 @@ export 'package:flutter/rendering.dart' show ...@@ -32,7 +32,7 @@ export 'package:flutter/rendering.dart' show
@immutable @immutable
class TableRow { class TableRow {
/// Creates a row in a [Table]. /// Creates a row in a [Table].
const TableRow({ this.key, this.decoration, this.children }); const TableRow({ this.key, this.decoration, this.children = const <Widget>[]});
/// An identifier for the row. /// An identifier for the row.
final LocalKey? key; final LocalKey? key;
...@@ -49,7 +49,7 @@ class TableRow { ...@@ -49,7 +49,7 @@ class TableRow {
/// Children may be wrapped in [TableCell] widgets to provide per-cell /// Children may be wrapped in [TableCell] widgets to provide per-cell
/// configuration to the [Table], but children are not required to be wrapped /// configuration to the [Table], but children are not required to be wrapped
/// in [TableCell] widgets. /// in [TableCell] widgets.
final List<Widget>? children; final List<Widget> children;
@override @override
String toString() { String toString() {
...@@ -61,9 +61,7 @@ class TableRow { ...@@ -61,9 +61,7 @@ class TableRow {
if (decoration != null) { if (decoration != null) {
result.write('$decoration, '); result.write('$decoration, ');
} }
if (children == null) { if (children.isEmpty) {
result.write('child list is null');
} else if (children!.isEmpty) {
result.write('no children'); result.write('no children');
} else { } else {
result.write('$children'); result.write('$children');
...@@ -127,15 +125,6 @@ class Table extends RenderObjectWidget { ...@@ -127,15 +125,6 @@ class Table extends RenderObjectWidget {
this.defaultVerticalAlignment = TableCellVerticalAlignment.top, this.defaultVerticalAlignment = TableCellVerticalAlignment.top,
this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be 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(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(() { assert(() {
if (children.any((TableRow row1) => row1.key != null && children.any((TableRow row2) => row1 != row2 && row1.key == row2.key))) { if (children.any((TableRow row1) => row1.key != null && children.any((TableRow row2) => row1 != row2 && row1.key == row2.key))) {
throw FlutterError( throw FlutterError(
...@@ -147,8 +136,8 @@ class Table extends RenderObjectWidget { ...@@ -147,8 +136,8 @@ class Table extends RenderObjectWidget {
}()), }()),
assert(() { assert(() {
if (children.isNotEmpty) { if (children.isNotEmpty) {
final int cellCount = children.first.children!.length; final int cellCount = children.first.children.length;
if (children.any((TableRow row) => row.children!.length != cellCount)) { if (children.any((TableRow row) => row.children.length != cellCount)) {
throw FlutterError( throw FlutterError(
'Table contains irregular row lengths.\n' 'Table contains irregular row lengths.\n'
'Every TableRow in a Table must have the same number of children, so that every cell is filled. ' '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 { ...@@ -162,7 +151,7 @@ class Table extends RenderObjectWidget {
? children.map<Decoration?>((TableRow row) => row.decoration).toList(growable: false) ? children.map<Decoration?>((TableRow row) => row.decoration).toList(growable: false)
: null { : null {
assert(() { assert(() {
final List<Widget> flatChildren = children.expand<Widget>((TableRow row) => row.children!).toList(growable: false); final List<Widget> flatChildren = children.expand<Widget>((TableRow row) => row.children).toList(growable: false);
return !debugChildrenHaveDuplicateKeys(this, flatChildren, message: return !debugChildrenHaveDuplicateKeys(this, flatChildren, message:
'Two or more cells in this Table contain widgets with the same key.\n' '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 ' '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 { ...@@ -238,7 +227,7 @@ class Table extends RenderObjectWidget {
RenderTable createRenderObject(BuildContext context) { RenderTable createRenderObject(BuildContext context) {
assert(debugCheckHasDirectionality(context)); assert(debugCheckHasDirectionality(context));
return RenderTable( return RenderTable(
columns: children.isNotEmpty ? children[0].children!.length : 0, columns: children.isNotEmpty ? children[0].children.length : 0,
rows: children.length, rows: children.length,
columnWidths: columnWidths, columnWidths: columnWidths,
defaultColumnWidth: defaultColumnWidth, defaultColumnWidth: defaultColumnWidth,
...@@ -254,7 +243,7 @@ class Table extends RenderObjectWidget { ...@@ -254,7 +243,7 @@ class Table extends RenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, RenderTable renderObject) { void updateRenderObject(BuildContext context, RenderTable renderObject) {
assert(debugCheckHasDirectionality(context)); 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); assert(renderObject.rows == children.length);
renderObject renderObject
..columnWidths = columnWidths ..columnWidths = columnWidths
...@@ -289,7 +278,7 @@ class _TableElement extends RenderObjectElement { ...@@ -289,7 +278,7 @@ class _TableElement extends RenderObjectElement {
rowIndex += 1; rowIndex += 1;
return _TableElementRow( return _TableElementRow(
key: row.key, key: row.key,
children: row.children!.map<Element>((Widget child) { children: row.children.map<Element>((Widget child) {
return inflateWidget(child, _TableSlot(columnIndex++, rowIndex)); return inflateWidget(child, _TableSlot(columnIndex++, rowIndex));
}).toList(growable: false), }).toList(growable: false),
); );
...@@ -347,12 +336,12 @@ class _TableElement extends RenderObjectElement { ...@@ -347,12 +336,12 @@ class _TableElement extends RenderObjectElement {
oldChildren = const <Element>[]; oldChildren = const <Element>[];
} }
final List<_TableSlot> slots = List<_TableSlot>.generate( final List<_TableSlot> slots = List<_TableSlot>.generate(
row.children!.length, row.children.length,
(int columnIndex) => _TableSlot(columnIndex, rowIndex), (int columnIndex) => _TableSlot(columnIndex, rowIndex),
); );
newChildren.add(_TableElementRow( newChildren.add(_TableElementRow(
key: row.key, key: row.key,
children: updateChildren(oldChildren, row.children!, forgottenChildren: _forgottenChildren, slots: slots), children: updateChildren(oldChildren, row.children, forgottenChildren: _forgottenChildren, slots: slots),
)); ));
} }
while (oldUnkeyedRows.moveNext()) { while (oldUnkeyedRows.moveNext()) {
......
...@@ -940,7 +940,7 @@ void main() { ...@@ -940,7 +940,7 @@ void main() {
}); });
testWidgets( 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 { (WidgetTester tester) async {
FlutterError? error; FlutterError? error;
try { try {
...@@ -959,7 +959,7 @@ void main() { ...@@ -959,7 +959,7 @@ void main() {
error = e; error = e;
} finally { } finally {
expect(error, isNotNull); 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.'));
} }
}, },
); );
......
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