diff --git a/default-recommendations/let-binding-suggestions-test.rkt b/default-recommendations/let-binding-suggestions-test.rkt index e380b99..c2dfb43 100644 --- a/default-recommendations/let-binding-suggestions-test.rkt +++ b/default-recommendations/let-binding-suggestions-test.rkt @@ -417,3 +417,43 @@ test: "let binding with obfuscated conflicting define inside" x)) (m x))) ------------------------------ + + +test: "variable definition with nested let binding refactorable to two variable definitions" +------------------------------ +(define (f) + (define y (let ([x 1]) (* x 2))) + (* y 3)) +------------------------------ +------------------------------ +(define (f) + (define x 1) + (define y (* x 2)) + (* y 3)) +------------------------------ + + +test: "variable definition with nested let binding of same name not refactorable" +------------------------------ +(define (f) + (define y (let ([y 1]) (* y 2))) + (* y 3)) +------------------------------ + + +test: "variable definition with nested let binding of name bound later not refactorable" +------------------------------ +(define (f) + (define y (let ([x 1]) (* x 2))) + (define x 5) + (* y 3)) +------------------------------ + + +test: "variable definition with nested let binding of name bound earlier not refactorable" +------------------------------ +(define (f) + (define x 5) + (define y (let ([x 1]) (* x 2))) + (* y 3)) +------------------------------ diff --git a/default-recommendations/let-binding-suggestions.rkt b/default-recommendations/let-binding-suggestions.rkt index ba4c142..b21baf2 100644 --- a/default-recommendations/let-binding-suggestions.rkt +++ b/default-recommendations/let-binding-suggestions.rkt @@ -66,7 +66,24 @@ (call-with-values (λ () expr) receiver)]) +(define-refactoring-rule define-let-to-double-define + #:description "This `let` expression can be pulled up into a `define` expression." + #:literals (define let) + [(header:header-form-allowing-internal-definitions + (define id:id (let ([nested-id:id nested-expr:expr]) expr:expr)) + body ...) + #:when (not (set-member? (syntax-bound-identifiers #'(id body ...)) #'nested-id)) + (header.formatted ... + (define nested-id nested-expr) + (define id expr) + body ...)]) + + (define let-binding-suggestions (refactoring-suite #:name (name let-binding-suggestions) - #:rules (list let-to-define let-values-then-call-to-call-with-values named-let-to-plain-let))) + #:rules + (list define-let-to-double-define + let-to-define + let-values-then-call-to-call-with-values + named-let-to-plain-let)))