Skip to content

Commit 2e84755

Browse files
Copilotjackfirth
andcommitted
Add #:suggested-fixes option to refactoring rules and support warning-only results
Co-authored-by: jackfirth <[email protected]>
1 parent 674ff30 commit 2e84755

File tree

3 files changed

+178
-91
lines changed

3 files changed

+178
-91
lines changed

base.rkt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
[refactoring-rule? (-> any/c boolean?)]
1616
[refactoring-rule-description (-> refactoring-rule? immutable-string?)]
1717
[refactoring-rule-analyzers (-> refactoring-rule? (set/c expansion-analyzer?))]
18+
[refactoring-rule-suggested-fixes (-> refactoring-rule? (or/c 'none 'one))]
1819
[refactoring-suite? (-> any/c boolean?)]
1920
[refactoring-suite
2021
(->* ()
@@ -108,7 +109,7 @@
108109
[(_ new-stx) (syntax-property #'new-stx 'focus-replacement-on #true)]))
109110

110111

111-
(define-object-type refactoring-rule (transformer description uses-universal-tagged-syntax? analyzers)
112+
(define-object-type refactoring-rule (transformer description uses-universal-tagged-syntax? analyzers suggested-fixes)
112113
#:omit-root-binding
113114
#:constructor-name constructor:refactoring-rule)
114115

@@ -140,12 +141,14 @@
140141
#:description description
141142
(~optional (~seq #:uses-universal-tagged-syntax? uses-universal-tagged-syntax?))
142143
(~optional (~seq #:analyzers analyzers))
144+
(~optional (~seq #:suggested-fixes suggested-fixes))
143145
parse-option:syntax-parse-option ...
144146
pattern
145147
pattern-directive:syntax-parse-pattern-directive ...
146148
replacement)
147149
#:declare description (expr/c #'string?)
148150
#:declare analyzers (expr/c #'(sequence/c expansion-analyzer?))
151+
#:declare suggested-fixes (expr/c #'(or/c 'none 'one))
149152

150153
#:attr partial-match-log-statement
151154
(and (not (empty? (attribute pattern-directive)))
@@ -162,6 +165,7 @@
162165
#:description (string->immutable-string description.c)
163166
#:uses-universal-tagged-syntax? (~? uses-universal-tagged-syntax? #false)
164167
#:analyzers (for/set ([analyzer (~? analyzers.c '())]) analyzer)
168+
#:suggested-fixes (~? suggested-fixes.c 'one)
165169
#:transformer
166170
(λ (stx)
167171
(syntax-parse stx
@@ -176,6 +180,7 @@
176180
(define-definition-context-refactoring-rule id:id
177181
#:description (~var description (expr/c #'string?))
178182
(~optional (~seq #:analyzers (~var analyzers (expr/c #'(sequence/c expansion-analyzer?)))))
183+
(~optional (~seq #:suggested-fixes (~var suggested-fixes (expr/c #'(or/c 'none 'one)))))
179184
parse-option:syntax-parse-option ...
180185
splicing-pattern
181186
pattern-directive:syntax-parse-pattern-directive ...
@@ -229,6 +234,7 @@
229234
(define-refactoring-rule id
230235
#:description description
231236
(~? (~@ #:analyzers analyzers))
237+
(~? (~@ #:suggested-fixes suggested-fixes))
232238
(~var expression expression-matching-id)
233239
expression.refactored)))
234240

main.rkt

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -382,48 +382,65 @@
382382
syntax
383383
(string-indent (exn-message e) #:amount 3))
384384
absent)])
385-
(guarded-block
386-
(guard-match (present replacement)
387-
(parameterize ([current-namespace (source-code-analysis-namespace analysis)])
388-
(refactoring-rule-refactor rule syntax (source-code-analysis-code analysis)))
389-
#:else absent)
390-
(guard (syntax-replacement-introduces-incorrect-bindings? replacement) #:else
391-
(define bad-ids (syntax-replacement-introduced-incorrect-identifiers replacement))
392-
(define orig-stx (syntax-replacement-original-syntax replacement))
393-
(define intro (syntax-replacement-introduction-scope replacement))
394-
(log-resyntax-warning
395-
(string-append
396-
"~a: suggestion discarded because it introduces identifiers with incorrect bindings\n"
397-
" incorrect identifiers: ~a\n"
398-
" bindings in original context: ~a\n"
399-
" bindings in syntax replacement: ~a\n"
400-
" replaced syntax: ~a")
401-
(object-name rule)
402-
bad-ids
403-
(for/list ([id (in-list bad-ids)])
404-
(identifier-binding (datum->syntax orig-stx (syntax->datum id))))
405-
(for/list ([id (in-list bad-ids)])
406-
(identifier-binding (intro id 'remove)))
407-
orig-stx)
408-
absent)
409-
(guard (syntax-replacement-preserves-comments? replacement comments) #:else
410-
(log-resyntax-warning
411-
(string-append "~a: suggestion discarded because it does not preserve all comments\n"
412-
" dropped comment locations: ~v\n"
413-
" original syntax:\n"
414-
" ~v\n"
415-
" replacement syntax:\n"
416-
" ~v")
417-
(object-name rule)
418-
(syntax-replacement-dropped-comment-locations replacement comments)
419-
(syntax-replacement-original-syntax replacement)
420-
(syntax-replacement-new-syntax replacement))
421-
absent)
422-
(present
423-
(refactoring-result
424-
#:rule-name (object-name rule)
425-
#:message (refactoring-rule-description rule)
426-
#:syntax-replacement replacement)))))
385+
;; Check if this is a warning-only rule
386+
(cond
387+
[(eq? (refactoring-rule-suggested-fixes rule) 'none)
388+
;; For warning-only rules, try to match the pattern
389+
(define match-result
390+
(parameterize ([current-namespace (source-code-analysis-namespace analysis)])
391+
(refactoring-rule-refactor rule syntax (source-code-analysis-code analysis))))
392+
;; If pattern matched, create a warning result
393+
(option-map match-result
394+
(λ (_)
395+
(warning-result
396+
#:rule-name (object-name rule)
397+
#:message (refactoring-rule-description rule)
398+
#:source (source-code-analysis-code analysis)
399+
#:original-syntax syntax)))]
400+
[else
401+
;; For rules with fixes, validate and create a regular refactoring result
402+
(guarded-block
403+
(guard-match (present replacement)
404+
(parameterize ([current-namespace (source-code-analysis-namespace analysis)])
405+
(refactoring-rule-refactor rule syntax (source-code-analysis-code analysis)))
406+
#:else absent)
407+
(guard (syntax-replacement-introduces-incorrect-bindings? replacement) #:else
408+
(define bad-ids (syntax-replacement-introduced-incorrect-identifiers replacement))
409+
(define orig-stx (syntax-replacement-original-syntax replacement))
410+
(define intro (syntax-replacement-introduction-scope replacement))
411+
(log-resyntax-warning
412+
(string-append
413+
"~a: suggestion discarded because it introduces identifiers with incorrect bindings\n"
414+
" incorrect identifiers: ~a\n"
415+
" bindings in original context: ~a\n"
416+
" bindings in syntax replacement: ~a\n"
417+
" replaced syntax: ~a")
418+
(object-name rule)
419+
bad-ids
420+
(for/list ([id (in-list bad-ids)])
421+
(identifier-binding (datum->syntax orig-stx (syntax->datum id))))
422+
(for/list ([id (in-list bad-ids)])
423+
(identifier-binding (intro id 'remove)))
424+
orig-stx)
425+
absent)
426+
(guard (syntax-replacement-preserves-comments? replacement comments) #:else
427+
(log-resyntax-warning
428+
(string-append "~a: suggestion discarded because it does not preserve all comments\n"
429+
" dropped comment locations: ~v\n"
430+
" original syntax:\n"
431+
" ~v\n"
432+
" replacement syntax:\n"
433+
" ~v")
434+
(object-name rule)
435+
(syntax-replacement-dropped-comment-locations replacement comments)
436+
(syntax-replacement-original-syntax replacement)
437+
(syntax-replacement-new-syntax replacement))
438+
absent)
439+
(present
440+
(refactoring-result
441+
#:rule-name (object-name rule)
442+
#:message (refactoring-rule-description rule)
443+
#:syntax-replacement replacement)))])))
427444

428445
(falsey->option
429446
(for*/first ([rule (in-list rules)]

0 commit comments

Comments
 (0)