|
14 | 14 | (contract-out |
15 | 15 | [refactoring-rule? (-> any/c boolean?)] |
16 | 16 | [refactoring-rule-description (-> refactoring-rule? immutable-string?)] |
| 17 | + [refactoring-rule-analyzers (-> refactoring-rule? (listof expansion-analyzer?))] |
17 | 18 | [refactoring-suite? (-> any/c boolean?)] |
18 | 19 | [refactoring-suite |
19 | 20 | (->* () |
20 | 21 | (#:rules (sequence/c refactoring-rule?) #:name (or/c interned-symbol? #false)) |
21 | 22 | refactoring-suite?)] |
22 | | - [refactoring-suite-rules (-> refactoring-suite? (listof refactoring-rule?))])) |
| 23 | + [refactoring-suite-rules (-> refactoring-suite? (listof refactoring-rule?))] |
| 24 | + [refactoring-suite-analyzers (-> refactoring-suite? (listof expansion-analyzer?))])) |
23 | 25 |
|
24 | 26 |
|
25 | 27 | (module+ private |
|
33 | 35 | racket/list |
34 | 36 | racket/syntax |
35 | 37 | resyntax/private/more-syntax-parse-classes) |
| 38 | + racket/list |
36 | 39 | racket/sequence |
37 | 40 | rebellion/base/immutable-string |
38 | 41 | rebellion/base/option |
39 | 42 | rebellion/base/symbol |
40 | 43 | rebellion/type/object |
| 44 | + resyntax/default-recommendations/analyzers/identifier-usage |
| 45 | + resyntax/default-recommendations/analyzers/ignored-result-values |
| 46 | + resyntax/default-recommendations/analyzers/variable-mutability |
41 | 47 | resyntax/default-recommendations/private/definition-context |
| 48 | + resyntax/private/analyzer |
42 | 49 | resyntax/private/logger |
43 | 50 | resyntax/private/source |
44 | 51 | resyntax/private/syntax-neighbors |
|
98 | 105 | [(_ new-stx) (syntax-property #'new-stx 'focus-replacement-on #true)])) |
99 | 106 |
|
100 | 107 |
|
101 | | -(define-object-type refactoring-rule (transformer description uses-universal-tagged-syntax?) |
| 108 | +(define-object-type refactoring-rule (transformer description uses-universal-tagged-syntax? analyzers) |
102 | 109 | #:omit-root-binding |
103 | 110 | #:constructor-name constructor:refactoring-rule) |
104 | 111 |
|
|
149 | 156 | #:name 'id |
150 | 157 | #:description (string->immutable-string description.c) |
151 | 158 | #:uses-universal-tagged-syntax? (~? uses-universal-tagged-syntax? #false) |
| 159 | + #:analyzers (list identifier-usage-analyzer |
| 160 | + ignored-result-values-analyzer |
| 161 | + variable-mutability-analyzer) |
152 | 162 | #:transformer |
153 | 163 | (λ (stx) |
154 | 164 | (syntax-parse stx |
|
218 | 228 | expression.refactored))) |
219 | 229 |
|
220 | 230 |
|
221 | | -(define-object-type refactoring-suite (rules) |
| 231 | +(define-object-type refactoring-suite (rules analyzers) |
222 | 232 | #:constructor-name constructor:refactoring-suite |
223 | 233 | #:omit-root-binding) |
224 | 234 |
|
225 | 235 |
|
226 | 236 | (define (refactoring-suite #:rules [rules '()] #:name [name #false]) |
227 | | - (constructor:refactoring-suite #:rules (sequence->list rules) #:name name)) |
| 237 | + (define rule-list (sequence->list rules)) |
| 238 | + (define combined-analyzers |
| 239 | + (remove-duplicates |
| 240 | + (append-map refactoring-rule-analyzers rule-list))) |
| 241 | + (constructor:refactoring-suite #:rules rule-list #:analyzers combined-analyzers #:name name)) |
228 | 242 |
|
229 | 243 |
|
230 | 244 | (begin-for-syntax |
|
249 | 263 | (refactoring-suite |
250 | 264 | #:name 'id |
251 | 265 | #:rules (append rules.as-list-expr suites.as-list-expr)))) |
| 266 | + |
| 267 | + |
| 268 | +(module+ test |
| 269 | + (require rackunit |
| 270 | + resyntax/private/analyzer) |
| 271 | + |
| 272 | + (test-case "refactoring-rule stores analyzers" |
| 273 | + (define-refactoring-rule test-rule |
| 274 | + #:description "test rule" |
| 275 | + pattern |
| 276 | + replacement) |
| 277 | + |
| 278 | + (check-true (refactoring-rule? test-rule)) |
| 279 | + (check-equal? (length (refactoring-rule-analyzers test-rule)) 3) |
| 280 | + (check-true (andmap expansion-analyzer? (refactoring-rule-analyzers test-rule)))) |
| 281 | + |
| 282 | + (test-case "refactoring-suite combines analyzers from rules" |
| 283 | + (define-refactoring-rule rule1 |
| 284 | + #:description "rule 1" |
| 285 | + pattern1 |
| 286 | + replacement1) |
| 287 | + |
| 288 | + (define-refactoring-rule rule2 |
| 289 | + #:description "rule 2" |
| 290 | + pattern2 |
| 291 | + replacement2) |
| 292 | + |
| 293 | + (define suite (refactoring-suite #:rules (list rule1 rule2))) |
| 294 | + |
| 295 | + (check-true (refactoring-suite? suite)) |
| 296 | + (check-equal? (length (refactoring-suite-rules suite)) 2) |
| 297 | + ;; All rules have the same analyzers, so the combined list should have 3 unique analyzers |
| 298 | + (check-equal? (length (refactoring-suite-analyzers suite)) 3) |
| 299 | + (check-true (andmap expansion-analyzer? (refactoring-suite-analyzers suite)))) |
| 300 | + |
| 301 | + (test-case "nested suites combine analyzers correctly" |
| 302 | + (define-refactoring-rule inner-rule |
| 303 | + #:description "inner rule" |
| 304 | + inner-pattern |
| 305 | + inner-replacement) |
| 306 | + |
| 307 | + (define inner-suite (refactoring-suite #:rules (list inner-rule))) |
| 308 | + |
| 309 | + (define-refactoring-rule outer-rule |
| 310 | + #:description "outer rule" |
| 311 | + outer-pattern |
| 312 | + outer-replacement) |
| 313 | + |
| 314 | + (define outer-suite (refactoring-suite #:rules (list outer-rule inner-rule))) |
| 315 | + |
| 316 | + (check-equal? (length (refactoring-suite-analyzers inner-suite)) 3) |
| 317 | + ;; Both rules have the same analyzers, so deduplicated should still be 3 |
| 318 | + (check-equal? (length (refactoring-suite-analyzers outer-suite)) 3))) |
0 commit comments