This repository has been archived by the owner on Oct 26, 2023. It is now read-only.
forked from jackfirth/resyntax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rkt
125 lines (103 loc) · 4.34 KB
/
main.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#lang racket/base
(require racket/contract/base)
(provide
(contract-out
[refactor! (-> (sequence/c refactoring-result?) void?)]
[refactor (->* (string?) (#:suite refactoring-suite?) (listof refactoring-result?))]
[refactor-file (->* (path-string?) (#:suite refactoring-suite?) (listof refactoring-result?))]))
(require fancy-app
racket/path
racket/port
racket/sequence
racket/syntax-srcloc
rebellion/base/immutable-string
rebellion/base/option
rebellion/base/symbol
rebellion/collection/entry
rebellion/collection/hash
rebellion/collection/list
rebellion/streaming/transducer
resyntax/private/code-snippet
resyntax/default-recommendations
resyntax/private/comment-reader
resyntax/private/refactoring-result
resyntax/refactoring-rule
(submod resyntax/refactoring-rule private)
resyntax/refactoring-suite
resyntax/private/source
resyntax/private/string-replacement
resyntax/private/syntax-replacement)
;@----------------------------------------------------------------------------------------------------
(struct exn:fail:refactoring exn:fail (rule syntax cause)
#:transparent
#:property prop:exn:srclocs
(λ (this) (list (syntax-srcloc (exn:fail:refactoring-syntax this)))))
(define (refactoring-rules-refactor rules syntax
#:comments comments
#:analysis analysis)
(define (refactor rule)
(with-handlers
([exn:fail?
(λ (e)
(define message
(format "~a: refactoring attempt failed\n syntax: ~e\n cause: ~e"
(object-name rule) syntax e))
(raise (exn:fail:refactoring message (current-continuation-marks) rule syntax e)))])
(option-map
(option-filter
(option-filter
(refactoring-rule-refactor rule syntax #:analysis analysis)
syntax-replacement-preserves-free-identifiers?)
(syntax-replacement-preserves-comments? _ comments))
(refactoring-result
#:source (source-code-analysis-code analysis)
#:rule-name (object-name rule)
#:message (refactoring-rule-description rule)
#:replacement _))))
(falsey->option
(for*/first ([rule (in-list rules)]
[result (in-option (refactor rule))])
result)))
(define (refactor code-string #:suite [suite default-recommendations])
(define rule-list (refactoring-suite-rules suite))
(define source (string-source code-string))
(define comments (with-input-from-string code-string read-comment-locations))
(parameterize ([current-namespace (make-base-namespace)])
(define analysis (source-analyze source))
(transduce
(source-code-analysis-visited-forms analysis)
(append-mapping
(λ (stx)
(in-option
(refactoring-rules-refactor rule-list stx #:comments comments #:analysis analysis))))
#:into into-list)))
(define (refactor-file path-string #:suite [suite default-recommendations])
(define path (simple-form-path path-string))
(printf "resyntax: analyzing ~a\n" path)
(define rule-list (refactoring-suite-rules suite))
(define source (file-source path))
(define (skip e)
(printf "resyntax: skipping ~a due to syntax error: ~e\n" path (exn-message e))
empty-list)
(with-handlers ([exn:fail:syntax? skip]
[exn:fail:filesystem:missing-module? skip])
(parameterize ([current-namespace (make-base-namespace)])
(define analysis (source-analyze source))
(define comments (with-input-from-file path read-comment-locations))
(transduce
(source-code-analysis-visited-forms analysis)
(append-mapping
(λ (stx)
(in-option
(refactoring-rules-refactor rule-list stx #:comments comments #:analysis analysis))))
#:into into-list))))
(define (refactor! results)
(define results-by-path
(transduce results
(bisecting
(λ (result) (file-source-path (refactoring-result-source result)))
refactoring-result-string-replacement)
(grouping union-into-string-replacement)
#:into into-hash))
(for ([(path replacement) (in-hash results-by-path)])
(file-apply-string-replacement! path replacement)))