Skip to content

Commit 30963bb

Browse files
authored
Improve string replacement logging (#486)
This makes debugging test failures easier.
1 parent f77d615 commit 30963bb

File tree

2 files changed

+175
-21
lines changed

2 files changed

+175
-21
lines changed

private/string-replacement.rkt

Lines changed: 163 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,17 @@
9393

9494
(define (string-replacement #:start start #:end end #:contents contents)
9595
(define content-list
96-
(transduce contents (filtering (λ (r) (positive? (replacement-string-span r)))) #:into into-list))
96+
(for/fold ([accumulated '()]
97+
[previous #false]
98+
#:result
99+
(reverse (append (if previous (list previous) (list)) accumulated)))
100+
([piece contents]
101+
#:when (positive? (replacement-string-span piece)))
102+
(match (list previous piece)
103+
[(list #false _) (values accumulated piece)]
104+
[(list (inserted-string s1) (inserted-string s2))
105+
(values accumulated (inserted-string (string-append s1 s2)))]
106+
[(list _ _) (values (cons previous accumulated) piece)])))
97107
(define new-span (transduce content-list (mapping replacement-string-span) #:into into-sum))
98108
(define max-end
99109
(transduce content-list
@@ -110,6 +120,63 @@
110120
#:contents content-list))
111121

112122

123+
(module+ test
124+
(test-case "string-replacement constructor"
125+
126+
(test-case "should merge insertions"
127+
(define initial-pieces
128+
(list (inserted-string "aaa") (inserted-string "bbb") (inserted-string "ccc")))
129+
(define expected-pieces (list (inserted-string "aaabbbccc")))
130+
(define replacement
131+
(string-replacement
132+
#:start 0
133+
#:end 10
134+
#:contents initial-pieces))
135+
(check-equal? (string-replacement-contents replacement) expected-pieces))
136+
137+
(test-case "should not merge copied pieces"
138+
(define initial-pieces
139+
(list (copied-string 2 5) (copied-string 5 7) (copied-string 7 9)))
140+
(define replacement
141+
(string-replacement
142+
#:start 0
143+
#:end 10
144+
#:contents initial-pieces))
145+
(check-equal? (string-replacement-contents replacement) initial-pieces))
146+
147+
(test-case "should not merge inserted pieces with copied pieces"
148+
(define initial-pieces
149+
(list (inserted-string "aaa") (copied-string 5 7) (inserted-string "bbb")))
150+
(define replacement
151+
(string-replacement
152+
#:start 0
153+
#:end 10
154+
#:contents initial-pieces))
155+
(check-equal? (string-replacement-contents replacement) initial-pieces))
156+
157+
(test-case "should merge inserted pieces when before copied piece"
158+
(define initial-pieces
159+
(list (inserted-string "aaa") (inserted-string "bbb") (copied-string 5 7)))
160+
(define expected-pieces (list (inserted-string "aaabbb") (copied-string 5 7)))
161+
(define replacement
162+
(string-replacement
163+
#:start 0
164+
#:end 10
165+
#:contents initial-pieces))
166+
(check-equal? (string-replacement-contents replacement) expected-pieces))
167+
168+
(test-case "should merge inserted pieces when after copied piece"
169+
(define initial-pieces
170+
(list (copied-string 5 7) (inserted-string "ccc") (inserted-string "ddd")))
171+
(define expected-pieces (list (copied-string 5 7) (inserted-string "cccddd")))
172+
(define replacement
173+
(string-replacement
174+
#:start 0
175+
#:end 10
176+
#:contents initial-pieces))
177+
(check-equal? (string-replacement-contents replacement) expected-pieces))))
178+
179+
113180
(define (string-replacement-length-change replacement)
114181
(- (string-replacement-new-span replacement) (string-replacement-original-span replacement)))
115182

@@ -250,13 +317,27 @@
250317
(define/guard (string-replacement-normalize replacement original-string
251318
#:preserve-start [preserve-start #false]
252319
#:preserve-end [preserve-end #false])
320+
(define left-normalized
321+
(string-replacement-left-normalize replacement original-string #:preserve-start preserve-start))
322+
(define left-reversed (string-replacement-reverse left-normalized original-string))
323+
(define reversed-original-string (string-reverse original-string))
324+
(define reversed
325+
(string-replacement-left-normalize
326+
left-reversed
327+
reversed-original-string
328+
#:preserve-start (and preserve-end (- (string-length original-string) preserve-end))))
329+
(string-replacement-reverse reversed reversed-original-string))
330+
331+
332+
(define/guard (string-replacement-left-normalize replacement original-string
333+
#:preserve-start [preserve-start #false])
253334
(define replaced (string-apply-replacement original-string replacement))
254335
(guard (not (equal? original-string replaced)) #:else replacement)
255336
(define actual-start
256-
(inexact->exact (min (or preserve-start +inf.0) (string-diff-start original-string replaced))))
257-
(define actual-end
258337
(inexact->exact
259-
(max actual-start (or preserve-end -inf.0) (string-diff-end original-string replaced))))
338+
(min (or preserve-start +inf.0)
339+
(string-diff-start original-string replaced)
340+
(string-replacement-original-end replacement))))
260341
(define left-trimmed-pieces
261342
(let loop ([pieces (string-replacement-contents replacement)]
262343
[pos (string-replacement-start replacement)])
@@ -267,20 +348,28 @@
267348
(if (< (+ pos piece-span) actual-start)
268349
(loop remaining (+ pos piece-span))
269350
(cons (replacement-string-drop-left next-piece (- actual-start pos)) remaining)))))
270-
(define right-trimmed-pieces
271-
(let loop ([pieces (reverse left-trimmed-pieces)]
272-
[pos (string-replacement-original-end replacement)])
273-
(guarded-block
274-
(guard (> pos actual-end) #:else (reverse pieces))
275-
(guard-match (cons next-piece remaining) pieces #:else (list))
276-
(define piece-span (replacement-string-span next-piece))
277-
(if (> (- pos piece-span) actual-start)
278-
(loop remaining (- pos piece-span))
279-
(reverse
280-
(cons (replacement-string-drop-right next-piece (- pos actual-start)) remaining))))))
281351
(string-replacement #:start actual-start
282-
#:end actual-end
283-
#:contents right-trimmed-pieces))
352+
#:end (string-replacement-original-end replacement)
353+
#:contents left-trimmed-pieces))
354+
355+
356+
(define (string-replacement-reverse replacement original-string)
357+
(define new-start (- (string-length original-string) (string-replacement-original-end replacement)))
358+
(define new-end (+ new-start (string-replacement-original-span replacement)))
359+
(define new-contents
360+
(reverse
361+
(for/list ([piece (in-list (string-replacement-contents replacement))])
362+
(match piece
363+
[(inserted-string s) (inserted-string (string-reverse s))]
364+
[(copied-string start end)
365+
(define new-start (- (string-length original-string) end))
366+
(define new-end (+ new-start (- end start)))
367+
(copied-string new-start new-end)]))))
368+
(string-replacement #:start new-start #:end new-end #:contents new-contents))
369+
370+
371+
(define (string-reverse s)
372+
(list->string (reverse (string->list s))))
284373

285374

286375
(define (string-diff-start original new)
@@ -414,7 +503,63 @@
414503
(check-equal? (string-replacement-normalize replacement s)
415504
(string-replacement #:start 13
416505
#:end 13
417-
#:contents (list (inserted-string "friend ")))))))
506+
#:contents (list (inserted-string "friend ")))))
507+
508+
(test-case "normalizing by left-trimming a single size-increasing insertion"
509+
(define s "hello my big friend")
510+
(define s2 "hello my little friend")
511+
(define replacement-pieces (list (inserted-string "my little")))
512+
(define replacement (string-replacement #:start 6 #:end 12 #:contents replacement-pieces))
513+
(check-equal? (string-apply-replacement s replacement) s2)
514+
515+
(define normalized (string-replacement-normalize replacement s))
516+
517+
(define expected
518+
(string-replacement #:start 9 #:end 12 #:contents (list (inserted-string "little"))))
519+
(check-equal? (string-apply-replacement s expected) s2)
520+
(check-equal? normalized expected))
521+
522+
(test-case "normalizing by left-trimming a single size-decreasing insertion"
523+
(define s "hello my little friend")
524+
(define s2 "hello my big friend")
525+
(define replacement-pieces (list (inserted-string "my big")))
526+
(define replacement (string-replacement #:start 6 #:end 15 #:contents replacement-pieces))
527+
(check-equal? (string-apply-replacement s replacement) s2)
528+
529+
(define normalized (string-replacement-normalize replacement s))
530+
531+
(define expected
532+
(string-replacement #:start 9 #:end 15 #:contents (list (inserted-string "big"))))
533+
(check-equal? (string-apply-replacement s expected) s2)
534+
(check-equal? normalized expected))
535+
536+
(test-case "normalizing by right-trimming a single size-increasing insertion"
537+
(define s "hello my big friend")
538+
(define s2 "hello my little friend")
539+
(define replacement-pieces (list (inserted-string "little friend")))
540+
(define replacement (string-replacement #:start 9 #:end 19 #:contents replacement-pieces))
541+
(check-equal? (string-apply-replacement s replacement) s2)
542+
543+
(define normalized (string-replacement-normalize replacement s))
544+
545+
(define expected
546+
(string-replacement #:start 9 #:end 12 #:contents (list (inserted-string "little"))))
547+
(check-equal? (string-apply-replacement s expected) s2)
548+
(check-equal? normalized expected))
549+
550+
(test-case "normalizing by right-trimming a single size-decreasing insertion"
551+
(define s "hello my little friend")
552+
(define s2 "hello my big friend")
553+
(define replacement-pieces (list (inserted-string "big friend")))
554+
(define replacement (string-replacement #:start 9 #:end 22 #:contents replacement-pieces))
555+
(check-equal? (string-apply-replacement s replacement) s2)
556+
557+
(define normalized (string-replacement-normalize replacement s))
558+
559+
(define expected
560+
(string-replacement #:start 9 #:end 15 #:contents (list (inserted-string "big"))))
561+
(check-equal? (string-apply-replacement s expected) s2)
562+
(check-equal? normalized expected))))
418563

419564

420565
(define/guard (string-replacement-union replacement1 replacement2)

private/syntax-replacement.rkt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@
6969

7070
(define/guard (pieces stx #:focused? [focused? #false])
7171
(guard (or focused? (not (syntax-property stx 'focus-replacement-on))) #:else
72+
(log-resyntax-debug "focusing in on ~a" stx)
7273
(list (focus (pieces stx #:focused? #true))))
7374
(guard (not (syntax-original? stx)) #:else
75+
(log-resyntax-debug "copying original syntax ~a" stx)
7476
(define start (sub1 (syntax-position stx)))
7577
(define end (+ start (syntax-span stx)))
7678
(list (copied-string start end)))
@@ -129,9 +131,6 @@
129131
(define start (sub1 (syntax-position orig-stx)))
130132
(define end (+ start (syntax-span orig-stx)))
131133
(define contents-with-possible-focus (pieces new-stx))
132-
(when (log-level? resyntax-logger 'debug)
133-
(define message (string-indent (pretty-format contents-with-possible-focus) #:amount 2))
134-
(log-resyntax-debug "string replacement contents:\n~a" message))
135134
(define has-focus? (and (findf focus? contents-with-possible-focus) #true))
136135
(define focused-start
137136
(+ start
@@ -150,6 +149,10 @@
150149
(string-replacement #:start start
151150
#:end end
152151
#:contents raw-contents))
152+
(when (log-level? resyntax-logger 'debug)
153+
(define message
154+
(string-indent (pretty-format unformatted) #:amount 2))
155+
(log-resyntax-debug "string replacement contents:\n~a" message))
153156
(cond
154157
[(not format?) unformatted]
155158
[else
@@ -159,12 +162,16 @@
159162
#:preserve-start focused-start
160163
#:preserve-end focused-end)
161164
unformatted))
165+
(when has-focus?
166+
(log-resyntax-debug "string replacement after focusing:\n~a"
167+
(string-indent (pretty-format normalized) #:amount 2)))
162168
(string-replacement-format normalized (source->string source))]))
163169

164170

165171
(define/guard (original-separator-piece stx trailing-stx)
166172
(guard (syntax-originally-neighbors? stx trailing-stx) #:else #false)
167173
(let-values ([(stx trailing-stx) (syntax-extract-originals-from-pair stx trailing-stx)])
174+
(log-resyntax-debug "copying separator between ~a and ~a" stx trailing-stx)
168175
(define stx-end (+ (sub1 (syntax-position stx)) (syntax-span stx)))
169176
(define trailing-start (sub1 (syntax-position trailing-stx)))
170177
(copied-string stx-end trailing-start)))
@@ -178,6 +185,8 @@
178185
(define end (string-replacement-new-end replacement))
179186
(define changed-code-substring (substring refactored-source-code start end))
180187
(define initial-columns (string-column-offset refactored-source-code start))
188+
(log-resyntax-debug "unformatted code after applying replacement:\n~a"
189+
(string-indent refactored-source-code #:amount 2))
181190
(log-resyntax-debug "about to format unformatted code at indentation ~a:\n~a"
182191
initial-columns changed-code-substring)
183192

0 commit comments

Comments
 (0)