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 {
150150 case . replaceChild( let replaceChildData) :
151151 range = sourceManager. range ( replaceChildData. replacementRange, in: replaceChildData. parent)
152152 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
153156 #if RESILIENT_LIBRARIES
154157 @unknown default :
155158 fatalError ( )
Original file line number Diff line number Diff line change @@ -77,6 +77,14 @@ public struct FixIt: Sendable {
7777 case replaceTrailingTrivia( token: TokenSyntax , newTrivia: Trivia )
7878 /// Replace the child node of the given parent node at the given replacement range with the given new child node
7979 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 )
8088 }
8189
8290 /// A description of what this Fix-It performs.
@@ -157,6 +165,9 @@ private extension FixIt.Change {
157165 range: replacingChildData. replacementRange,
158166 replacement: replacingChildData. newChild. description
159167 )
168+
169+ case . textualReplacement( replacementRange: let replacementRange, sourceFile: _, newText: let newText) :
170+ return SourceEdit ( range: replacementRange, replacement: newText)
160171 }
161172 }
162173}
Original file line number Diff line number Diff line change @@ -632,6 +632,11 @@ fileprivate extension FixIt.Change {
632632 range: start..< end,
633633 replacement: replacingChildData. newChild. description
634634 )
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)
635640 }
636641 }
637642}
Original file line number Diff line number Diff line change 1010//
1111//===----------------------------------------------------------------------===//
1212
13+ import SwiftDiagnostics
1314import SwiftParser
1415import SwiftParserDiagnostics
1516import SwiftSyntax
1617import XCTest
1718import _SwiftSyntaxTestSupport
1819
20+ struct SimpleFixItMessage : FixItMessage {
21+ let message : String
22+
23+ var fixItID : MessageID {
24+ MessageID ( domain: " here " , id: " this " )
25+ }
26+ }
27+
1928final class FixItTests : XCTestCase {
2029 func testEditsForFixIt( ) throws {
2130 let markedSource = " protocol 1️⃣Multi2️⃣ 3️⃣ident 4️⃣{} "
@@ -39,4 +48,18 @@ final class FixItTests: XCTestCase {
3948 XCTAssertNotEqual ( changes. count, edits. count)
4049 XCTAssertEqual ( expectedEdits, edits)
4150 }
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+ }
4265}
You can’t perform that action at this time.
0 commit comments