Skip to content

Commit 6cb6eef

Browse files
authored
Make Material/CupertinoLocalizations non-nullable (flutter#68807)
1 parent ce3ce20 commit 6cb6eef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+245
-122
lines changed

packages/flutter/lib/src/cupertino/bottom_tab_bar.dart

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
209209

210210
List<Widget> _buildTabItems(BuildContext context) {
211211
final List<Widget> result = <Widget>[];
212-
final CupertinoLocalizations? localizations = CupertinoLocalizations.of(context);
213-
assert(
214-
localizations != null,
215-
'CupertinoTabBar requires a Localizations parent in order to provide an '
216-
'appropriate Semantics hint for tab indexing. A CupertinoApp will '
217-
'provide the DefaultCupertinoLocalizations, or you can instantiate your '
218-
'own Localizations.'
219-
);
212+
final CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
220213

221214
for (int index = 0; index < items.length; index += 1) {
222215
final bool active = index == currentIndex;
@@ -226,7 +219,7 @@ class CupertinoTabBar extends StatelessWidget implements PreferredSizeWidget {
226219
Expanded(
227220
child: Semantics(
228221
selected: active,
229-
hint: localizations!.tabSemanticsLabel(
222+
hint: localizations.tabSemanticsLabel(
230223
tabIndex: index + 1,
231224
tabCount: items.length,
232225
),

packages/flutter/lib/src/cupertino/date_picker.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ class _CupertinoDatePickerDateTimeState extends State<CupertinoDatePicker> {
623623
super.didChangeDependencies();
624624

625625
textDirectionFactor = Directionality.of(context) == TextDirection.ltr ? 1 : -1;
626-
localizations = CupertinoLocalizations.of(context)!;
626+
localizations = CupertinoLocalizations.of(context);
627627

628628
alignCenterLeft = textDirectionFactor == 1 ? Alignment.centerLeft : Alignment.centerRight;
629629
alignCenterRight = textDirectionFactor == 1 ? Alignment.centerRight : Alignment.centerLeft;
@@ -1113,7 +1113,7 @@ class _CupertinoDatePickerDateState extends State<CupertinoDatePicker> {
11131113
super.didChangeDependencies();
11141114

11151115
textDirectionFactor = Directionality.of(context) == TextDirection.ltr ? 1 : -1;
1116-
localizations = CupertinoLocalizations.of(context)!;
1116+
localizations = CupertinoLocalizations.of(context);
11171117

11181118
alignCenterLeft = textDirectionFactor == 1 ? Alignment.centerLeft : Alignment.centerRight;
11191119
alignCenterRight = textDirectionFactor == 1 ? Alignment.centerRight : Alignment.centerLeft;
@@ -1621,7 +1621,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
16211621
super.didChangeDependencies();
16221622

16231623
textDirection = Directionality.of(context)!;
1624-
localizations = CupertinoLocalizations.of(context)!;
1624+
localizations = CupertinoLocalizations.of(context);
16251625

16261626
_measureLabelMetrics();
16271627
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/foundation.dart';
6+
import 'package:flutter/widgets.dart';
7+
8+
import 'localizations.dart';
9+
10+
/// Asserts that the given context has a [Localizations] ancestor that contains
11+
/// a [CupertinoLocalizations] delegate.
12+
///
13+
/// To call this function, use the following pattern, typically in the
14+
/// relevant Widget's build method:
15+
///
16+
/// ```dart
17+
/// assert(debugCheckHasCupertinoLocalizations(context));
18+
/// ```
19+
///
20+
/// Does nothing if asserts are disabled. Always returns true.
21+
bool debugCheckHasCupertinoLocalizations(BuildContext context) {
22+
assert(() {
23+
if (Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations) == null) {
24+
throw FlutterError.fromParts(<DiagnosticsNode>[
25+
ErrorSummary('No CupertinoLocalizations found.'),
26+
ErrorDescription(
27+
'${context.widget.runtimeType} widgets require CupertinoLocalizations '
28+
'to be provided by a Localizations widget ancestor.'
29+
),
30+
ErrorDescription(
31+
'The cupertino library uses Localizations to generate messages, '
32+
'labels, and abbreviations.'
33+
),
34+
ErrorHint(
35+
'To introduce a CupertinoLocalizations, either use a '
36+
'CupertinoApp at the root of your application to include them '
37+
'automatically, or add a Localization widget with a '
38+
'CupertinoLocalizations delegate.'
39+
),
40+
...context.describeMissingAncestor(expectedAncestorType: CupertinoLocalizations)
41+
]);
42+
}
43+
return true;
44+
}());
45+
return true;
46+
}

packages/flutter/lib/src/cupertino/dialog.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class CupertinoAlertDialog extends StatelessWidget {
226226

227227
@override
228228
Widget build(BuildContext context) {
229-
final CupertinoLocalizations localizations = CupertinoLocalizations.of(context)!;
229+
final CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
230230
final bool isInAccessibilityMode = _isInAccessibilityMode(context);
231231
final double textScaleFactor = MediaQuery.of(context)!.textScaleFactor;
232232
return CupertinoUserInterfaceLevel(

packages/flutter/lib/src/cupertino/localizations.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import 'package:flutter/foundation.dart';
66
import 'package:flutter/widgets.dart';
77

8-
import 'date_picker.dart';
8+
import 'debug.dart';
99

1010
/// Determines the order of the columns inside [CupertinoDatePicker] in
1111
/// time and date time mode.
@@ -242,17 +242,21 @@ abstract class CupertinoLocalizations {
242242
/// The `CupertinoLocalizations` from the closest [Localizations] instance
243243
/// that encloses the given context.
244244
///
245+
/// If no [CupertinoLocalizations] are available in the given `context`, this
246+
/// method throws an exception.
247+
///
245248
/// This method is just a convenient shorthand for:
246-
/// `Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations)`.
249+
/// `Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations)!`.
247250
///
248251
/// References to the localized resources defined by this class are typically
249252
/// written in terms of this method. For example:
250253
///
251254
/// ```dart
252255
/// CupertinoLocalizations.of(context).anteMeridiemAbbreviation;
253256
/// ```
254-
static CupertinoLocalizations? of(BuildContext context) {
255-
return Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations);
257+
static CupertinoLocalizations of(BuildContext context) {
258+
debugCheckHasCupertinoLocalizations(context);
259+
return Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations)!;
256260
}
257261
}
258262

packages/flutter/lib/src/cupertino/route.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ Future<T?> showCupertinoDialog<T>({
11461146
return showGeneralDialog(
11471147
context: context,
11481148
barrierDismissible: barrierDismissible,
1149-
barrierLabel: CupertinoLocalizations.of(context)!.modalBarrierDismissLabel,
1149+
barrierLabel: CupertinoLocalizations.of(context).modalBarrierDismissLabel,
11501150
barrierColor: CupertinoDynamicColor.resolve(_kModalBarrierColor, context)!,
11511151
// This transition duration was eyeballed comparing with iOS
11521152
transitionDuration: const Duration(milliseconds: 250),

packages/flutter/lib/src/cupertino/text_selection.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class _CupertinoTextSelectionToolbarWrapperState extends State<_CupertinoTextSel
152152
}
153153

154154
final List<Widget> items = <Widget>[];
155-
final CupertinoLocalizations? localizations = CupertinoLocalizations.of(context);
155+
final CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
156156
final EdgeInsets arrowPadding = widget.isArrowPointingDown
157157
? EdgeInsets.only(bottom: _kToolbarArrowSize.height)
158158
: EdgeInsets.only(top: _kToolbarArrowSize.height);
@@ -183,17 +183,17 @@ class _CupertinoTextSelectionToolbarWrapperState extends State<_CupertinoTextSel
183183
}
184184

185185
if (widget.handleCut != null) {
186-
addToolbarButton(localizations!.cutButtonLabel, widget.handleCut!);
186+
addToolbarButton(localizations.cutButtonLabel, widget.handleCut!);
187187
}
188188
if (widget.handleCopy != null) {
189-
addToolbarButton(localizations!.copyButtonLabel, widget.handleCopy!);
189+
addToolbarButton(localizations.copyButtonLabel, widget.handleCopy!);
190190
}
191191
if (widget.handlePaste != null
192192
&& _clipboardStatus.value == ClipboardStatus.pasteable) {
193-
addToolbarButton(localizations!.pasteButtonLabel, widget.handlePaste!);
193+
addToolbarButton(localizations.pasteButtonLabel, widget.handlePaste!);
194194
}
195195
if (widget.handleSelectAll != null) {
196-
addToolbarButton(localizations!.selectAllButtonLabel, widget.handleSelectAll!);
196+
addToolbarButton(localizations.selectAllButtonLabel, widget.handleSelectAll!);
197197
}
198198

199199
return CupertinoTextSelectionToolbar._(

packages/flutter/lib/src/material/about.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class AboutListTile extends StatelessWidget {
201201
assert(debugCheckHasMaterialLocalizations(context));
202202
return ListTile(
203203
leading: icon,
204-
title: child ?? Text(MaterialLocalizations.of(context)!.aboutListTileTitle(
204+
title: child ?? Text(MaterialLocalizations.of(context).aboutListTileTitle(
205205
applicationName ?? _defaultApplicationName(context),
206206
)),
207207
dense: dense,
@@ -405,7 +405,7 @@ class AboutDialog extends StatelessWidget {
405405
),
406406
actions: <Widget>[
407407
TextButton(
408-
child: Text(MaterialLocalizations.of(context)!.viewLicensesButtonLabel),
408+
child: Text(MaterialLocalizations.of(context).viewLicensesButtonLabel),
409409
onPressed: () {
410410
showLicensePage(
411411
context: context,
@@ -417,7 +417,7 @@ class AboutDialog extends StatelessWidget {
417417
},
418418
),
419419
TextButton(
420-
child: Text(MaterialLocalizations.of(context)!.closeButtonLabel),
420+
child: Text(MaterialLocalizations.of(context).closeButtonLabel),
421421
onPressed: () {
422422
Navigator.pop(context);
423423
},
@@ -493,7 +493,7 @@ class _LicensePageState extends State<LicensePage> {
493493
Widget build(BuildContext context) {
494494
return _MasterDetailFlow(
495495
detailPageFABlessGutterWidth: _getGutterSize(context),
496-
title: Text(MaterialLocalizations.of(context)!.licensesPageTitle),
496+
title: Text(MaterialLocalizations.of(context).licensesPageTitle),
497497
detailPageBuilder: _packageLicensePage,
498498
masterViewBuilder: _packagesView,
499499
);
@@ -720,7 +720,7 @@ class _PackageListTile extends StatelessWidget {
720720
color: isSelected ? Theme.of(context)!.highlightColor : Theme.of(context)!.cardColor,
721721
child: ListTile(
722722
title: Text(packageName),
723-
subtitle: Text(MaterialLocalizations.of(context)!.licensesPackageDetailText(numberLicenses)),
723+
subtitle: Text(MaterialLocalizations.of(context).licensesPackageDetailText(numberLicenses)),
724724
selected: isSelected,
725725
onTap: onTap,
726726
),
@@ -890,7 +890,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> {
890890
@override
891891
Widget build(BuildContext context) {
892892
assert(debugCheckHasMaterialLocalizations(context));
893-
final MaterialLocalizations localizations = MaterialLocalizations.of(context)!;
893+
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
894894
final ThemeData? theme = Theme.of(context);
895895
final String title = widget.packageName;
896896
final String subtitle = localizations.licensesPackageDetailText(widget.licenseEntries.length);

packages/flutter/lib/src/material/app_bar.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ class _AppBarState extends State<AppBar> {
543543
leading = IconButton(
544544
icon: const Icon(Icons.menu),
545545
onPressed: _handleDrawerButton,
546-
tooltip: MaterialLocalizations.of(context)!.openAppDrawerTooltip,
546+
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
547547
);
548548
} else {
549549
if (!hasEndDrawer && canPop)
@@ -616,7 +616,7 @@ class _AppBarState extends State<AppBar> {
616616
actions = IconButton(
617617
icon: const Icon(Icons.menu),
618618
onPressed: _handleDrawerButtonEnd,
619-
tooltip: MaterialLocalizations.of(context)!.openAppDrawerTooltip,
619+
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
620620
);
621621
}
622622

packages/flutter/lib/src/material/back_button.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class BackButton extends StatelessWidget {
9898
return IconButton(
9999
icon: const BackButtonIcon(),
100100
color: color,
101-
tooltip: MaterialLocalizations.of(context)!.backButtonTooltip,
101+
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
102102
onPressed: () {
103103
if (onPressed != null) {
104104
onPressed!();
@@ -152,7 +152,7 @@ class CloseButton extends StatelessWidget {
152152
return IconButton(
153153
icon: const Icon(Icons.close),
154154
color: color,
155-
tooltip: MaterialLocalizations.of(context)!.closeButtonTooltip,
155+
tooltip: MaterialLocalizations.of(context).closeButtonTooltip,
156156
onPressed: () {
157157
if (onPressed != null) {
158158
onPressed!();

0 commit comments

Comments
 (0)