Implementing a few switch statements (#150946)

I really like how patterns can be used for variable assignment and avoiding duplicated logic. (related: #150942)

```dart
// before
final GestureRecognizer? recognizer = info.recognizer;
if (recognizer is TapGestureRecognizer) {
  if (recognizer.onTap != null) {
    configuration.onTap = recognizer.onTap;
    configuration.isLink = true;
  }
} else if (recognizer is DoubleTapGestureRecognizer) {
  if (recognizer.onDoubleTap != null) {
    configuration.onTap = recognizer.onDoubleTap;
    configuration.isLink = true;
  }
}

// after
switch (info.recognizer) {
  case TapGestureRecognizer(:final VoidCallback? onTap):
  case DoubleTapGestureRecognizer(onDoubleTap: final VoidCallback? onTap):
    if (onTap != null) {
      configuration.onTap = onTap;
      configuration.isLink = true;
    }
}
```
This commit is contained in:
Nate Wilson 2024-07-01 17:36:32 -06:00 committed by GitHub
parent dbc2dc88bc
commit d07a165d22
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 107 additions and 175 deletions

View File

@ -1884,14 +1884,9 @@ Stream<File> _allFiles(String workingDirectory, String? extension, { required in
if (_isGeneratedPluginRegistrant(entity)) {
continue;
}
if (path.basename(entity.path) == 'flutter_export_environment.sh') {
continue;
}
if (path.basename(entity.path) == 'gradlew.bat') {
continue;
}
if (path.basename(entity.path) == '.DS_Store') {
continue;
switch (path.basename(entity.path)) {
case 'flutter_export_environment.sh' || 'gradlew.bat' || '.DS_Store':
continue;
}
if (extension == null || path.extension(entity.path) == '.$extension') {
matches += 1;
@ -1901,23 +1896,9 @@ Stream<File> _allFiles(String workingDirectory, String? extension, { required in
if (File(path.join(entity.path, '.dartignore')).existsSync()) {
continue;
}
if (path.basename(entity.path) == '.git') {
continue;
}
if (path.basename(entity.path) == '.idea') {
continue;
}
if (path.basename(entity.path) == '.gradle') {
continue;
}
if (path.basename(entity.path) == '.dart_tool') {
continue;
}
if (path.basename(entity.path) == '.idea') {
continue;
}
if (path.basename(entity.path) == 'build') {
continue;
switch (path.basename(entity.path)) {
case '.git' || '.idea' || '.gradle' || '.dart_tool' || 'build':
continue;
}
pending.addAll(entity.listSync());
}

View File

@ -164,61 +164,51 @@ String _jsonToMapEntry(String key, dynamic value) {
}
String _jsonToObject(dynamic json) {
if (json == null || json is num || json is bool) {
return '$json';
}
if (json is String) {
return generateEncodedString(currentLocale, json);
}
if (json is Iterable<Object?>) {
final String type = json.first.runtimeType.toString();
final StringBuffer buffer = StringBuffer('const <$type>[');
for (final dynamic value in json) {
buffer.writeln('${_jsonToMap(value)},');
}
buffer.write(']');
return buffer.toString();
}
if (json is Map<String, dynamic>) {
final StringBuffer buffer = StringBuffer('<String, Object>{');
json.forEach((String key, dynamic value) {
buffer.writeln(_jsonToMapEntry(key, value));
});
buffer.write('}');
return buffer.toString();
switch (json) {
case null || num() || bool():
return '$json';
case String():
return generateEncodedString(currentLocale, json);
case Iterable<Object?>():
final Type type = json.first.runtimeType;
final StringBuffer buffer = StringBuffer('const <$type>[');
for (final dynamic value in json) {
buffer.writeln('${_jsonToMap(value)},');
}
buffer.write(']');
return buffer.toString();
case Map<String, dynamic>():
final StringBuffer buffer = StringBuffer('<String, Object>{');
json.forEach((String key, dynamic value) {
buffer.writeln(_jsonToMapEntry(key, value));
});
buffer.write('}');
return buffer.toString();
}
throw 'Unsupported JSON type ${json.runtimeType} of value $json.';
}
String _jsonToMap(dynamic json) {
if (json == null || json is num || json is bool) {
return '$json';
}
if (json is String) {
return generateEncodedString(currentLocale, json);
}
if (json is Iterable) {
final StringBuffer buffer = StringBuffer('<String>[');
for (final dynamic value in json) {
buffer.writeln('${_jsonToMap(value)},');
}
buffer.write(']');
return buffer.toString();
}
if (json is Map<String, dynamic>) {
final StringBuffer buffer = StringBuffer('<String, Object>{');
json.forEach((String key, dynamic value) {
buffer.writeln(_jsonToMapEntry(key, value));
});
buffer.write('}');
return buffer.toString();
switch (json) {
case null || num() || bool():
return '$json';
case String():
return generateEncodedString(currentLocale, json);
case Iterable<dynamic>():
final StringBuffer buffer = StringBuffer('<String>[');
for (final dynamic value in json) {
buffer.writeln('${_jsonToMap(value)},');
}
buffer.write(']');
return buffer.toString();
case Map<String, dynamic>():
final StringBuffer buffer = StringBuffer('<String, Object>{');
json.forEach((String key, dynamic value) {
buffer.writeln(_jsonToMapEntry(key, value));
});
buffer.write('}');
return buffer.toString();
}
throw 'Unsupported JSON type ${json.runtimeType} of value $json.';

View File

@ -148,17 +148,13 @@ void _copy(Directory source, Directory target) {
for (final FileSystemEntity entity in source.listSync(followLinks: false)) {
final String name = path.basename(entity.path);
if (entity is Directory) {
if (name == 'build' || name.startsWith('.')) {
continue;
}
_copy(entity, Directory(path.join(target.path, name)));
} else if (entity is File) {
if (name == '.packages' || name == 'pubspec.lock') {
continue;
}
final File dest = File(path.join(target.path, name));
dest.writeAsBytesSync(entity.readAsBytesSync());
switch (entity) {
case Directory() when name != 'build' && !name.startsWith('.'):
_copy(entity, Directory(path.join(target.path, name)));
case File() when name != '.packages' && name != 'pubspec.lock':
final File dest = File(path.join(target.path, name));
dest.writeAsBytesSync(entity.readAsBytesSync());
}
}
}

View File

@ -113,9 +113,7 @@ abstract class BoxBorder extends ShapeBorder {
return BorderDirectional.lerp(a, b, t);
}
if (b is Border && a is BorderDirectional) {
final BoxBorder c = b;
b = a;
a = c;
(a, b) = (b, a);
t = 1.0 - t;
// fall through to next case
}

View File

@ -1452,25 +1452,21 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
..sortKey = OrdinalSortKey(ordinal++)
..textDirection = initialDirection
..attributedLabel = AttributedString(info.semanticsLabel ?? info.text, attributes: info.stringAttributes);
final GestureRecognizer? recognizer = info.recognizer;
if (recognizer != null) {
if (recognizer is TapGestureRecognizer) {
if (recognizer.onTap != null) {
configuration.onTap = recognizer.onTap;
switch (info.recognizer) {
case TapGestureRecognizer(onTap: final VoidCallback? onTap):
case DoubleTapGestureRecognizer(onDoubleTap: final VoidCallback? onTap):
if (onTap != null) {
configuration.onTap = onTap;
configuration.isLink = true;
}
} else if (recognizer is DoubleTapGestureRecognizer) {
if (recognizer.onDoubleTap != null) {
configuration.onTap = recognizer.onDoubleTap;
configuration.isLink = true;
case LongPressGestureRecognizer(onLongPress: final GestureLongPressCallback? onLongPress):
if (onLongPress != null) {
configuration.onLongPress = onLongPress;
}
} else if (recognizer is LongPressGestureRecognizer) {
if (recognizer.onLongPress != null) {
configuration.onLongPress = recognizer.onLongPress;
}
} else {
assert(false, '${recognizer.runtimeType} is not supported.');
}
case null:
break;
default:
assert(false, '${info.recognizer.runtimeType} is not supported.');
}
if (node.parentPaintClipRect != null) {
final Rect paintRect = node.parentPaintClipRect!.intersect(currentRect);

View File

@ -1214,25 +1214,21 @@ class RenderParagraph extends RenderBox with ContainerRenderObjectMixin<RenderBo
..sortKey = OrdinalSortKey(ordinal++)
..textDirection = initialDirection
..attributedLabel = AttributedString(info.semanticsLabel ?? info.text, attributes: info.stringAttributes);
final GestureRecognizer? recognizer = info.recognizer;
if (recognizer != null) {
if (recognizer is TapGestureRecognizer) {
if (recognizer.onTap != null) {
configuration.onTap = recognizer.onTap;
switch (info.recognizer) {
case TapGestureRecognizer(onTap: final VoidCallback? onTap):
case DoubleTapGestureRecognizer(onDoubleTap: final VoidCallback? onTap):
if (onTap != null) {
configuration.onTap = onTap;
configuration.isLink = true;
}
} else if (recognizer is DoubleTapGestureRecognizer) {
if (recognizer.onDoubleTap != null) {
configuration.onTap = recognizer.onDoubleTap;
configuration.isLink = true;
case LongPressGestureRecognizer(onLongPress: final GestureLongPressCallback? onLongPress):
if (onLongPress != null) {
configuration.onLongPress = onLongPress;
}
} else if (recognizer is LongPressGestureRecognizer) {
if (recognizer.onLongPress != null) {
configuration.onLongPress = recognizer.onLongPress;
}
} else {
assert(false, '${recognizer.runtimeType} is not supported.');
}
case null:
break;
default:
assert(false, '${info.recognizer.runtimeType} is not supported.');
}
if (node.parentPaintClipRect != null) {
final Rect paintRect = node.parentPaintClipRect!.intersect(currentRect);

View File

@ -3799,27 +3799,17 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
&& notification is! ScrollEndNotification) {
return;
}
if (notification is ScrollStartNotification
&& _dataWhenToolbarShowScheduled != null) {
return;
switch (notification) {
case ScrollStartNotification() when _dataWhenToolbarShowScheduled != null:
case ScrollEndNotification() when _dataWhenToolbarShowScheduled == null:
break;
case ScrollEndNotification() when _dataWhenToolbarShowScheduled!.value != _value:
_dataWhenToolbarShowScheduled = null;
_disposeScrollNotificationObserver();
case ScrollNotification(:final BuildContext? context)
when !_isInternalScrollableNotification(context) && _scrollableNotificationIsFromSameSubtree(context):
_handleContextMenuOnScroll(notification);
}
if (notification is ScrollEndNotification
&& _dataWhenToolbarShowScheduled == null) {
return;
}
if (notification is ScrollEndNotification
&& _dataWhenToolbarShowScheduled!.value != _value) {
_dataWhenToolbarShowScheduled = null;
_disposeScrollNotificationObserver();
return;
}
if (_isInternalScrollableNotification(notification.context)) {
return;
}
if (!_scrollableNotificationIsFromSameSubtree(notification.context)) {
return;
}
_handleContextMenuOnScroll(notification);
}
Rect _calculateDeviceRect() {

View File

@ -1591,22 +1591,15 @@ mixin WidgetInspectorService {
/// API surface of methods called from the Flutter IntelliJ Plugin.
@protected
bool setSelection(Object? object, [ String? groupName ]) {
if (object is Element || object is RenderObject) {
if (object is Element) {
if (object == selection.currentElement) {
return false;
}
switch (object) {
case Element() when object != selection.currentElement:
selection.currentElement = object;
_sendInspectEvent(selection.currentElement);
} else {
if (object == selection.current) {
return false;
}
selection.current = object! as RenderObject;
return true;
case RenderObject() when object != selection.current:
selection.current = object;
_sendInspectEvent(selection.current);
}
return true;
return true;
}
return false;
}

View File

@ -64,14 +64,11 @@ void main() {
return widget is PhysicalShape || widget is PhysicalModel;
}),
);
final Widget widget = tester.widgetList(finder).single;
if (widget is PhysicalShape) {
expect(widget.color, bottomAppBarColor);
} else if (widget is PhysicalModel) {
expect(widget.color, bottomAppBarColor);
} else {
// Should be unreachable: compare with the finder.
assert(false);
switch (tester.widgetList(finder).single) {
case PhysicalShape(:final Color color) || PhysicalModel(:final Color color):
expect(color, bottomAppBarColor);
default:
assert(false); // Should be unreachable: compare with the finder.
}
});

View File

@ -264,12 +264,10 @@ BorderSide? getBorderSide(WidgetTester tester) {
}
BorderRadius? getBorderRadius(WidgetTester tester) {
final InputBorder border = getBorder(tester)!;
if (border is UnderlineInputBorder) {
return border.borderRadius;
}
if (border is OutlineInputBorder) {
return border.borderRadius;
switch (getBorder(tester)!) {
case UnderlineInputBorder(:final BorderRadius borderRadius):
case OutlineInputBorder(:final BorderRadius borderRadius):
return borderRadius;
}
return null;
}

View File

@ -1015,14 +1015,11 @@ void main() {
await tester.pump(const Duration(milliseconds: 750));
final Element actionTextBox = tester.element(find.text('ACTION'));
final Widget textWidget = actionTextBox.widget;
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(actionTextBox);
if (textWidget is Text) {
final TextStyle effectiveStyle = defaultTextStyle.style.merge(textWidget.style);
expect(effectiveStyle.color, Colors.lightBlue);
} else {
expect(false, true);
}
expect(actionTextBox.widget, isA<Text>());
final Text(:TextStyle? style) = actionTextBox.widget as Text;
final TextStyle defaultStyle = DefaultTextStyle.of(actionTextBox).style;
expect(defaultStyle.merge(style).color, Colors.lightBlue);
});
testWidgets('Material3 - Snackbar labels can be colored as MaterialColor', (WidgetTester tester) async {