From 2a6a8c64ade7f1281dbd6a1920cf46c5b78231ab Mon Sep 17 00:00:00 2001 From: Jack Firth Date: Fri, 30 Aug 2024 22:56:04 -0700 Subject: [PATCH] Improve `always-throwing-if-to-when` rule Now it can detect cases where either branch of the `if` expression always throws, instead of just cases where the true branch always throws. --- .../conditional-shortcuts-test.rkt | 30 +++++++++++++++++++ .../conditional-shortcuts.rkt | 23 ++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/default-recommendations/conditional-shortcuts-test.rkt b/default-recommendations/conditional-shortcuts-test.rkt index 7c7212b..36a8d76 100644 --- a/default-recommendations/conditional-shortcuts-test.rkt +++ b/default-recommendations/conditional-shortcuts-test.rkt @@ -152,6 +152,21 @@ test: "if expressions with an always-throwing first branch can be refactored to ------------------------------ +test: "if expressions with an always-throwing second branch can be refactored to unless" +------------------------------ +(define (f c) + (if c + (displayln "foo") + (error 'oops))) +------------------------------ +------------------------------ +(define (f c) + (unless c + (error 'oops)) + (displayln "foo")) +------------------------------ + + test: "negated if expressions with an always-throwing first branch can be refactored to unless" ------------------------------ (define (f c) @@ -167,6 +182,21 @@ test: "negated if expressions with an always-throwing first branch can be refact ------------------------------ +test: "negated if expressions with an always-throwing second branch can be refactored to when" +------------------------------ +(define (f c) + (if (not c) + (displayln "foo") + (error 'oops))) +------------------------------ +------------------------------ +(define (f c) + (when c + (error 'oops)) + (displayln "foo")) +------------------------------ + + test: "cond expressions with an always-throwing first branch can be refactored to when" ------------------------------ (define (f c) diff --git a/default-recommendations/conditional-shortcuts.rkt b/default-recommendations/conditional-shortcuts.rkt index 2b0763d..03350ff 100644 --- a/default-recommendations/conditional-shortcuts.rkt +++ b/default-recommendations/conditional-shortcuts.rkt @@ -93,18 +93,31 @@ conditional.condition conditional.body ...)]) +(define-syntax-class always-throwing-if-expression + #:attributes (equivalent-guard-expression success-expression) + #:literals (if) + (pattern (if condition:condition-expression + fail:always-throwing-expression + success-expression) + #:with equivalent-guard-expression + #'((~if condition.negated? unless when) condition.base-condition fail)) + (pattern (if condition:condition-expression + success-expression + fail:always-throwing-expression) + #:with equivalent-guard-expression + #'((~if condition.negated? when unless) condition.base-condition fail))) + + (define-refactoring-rule always-throwing-if-to-when #:description "Using `when` and `unless` is simpler than a conditional with an always-throwing branch." #:literals (if) [(header:header-form-allowing-internal-definitions - (if condition:condition-expression - fail:always-throwing-expression - else-expression)) + throwing-if:always-throwing-if-expression) (header.formatted ... - ((~if condition.negated? unless when) condition.base-condition fail) - else-expression)]) + throwing-if.equivalent-guard-expression + throwing-if.success-expression)]) (define-refactoring-rule always-throwing-cond-to-when