Skip to content

Commit 74fb36f

Browse files
committed
Translate Fix-Its from the C++ diagnostics into swift-syntax diagnostics
The swift-syntax diagnostic formatter doesn't actually print Fix-Its, but at least they're available now.
1 parent ceb1152 commit 74fb36f

File tree

4 files changed

+62
-11
lines changed

4 files changed

+62
-11
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ class BridgedDiagnosticArgument {
544544
BridgedDiagnosticArgument(BridgedStringRef s);
545545
};
546546

547+
class BridgedFixIt {
548+
public:
549+
BridgedCharSourceRange replacementRange;
550+
BridgedStringRef replacementText;
551+
};
552+
547553
class BridgedDiagnosticFixIt {
548554
public:
549555
int64_t storage[7];

include/swift/Bridging/ASTGen.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ void swift_ASTGen_addQueuedDiagnostic(
3333
BridgedStringRef categoryName,
3434
BridgedStringRef documentationPath,
3535
const BridgedCharSourceRange *_Nullable highlightRanges,
36-
ptrdiff_t numHighlightRanges);
36+
ptrdiff_t numHighlightRanges,
37+
BridgedArrayRef /*BridgedFixIt*/ fixIts);
3738
void swift_ASTGen_renderQueuedDiagnostics(
3839
void *_Nonnull queued, ssize_t contextSize, ssize_t colorize,
3940
BridgedStringRef *_Nonnull renderedString);

lib/AST/DiagnosticBridge.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/DiagnosticEngine.h"
2121
#include "swift/Basic/SourceManager.h"
2222
#include "swift/Bridging/ASTGen.h"
23+
#include "llvm/ADT/ArrayRef.h"
2324
#include "llvm/Support/raw_ostream.h"
2425

2526
using namespace swift;
@@ -66,14 +67,19 @@ static void addQueueDiagnostic(void *queuedDiagnostics,
6667
if (info.EducationalNotePaths.size() > 0)
6768
documentationPath = info.EducationalNotePaths[0];
6869

69-
// FIXME: Translate Fix-Its.
70-
swift_ASTGen_addQueuedDiagnostic(queuedDiagnostics, perFrontendState,
71-
text.str(),
72-
severity, info.Loc,
73-
info.Category,
74-
documentationPath,
75-
highlightRanges.data(),
76-
highlightRanges.size());
70+
SmallVector<BridgedFixIt, 2> fixIts;
71+
for (const auto &fixIt : info.FixIts) {
72+
fixIts.push_back(BridgedFixIt{ fixIt.getRange(), fixIt.getText() });
73+
}
74+
75+
swift_ASTGen_addQueuedDiagnostic(
76+
queuedDiagnostics, perFrontendState,
77+
text.str(),
78+
severity, info.Loc,
79+
info.Category,
80+
documentationPath,
81+
highlightRanges.data(), highlightRanges.size(),
82+
llvm::ArrayRef<BridgedFixIt>(fixIts));
7783

7884
// TODO: A better way to do this would be to pass the notes as an
7985
// argument to `swift_ASTGen_addQueuedDiagnostic` but that requires

lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ public func addQueuedSourceFile(
236236
queuedDiagnostics.pointee.sourceFileIDs[bufferID] = allocatedSourceFileID
237237
}
238238

239+
private struct BridgedFixItMessage: FixItMessage {
240+
var message: String { "" }
241+
242+
var fixItID: MessageID {
243+
.init(domain: "SwiftCompiler", id: "BridgedFixIt")
244+
}
245+
}
246+
239247
/// Add a new diagnostic to the queue.
240248
@_cdecl("swift_ASTGen_addQueuedDiagnostic")
241249
public func addQueuedDiagnostic(
@@ -247,7 +255,8 @@ public func addQueuedDiagnostic(
247255
categoryName: BridgedStringRef,
248256
documentationPath: BridgedStringRef,
249257
highlightRangesPtr: UnsafePointer<BridgedCharSourceRange>?,
250-
numHighlightRanges: Int
258+
numHighlightRanges: Int,
259+
fixItsUntyped: BridgedArrayRef
251260
) {
252261
let queuedDiagnostics = queuedDiagnosticsPtr.assumingMemoryBound(
253262
to: QueuedDiagnostics.self
@@ -374,6 +383,34 @@ public func addQueuedDiagnostic(
374383
diagnosticState.pointee.referencedCategories.insert(category)
375384
}
376385

386+
// Map the Fix-Its
387+
let fixItChanges: [FixIt.Change] = fixItsUntyped.withElements(ofType: BridgedFixIt.self) { fixIts in
388+
fixIts.compactMap { fixIt in
389+
guard let startPos = sourceFile.position(of: fixIt.replacementRange.start),
390+
let endPos = sourceFile.position(
391+
of: fixIt.replacementRange.start.advanced(
392+
by: fixIt.replacementRange.byteLength)),
393+
let sourceFileSyntax = sourceFile.syntax.as(SourceFileSyntax.self) else {
394+
return nil
395+
}
396+
397+
return FixIt.Change.textualReplacement(
398+
replacementRange: startPos..<endPos,
399+
sourceFile: sourceFileSyntax,
400+
newText: String(bridged: fixIt.replacementText)
401+
)
402+
}
403+
}
404+
405+
let fixIts: [FixIt] = fixItChanges.isEmpty
406+
? []
407+
: [
408+
FixIt(
409+
message: BridgedFixItMessage(),
410+
changes: fixItChanges
411+
)
412+
]
413+
377414
let diagnostic = Diagnostic(
378415
node: node,
379416
position: position,
@@ -382,7 +419,8 @@ public func addQueuedDiagnostic(
382419
severity: severity.asSeverity,
383420
category: category
384421
),
385-
highlights: highlights
422+
highlights: highlights,
423+
fixIts: fixIts
386424
)
387425

388426
queuedDiagnostics.pointee.grouped.addDiagnostic(diagnostic)

0 commit comments

Comments
 (0)