Unverified Commit 9d41ddcb authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate some material files to nullsafety (#66985)

* migrate some material files to nullsafety

* fix test_private

* address review comments

* fix private test on windows

* use uri in include entry of analysis_options
parent d3155658
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// Flutter widgets implementing Material Design animated icons.
library material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
part of material_animated_icons;
// The code for drawing animated icons is kept in a private API, as we are not
......@@ -38,9 +36,9 @@ class AnimatedIcon extends StatelessWidget {
/// The [progress] and [icon] arguments must not be null.
/// The [size] and [color] default to the value given by the current [IconTheme].
const AnimatedIcon({
Key key,
@required this.icon,
@required this.progress,
Key? key,
required this.icon,
required this.progress,
this.color,
this.size,
this.semanticLabel,
......@@ -71,14 +69,14 @@ class AnimatedIcon extends StatelessWidget {
///
/// See [Theme] to set the current theme and [ThemeData.brightness]
/// for setting the current theme's brightness.
final Color color;
final Color? color;
/// The size of the icon in logical pixels.
///
/// Icons occupy a square with width and height equal to size.
///
/// Defaults to the current [IconTheme] size.
final double size;
final double? size;
/// The icon to display. Available icons are listed in [AnimatedIcons].
final AnimatedIconData icon;
......@@ -92,7 +90,7 @@ class AnimatedIcon extends StatelessWidget {
///
/// * [SemanticsProperties.label], which is set to [semanticLabel] in the
/// underlying [Semantics] widget.
final String semanticLabel;
final String? semanticLabel;
/// The text direction to use for rendering the icon.
///
......@@ -100,18 +98,20 @@ class AnimatedIcon extends StatelessWidget {
///
/// If the text direction is [TextDirection.rtl], the icon will be mirrored
/// horizontally (e.g back arrow will point right).
final TextDirection textDirection;
final TextDirection? textDirection;
static final _UiPathFactory _pathFactory = () => ui.Path();
@override
Widget build(BuildContext context) {
assert(debugCheckHasDirectionality(context));
final _AnimatedIconData iconData = icon as _AnimatedIconData;
final IconThemeData iconTheme = IconTheme.of(context);
final double iconSize = size ?? iconTheme.size;
final TextDirection textDirection = this.textDirection ?? Directionality.of(context);
final double iconOpacity = iconTheme.opacity;
Color iconColor = color ?? iconTheme.color;
assert(iconTheme.isConcrete);
final double iconSize = size ?? iconTheme.size!;
final TextDirection textDirection = this.textDirection ?? Directionality.of(context)!;
final double iconOpacity = iconTheme.opacity!;
Color iconColor = color ?? iconTheme.color!;
if (iconOpacity != 1.0)
iconColor = iconColor.withOpacity(iconColor.opacity * iconOpacity);
return Semantics(
......@@ -135,12 +135,12 @@ typedef _UiPathFactory = ui.Path Function();
class _AnimatedIconPainter extends CustomPainter {
_AnimatedIconPainter({
@required this.paths,
@required this.progress,
@required this.color,
@required this.scale,
@required this.shouldMirror,
@required this.uiPathFactory,
required this.paths,
required this.progress,
required this.color,
required this.scale,
required this.shouldMirror,
required this.uiPathFactory,
}) : super(repaint: progress);
// This list is assumed to be immutable, changes to the contents of the list
......@@ -163,7 +163,7 @@ class _AnimatedIconPainter extends CustomPainter {
canvas.translate(-size.width, -size.height);
}
final double clampedProgress = progress.value.clamp(0.0, 1.0) as double;
final double clampedProgress = progress.value.clamp(0.0, 1.0);
for (final _PathFrames path in paths)
path.paint(canvas, color, uiPathFactory, clampedProgress);
}
......@@ -181,26 +181,26 @@ class _AnimatedIconPainter extends CustomPainter {
}
@override
bool hitTest(Offset position) => null;
bool? hitTest(Offset position) => null;
@override
bool shouldRebuildSemantics(CustomPainter oldDelegate) => false;
@override
SemanticsBuilderCallback get semanticsBuilder => null;
SemanticsBuilderCallback? get semanticsBuilder => null;
}
class _PathFrames {
const _PathFrames({
@required this.commands,
@required this.opacities,
required this.commands,
required this.opacities,
});
final List<_PathCommand> commands;
final List<double> opacities;
void paint(ui.Canvas canvas, Color color, _UiPathFactory uiPathFactory, double progress) {
final double opacity = _interpolate<double>(opacities, progress, lerpDouble);
final double opacity = _interpolate<double?>(opacities, progress, lerpDouble)!;
final ui.Paint paint = ui.Paint()
..style = PaintingStyle.fill
..color = color.withOpacity(color.opacity * opacity);
......@@ -232,7 +232,7 @@ class _PathMoveTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset offset = _interpolate<Offset>(points, progress, Offset.lerp);
final Offset offset = _interpolate<Offset?>(points, progress, Offset.lerp)!;
path.moveTo(offset.dx, offset.dy);
}
}
......@@ -246,9 +246,9 @@ class _PathCubicTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset controlPoint1 = _interpolate<Offset>(controlPoints1, progress, Offset.lerp);
final Offset controlPoint2 = _interpolate<Offset>(controlPoints2, progress, Offset.lerp);
final Offset targetPoint = _interpolate<Offset>(targetPoints, progress, Offset.lerp);
final Offset controlPoint1 = _interpolate<Offset?>(controlPoints1, progress, Offset.lerp)!;
final Offset controlPoint2 = _interpolate<Offset?>(controlPoints2, progress, Offset.lerp)!;
final Offset targetPoint = _interpolate<Offset?>(targetPoints, progress, Offset.lerp)!;
path.cubicTo(
controlPoint1.dx, controlPoint1.dy,
controlPoint2.dx, controlPoint2.dy,
......@@ -265,7 +265,7 @@ class _PathLineTo extends _PathCommand {
@override
void apply(Path path, double progress) {
final Offset point = _interpolate<Offset>(points, progress, Offset.lerp);
final Offset point = _interpolate<Offset?>(points, progress, Offset.lerp)!;
path.lineTo(point.dx, point.dy);
}
}
......@@ -295,7 +295,7 @@ T _interpolate<T>(List<T> values, double progress, _Interpolator<T> interpolator
assert(progress >= 0.0);
if (values.length == 1)
return values[0];
final double targetIdx = lerpDouble(0, values.length -1, progress);
final double targetIdx = lerpDouble(0, values.length -1, progress)!;
final int lowIdx = targetIdx.floor();
final int highIdx = targetIdx.ceil();
final double t = targetIdx - lowIdx;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This file serves as the interface between the public and private APIs for
// animated icons.
// The AnimatedIcons class is public and is used to specify available icons,
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// AUTOGENERATED FILE DO NOT EDIT!
// This file was generated by vitool.
part of material_animated_icons;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart';
......@@ -61,8 +59,8 @@ class DateTimeRange {
///
/// [start] and [end] must be non-null.
const DateTimeRange({
@required this.start,
@required this.end,
required this.start,
required this.end,
}) : assert(start != null),
assert(end != null);
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'package:flutter/services.dart';
......@@ -102,26 +100,26 @@ const double _inputFormLandscapeHeight = 108.0;
/// * [InputDatePickerFormField], which provides a text input field for entering dates.
///
Future<DateTime> showDatePicker({
@required BuildContext context,
@required DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
required BuildContext context,
required DateTime initialDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar,
SelectableDayPredicate selectableDayPredicate,
String helpText,
String cancelText,
String confirmText,
Locale locale,
SelectableDayPredicate? selectableDayPredicate,
String? helpText,
String? cancelText,
String? confirmText,
Locale? locale,
bool useRootNavigator = true,
RouteSettings routeSettings,
TextDirection textDirection,
TransitionBuilder builder,
RouteSettings? routeSettings,
TextDirection? textDirection,
TransitionBuilder? builder,
DatePickerMode initialDatePickerMode = DatePickerMode.day,
String errorFormatText,
String errorInvalidText,
String fieldHintText,
String fieldLabelText,
String? errorFormatText,
String? errorInvalidText,
String? fieldHintText,
String? fieldLabelText,
}) async {
assert(context != null);
assert(initialDate != null);
......@@ -195,11 +193,11 @@ Future<DateTime> showDatePicker({
class _DatePickerDialog extends StatefulWidget {
_DatePickerDialog({
Key key,
@required DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
DateTime currentDate,
Key? key,
required DateTime initialDate,
required DateTime firstDate,
required DateTime lastDate,
DateTime? currentDate,
this.initialEntryMode = DatePickerEntryMode.calendar,
this.selectableDayPredicate,
this.cancelText,
......@@ -233,7 +231,7 @@ class _DatePickerDialog extends StatefulWidget {
'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.'
);
assert(
selectableDayPredicate == null || selectableDayPredicate(this.initialDate),
selectableDayPredicate == null || selectableDayPredicate!(this.initialDate),
'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate'
);
}
......@@ -253,29 +251,29 @@ class _DatePickerDialog extends StatefulWidget {
final DatePickerEntryMode initialEntryMode;
/// Function to provide full control over which [DateTime] can be selected.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// The text that is displayed on the cancel button.
final String cancelText;
final String? cancelText;
/// The text that is displayed on the confirm button.
final String confirmText;
final String? confirmText;
/// The text that is displayed at the top of the header.
///
/// This is used to indicate to the user what they are selecting a date for.
final String helpText;
final String? helpText;
/// The initial display of the calendar picker.
final DatePickerMode initialCalendarMode;
final String errorFormatText;
final String? errorFormatText;
final String errorInvalidText;
final String? errorInvalidText;
final String fieldHintText;
final String? fieldHintText;
final String fieldLabelText;
final String? fieldLabelText;
@override
_DatePickerDialogState createState() => _DatePickerDialogState();
......@@ -283,9 +281,9 @@ class _DatePickerDialog extends StatefulWidget {
class _DatePickerDialogState extends State<_DatePickerDialog> {
DatePickerEntryMode _entryMode;
DateTime _selectedDate;
bool _autoValidate;
late DatePickerEntryMode _entryMode;
late DateTime _selectedDate;
late bool _autoValidate;
final GlobalKey _calendarPickerKey = GlobalKey();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
......@@ -299,7 +297,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
void _handleOk() {
if (_entryMode == DatePickerEntryMode.input) {
final FormState form = _formKey.currentState;
final FormState form = _formKey.currentState!;
if (!form.validate()) {
setState(() => _autoValidate = true);
return;
......@@ -321,7 +319,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
_entryMode = DatePickerEntryMode.input;
break;
case DatePickerEntryMode.input:
_formKey.currentState.save();
_formKey.currentState!.save();
_entryMode = DatePickerEntryMode.calendar;
break;
}
......@@ -333,7 +331,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
}
Size _dialogSize(BuildContext context) {
final Orientation orientation = MediaQuery.of(context).orientation;
final Orientation orientation = MediaQuery.of(context)!.orientation;
switch (_entryMode) {
case DatePickerEntryMode.calendar:
switch (orientation) {
......@@ -342,7 +340,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
case Orientation.landscape:
return _calendarLandscapeDialogSize;
}
break;
case DatePickerEntryMode.input:
switch (orientation) {
case Orientation.portrait:
......@@ -350,9 +347,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
case Orientation.landscape:
return _inputLandscapeDialogSize;
}
break;
}
return null;
}
static final Map<LogicalKeySet, Intent> _formShortcutMap = <LogicalKeySet, Intent>{
......@@ -362,22 +357,20 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final Orientation orientation = MediaQuery.of(context)!.orientation;
final TextTheme textTheme = theme.textTheme;
// Constrain the textScaleFactor to the largest supported value to prevent
// layout issues.
final double textScaleFactor = math.min(MediaQuery.of(context).textScaleFactor, 1.3);
final double textScaleFactor = math.min(MediaQuery.of(context)!.textScaleFactor, 1.3);
final String dateText = _selectedDate != null
? localizations.formatMediumDate(_selectedDate)
: localizations.unspecifiedDate;
final String dateText = localizations.formatMediumDate(_selectedDate);
final Color dateColor = colorScheme.brightness == Brightness.light
? colorScheme.onPrimary
: colorScheme.onSurface;
final TextStyle dateStyle = orientation == Orientation.landscape
final TextStyle? dateStyle = orientation == Orientation.landscape
? textTheme.headline5?.copyWith(color: dateColor)
: textTheme.headline4?.copyWith(color: dateColor);
......@@ -474,7 +467,7 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
duration: _dialogSizeAnimationDuration,
curve: Curves.easeIn,
child: MediaQuery(
data: MediaQuery.of(context).copyWith(
data: MediaQuery.of(context)!.copyWith(
textScaleFactor: textScaleFactor,
),
child: Builder(builder: (BuildContext context) {
......@@ -508,7 +501,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
],
);
}
return null;
}),
),
),
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/widgets.dart';
import '../color_scheme.dart';
......@@ -35,16 +33,16 @@ const double _headerPaddingLandscape = 16.0;
class DatePickerHeader extends StatelessWidget {
/// Creates a header for use in a date picker dialog.
const DatePickerHeader({
Key key,
@required this.helpText,
@required this.titleText,
Key? key,
required this.helpText,
required this.titleText,
this.titleSemanticsLabel,
@required this.titleStyle,
@required this.orientation,
required this.titleStyle,
required this.orientation,
this.isShort = false,
@required this.icon,
@required this.iconTooltip,
@required this.onIconPressed,
required this.icon,
required this.iconTooltip,
required this.onIconPressed,
}) : assert(helpText != null),
assert(orientation != null),
assert(isShort != null),
......@@ -59,10 +57,10 @@ class DatePickerHeader extends StatelessWidget {
final String titleText;
/// The semantic label associated with the [titleText].
final String titleSemanticsLabel;
final String? titleSemanticsLabel;
/// The [TextStyle] that the title text is displayed with.
final TextStyle titleStyle;
final TextStyle? titleStyle;
/// The orientation is used to decide how to layout its children.
final Orientation orientation;
......@@ -93,7 +91,7 @@ class DatePickerHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ThemeData theme = Theme.of(context)!;
final ColorScheme colorScheme = theme.colorScheme;
final TextTheme textTheme = theme.textTheme;
......@@ -102,7 +100,7 @@ class DatePickerHeader extends StatelessWidget {
final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary;
final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary;
final TextStyle helpStyle = textTheme.overline?.copyWith(
final TextStyle? helpStyle = textTheme.overline?.copyWith(
color: onPrimarySurfaceColor,
);
......@@ -189,6 +187,5 @@ class DatePickerHeader extends StatelessWidget {
),
);
}
return null;
}
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// Common date utility functions used by the date picker implementation
// This is an internal implementation file. Even though there are public
......@@ -27,7 +25,7 @@ DateTimeRange datesOnly(DateTimeRange range) {
/// Returns true if the two [DateTime] objects have the same day, month, and
/// year, or are both null.
bool isSameDay(DateTime dateA, DateTime dateB) {
bool isSameDay(DateTime? dateA, DateTime? dateB) {
return
dateA?.year == dateB?.year &&
dateA?.month == dateB?.month &&
......@@ -36,7 +34,7 @@ bool isSameDay(DateTime dateA, DateTime dateB) {
/// Returns true if the two [DateTime] objects have the same month, and
/// year, or are both null.
bool isSameMonth(DateTime dateA, DateTime dateB) {
bool isSameMonth(DateTime? dateA, DateTime? dateB) {
return
dateA?.year == dateB?.year &&
dateA?.month == dateB?.month;
......@@ -148,7 +146,7 @@ int getDaysInMonth(int year, int month) {
/// is in the same year as the `endDate` then it will use the short month
/// day format (i.e. 'Jan 21'). Otherwise it will return the short date format
/// (i.e. 'Jan 21, 2020').
String formatRangeStartDate(MaterialLocalizations localizations, DateTime startDate, DateTime endDate) {
String formatRangeStartDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate) {
return startDate == null
? localizations.dateRangeStartLabel
: (endDate == null || startDate.year == endDate.year)
......@@ -162,7 +160,7 @@ String formatRangeStartDate(MaterialLocalizations localizations, DateTime startD
/// is in the same year as the `startDate` and the `currentDate` then it will
/// just use the short month day format (i.e. 'Jan 21'), otherwise it will
/// include the year (i.e. 'Jan 21, 2020').
String formatRangeEndDate(MaterialLocalizations localizations, DateTime startDate, DateTime endDate, DateTime currentDate) {
String formatRangeEndDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate, DateTime currentDate) {
return endDate == null
? localizations.dateRangeEndLabel
: (startDate != null && startDate.year == endDate.year && startDate.year == currentDate.year)
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
......@@ -50,10 +48,10 @@ class InputDatePickerFormField extends StatefulWidget {
/// [firstDate], [lastDate], and [autofocus] must be non-null.
///
InputDatePickerFormField({
Key key,
DateTime initialDate,
@required DateTime firstDate,
@required DateTime lastDate,
Key? key,
DateTime? initialDate,
required DateTime firstDate,
required DateTime lastDate,
this.onDateSubmitted,
this.onDateSaved,
this.selectableDayPredicate,
......@@ -74,21 +72,21 @@ class InputDatePickerFormField extends StatefulWidget {
'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.'
);
assert(
initialDate == null || !this.initialDate.isBefore(this.firstDate),
initialDate == null || !this.initialDate!.isBefore(this.firstDate),
'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.'
);
assert(
initialDate == null || !this.initialDate.isAfter(this.lastDate),
initialDate == null || !this.initialDate!.isAfter(this.lastDate),
'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.'
);
assert(
selectableDayPredicate == null || initialDate == null || selectableDayPredicate(this.initialDate),
selectableDayPredicate == null || initialDate == null || selectableDayPredicate!(this.initialDate!),
'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate.'
);
}
/// If provided, it will be used as the default value of the field.
final DateTime initialDate;
final DateTime? initialDate;
/// The earliest allowable [DateTime] that the user can input.
final DateTime firstDate;
......@@ -99,36 +97,36 @@ class InputDatePickerFormField extends StatefulWidget {
/// An optional method to call when the user indicates they are done editing
/// the text in the field. Will only be called if the input represents a valid
/// [DateTime].
final ValueChanged<DateTime> onDateSubmitted;
final ValueChanged<DateTime>? onDateSubmitted;
/// An optional method to call with the final date when the form is
/// saved via [FormState.save]. Will only be called if the input represents
/// a valid [DateTime].
final ValueChanged<DateTime> onDateSaved;
final ValueChanged<DateTime>? onDateSaved;
/// Function to provide full control over which [DateTime] can be selected.
final SelectableDayPredicate selectableDayPredicate;
final SelectableDayPredicate? selectableDayPredicate;
/// The error text displayed if the entered date is not in the correct format.
final String errorFormatText;
final String? errorFormatText;
/// The error text displayed if the date is not valid.
///
/// A date is not valid if it is earlier than [firstDate], later than
/// [lastDate], or doesn't pass the [selectableDayPredicate].
final String errorInvalidText;
final String? errorInvalidText;
/// The hint text displayed in the [TextField].
///
/// If this is null, it will default to the date format string. For example,
/// 'mm/dd/yyyy' for en_US.
final String fieldHintText;
final String? fieldHintText;
/// The label text displayed in the [TextField].
///
/// If this is null, it will default to the words representing the date format
/// string. For example, 'Month, Day, Year' for en_US.
final String fieldLabelText;
final String? fieldLabelText;
/// {@macro flutter.widgets.editableText.autofocus}
final bool autofocus;
......@@ -139,8 +137,8 @@ class InputDatePickerFormField extends StatefulWidget {
class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
final TextEditingController _controller = TextEditingController();
DateTime _selectedDate;
String _inputText;
DateTime? _selectedDate;
String? _inputText;
bool _autoSelected = false;
@override
......@@ -159,14 +157,14 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
void didChangeDependencies() {
super.didChangeDependencies();
if (_selectedDate != null) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
_inputText = localizations.formatCompactDate(_selectedDate);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
_inputText = localizations.formatCompactDate(_selectedDate!);
TextEditingValue textEditingValue = _controller.value.copyWith(text: _inputText);
// Select the new text if we are auto focused and haven't selected the text before.
if (widget.autofocus && !_autoSelected) {
textEditingValue = textEditingValue.copyWith(selection: TextSelection(
baseOffset: 0,
extentOffset: _inputText.length,
extentOffset: _inputText!.length,
));
_autoSelected = true;
}
......@@ -174,55 +172,55 @@ class _InputDatePickerFormFieldState extends State<InputDatePickerFormField> {
}
}
DateTime _parseDate(String text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
DateTime? _parseDate(String? text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
return localizations.parseCompactDate(text);
}
bool _isValidAcceptableDate(DateTime date) {
bool _isValidAcceptableDate(DateTime? date) {
return
date != null &&
!date.isBefore(widget.firstDate) &&
!date.isAfter(widget.lastDate) &&
(widget.selectableDayPredicate == null || widget.selectableDayPredicate(date));
(widget.selectableDayPredicate == null || widget.selectableDayPredicate!(date));
}
String _validateDate(String text) {
final DateTime date = _parseDate(text);
String? _validateDate(String? text) {
final DateTime? date = _parseDate(text);
if (date == null) {
return widget.errorFormatText ?? MaterialLocalizations.of(context).invalidDateFormatLabel;
return widget.errorFormatText ?? MaterialLocalizations.of(context)!.invalidDateFormatLabel;
} else if (!_isValidAcceptableDate(date)) {
return widget.errorInvalidText ?? MaterialLocalizations.of(context).dateOutOfRangeLabel;
return widget.errorInvalidText ?? MaterialLocalizations.of(context)!.dateOutOfRangeLabel;
}
return null;
}
void _handleSaved(String text) {
void _handleSaved(String? text) {
if (widget.onDateSaved != null) {
final DateTime date = _parseDate(text);
final DateTime? date = _parseDate(text);
if (_isValidAcceptableDate(date)) {
_selectedDate = date;
_inputText = text;
widget.onDateSaved(date);
widget.onDateSaved!(date!);
}
}
}
void _handleSubmitted(String text) {
if (widget.onDateSubmitted != null) {
final DateTime date = _parseDate(text);
final DateTime? date = _parseDate(text);
if (_isValidAcceptableDate(date)) {
_selectedDate = date;
_inputText = text;
widget.onDateSubmitted(date);
widget.onDateSubmitted!(date!);
}
}
}
@override
Widget build(BuildContext context) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final InputDecorationTheme inputTheme = Theme.of(context)!.inputDecorationTheme;
return TextFormField(
decoration: InputDecoration(
border: inputTheme.border ?? const UnderlineInputBorder(),
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
......@@ -24,13 +22,13 @@ class InputDateRangePicker extends StatefulWidget {
/// Creates a row with two text fields configured to accept the start and end dates
/// of a date range.
InputDateRangePicker({
Key key,
DateTime initialStartDate,
DateTime initialEndDate,
@required DateTime firstDate,
@required DateTime lastDate,
@required this.onStartDateChanged,
@required this.onEndDateChanged,
Key? key,
DateTime? initialStartDate,
DateTime? initialEndDate,
required DateTime firstDate,
required DateTime lastDate,
required this.onStartDateChanged,
required this.onEndDateChanged,
this.helpText,
this.errorFormatText,
this.errorInvalidText,
......@@ -54,10 +52,10 @@ class InputDateRangePicker extends StatefulWidget {
super(key: key);
/// The [DateTime] that represents the start of the initial date range selection.
final DateTime initialStartDate;
final DateTime? initialStartDate;
/// The [DateTime] that represents the end of the initial date range selection.
final DateTime initialEndDate;
final DateTime? initialEndDate;
/// The earliest allowable [DateTime] that the user can select.
final DateTime firstDate;
......@@ -66,38 +64,38 @@ class InputDateRangePicker extends StatefulWidget {
final DateTime lastDate;
/// Called when the user changes the start date of the selected range.
final ValueChanged<DateTime> onStartDateChanged;
final ValueChanged<DateTime>? onStartDateChanged;
/// Called when the user changes the end date of the selected range.
final ValueChanged<DateTime> onEndDateChanged;
final ValueChanged<DateTime>? onEndDateChanged;
/// The text that is displayed at the top of the header.
///
/// This is used to indicate to the user what they are selecting a date for.
final String helpText;
final String? helpText;
/// Error text used to indicate the text in a field is not a valid date.
final String errorFormatText;
final String? errorFormatText;
/// Error text used to indicate the date in a field is not in the valid range
/// of [firstDate] - [lastDate].
final String errorInvalidText;
final String? errorInvalidText;
/// Error text used to indicate the dates given don't form a valid date
/// range (i.e. the start date is after the end date).
final String errorInvalidRangeText;
final String? errorInvalidRangeText;
/// Hint text shown when the start date field is empty.
final String fieldStartHintText;
final String? fieldStartHintText;
/// Hint text shown when the end date field is empty.
final String fieldEndHintText;
final String? fieldEndHintText;
/// Label used for the start date field.
final String fieldStartLabelText;
final String? fieldStartLabelText;
/// Label used for the end date field.
final String fieldEndLabelText;
final String? fieldEndLabelText;
/// {@macro flutter.widgets.editableText.autofocus}
final bool autofocus;
......@@ -114,14 +112,14 @@ class InputDateRangePicker extends StatefulWidget {
/// The current state of an [InputDateRangePicker]. Can be used to
/// [validate] the date field entries.
class InputDateRangePickerState extends State<InputDateRangePicker> {
String _startInputText;
String _endInputText;
DateTime _startDate;
DateTime _endDate;
TextEditingController _startController;
TextEditingController _endController;
String _startErrorText;
String _endErrorText;
late String _startInputText;
late String _endInputText;
DateTime? _startDate;
DateTime? _endDate;
late TextEditingController _startController;
late TextEditingController _endController;
String? _startErrorText;
String? _endErrorText;
bool _autoSelected = false;
@override
......@@ -143,16 +141,16 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
if (_startDate != null) {
_startInputText = localizations.formatCompactDate(_startDate);
_startInputText = localizations.formatCompactDate(_startDate!);
final bool selectText = widget.autofocus && !_autoSelected;
_updateController(_startController, _startInputText, selectText);
_autoSelected = selectText;
}
if (_endDate != null) {
_endInputText = localizations.formatCompactDate(_endDate);
_endInputText = localizations.formatCompactDate(_endDate!);
_updateController(_endController, _endInputText, false);
}
}
......@@ -164,11 +162,11 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
/// return false and display an appropriate error message under one of the
/// text fields.
bool validate() {
String startError = _validateDate(_startDate);
final String endError = _validateDate(_endDate);
String? startError = _validateDate(_startDate);
final String? endError = _validateDate(_endDate);
if (startError == null && endError == null) {
if (_startDate.isAfter(_endDate)) {
startError = widget.errorInvalidRangeText ?? MaterialLocalizations.of(context).invalidDateRangeLabel;
if (_startDate!.isAfter(_endDate!)) {
startError = widget.errorInvalidRangeText ?? MaterialLocalizations.of(context)!.invalidDateRangeLabel;
}
}
setState(() {
......@@ -178,16 +176,16 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
return startError == null && endError == null;
}
DateTime _parseDate(String text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
DateTime? _parseDate(String? text) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
return localizations.parseCompactDate(text);
}
String _validateDate(DateTime date) {
String? _validateDate(DateTime? date) {
if (date == null) {
return widget.errorFormatText ?? MaterialLocalizations.of(context).invalidDateFormatLabel;
return widget.errorFormatText ?? MaterialLocalizations.of(context)!.invalidDateFormatLabel;
} else if (date.isBefore(widget.firstDate) || date.isAfter(widget.lastDate)) {
return widget.errorInvalidText ?? MaterialLocalizations.of(context).dateOutOfRangeLabel;
return widget.errorInvalidText ?? MaterialLocalizations.of(context)!.dateOutOfRangeLabel;
}
return null;
}
......@@ -207,7 +205,7 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
setState(() {
_startInputText = text;
_startDate = _parseDate(text);
widget.onStartDateChanged?.call(_startDate);
widget.onStartDateChanged?.call(_startDate!);
});
if (widget.autovalidate) {
validate();
......@@ -218,7 +216,7 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
setState(() {
_endInputText = text;
_endDate = _parseDate(text);
widget.onEndDateChanged?.call(_endDate);
widget.onEndDateChanged?.call(_endDate!);
});
if (widget.autovalidate) {
validate();
......@@ -227,8 +225,8 @@ class InputDateRangePickerState extends State<InputDateRangePicker> {
@override
Widget build(BuildContext context) {
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
final InputDecorationTheme inputTheme = Theme.of(context)!.inputDecorationTheme;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// Date Picker public API
export 'calendar_date_picker.dart' show CalendarDatePicker;
export 'date_picker_common.dart' show
......
......@@ -193,9 +193,9 @@ class TestCase {
makeAbsolute(pubspec, workingDirectory: privateTestsDir)
.copySync(path.join(tmpdir.absolute.path, 'pubspec.yaml'));
// Copy Flutter's analysis_options.yaml file to the root of the tmpdir.
makeAbsolute(File('analysis_options.yaml'), workingDirectory: flutterRoot)
.copySync(path.join(tmpdir.absolute.path, 'analysis_options.yaml'));
// Use Flutter's analysis_options.yaml file from packages/flutter.
File(path.join(tmpdir.absolute.path, 'analysis_options.yaml'))
.writeAsStringSync('include: ${path.toUri(path.join(flutterRoot.path, 'packages', 'flutter', 'analysis_options.yaml'))}');
return true;
}
......@@ -225,7 +225,7 @@ class TestCase {
for (final File test in tests) {
final String testPath = path.join(path.dirname(test.path), 'lib', path.basenameWithoutExtension(test.path));
final ProcessRunnerResult result = await runner.runProcess(
<String>[flutter, 'test', testPath],
<String>[flutter, 'test', '--enable-experiment=non-nullable', '--null-assertions', testPath],
failOk: true,
);
if (result.exitCode != 0) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This is the test for the private implementation of animated icons.
// To make the private API accessible from the test we do not import the
// material material_animated_icons library, but instead, this test file is an
......@@ -17,7 +15,6 @@ import 'dart:ui' as ui show Paint, Path, Canvas;
import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
import 'test/flutter_test_alternative.dart';
......@@ -82,10 +79,10 @@ void main() {
group('_AnimatedIconPainter', () {
const Size size = Size(48.0, 48.0);
MockPath mockPath;
MockCanvas mockCanvas;
List<MockPath> generatedPaths;
_UiPathFactory pathFactory;
late MockPath mockPath;
late MockCanvas mockCanvas;
late List<MockPath> generatedPaths;
late _UiPathFactory pathFactory;
setUp(() {
generatedPaths = <MockPath>[];
......@@ -365,12 +362,12 @@ class MockCall {
final Symbol memberSymbol;
String get memberName {
final RegExp symbolMatch = RegExp(r'Symbol\("(?<name>.*)"\)');
final RegExpMatch match = symbolMatch.firstMatch(memberSymbol.toString());
final RegExpMatch? match = symbolMatch.firstMatch(memberSymbol.toString());
assert(match != null);
return match.namedGroup('name');
return match!.namedGroup('name')!;
}
final List<dynamic> positionalArguments;
final List<dynamic>? positionalArguments;
final bool acceptAny;
@override
......@@ -399,10 +396,10 @@ class Mock {
'${expected[count].memberName} instead.');
if (call.positionalArguments != null && !expected[count].acceptAny) {
int countArg = 0;
for (final dynamic arg in call.positionalArguments) {
expect(arg, equals(expected[count].positionalArguments[countArg]),
for (final dynamic arg in call.positionalArguments!) {
expect(arg, equals(expected[count].positionalArguments![countArg]),
reason: 'Failed at call $count. Positional argument $countArg to ${call.memberName} '
'not as expected. Expected ${expected[count].positionalArguments[countArg]} '
'not as expected. Expected ${expected[count].positionalArguments![countArg]} '
'and received $arg');
countArg++;
}
......
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