diff --git a/default-recommendations.rkt b/default-recommendations.rkt index e6857eb..6255186 100644 --- a/default-recommendations.rkt +++ b/default-recommendations.rkt @@ -22,6 +22,7 @@ resyntax/default-recommendations/match-shortcuts resyntax/default-recommendations/miscellaneous-suggestions resyntax/default-recommendations/numeric-shortcuts + resyntax/default-recommendations/require-and-provide-suggestions resyntax/default-recommendations/string-shortcuts resyntax/default-recommendations/syntax-shortcuts resyntax/default-recommendations/syntax-parse-shortcuts @@ -48,6 +49,7 @@ resyntax/default-recommendations/match-shortcuts resyntax/default-recommendations/miscellaneous-suggestions resyntax/default-recommendations/numeric-shortcuts + resyntax/default-recommendations/require-and-provide-suggestions resyntax/default-recommendations/string-shortcuts resyntax/default-recommendations/syntax-shortcuts resyntax/default-recommendations/syntax-parse-shortcuts @@ -86,6 +88,7 @@ (refactoring-suite-rules match-shortcuts) (refactoring-suite-rules miscellaneous-suggestions) (refactoring-suite-rules numeric-shortcuts) + (refactoring-suite-rules require-and-provide-suggestions) (refactoring-suite-rules string-shortcuts) (refactoring-suite-rules syntax-shortcuts) (refactoring-suite-rules syntax-parse-shortcuts) diff --git a/default-recommendations/require-and-provide-suggestions-test.rkt b/default-recommendations/require-and-provide-suggestions-test.rkt new file mode 100644 index 0000000..416d21e --- /dev/null +++ b/default-recommendations/require-and-provide-suggestions-test.rkt @@ -0,0 +1,56 @@ +#lang resyntax/testing/refactoring-test + + +require: resyntax/default-recommendations require-and-provide-suggestions + + +header: +- #lang racket/base + + +test: "duplicate provided identifiers should be removed" +---------------------------------------- +(provide foo + foo + foo) +(define foo 1) +---------------------------------------- +---------------------------------------- +(provide foo) +(define foo 1) +---------------------------------------- + + +test: "removing duplicate provided identifiers leaves other exports unchanged" +---------------------------------------- +(provide a + foo + b + foo + c) +(define a 1) +(define b 1) +(define c 1) +(define foo 1) +---------------------------------------- +---------------------------------------- +(provide a + foo + b + c) +(define a 1) +(define b 1) +(define c 1) +(define foo 1) +---------------------------------------- + + +test: "provide deduplication doesn't affect exports at different phases" +---------------------------------------- +(provide foo + (for-syntax foo)) +(require (for-syntax racket/base)) +(define foo 1) +(begin-for-syntax + (define foo 2)) +---------------------------------------- diff --git a/default-recommendations/require-and-provide-suggestions.rkt b/default-recommendations/require-and-provide-suggestions.rkt new file mode 100644 index 0000000..72f39a8 --- /dev/null +++ b/default-recommendations/require-and-provide-suggestions.rkt @@ -0,0 +1,43 @@ +#lang racket/base + + +(require racket/contract/base) + + +(provide + (contract-out + [require-and-provide-suggestions refactoring-suite?])) + + +(require racket/list + rebellion/private/static-name + resyntax/refactoring-rule + resyntax/refactoring-suite + syntax/parse) + + +;@---------------------------------------------------------------------------------------------------- + + +(define-syntax-class export-spec + #:attributes (id) + (pattern id:id)) + + +(define-refactoring-rule provide-deduplication + #:description "Providing the same identifier multiple times is unnecessary." + #:literals (provide) + (provide spec:export-spec ...) + #:when (check-duplicate-identifier (attribute spec.id)) + + #:with (deduped-spec ...) + (remove-duplicates (attribute spec) bound-identifier=? + #:key (λ (spec-stx) (syntax-parse spec-stx [:export-spec #'id]))) + + (provide deduped-spec ...)) + + +(define require-and-provide-suggestions + (refactoring-suite + #:name (name require-and-provide-suggestions) + #:rules (list provide-deduplication)))