Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions default-recommendations/hash-shortcuts-test.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,71 @@ no-change-test:
(define sum (hash-ref! h1 (cadr term) 0))
(hash-set! h2 (cadr term) (+ (car term) sum)))
------------------------------


test: "make-immutable-hash with quasiquoted alist refactorable to hash"
------------------------------
(define (f body event)
(make-immutable-hash
`((body . ,body)
(event . ,event))))
==============================
(define (f body event)
(hash 'body body 'event event))
------------------------------


test: "make-immutable-hash with self-quoting keys and values refactorable to hash"
------------------------------
(define (f x)
(make-immutable-hash
`(("a" . ,x)
(b . 5))))
==============================
(define (f x)
(hash "a" x 'b 5))
------------------------------


no-change-test: "make-immutable-hash with fully quoted alist not refactorable to hash"
------------------------------
(make-immutable-hash `((a . 1) (b . 2)))
------------------------------


no-change-test: "make-immutable-hash with dynamic keys not refactorable to hash"
------------------------------
(define (f k v)
(make-immutable-hash `((,k . ,v))))
------------------------------


no-change-test: "make-immutable-hash with unquote-splicing not refactorable to hash"
------------------------------
(define (f pairs)
(make-immutable-hash `(,@pairs (a . 1))))
------------------------------


no-change-test: "make-immutable-hash with quoted datum values not refactorable to hash"
------------------------------
(define (f x)
(make-immutable-hash `((a . ,x) (b . 'c))))
------------------------------


test: "make-immutable-hash with symbol values refactorable to hash"
------------------------------
(define (f x)
(make-immutable-hash `((a . ,x) (b . c))))
==============================
(define (f x)
(hash 'a x 'b 'c))
------------------------------


no-change-test: "make-immutable-hash with list keys not refactorable to hash"
------------------------------
(define (f x)
(make-immutable-hash `(((a b) . ,x))))
------------------------------
41 changes: 41 additions & 0 deletions default-recommendations/hash-shortcuts.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,46 @@
#:original-splice (orig-definition orig-hash-set!)))))


(define-syntax-class self-quoting-literal
(pattern (~or _:boolean _:character _:number _:regexp _:byte-regexp _:string _:bytes)))


;; A datum within a quasiquoted expression that can be lifted directly into expression position,
;; either because it's self-quoting or because it's a symbol that can be wrapped in a quote. Quoted
;; datums like (quote x) are excluded because quasiquote treats them as plain data: the quasiquoted
;; pair (a . 'x) maps the key a to the two-element list (quote x), not to the symbol x.
(define-syntax-class liftable-quasiquoted-datum
#:attributes (as-expr)
(pattern sym:id
#:when (not (memq (syntax-e #'sym) '(unquote unquote-splicing quasiquote)))
#:with as-expr #'(quote sym))
(pattern datum:self-quoting-literal
#:with as-expr #'datum))


(define-syntax-class quasiquoted-hash-pair
#:attributes (key-expr value-expr unquoted-value?)
#:literals (unquote)
(pattern (key:liftable-quasiquoted-datum . (unquote value-expr:expr))
#:with key-expr #'key.as-expr
#:attr unquoted-value? #true)
(pattern (key:liftable-quasiquoted-datum . value:liftable-quasiquoted-datum)
#:with key-expr #'key.as-expr
#:with value-expr #'value.as-expr
#:attr unquoted-value? #false))


(define-refactoring-rule make-immutable-hash-with-quasiquote-to-hash
#:description
"This `make-immutable-hash` call with statically known keys can be replaced with a simpler,
equivalent `hash` call."
#:literals (make-immutable-hash quasiquote)
(make-immutable-hash (quasiquote (pair:quasiquoted-hash-pair ...)))
#:when (for/or ([unquoted? (in-list (attribute pair.unquoted-value?))])
unquoted?)
(hash (~@ pair.key-expr pair.value-expr) ...))


(define-refactoring-rule hash-map-to-hash-keys
#:description "This `hash-map` expression is equivalent to the `hash-keys` function."
#:literals (hash-map)
Expand All @@ -169,4 +209,5 @@
hash-ref-with-constant-lambda-to-hash-ref-without-lambda
hash-ref!-with-constant-lambda-to-hash-ref!-without-lambda
hash-set!-ref-to-hash-update!
make-immutable-hash-with-quasiquote-to-hash
or-hash-ref-set!-to-hash-ref!))
Loading