|
9 | 9 | [syntax-shortcuts refactoring-suite?])) |
10 | 10 |
|
11 | 11 |
|
12 | | -(require racket/syntax |
| 12 | +(require racket/string |
| 13 | + racket/syntax |
13 | 14 | rebellion/private/static-name |
14 | 15 | resyntax/base |
15 | 16 | syntax/parse) |
|
43 | 44 | (format-id lctx fmt arg.simplified ...)) |
44 | 45 |
|
45 | 46 |
|
| 47 | +(define-syntax-class format-symbol-argument |
| 48 | + #:attributes (simplified) |
| 49 | + #:literals (syntax-e keyword->string symbol->string) |
| 50 | + |
| 51 | + (pattern (syntax-e inner:format-symbol-argument) #:attr simplified (attribute inner.simplified)) |
| 52 | + |
| 53 | + (pattern (keyword->string inner:format-symbol-argument) |
| 54 | + #:attr simplified (attribute inner.simplified)) |
| 55 | + |
| 56 | + (pattern (symbol->string inner:format-symbol-argument) |
| 57 | + #:attr simplified (attribute inner.simplified)) |
| 58 | + |
| 59 | + (pattern simplified:expr)) |
| 60 | + |
| 61 | + |
| 62 | +;; The format-symbol function only allows ~a placeholders. Rather a fancy generic utilty that finds |
| 63 | +;; all placeholders, we just explicitly list out all the other ones and check one-by-one whether any |
| 64 | +;; of them are contained in the template string. That's easier to implement and the performance |
| 65 | +;; doesn't matter at all since template strings are almost always short. |
| 66 | +(define disallowed-format-symbol-placeholders |
| 67 | + (list "~n" |
| 68 | + "~%" |
| 69 | + "~s" |
| 70 | + "~S" |
| 71 | + "~v" |
| 72 | + "~V" |
| 73 | + "~.a" |
| 74 | + "~.A" |
| 75 | + "~.s" |
| 76 | + "~.S" |
| 77 | + "~.v" |
| 78 | + "~.V" |
| 79 | + "~e" |
| 80 | + "~E" |
| 81 | + "~c" |
| 82 | + "~C" |
| 83 | + "~b" |
| 84 | + "~B" |
| 85 | + "~o" |
| 86 | + "~O" |
| 87 | + "~x" |
| 88 | + "~X" |
| 89 | + "~ " |
| 90 | + "~\n" |
| 91 | + "~\t")) |
| 92 | + |
| 93 | + |
| 94 | +(define-refactoring-rule format-string-to-format-symbol |
| 95 | + #:description |
| 96 | + "This `format` expression can be simplified to an equivalent `format-symbol` expression." |
| 97 | + #:literals (format string->symbol) |
| 98 | + |
| 99 | + (string->symbol (format template:str arg:format-symbol-argument ...)) |
| 100 | + #:when (for/and ([disallowed (in-list disallowed-format-symbol-placeholders)]) |
| 101 | + (not (string-contains? (syntax-e #'template) disallowed))) |
| 102 | + |
| 103 | + (format-symbol template (~replacement arg.simplified #:original arg) ...)) |
| 104 | + |
| 105 | + |
46 | 106 | (define-refactoring-suite syntax-shortcuts |
47 | | - #:rules (syntax-e-in-format-id-unnecessary)) |
| 107 | + #:rules (format-string-to-format-symbol |
| 108 | + syntax-e-in-format-id-unnecessary)) |
0 commit comments