|
204 | 204 | (~replacement [else else-expr.refactored ...] #:original else-expr))) |
205 | 205 |
|
206 | 206 |
|
| 207 | +;; Syntax class to count and extract deeply nested when expressions |
| 208 | +(define-syntax-class deeply-nested-when-expression |
| 209 | + #:attributes ([condition 1] [body 1]) |
| 210 | + #:literals (when) |
| 211 | + |
| 212 | + ;; Base case: innermost when with any condition |
| 213 | + (pattern (when inner-condition:expr inner-body:expr ...) |
| 214 | + #:with (condition ...) #'(inner-condition) |
| 215 | + #:with (body ...) #'(inner-body ...)) |
| 216 | + |
| 217 | + ;; Recursive case: nest of when expressions |
| 218 | + (pattern (when outer-condition:expr nested:deeply-nested-when-expression) |
| 219 | + #:with (condition ...) #'(outer-condition nested.condition ...) |
| 220 | + #:with (body ...) #'(nested.body ...))) |
| 221 | + |
| 222 | + |
| 223 | +;; Match three or more nested when expressions |
| 224 | +(define-syntax-class triple-nested-when-expression |
| 225 | + #:attributes ([condition 1] [body 1]) |
| 226 | + #:literals (when) |
| 227 | + (pattern (when c1:expr (when c2:expr nested:deeply-nested-when-expression)) |
| 228 | + #:when (>= (length (syntax->list #'(c1 c2 nested.condition ...))) 3) |
| 229 | + #:with (condition ...) #'(c1 c2 nested.condition ...) |
| 230 | + #:with (body ...) #'(nested.body ...))) |
| 231 | + |
| 232 | + |
| 233 | +;; Match two nested when where outer has and |
| 234 | +(define-syntax-class double-nested-when-outer-and |
| 235 | + #:attributes ([condition 1] [body 1]) |
| 236 | + #:literals (when and) |
| 237 | + (pattern (when (and outer-parts ...) (when inner-condition:expr inner-body:expr ...)) |
| 238 | + #:with (condition ...) #'(outer-parts ... inner-condition) |
| 239 | + #:with (body ...) #'(inner-body ...))) |
| 240 | + |
| 241 | + |
| 242 | +;; Match two nested when where inner has and |
| 243 | +(define-syntax-class double-nested-when-inner-and |
| 244 | + #:attributes ([condition 1] [body 1]) |
| 245 | + #:literals (when and) |
| 246 | + (pattern (when outer-condition:expr (when (and inner-parts ...) inner-body:expr ...)) |
| 247 | + #:with (condition ...) #'(outer-condition inner-parts ...) |
| 248 | + #:with (body ...) #'(inner-body ...))) |
| 249 | + |
| 250 | + |
| 251 | +;; Match two nested when where both are identifiers |
| 252 | +(define-syntax-class double-nested-when-both-ids |
| 253 | + #:attributes ([condition 1] [body 1]) |
| 254 | + #:literals (when) |
| 255 | + (pattern (when outer-id:id (when inner-id:id inner-body:expr ...)) |
| 256 | + #:with (condition ...) #'(outer-id inner-id) |
| 257 | + #:with (body ...) #'(inner-body ...))) |
| 258 | + |
| 259 | + |
207 | 260 | (define-refactoring-rule nested-when-to-compound-when |
208 | 261 | #:description |
209 | 262 | "Nested `when` expressions can be merged into a single compound `when` expression." |
210 | 263 | #:literals (when and) |
211 | | - (when outer-condition:expr (when inner-condition:expr body:expr ...)) |
212 | | - (when (and outer-condition inner-condition) body ...)) |
| 264 | + (~or nested:triple-nested-when-expression |
| 265 | + nested:double-nested-when-outer-and |
| 266 | + nested:double-nested-when-inner-and |
| 267 | + nested:double-nested-when-both-ids) |
| 268 | + (when (and nested.condition ...) nested.body ...)) |
213 | 269 |
|
214 | 270 |
|
215 | 271 | (define-refactoring-rule ignored-and-to-when |
|
0 commit comments