flutter/examples/api/lib/widgets
Nate Wilson 5ecf10052f
pattern-matching refactor (#154753)
This pull request aims to improve code readability, based on feedback gathered in a recent design doc.

<br>

There are two factors that hugely impact how easy it is to understand a piece of code: **verbosity** and **complexity**.

Reducing **verbosity** is important, because boilerplate makes a project more difficult to navigate. It also has a tendency to make one's eyes gloss over, and subtle typos/bugs become more likely to slip through.

Reducing **complexity** makes the code more accessible to more people. This is especially important for open-source projects like Flutter, where the code is read by those who make contributions, as well as others who read through source code as they debug their own projects.

<hr>

<br>

The following examples show how pattern-matching might affect these two factors:

<details> <summary><h3>Example 1 (GOOD)</h3> [click to expand]</summary>

```dart
if (ancestor case InheritedElement(:final InheritedTheme widget)) {
  themes.add(widget);
}
```

Without using patterns, this might expand to

```dart
if (ancestor is InheritedElement) {
  final InheritedWidget widget = ancestor.widget;
  if (widget is InheritedTheme) {
    themes.add(widget);
  }
}
```

Had `ancestor` been a non-local variable, it would need to be "converted" as well:

```dart
final Element ancestor = this.ancestor;
if (ancestor is InheritedElement) {
  final InheritedWidget inheritedWidget = ancestor.widget;
  if (widget is InheritedTheme) {
    themes.add(theme);
  }
}
```

</details>

<details> <summary><h3>Example 2 (BAD) </h3> [click to expand]</summary>

```dart
if (widget case PreferredSizeWidget(preferredSize: Size(:final double height))) {
  return height;
}
```

Assuming `widget` is a non-local variable, this would expand to:

```dart
final Widget widget = this.widget;
if (widget is PreferredSizeWidget) {
  return widget.preferredSize.height;
}
```

<br>

</details>

In both of the examples above, an `if-case` statement simultaneously verifies that an object meets the specified criteria and performs a variable assignment accordingly.

But there are some differences: Example 2 uses a more deeply-nested pattern than Example 1 but makes fewer useful checks.

**Example 1:**
- checks that `ancestor` is an `InheritedElement`
- checks that the inherited element's `widget` is an `InheritedTheme`

**Example 2:**
- checks that `widget` is a `PreferredSizeWidget`
(every `PreferredSizeWidget` has a `size` field, and every `Size` has a `height` field)

<br>

<hr>

I feel hesitant to try presenting a set of cut-and-dry rules as to which scenarios should/shouldn't use pattern-matching, since there are an abundance of different types of patterns, and an abundance of different places where they might be used.

But hopefully the conversations we've had recently will help us converge toward a common intuition of how pattern-matching can best be utilized for improved readability.

<br><br>

- resolves https://github.com/flutter/flutter/issues/152313
- Design Doc: [flutter.dev/go/dart-patterns](https://flutter.dev/go/dart-patterns)
2024-10-03 18:21:04 +00:00
..
actions docimports for API samples (#151606) 2024-07-11 20:36:55 +00:00
animated_grid Fix references in examples (#151204) 2024-07-03 17:56:48 +00:00
animated_list Fix references in examples (#151204) 2024-07-03 17:56:48 +00:00
animated_size Add test for animated_size.0.dart API example. (#147828) 2024-05-10 21:55:51 +00:00
animated_switcher Add tests for animated_switcher.0.dart API example. (#149180) 2024-05-29 12:10:34 +00:00
app Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
app_lifecycle_listener Update misc tests for Material3 (#128712) 2023-06-13 08:57:27 -07:00
async Add tests for stream_builder.0.dart API example. (#147832) 2024-05-10 21:48:35 +00:00
autocomplete Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
autofill Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
basic Update collection-fors to prefer final (as per updated prefer_final_in_for_each) (#127511) 2023-05-26 23:34:36 +00:00
binding Fix references in examples (#151204) 2024-07-03 17:56:48 +00:00
color_filter Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
dismissible Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
drag_target Deprecates onWillAccept and onAccept callbacks in DragTarget. (#133691) 2023-11-10 22:47:22 +00:00
draggable_scrollable_sheet Reland "Reland - Introduce tone-based surfaces and accent color add-ons - Part 2" (#144273) 2024-02-28 13:55:50 -08:00
editable_text Fix references in examples (#151204) 2024-07-03 17:56:48 +00:00
focus_manager Turning if chains into shorter switch statements (#144977) 2024-03-13 17:16:17 +00:00
focus_scope improve focus example (#147464) 2024-05-07 20:07:49 +00:00
focus_traversal pattern-matching refactor (#154753) 2024-10-03 18:21:04 +00:00
form Reapply new PopScope API (#147607) 2024-05-07 09:04:49 -07:00
framework Add test for error_widget.0_test.dart (#153103) 2024-08-26 18:11:02 +00:00
gesture_detector Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
hardware_keyboard cleanup now-irrelevant ignores for deprecated_member_use (#143403) 2024-02-14 21:08:25 +00:00
heroes Dev, examples/api, etc updated for Material 3 by default (#129683) 2023-06-28 09:41:58 -07:00
image Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
implicit_animations Add test for animated_fractionally_sized_box.0.dart API example. (#146721) 2024-05-01 16:03:12 +00:00
inherited_model Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
inherited_notifier Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
inherited_theme Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
interactive_viewer Update links and surrounding text for new main-api docs (#138602) 2023-11-17 22:27:53 +00:00
layout_builder Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
magnifier Enhances intuitiveness of RawMagnifier's example (#150308) 2024-07-19 14:09:18 +00:00
media_query Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
navigator Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
navigator_pop_handler Nested Navigator state restoration predictive back examples (#153723) 2024-08-22 03:40:09 +00:00
nested_scroll_view Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
notification_listener Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
overflow_bar Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
overlay Optimize Overlay sample to avoid overflow (#155861) 2024-09-28 09:20:32 +00:00
overscroll_indicator Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
page Refactors page API (#137792) 2024-05-13 22:45:51 +00:00
page_storage Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
page_view Reland "Reland - Introduce tone-based surfaces and accent color add-ons - Part 2" (#144273) 2024-02-28 13:55:50 -08:00
pop_scope Reapply new PopScope API (#147607) 2024-05-07 09:04:49 -07:00
preferred_size Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
restoration Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
restoration_properties Add tests for restorable_value.0.dart API example. (#148676) 2024-05-23 08:34:23 +00:00
routes Allow mixing route transitions in one app. (#150031) 2024-10-02 20:08:11 +00:00
scroll_end_notification chore: fix typos and link broken (#150402) 2024-07-03 17:10:19 +00:00
scroll_notification_observer Add ScrollNotificationObserver sample (#127023) 2023-05-25 15:58:52 +00:00
scroll_position Fix references in examples (#151204) 2024-07-03 17:56:48 +00:00
scroll_view Use super.key instead of manually passing the Key parameter to the parent class (#147621) 2024-05-13 22:12:49 +00:00
scrollbar Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
shared_app_data Add tests for shared_app_data.#.dart API examples. (#147830) 2024-05-20 17:49:04 +00:00
shortcuts Add tests for single_activator.0.dart API example. (#147426) 2024-05-01 14:52:57 +00:00
single_child_scroll_view Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
sliver Factor out deprecated names in example code (#151374) 2024-07-08 19:06:54 +00:00
sliver_fill Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
slotted_render_object_widget Replace RenderBox.compute* with RenderBox.get* and add @visibleForOverriding (#145503) 2024-03-22 02:44:55 +00:00
system_context_menu Reland Native ios context menu (#143002) (#148238) (#148265) 2024-05-15 18:37:05 +00:00
table Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
tap_region Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
text Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
text_magnifier Updated TextMagnifierExampleApp to M3 (#129381) 2023-06-26 10:44:11 -07:00
transitions Test remaining transitions api examples (#148302) 2024-05-23 18:57:14 +00:00
tween_animation_builder Add tests for tween_animation_builder.0.dart API example. (#148902) 2024-05-30 20:17:04 +00:00
undo_history Rename Sample classes (#124080) 2023-04-04 20:34:29 +00:00
value_listenable_builder Remove deprecated TextTheme members (#139255) 2024-03-28 01:20:55 +00:00
widget_state Add WidgetStateMouseCursor example and tests for it. (#155552) 2024-10-01 23:15:53 +00:00