Skip to content

Commit 7f61e1e

Browse files
Copilotjackfirth
andcommitted
Fix: Make when merging rule less aggressive
- Only merge two nested when expressions if both conditions are identifiers, or one uses 'and' - Always merge three or more nested when expressions - Add test cases for the new behavior Co-authored-by: jackfirth <[email protected]>
1 parent d6cbe8a commit 7f61e1e

File tree

2 files changed

+103
-11
lines changed

2 files changed

+103
-11
lines changed

default-recommendations/conditional-shortcuts-test.rkt

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -698,20 +698,56 @@ test: "if clause with begin in false branch and commented true branch refactorab
698698
------------------------------
699699

700700

701-
test: "immediately-nested when expressions can be merged"
701+
no-change-test: "two when forms with non-trivial conditions"
702702
--------------------
703-
(define (f c1 c2)
704-
(when c1
705-
(when c2
706-
(displayln "both passed"))))
703+
(define (f a b c)
704+
(when (a)
705+
(when (b)
706+
c)))
707+
--------------------
708+
709+
710+
test: "three when forms"
711+
--------------------
712+
(define (f a b c d)
713+
(when (a)
714+
(when (b)
715+
(when (c)
716+
d))))
707717
====================
708-
(define (f c1 c2)
709-
(when (and c1 c2)
710-
(displayln "both passed")))
718+
(define (f a b c d)
719+
(when (and (a) (b) (c))
720+
d))
721+
--------------------
722+
723+
724+
test: "two when forms with and"
725+
--------------------
726+
(define (f a b c d)
727+
(when (and (a) (b))
728+
(when (c)
729+
d)))
730+
====================
731+
(define (f a b c d)
732+
(when (and (a) (b) (c))
733+
d))
734+
--------------------
735+
736+
737+
test: "two when forms with identifiers"
738+
--------------------
739+
(define (f a b c)
740+
(when a
741+
(when b
742+
c)))
743+
====================
744+
(define (f a b c)
745+
(when (and a b)
746+
c))
711747
--------------------
712748

713749

714-
test: "nested when with multiple body expressions can be merged"
750+
test: "two when forms with identifiers and multiple body expressions"
715751
--------------------
716752
(define (f c1 c2)
717753
(when c1

default-recommendations/conditional-shortcuts.rkt

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,68 @@
204204
(~replacement [else else-expr.refactored ...] #:original else-expr)))
205205

206206

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+
207260
(define-refactoring-rule nested-when-to-compound-when
208261
#:description
209262
"Nested `when` expressions can be merged into a single compound `when` expression."
210263
#: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 ...))
213269

214270

215271
(define-refactoring-rule ignored-and-to-when

0 commit comments

Comments
 (0)