Skip to content

Commit 172229e

Browse files
authored
Merge pull request #80988 from DougGregor/new-diagnostics-formatter-without-sourceloc-6.2
2 parents 2332e15 + 3ecd055 commit 172229e

File tree

5 files changed

+128
-28
lines changed

5 files changed

+128
-28
lines changed

include/swift/AST/DiagnosticBridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class DiagnosticBridge {
4646
void enqueueDiagnostic(SourceManager &SM, const DiagnosticInfo &Info,
4747
unsigned innermostBufferID);
4848

49+
/// Emit a single diagnostic without location information.
50+
void emitDiagnosticWithoutLocation(
51+
const DiagnosticInfo &Info, llvm::raw_ostream &out, bool forceColors);
52+
4953
/// Flush all enqueued diagnostics.
5054
void flush(llvm::raw_ostream &OS, bool includeTrailingBreak,
5155
bool forceColors);

include/swift/Bridging/ASTGen.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ void swift_ASTGen_addQueuedDiagnostic(
3535
const BridgedCharSourceRange *_Nullable highlightRanges,
3636
ptrdiff_t numHighlightRanges,
3737
BridgedArrayRef /*BridgedFixIt*/ fixIts);
38+
void swift_ASTGen_renderSingleDiagnostic(
39+
void *_Nonnull state,
40+
BridgedStringRef text,
41+
BridgedDiagnosticSeverity severity,
42+
BridgedStringRef categoryName,
43+
BridgedStringRef documentationPath,
44+
ssize_t colorize,
45+
BridgedStringRef *_Nonnull renderedString);
3846
void swift_ASTGen_renderQueuedDiagnostics(
3947
void *_Nonnull queued, ssize_t contextSize, ssize_t colorize,
4048
BridgedStringRef *_Nonnull renderedString);

lib/AST/DiagnosticBridge.cpp

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@
2626
using namespace swift;
2727

2828
#if SWIFT_BUILD_SWIFT_SYNTAX
29+
static BridgedDiagnosticSeverity bridgeDiagnosticSeverity(DiagnosticKind kind) {
30+
switch (kind) {
31+
case DiagnosticKind::Error:
32+
return BridgedDiagnosticSeverity::BridgedError;
33+
34+
case DiagnosticKind::Warning:
35+
return BridgedDiagnosticSeverity::BridgedWarning;
36+
37+
case DiagnosticKind::Remark:
38+
return BridgedDiagnosticSeverity::BridgedRemark;
39+
40+
case DiagnosticKind::Note:
41+
return BridgedDiagnosticSeverity::BridgedNote;
42+
}
43+
}
44+
2945
/// Enqueue a diagnostic with ASTGen's diagnostic rendering.
3046
static void addQueueDiagnostic(void *queuedDiagnostics,
3147
void *perFrontendState,
@@ -37,24 +53,7 @@ static void addQueueDiagnostic(void *queuedDiagnostics,
3753
info.FormatArgs);
3854
}
3955

40-
BridgedDiagnosticSeverity severity;
41-
switch (info.Kind) {
42-
case DiagnosticKind::Error:
43-
severity = BridgedDiagnosticSeverity::BridgedError;
44-
break;
45-
46-
case DiagnosticKind::Warning:
47-
severity = BridgedDiagnosticSeverity::BridgedWarning;
48-
break;
49-
50-
case DiagnosticKind::Remark:
51-
severity = BridgedDiagnosticSeverity::BridgedRemark;
52-
break;
53-
54-
case DiagnosticKind::Note:
55-
severity = BridgedDiagnosticSeverity::BridgedNote;
56-
break;
57-
}
56+
BridgedDiagnosticSeverity severity = bridgeDiagnosticSeverity(info.Kind);
5857

5958
// Map the highlight ranges.
6059
SmallVector<BridgedCharSourceRange, 2> highlightRanges;
@@ -87,6 +86,39 @@ static void addQueueDiagnostic(void *queuedDiagnostics,
8786
}
8887
}
8988

89+
void DiagnosticBridge::emitDiagnosticWithoutLocation(
90+
const DiagnosticInfo &info, llvm::raw_ostream &out, bool forceColors) {
91+
ASSERT(queuedDiagnostics == nullptr);
92+
93+
// If we didn't have per-frontend state before, create it now.
94+
if (!perFrontendState) {
95+
perFrontendState = swift_ASTGen_createPerFrontendDiagnosticState();
96+
}
97+
98+
llvm::SmallString<256> text;
99+
{
100+
llvm::raw_svector_ostream out(text);
101+
DiagnosticEngine::formatDiagnosticText(out, info.FormatString,
102+
info.FormatArgs);
103+
}
104+
105+
BridgedDiagnosticSeverity severity = bridgeDiagnosticSeverity(info.Kind);
106+
107+
BridgedStringRef bridgedRenderedString{nullptr, 0};
108+
swift_ASTGen_renderSingleDiagnostic(
109+
perFrontendState, text.str(), severity, info.Category,
110+
llvm::StringRef(info.CategoryDocumentationURL), forceColors ? 1 : 0,
111+
&bridgedRenderedString);
112+
113+
auto renderedString = bridgedRenderedString.unbridged();
114+
if (renderedString.data()) {
115+
out << "<unknown>:0: ";
116+
out.write(renderedString.data(), renderedString.size());
117+
swift_ASTGen_freeBridgedString(renderedString);
118+
out << "\n";
119+
}
120+
}
121+
90122
void DiagnosticBridge::enqueueDiagnostic(SourceManager &SM,
91123
const DiagnosticInfo &Info,
92124
unsigned innermostBufferID) {

lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,60 @@ public func addQueuedDiagnostic(
425425
queuedDiagnostics.pointee.grouped.addDiagnostic(diagnostic)
426426
}
427427

428+
/// Render a single diagnostic that has no source location information.
429+
@_cdecl("swift_ASTGen_renderSingleDiagnostic")
430+
public func renderSingleDiagnostic(
431+
perFrontendDiagnosticStatePtr: UnsafeMutableRawPointer,
432+
text: BridgedStringRef,
433+
severity: BridgedDiagnosticSeverity,
434+
categoryName: BridgedStringRef,
435+
documentationPath: BridgedStringRef,
436+
colorize: Int,
437+
renderedStringOutPtr: UnsafeMutablePointer<BridgedStringRef>
438+
) {
439+
let diagnosticState = perFrontendDiagnosticStatePtr.assumingMemoryBound(
440+
to: PerFrontendDiagnosticState.self
441+
)
442+
443+
let documentationPath = String(bridged: documentationPath)
444+
let documentationURL: String? = if !documentationPath.isEmpty {
445+
// If this looks doesn't look like a URL, prepend file://.
446+
documentationPath.looksLikeURL ? documentationPath : "file://\(documentationPath)"
447+
} else {
448+
nil
449+
}
450+
451+
let categoryName = String(bridged: categoryName)
452+
// If the data comes from serialized diagnostics, it's possible that
453+
// the category name is empty because StringRef() is serialized into
454+
// an empty string.
455+
let category: DiagnosticCategory? = if !categoryName.isEmpty {
456+
DiagnosticCategory(
457+
name: categoryName,
458+
documentationURL: documentationURL
459+
)
460+
} else {
461+
nil
462+
}
463+
464+
// Note that we referenced this category.
465+
if let category {
466+
diagnosticState.pointee.referencedCategories.insert(category)
467+
}
468+
469+
let formatter = DiagnosticsFormatter(colorize: colorize != 0)
470+
471+
let renderedStr = formatter.formattedMessage(
472+
SimpleDiagnostic(
473+
message: String(bridged: text),
474+
severity: severity.asSeverity,
475+
category: category
476+
)
477+
)
478+
479+
renderedStringOutPtr.pointee = allocateBridgedString(renderedStr)
480+
}
481+
428482
/// Render the queued diagnostics into a UTF-8 string.
429483
@_cdecl("swift_ASTGen_renderQueuedDiagnostics")
430484
public func renderQueuedDiagnostics(

lib/Frontend/PrintingDiagnosticConsumer.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,20 @@ void PrintingDiagnosticConsumer::handleDiagnostic(SourceManager &SM,
4848
#if SWIFT_BUILD_SWIFT_SYNTAX
4949
// Use the swift-syntax formatter.
5050
auto bufferStack = DiagnosticBridge::getSourceBufferStack(SM, Info.Loc);
51-
if (!bufferStack.empty()) {
52-
if (Info.Kind != DiagnosticKind::Note)
53-
DiagBridge.flush(Stream, /*includeTrailingBreak=*/true,
54-
/*forceColors=*/ForceColors);
51+
if (Info.Kind != DiagnosticKind::Note || bufferStack.empty())
52+
DiagBridge.flush(Stream, /*includeTrailingBreak=*/true,
53+
/*forceColors=*/ForceColors);
5554

55+
if (bufferStack.empty()) {
56+
DiagBridge.emitDiagnosticWithoutLocation(Info, Stream, ForceColors);
57+
} else {
5658
DiagBridge.enqueueDiagnostic(SM, Info, bufferStack.front());
57-
break;
5859
}
59-
#endif
60-
60+
return;
61+
#else
6162
// Fall through when we don't have the new diagnostics renderer available.
62-
// This also happens if the location of the diagnostic is invalid, because
63-
// the new rendered cannot cope with that.
6463
LLVM_FALLTHROUGH;
64+
#endif
6565
}
6666

6767
case DiagnosticOptions::FormattingStyle::LLVM:
@@ -215,4 +215,6 @@ PrintingDiagnosticConsumer::PrintingDiagnosticConsumer(
215215
llvm::raw_ostream &stream)
216216
: Stream(stream) {}
217217

218-
PrintingDiagnosticConsumer::~PrintingDiagnosticConsumer() {}
218+
PrintingDiagnosticConsumer::~PrintingDiagnosticConsumer() {
219+
flush();
220+
}

0 commit comments

Comments
 (0)