Skip to content

Commit 7a4c246

Browse files
Implementing switch expressions: everything in flutter/lib/src/ (#143634)
This PR is the 9�ʰ step in the journey to solve issue #136139 and make the entire Flutter repo more readable. (previous pull requests: #139048, #139882, #141591, #142279, #142634, #142793, #143293, #143496) I did a pass through all of `packages/flutter/lib/src/` and found an abundance of `switch` statements to improve. Whereas #143496 focused on in-depth refactoring, this PR is full of simple, straightforward changes. (I ended up making some more complicated changes in `rendering/` and will file those separately after this PR is done.)
1 parent 3538e4c commit 7a4c246

Some content is hidden

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

50 files changed

+503
-925
lines changed

packages/flutter/lib/src/animation/animation_controller.dart

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -598,20 +598,15 @@ class AnimationController extends Animation<double>
598598
}
599599

600600
TickerFuture _animateToInternal(double target, { Duration? duration, Curve curve = Curves.linear }) {
601-
double scale = 1.0;
602-
if (SemanticsBinding.instance.disableAnimations) {
603-
switch (animationBehavior) {
604-
case AnimationBehavior.normal:
605-
// Since the framework cannot handle zero duration animations, we run it at 5% of the normal
606-
// duration to limit most animations to a single frame.
607-
// Ideally, the framework would be able to handle zero duration animations, however, the common
608-
// pattern of an eternally repeating animation might cause an endless loop if it weren't delayed
609-
// for at least one frame.
610-
scale = 0.05;
611-
case AnimationBehavior.preserve:
612-
break;
613-
}
614-
}
601+
final double scale = switch (animationBehavior) {
602+
// Since the framework cannot handle zero duration animations, we run it at 5% of the normal
603+
// duration to limit most animations to a single frame.
604+
// Ideally, the framework would be able to handle zero duration animations, however, the common
605+
// pattern of an eternally repeating animation might cause an endless loop if it weren't delayed
606+
// for at least one frame.
607+
AnimationBehavior.normal when SemanticsBinding.instance.disableAnimations => 0.05,
608+
AnimationBehavior.normal || AnimationBehavior.preserve => 1.0,
609+
};
615610
Duration? simulationDuration = duration;
616611
if (simulationDuration == null) {
617612
assert(!(this.duration == null && _direction == _AnimationDirection.forward));
@@ -721,16 +716,12 @@ class AnimationController extends Animation<double>
721716
_direction = velocity < 0.0 ? _AnimationDirection.reverse : _AnimationDirection.forward;
722717
final double target = velocity < 0.0 ? lowerBound - _kFlingTolerance.distance
723718
: upperBound + _kFlingTolerance.distance;
724-
double scale = 1.0;
725719
final AnimationBehavior behavior = animationBehavior ?? this.animationBehavior;
726-
if (SemanticsBinding.instance.disableAnimations) {
727-
switch (behavior) {
728-
case AnimationBehavior.normal:
729-
scale = 200.0; // This is arbitrary (it was chosen because it worked for the drawer widget).
730-
case AnimationBehavior.preserve:
731-
break;
732-
}
733-
}
720+
final double scale = switch (behavior) {
721+
// This is arbitrary (it was chosen because it worked for the drawer widget).
722+
AnimationBehavior.normal when SemanticsBinding.instance.disableAnimations => 200.0,
723+
AnimationBehavior.normal || AnimationBehavior.preserve => 1.0,
724+
};
734725
final SpringSimulation simulation = SpringSimulation(springDescription, value, target, velocity * scale)
735726
..tolerance = _kFlingTolerance;
736727
assert(

packages/flutter/lib/src/animation/animations.dart

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -425,15 +425,10 @@ class CurvedAnimation extends Animation<double> with AnimationWithParentMixin<do
425425
bool isDisposed = false;
426426

427427
void _updateCurveDirection(AnimationStatus status) {
428-
switch (status) {
429-
case AnimationStatus.dismissed:
430-
case AnimationStatus.completed:
431-
_curveDirection = null;
432-
case AnimationStatus.forward:
433-
_curveDirection ??= AnimationStatus.forward;
434-
case AnimationStatus.reverse:
435-
_curveDirection ??= AnimationStatus.reverse;
436-
}
428+
_curveDirection = switch (status) {
429+
AnimationStatus.dismissed || AnimationStatus.completed => null,
430+
AnimationStatus.forward || AnimationStatus.reverse => _curveDirection ?? status,
431+
};
437432
}
438433

439434
bool get _useForwardCurve {
@@ -584,12 +579,10 @@ class TrainHoppingAnimation extends Animation<double>
584579
bool hop = false;
585580
if (_nextTrain != null) {
586581
assert(_mode != null);
587-
switch (_mode!) {
588-
case _TrainHoppingMode.minimize:
589-
hop = _nextTrain!.value <= _currentTrain!.value;
590-
case _TrainHoppingMode.maximize:
591-
hop = _nextTrain!.value >= _currentTrain!.value;
592-
}
582+
hop = switch (_mode!) {
583+
_TrainHoppingMode.minimize => _nextTrain!.value <= _currentTrain!.value,
584+
_TrainHoppingMode.maximize => _nextTrain!.value >= _currentTrain!.value,
585+
};
593586
if (hop) {
594587
_currentTrain!
595588
..removeStatusListener(_statusChangeHandler)

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -414,20 +414,18 @@ class CupertinoDatePicker extends StatefulWidget {
414414
final double itemExtent;
415415

416416
@override
417-
State<StatefulWidget> createState() { // ignore: no_logic_in_create_state, https://github.com/flutter/flutter/issues/70499
418-
// The `time` mode and `dateAndTime` mode of the picker share the time
419-
// columns, so they are placed together to one state.
420-
// The `date` mode has different children and is implemented in a different
421-
// state.
422-
switch (mode) {
423-
case CupertinoDatePickerMode.time:
424-
case CupertinoDatePickerMode.dateAndTime:
425-
return _CupertinoDatePickerDateTimeState();
426-
case CupertinoDatePickerMode.date:
427-
return _CupertinoDatePickerDateState(dateOrder: dateOrder);
428-
case CupertinoDatePickerMode.monthYear:
429-
return _CupertinoDatePickerMonthYearState(dateOrder: dateOrder);
430-
}
417+
State<StatefulWidget> createState() {
418+
// ignore: no_logic_in_create_state, https://github.com/flutter/flutter/issues/70499
419+
return switch (mode) {
420+
// The `time` mode and `dateAndTime` mode of the picker share the time
421+
// columns, so they are placed together to one state.
422+
// The `date` mode has different children and is implemented in a different
423+
// state.
424+
CupertinoDatePickerMode.time => _CupertinoDatePickerDateTimeState(),
425+
CupertinoDatePickerMode.dateAndTime => _CupertinoDatePickerDateTimeState(),
426+
CupertinoDatePickerMode.date => _CupertinoDatePickerDateState(dateOrder: dateOrder),
427+
CupertinoDatePickerMode.monthYear => _CupertinoDatePickerMonthYearState(dateOrder: dateOrder),
428+
};
431429
}
432430

433431
// Estimate the minimum width that each column needs to layout its content.

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

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,12 @@ class _CupertinoListTileState extends State<CupertinoListTile> {
287287
child: widget.title,
288288
);
289289

290-
EdgeInsetsGeometry? padding = widget.padding;
291-
if (padding == null) {
292-
switch (widget._type) {
293-
case _CupertinoListTileType.base:
294-
padding = widget.subtitle == null ? _kPadding : _kPaddingWithSubtitle;
295-
case _CupertinoListTileType.notched:
296-
padding = widget.leading == null ? _kNotchedPaddingWithoutLeading : _kNotchedPadding;
297-
}
298-
}
290+
final EdgeInsetsGeometry padding = widget.padding ?? switch (widget._type) {
291+
_CupertinoListTileType.base when widget.subtitle != null => _kPaddingWithSubtitle,
292+
_CupertinoListTileType.notched when widget.leading != null => _kNotchedPadding,
293+
_CupertinoListTileType.base => _kPadding,
294+
_CupertinoListTileType.notched => _kNotchedPaddingWithoutLeading,
295+
};
299296

300297
Widget? subtitle;
301298
if (widget.subtitle != null) {
@@ -325,13 +322,12 @@ class _CupertinoListTileState extends State<CupertinoListTile> {
325322
backgroundColor = widget.backgroundColorActivated ?? CupertinoColors.systemGrey4.resolveFrom(context);
326323
}
327324

328-
double minHeight;
329-
switch (widget._type) {
330-
case _CupertinoListTileType.base:
331-
minHeight = subtitle == null ? _kMinHeight : _kMinHeightWithSubtitle;
332-
case _CupertinoListTileType.notched:
333-
minHeight = widget.leading == null ? _kNotchedMinHeightWithoutLeading : _kNotchedMinHeight;
334-
}
325+
final double minHeight = switch (widget._type) {
326+
_CupertinoListTileType.base when subtitle != null => _kMinHeightWithSubtitle,
327+
_CupertinoListTileType.notched when widget.leading != null => _kNotchedMinHeight,
328+
_CupertinoListTileType.base => _kMinHeight,
329+
_CupertinoListTileType.notched => _kNotchedMinHeightWithoutLeading,
330+
};
335331

336332
final Widget child = Container(
337333
constraints: BoxConstraints(minWidth: double.infinity, minHeight: minHeight),

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -975,16 +975,10 @@ class _CupertinoEdgeShadowPainter extends BoxPainter {
975975

976976
final TextDirection? textDirection = configuration.textDirection;
977977
assert(textDirection != null);
978-
final double start;
979-
final double shadowDirection; // -1 for ltr, 1 for rtl.
980-
switch (textDirection!) {
981-
case TextDirection.rtl:
982-
start = offset.dx + configuration.size!.width;
983-
shadowDirection = 1;
984-
case TextDirection.ltr:
985-
start = offset.dx;
986-
shadowDirection = -1;
987-
}
978+
final (double shadowDirection, double start) = switch (textDirection!) {
979+
TextDirection.rtl => (1, offset.dx + configuration.size!.width),
980+
TextDirection.ltr => (-1, offset.dx),
981+
};
988982

989983
int bandColorIndex = 0;
990984
for (int dx = 0; dx < shadowWidth; dx += 1) {

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,10 @@ class _CupertinoScrollbarState extends RawScrollbarState<CupertinoScrollbar> {
174174
if (direction == null) {
175175
return;
176176
}
177-
switch (direction) {
178-
case Axis.vertical:
179-
_pressStartAxisPosition = localPosition.dy;
180-
case Axis.horizontal:
181-
_pressStartAxisPosition = localPosition.dx;
182-
}
177+
_pressStartAxisPosition = switch (direction) {
178+
Axis.vertical => localPosition.dy,
179+
Axis.horizontal => localPosition.dx,
180+
};
183181
}
184182

185183
@override

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -503,19 +503,10 @@ class _RenderCupertinoSlider extends RenderConstrainedBox implements MouseTracke
503503

504504
@override
505505
void paint(PaintingContext context, Offset offset) {
506-
final double visualPosition;
507-
final Color leftColor;
508-
final Color rightColor;
509-
switch (textDirection) {
510-
case TextDirection.rtl:
511-
visualPosition = 1.0 - _position.value;
512-
leftColor = _activeColor;
513-
rightColor = trackColor;
514-
case TextDirection.ltr:
515-
visualPosition = _position.value;
516-
leftColor = trackColor;
517-
rightColor = _activeColor;
518-
}
506+
final (double visualPosition, Color leftColor, Color rightColor) = switch (textDirection) {
507+
TextDirection.rtl => (1.0 - _position.value, _activeColor, trackColor),
508+
TextDirection.ltr => (_position.value, trackColor, _activeColor),
509+
};
519510

520511
final double trackCenter = offset.dy + size.height / 2.0;
521512
final double trackLeft = offset.dx + _trackLeft;

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -429,12 +429,10 @@ class _RenderButtonBarRow extends RenderFlex {
429429
}
430430
}
431431
currentHeight += child.size.height;
432-
switch (verticalDirection) {
433-
case VerticalDirection.down:
434-
child = childParentData.nextSibling;
435-
case VerticalDirection.up:
436-
child = childParentData.previousSibling;
437-
}
432+
child = switch (verticalDirection) {
433+
VerticalDirection.down => childParentData.nextSibling,
434+
VerticalDirection.up => childParentData.previousSibling,
435+
};
438436

439437
if (overflowButtonSpacing != null && child != null) {
440438
currentHeight += overflowButtonSpacing!;

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -617,21 +617,11 @@ class ButtonThemeData with Diagnosticable {
617617
/// [getTextTheme] is [ButtonTextTheme.primary], 16.0 on the left and right
618618
/// otherwise.
619619
EdgeInsetsGeometry getPadding(MaterialButton button) {
620-
if (button.padding != null) {
621-
return button.padding!;
622-
}
623-
624-
if (_padding != null) {
625-
return _padding;
626-
}
627-
628-
switch (getTextTheme(button)) {
629-
case ButtonTextTheme.normal:
630-
case ButtonTextTheme.accent:
631-
return const EdgeInsets.symmetric(horizontal: 16.0);
632-
case ButtonTextTheme.primary:
633-
return const EdgeInsets.symmetric(horizontal: 24.0);
634-
}
620+
return button.padding ?? _padding ?? switch (getTextTheme(button)) {
621+
ButtonTextTheme.normal => const EdgeInsets.symmetric(horizontal: 16.0),
622+
ButtonTextTheme.accent => const EdgeInsets.symmetric(horizontal: 16.0),
623+
ButtonTextTheme.primary => const EdgeInsets.symmetric(horizontal: 24.0),
624+
};
635625
}
636626

637627
/// The shape of the [button]'s [Material].

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,11 @@ class Card extends StatelessWidget {
213213
final CardTheme cardTheme = CardTheme.of(context);
214214
final CardTheme defaults;
215215
if (Theme.of(context).useMaterial3) {
216-
switch (_variant) {
217-
case _CardVariant.elevated:
218-
defaults = _CardDefaultsM3(context);
219-
case _CardVariant.filled:
220-
defaults = _FilledCardDefaultsM3(context);
221-
case _CardVariant.outlined:
222-
defaults = _OutlinedCardDefaultsM3(context);
223-
}
216+
defaults = switch (_variant) {
217+
_CardVariant.elevated => _CardDefaultsM3(context),
218+
_CardVariant.filled => _FilledCardDefaultsM3(context),
219+
_CardVariant.outlined => _OutlinedCardDefaultsM3(context),
220+
};
224221
} else {
225222
defaults = _CardDefaultsM2(context);
226223
}

0 commit comments

Comments
 (0)