@bdayadev/flutter-ultra-mcp 1.11.7 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: use-pattern-matching
3
+ description: Use switch expressions and pattern matching where appropriate
4
+ ---
5
+
6
+ # Implementing Dart Patterns
7
+
8
+ ## Contents
9
+
10
+ - [Pattern Selection Strategy](#pattern-selection-strategy)
11
+ - [Switch Statements vs. Expressions](#switch-statements-vs-expressions)
12
+ - [Core Pattern Implementations](#core-pattern-implementations)
13
+ - [Workflows](#workflows)
14
+ - [Examples](#examples)
15
+
16
+ ## Pattern Selection Strategy
17
+
18
+ - **If validating and extracting from deserialized data (e.g., JSON):** Use Map and List patterns.
19
+ - **If handling multiple return values:** Use Record patterns.
20
+ - **If executing type-specific behavior (Algebraic Data Types):** Use Object patterns with `sealed` classes.
21
+ - **If matching numeric ranges or conditions:** Use Relational and Logical-and patterns.
22
+ - **If multiple cases share logic:** Use Logical-or (`||`) patterns.
23
+ - **If ignoring specific values:** Use the Wildcard pattern (`_`).
24
+
25
+ ## Switch Statements vs. Expressions
26
+
27
+ - **If producing a value:** Use a **switch expression**. Syntax: `switch (value) { pattern => expression, }`. Must be exhaustive.
28
+ - **If executing statements or side effects:** Use a **switch statement**. Empty cases fall through. Non-empty cases implicitly break.
29
+
30
+ ## Core Pattern Implementations
31
+
32
+ - **Logical-or (`||`):** Both branches must define the exact same set of variables.
33
+ - **Logical-and (`&&`):** Branches must _not_ define overlapping variables.
34
+ - **Relational:** `==`, `!=`, `<`, `>`, `<=`, `>=` followed by a constant expression.
35
+ - **Cast (`as`):** Throws if the value does not match the type.
36
+ - **Null-check (`?`):** Fails the match if the value is null.
37
+ - **Null-assert (`!`):** Throws if the value is null.
38
+ - **Variable:** `var name` or `Type name`. Binds the matched value.
39
+ - **Wildcard (`_`):** Matches any value and discards it.
40
+ - **List:** `[pattern1, pattern2]`. Matches lists of exact length unless a Rest element (`...`) is used.
41
+ - **Map:** `{"key": pattern}`. Matches maps containing the specified keys.
42
+ - **Record:** `(pattern1, named: pattern2)`. Use `:var name` to infer the getter name.
43
+ - **Object:** `ClassName(field: pattern)`. Use `:var field` to infer the getter name.
44
+
45
+ ## Workflows
46
+
47
+ ### Task Progress: Implementing Pattern Matching
48
+
49
+ - [ ] Identify the data structure being evaluated.
50
+ - [ ] Select the appropriate switch construct.
51
+ - [ ] Define the required patterns.
52
+ - [ ] Extract required data using Variable patterns.
53
+ - [ ] Apply Guard clauses (`when condition`) for logic that cannot be expressed via patterns.
54
+ - [ ] Handle unmatched cases using a Wildcard (`_`) or `default`.
55
+ - [ ] Run exhaustiveness validator.
56
+
57
+ ### Feedback Loop: Exhaustiveness Checking
58
+
59
+ 1. Execute `dart analyze`.
60
+ 2. Look for "The type 'X' is not exhaustively matched" errors.
61
+ 3. Add the missing Object patterns for unhandled subtypes, or add a Wildcard case.
62
+
63
+ ## Examples
64
+
65
+ ### JSON Validation and Destructuring
66
+
67
+ ```dart
68
+ var data = {
69
+ 'user': ['Lily', 13],
70
+ };
71
+
72
+ if (data case {'user': [String name, int age]}) {
73
+ print('User $name is $age years old.');
74
+ } else {
75
+ print('Invalid JSON structure.');
76
+ }
77
+ ```
78
+
79
+ ### Algebraic Data Types (Sealed Classes)
80
+
81
+ ```dart
82
+ sealed class Shape {}
83
+
84
+ class Square implements Shape {
85
+ final double length;
86
+ Square(this.length);
87
+ }
88
+
89
+ class Circle implements Shape {
90
+ final double radius;
91
+ Circle(this.radius);
92
+ }
93
+
94
+ double calculateArea(Shape shape) => switch (shape) {
95
+ Square(length: var l) => l * l,
96
+ Circle(:var radius) => math.pi * radius * radius,
97
+ };
98
+ ```
99
+
100
+ ### Variable Swapping and Destructuring
101
+
102
+ ```dart
103
+ var (a, b) = ('left', 'right');
104
+ (b, a) = (a, b); // Swap values
105
+
106
+ var (name, age) = getUserInfo();
107
+ ```
108
+
109
+ ### Guard Clauses and Logical-or
110
+
111
+ ```dart
112
+ switch (shape) {
113
+ case Square(size: var s) || Circle(size: var s) when s > 0:
114
+ print('Valid symmetric shape with size $s');
115
+ case Square() || Circle():
116
+ print('Invalid or empty shape');
117
+ default:
118
+ print('Unknown shape');
119
+ }
120
+ ```
121
+
122
+ ## Flutter Ultra Integration
123
+
124
+ Validate pattern matching usage with analysis:
125
+
126
+ - `mcp__plugin_flutter_flutter-ultra-build__analyze` — Check for exhaustiveness and type errors
127
+ - `mcp__plugin_flutter_flutter-ultra-build__fix` — Apply automated pattern matching migrations
128
+
129
+ ---
130
+
131
+ > **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
132
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.