diff --git a/default-recommendations/file-io-suggestions-test.rkt b/default-recommendations/file-io-suggestions-test.rkt index 0875350..2f1447f 100644 --- a/default-recommendations/file-io-suggestions-test.rkt +++ b/default-recommendations/file-io-suggestions-test.rkt @@ -11,6 +11,86 @@ header: ---------------------------------------- +test: "call-with-output-file displaying a value refactorable to display-to-file" +---------------------------------------- +(define (f path s) + (call-with-output-file path + (lambda (out) + (display s out)))) +======================================== +(define (f path s) + (call-with-output-file path + (λ (out) + (display s out)))) +======================================== +(define (f path s) + (display-to-file s path)) +---------------------------------------- + + +test: "call-with-output-file displaying a line refactorable to display-lines-to-file" +---------------------------------------- +(define (f path s) + (call-with-output-file path + (lambda (out) + (displayln s out)))) +======================================== +(define (f path s) + (display-lines-to-file (list s) path)) +---------------------------------------- + + +test: "call-with-output-file displaying multiple lines refactorable to display-lines-to-file" +---------------------------------------- +(define (f path a b) + (call-with-output-file path + (lambda (out) + (displayln a out) + (displayln b out)))) +======================================== +(define (f path a b) + (display-lines-to-file (list a b) path)) +---------------------------------------- + + +no-change-test: "call-with-output-file with keyword arguments not refactorable" +---------------------------------------- +(define (f path s) + (call-with-output-file path + (lambda (out) + (displayln s out)) + #:exists 'replace)) +---------------------------------------- + + +no-change-test: "call-with-output-file displaying to a different port not refactorable" +---------------------------------------- +(define (f path s other-port) + (call-with-output-file path + (lambda (out) + (displayln s other-port)))) +---------------------------------------- + + +no-change-test: "call-with-output-file with displayed value depending on the port not refactorable" +---------------------------------------- +(define (f path) + (call-with-output-file path + (lambda (out) + (displayln (object-name out) out)))) +---------------------------------------- + + +no-change-test: "call-with-output-file with non-display body forms not refactorable" +---------------------------------------- +(define (f path s) + (call-with-output-file path + (lambda (out) + (displayln s out) + (flush-output out)))) +---------------------------------------- + + no-change-test: "should not migrate make-temporary-file without 'directory to make-temporary-directory" - (make-temporary-file #:copy-from #false) diff --git a/default-recommendations/file-io-suggestions.rkt b/default-recommendations/file-io-suggestions.rkt index 2e11c3a..212d2a2 100644 --- a/default-recommendations/file-io-suggestions.rkt +++ b/default-recommendations/file-io-suggestions.rkt @@ -9,12 +9,42 @@ [file-io-suggestions refactoring-suite?])) -(require rebellion/private/static-name - resyntax/base) +(require racket/file + racket/set + rebellion/private/static-name + resyntax/base + resyntax/default-recommendations/private/lambda-by-any-name + resyntax/default-recommendations/private/syntax-identifier-sets + syntax/parse) ;@---------------------------------------------------------------------------------------------------- +(define-refactoring-rule call-with-output-file-to-display-to-file + #:description + "This use of `call-with-output-file` can be replaced with a simpler call to `display-to-file`." + #:literals (call-with-output-file display) + (call-with-output-file path:expr + (_:lambda-by-any-name (out:id) (display v:expr out-use:id))) + #:when (free-identifier=? (attribute out-use) (attribute out)) + #:when (not (set-member? (syntax-free-identifiers (attribute v)) (attribute out))) + (display-to-file v path)) + + +(define-refactoring-rule call-with-output-file-to-display-lines-to-file + #:description + "This use of `call-with-output-file` can be replaced with a simpler call to\ + `display-lines-to-file`." + #:literals (call-with-output-file displayln) + (call-with-output-file path:expr + (_:lambda-by-any-name (out:id) (displayln v:expr out-use:id) ...+)) + #:when (for/and ([out-use-id (in-list (attribute out-use))]) + (free-identifier=? out-use-id (attribute out))) + #:when (not (set-member? (syntax-free-identifiers #'(v ...)) (attribute out))) + (display-lines-to-file (list v ...) path)) + + (define-refactoring-suite file-io-suggestions - #:rules ()) + #:rules (call-with-output-file-to-display-lines-to-file + call-with-output-file-to-display-to-file))