diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 0b57a09e2551a..cce347ee0be7f 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -544,6 +544,12 @@ class BridgedDiagnosticArgument { BridgedDiagnosticArgument(BridgedStringRef s); }; +class BridgedFixIt { +public: + BridgedCharSourceRange replacementRange; + BridgedStringRef replacementText; +}; + class BridgedDiagnosticFixIt { public: int64_t storage[7]; diff --git a/include/swift/Bridging/ASTGen.h b/include/swift/Bridging/ASTGen.h index 936e28a4af3d1..afef5603a99c7 100644 --- a/include/swift/Bridging/ASTGen.h +++ b/include/swift/Bridging/ASTGen.h @@ -33,7 +33,8 @@ void swift_ASTGen_addQueuedDiagnostic( BridgedStringRef categoryName, BridgedStringRef documentationPath, const BridgedCharSourceRange *_Nullable highlightRanges, - ptrdiff_t numHighlightRanges); + ptrdiff_t numHighlightRanges, + BridgedArrayRef /*BridgedFixIt*/ fixIts); void swift_ASTGen_renderQueuedDiagnostics( void *_Nonnull queued, ssize_t contextSize, ssize_t colorize, BridgedStringRef *_Nonnull renderedString); diff --git a/lib/AST/DiagnosticBridge.cpp b/lib/AST/DiagnosticBridge.cpp index c2c7ab5bb6b73..039eadf639355 100644 --- a/lib/AST/DiagnosticBridge.cpp +++ b/lib/AST/DiagnosticBridge.cpp @@ -20,6 +20,7 @@ #include "swift/AST/DiagnosticEngine.h" #include "swift/Basic/SourceManager.h" #include "swift/Bridging/ASTGen.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/raw_ostream.h" using namespace swift; @@ -66,14 +67,19 @@ static void addQueueDiagnostic(void *queuedDiagnostics, if (info.EducationalNotePaths.size() > 0) documentationPath = info.EducationalNotePaths[0]; - // FIXME: Translate Fix-Its. - swift_ASTGen_addQueuedDiagnostic(queuedDiagnostics, perFrontendState, - text.str(), - severity, info.Loc, - info.Category, - documentationPath, - highlightRanges.data(), - highlightRanges.size()); + SmallVector fixIts; + for (const auto &fixIt : info.FixIts) { + fixIts.push_back(BridgedFixIt{ fixIt.getRange(), fixIt.getText() }); + } + + swift_ASTGen_addQueuedDiagnostic( + queuedDiagnostics, perFrontendState, + text.str(), + severity, info.Loc, + info.Category, + documentationPath, + highlightRanges.data(), highlightRanges.size(), + llvm::ArrayRef(fixIts)); // TODO: A better way to do this would be to pass the notes as an // argument to `swift_ASTGen_addQueuedDiagnostic` but that requires diff --git a/lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift b/lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift index d5d933605f6c3..6d733229c2e1a 100644 --- a/lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift +++ b/lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift @@ -236,6 +236,14 @@ public func addQueuedSourceFile( queuedDiagnostics.pointee.sourceFileIDs[bufferID] = allocatedSourceFileID } +private struct BridgedFixItMessage: FixItMessage { + var message: String { "" } + + var fixItID: MessageID { + .init(domain: "SwiftCompiler", id: "BridgedFixIt") + } +} + /// Add a new diagnostic to the queue. @_cdecl("swift_ASTGen_addQueuedDiagnostic") public func addQueuedDiagnostic( @@ -247,7 +255,8 @@ public func addQueuedDiagnostic( categoryName: BridgedStringRef, documentationPath: BridgedStringRef, highlightRangesPtr: UnsafePointer?, - numHighlightRanges: Int + numHighlightRanges: Int, + fixItsUntyped: BridgedArrayRef ) { let queuedDiagnostics = queuedDiagnosticsPtr.assumingMemoryBound( to: QueuedDiagnostics.self @@ -374,6 +383,33 @@ public func addQueuedDiagnostic( diagnosticState.pointee.referencedCategories.insert(category) } + // Map the Fix-Its + let fixItChanges: [FixIt.Change] = fixItsUntyped.withElements(ofType: BridgedFixIt.self) { fixIts in + fixIts.compactMap { fixIt in + guard let startPos = sourceFile.position(of: fixIt.replacementRange.start), + let endPos = sourceFile.position( + of: fixIt.replacementRange.start.advanced( + by: fixIt.replacementRange.byteLength)) else { + return nil + } + + return FixIt.Change.replaceText( + range: startPos..