File tree Expand file tree Collapse file tree 4 files changed +42
-0
lines changed
SwiftCompilerPluginMessageHandling
SwiftSyntaxMacrosGenericTestSupport
Tests/SwiftDiagnosticsTest Expand file tree Collapse file tree 4 files changed +42
-0
lines changed Original file line number Diff line number Diff line change @@ -150,6 +150,9 @@ extension PluginMessage.Diagnostic {
150
150
case . replaceChild( let replaceChildData) :
151
151
range = sourceManager. range ( replaceChildData. replacementRange, in: replaceChildData. parent)
152
152
text = replaceChildData. newChild. description
153
+ case . textualReplacement( replacementRange: let replacementRange, sourceFile: let sourceFile, newText: let newText) :
154
+ range = sourceManager. range ( replacementRange, in: sourceFile)
155
+ text = newText
153
156
#if RESILIENT_LIBRARIES
154
157
@unknown default :
155
158
fatalError ( )
Original file line number Diff line number Diff line change @@ -77,6 +77,14 @@ public struct FixIt: Sendable {
77
77
case replaceTrailingTrivia( token: TokenSyntax , newTrivia: Trivia )
78
78
/// Replace the child node of the given parent node at the given replacement range with the given new child node
79
79
case replaceChild( data: any ReplacingChildData )
80
+ /// Replace the text within the given range in a source file with new text.
81
+ ///
82
+ /// Generally, one should use other cases to replace specific syntax nodes
83
+ /// or trivia, because it more easily leads to a correct result. However,
84
+ /// this case provides a fallback for textual replacement that ignores
85
+ /// syntactic structure. After applying a textual replacement, there is no
86
+ /// way to get back to a syntax tree without reparsing.
87
+ case textualReplacement( replacementRange: Range < AbsolutePosition > , sourceFile: SourceFileSyntax , newText: String )
80
88
}
81
89
82
90
/// A description of what this Fix-It performs.
@@ -157,6 +165,9 @@ private extension FixIt.Change {
157
165
range: replacingChildData. replacementRange,
158
166
replacement: replacingChildData. newChild. description
159
167
)
168
+
169
+ case . textualReplacement( replacementRange: let replacementRange, sourceFile: _, newText: let newText) :
170
+ return SourceEdit ( range: replacementRange, replacement: newText)
160
171
}
161
172
}
162
173
}
Original file line number Diff line number Diff line change @@ -632,6 +632,11 @@ fileprivate extension FixIt.Change {
632
632
range: start..< end,
633
633
replacement: replacingChildData. newChild. description
634
634
)
635
+
636
+ case . textualReplacement( replacementRange: let range, sourceFile: let sourceFile, newText: let newText) :
637
+ let start = expansionContext. position ( of: range. lowerBound, anchoredAt: sourceFile)
638
+ let end = expansionContext. position ( of: range. upperBound, anchoredAt: sourceFile)
639
+ return SourceEdit ( range: start..< end, replacement: newText)
635
640
}
636
641
}
637
642
}
Original file line number Diff line number Diff line change 10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
+ import SwiftDiagnostics
13
14
import SwiftParser
14
15
import SwiftParserDiagnostics
15
16
import SwiftSyntax
16
17
import XCTest
17
18
import _SwiftSyntaxTestSupport
18
19
20
+ struct SimpleFixItMessage : FixItMessage {
21
+ let message : String
22
+
23
+ var fixItID : MessageID {
24
+ MessageID ( domain: " here " , id: " this " )
25
+ }
26
+ }
27
+
19
28
final class FixItTests : XCTestCase {
20
29
func testEditsForFixIt( ) throws {
21
30
let markedSource = " protocol 1️⃣Multi2️⃣ 3️⃣ident 4️⃣{} "
@@ -39,4 +48,18 @@ final class FixItTests: XCTestCase {
39
48
XCTAssertNotEqual ( changes. count, edits. count)
40
49
XCTAssertEqual ( expectedEdits, edits)
41
50
}
51
+
52
+ func testTextualReplacement( ) throws {
53
+ let five = AbsolutePosition ( utf8Offset: 5 )
54
+ let fifteen = AbsolutePosition ( utf8Offset: 15 )
55
+ let change = FixIt (
56
+ message: SimpleFixItMessage ( message: " fix it please " ) ,
57
+ changes: [
58
+ . textualReplacement( replacementRange: five..< fifteen, sourceFile: " func myFunction() { } " , newText: " yours " )
59
+ ]
60
+ )
61
+ XCTAssertEqual ( change. edits. count, 1 )
62
+ XCTAssertEqual ( change. edits [ 0 ] . range, five..< fifteen)
63
+ XCTAssertEqual ( change. edits [ 0 ] . replacement, " yours " )
64
+ }
42
65
}
You can’t perform that action at this time.
0 commit comments