[Diagnostics] Remove rendering of educational notes to the terminal

We're moving over to a model where we provide direct links to educational notes /
diagnostic group notes whenever relevant. Rendering the Markdown from these
files to the terminal is less relevant with this approach, so remove it from the
compiler.
This commit is contained in:
Doug Gregor
2025-03-28 14:02:28 -07:00
parent f3329376ca
commit 7d569b989d
6 changed files with 0 additions and 314 deletions

View File

@@ -69,10 +69,6 @@ public:
PrintDiagnosticNamesMode PrintDiagnosticNames =
PrintDiagnosticNamesMode::None;
/// If set to true, include educational notes in printed output if available.
/// Educational notes are documentation which supplement diagnostics.
bool PrintEducationalNotes = false;
/// Whether to emit diagnostics in the terse LLVM style or in a more
/// descriptive style that's specific to Swift.
FormattingStyle PrintedFormattingStyle = FormattingStyle::Swift;

View File

@@ -32,14 +32,10 @@ namespace swift {
class PrintingDiagnosticConsumer : public DiagnosticConsumer {
llvm::raw_ostream &Stream;
bool ForceColors = false;
bool PrintEducationalNotes = false;
bool EmitMacroExpansionFiles = false;
bool DidErrorOccur = false;
DiagnosticOptions::FormattingStyle FormattingStyle =
DiagnosticOptions::FormattingStyle::LLVM;
// Educational notes which are buffered until the consumer is finished
// constructing a snippet.
SmallVector<std::string, 1> BufferedEducationalNotes;
bool SuppressOutput = false;
#if SWIFT_BUILD_SWIFT_SYNTAX
@@ -65,10 +61,6 @@ public:
llvm::sys::Process::UseANSIEscapeCodes(true);
}
void setPrintEducationalNotes(bool ShouldPrint) {
PrintEducationalNotes = ShouldPrint;
}
void setFormattingStyle(DiagnosticOptions::FormattingStyle style) {
FormattingStyle = style;
}

View File

@@ -2562,7 +2562,6 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
} else if (Args.hasArg(OPT_print_diagnostic_groups)) {
Opts.PrintDiagnosticNames = PrintDiagnosticNamesMode::Group;
}
Opts.PrintEducationalNotes |= Args.hasArg(OPT_print_educational_notes);
if (Arg *A = Args.getLastArg(OPT_diagnostic_documentation_path)) {
Opts.DiagnosticDocumentationPath = A->getValue();
}

View File

@@ -377,9 +377,6 @@ void DiagnosticHelper::Implementation::beginMessage() {
if (invocation.getDiagnosticOptions().UseColor)
PDC.forceColors();
PDC.setPrintEducationalNotes(
invocation.getDiagnosticOptions().PrintEducationalNotes);
PDC.setFormattingStyle(
invocation.getDiagnosticOptions().PrintedFormattingStyle);

View File

@@ -22,7 +22,6 @@
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Bridging/ASTGen.h"
#include "swift/Markup/Markup.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -30,202 +29,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace swift;
using namespace swift::markup;
namespace {
// MARK: Markdown Printing
class TerminalMarkupPrinter : public MarkupASTVisitor<TerminalMarkupPrinter> {
llvm::raw_ostream &OS;
unsigned Indent;
unsigned ShouldBold;
void indent(unsigned Amount = 2) { Indent += Amount; }
void dedent(unsigned Amount = 2) {
assert(Indent >= Amount && "dedent without matching indent");
Indent -= Amount;
}
void bold() {
++ShouldBold;
updateFormatting();
}
void unbold() {
assert(ShouldBold > 0 && "unbolded without matching bold");
--ShouldBold;
updateFormatting();
}
void updateFormatting() {
OS.resetColor();
if (ShouldBold > 0)
OS.changeColor(raw_ostream::Colors::SAVEDCOLOR, true);
}
void print(StringRef Str) {
for (auto c : Str) {
OS << c;
if (c == '\n')
for (unsigned i = 0; i < Indent; ++i)
OS << ' ';
}
}
public:
TerminalMarkupPrinter(llvm::raw_ostream &OS)
: OS(OS), Indent(0), ShouldBold(0) {}
void printNewline() { print("\n"); }
void visitDocument(const Document *D) {
for (const auto *Child : D->getChildren()) {
if (Child->getKind() == markup::ASTNodeKind::Paragraph) {
// Add a newline before top-level paragraphs
printNewline();
}
visit(Child);
}
}
void visitInlineAttributes(const InlineAttributes *A) {
print("^[");
for (const auto *Child : A->getChildren())
visit(Child);
print("](");
print(A->getAttributes());
print(")");
}
void visitBlockQuote(const BlockQuote *BQ) {
indent();
printNewline();
for (const auto *Child : BQ->getChildren())
visit(Child);
dedent();
}
void visitList(const List *BL) {
indent();
printNewline();
for (const auto *Child : BL->getChildren())
visit(Child);
dedent();
}
void visitItem(const Item *I) {
print("- ");
for (const auto *N : I->getChildren())
visit(N);
}
void visitCodeBlock(const CodeBlock *CB) {
indent();
printNewline();
print(CB->getLiteralContent());
dedent();
}
void visitCode(const Code *C) {
print("'");
print(C->getLiteralContent());
print("'");
}
void visitHTML(const HTML *H) { print(H->getLiteralContent()); }
void visitInlineHTML(const InlineHTML *IH) {
print(IH->getLiteralContent());
}
void visitSoftBreak(const SoftBreak *SB) { printNewline(); }
void visitLineBreak(const LineBreak *LB) {
printNewline();
printNewline();
}
void visitLink(const Link *L) {
print("[");
for (const auto *Child : L->getChildren())
visit(Child);
print("](");
print(L->getDestination());
print(")");
}
void visitImage(const Image *I) { llvm_unreachable("unsupported"); }
void visitParagraph(const Paragraph *P) {
for (const auto *Child : P->getChildren())
visit(Child);
printNewline();
}
// TODO: add raw_ostream support for italics ANSI codes in LLVM.
void visitEmphasis(const Emphasis *E) {
for (const auto *Child : E->getChildren())
visit(Child);
}
void visitStrong(const Strong *E) {
bold();
for (const auto *Child : E->getChildren())
visit(Child);
unbold();
}
void visitHRule(const HRule *HR) {
print("--------------");
printNewline();
}
void visitHeader(const Header *H) {
bold();
for (const auto *Child : H->getChildren())
visit(Child);
unbold();
printNewline();
}
void visitText(const Text *T) { print(T->getLiteralContent()); }
void visitPrivateExtension(const PrivateExtension *PE) {
llvm_unreachable("unsupported");
}
void visitParamField(const ParamField *PF) {
llvm_unreachable("unsupported");
}
void visitReturnField(const ReturnsField *RF) {
llvm_unreachable("unsupported");
}
void visitThrowField(const ThrowsField *TF) {
llvm_unreachable("unsupported");
}
#define MARKUP_SIMPLE_FIELD(Id, Keyword, XMLKind) \
void visit##Id(const Id *Field) { llvm_unreachable("unsupported"); }
#include "swift/Markup/SimpleFields.def"
};
static void printMarkdown(StringRef Content, raw_ostream &Out,
bool UseColor) {
markup::MarkupContext ctx;
auto document = markup::parseDocument(ctx, Content);
if (UseColor) {
ColoredStream stream{Out};
TerminalMarkupPrinter printer(stream);
printer.visit(document);
} else {
NoColorStream stream{Out};
TerminalMarkupPrinter printer(stream);
printer.visit(document);
}
}
} // end anonymous namespace
// MARK: Main DiagnosticConsumer entrypoint.
void PrintingDiagnosticConsumer::handleDiagnostic(SourceManager &SM,
@@ -261,16 +64,6 @@ void PrintingDiagnosticConsumer::handleDiagnostic(SourceManager &SM,
case DiagnosticOptions::FormattingStyle::LLVM:
printDiagnostic(SM, Info);
if (PrintEducationalNotes) {
for (auto path : Info.EducationalNotePaths) {
if (auto buffer = SM.getFileSystem()->getBufferForFile(path)) {
printMarkdown(buffer->get()->getBuffer(), Stream, ForceColors);
Stream << "\n";
}
}
}
for (auto ChildInfo : Info.ChildDiagnosticInfo) {
printDiagnostic(SM, *ChildInfo);
}
@@ -283,13 +76,6 @@ void PrintingDiagnosticConsumer::flush(bool includeTrailingBreak) {
DiagBridge.flush(Stream, includeTrailingBreak,
/*forceColors=*/ForceColors);
#endif
for (auto note : BufferedEducationalNotes) {
printMarkdown(note, Stream, ForceColors);
Stream << "\n";
}
BufferedEducationalNotes.clear();
}
bool PrintingDiagnosticConsumer::finishProcessing() {

View File

@@ -1,84 +0,0 @@
// RUN: not %target-swift-frontend -color-diagnostics -diagnostic-style=llvm -print-educational-notes -diagnostic-documentation-path %S/test-docs/ -diagnostic-style llvm -typecheck %s 2>&1 | %FileCheck %s --match-full-lines --strict-whitespace
// RUN: not %target-swift-frontend -no-color-diagnostics -print-educational-notes -diagnostic-documentation-path %S/test-docs/ -diagnostic-style llvm -typecheck %s 2>&1 | %FileCheck %s --match-full-lines --strict-whitespace --check-prefix=NO-COLOR
// A diagnostic with no educational notes
let x = 1 +
// CHECK:{{.*}}[0merror: expected expression after operator
// CHECK-NOT: {{-+$}}
// NO-COLOR:{{.*}}error: expected expression after operator
// NO-COLOR-NOT: {{-+$}}
// A diagnostic with an educational note using supported markdown features
typealias Crap = () -> ()
extension Crap {}
// CHECK:{{.*}}[0merror: non-nominal type 'Crap' (aka '() -> ()') cannot be extended
// CHECK-NEXT:extension Crap {}
// CHECK-NEXT:^ ~~~~
// CHECK-NEXT:Nominal Types
// CHECK-NEXT:--------------
// CHECK-EMPTY:
// CHECK-NEXT:Nominal types documentation content. This is a paragraph
// CHECK-EMPTY:
// CHECK-NEXT: blockquote
// CHECK-NEXT: {{$}}
// CHECK-NEXT: - item 1
// CHECK-NEXT: - item 2
// CHECK-NEXT: - item 3
// CHECK-NEXT: {{$}}
// CHECK-NEXT: let x = 42
// CHECK-NEXT: if x > 0 {
// CHECK-NEXT: print("positive")
// CHECK-NEXT: }
// CHECK-NEXT: {{$}}
// CHECK-NEXT:Type 'MyClass'
// CHECK-EMPTY:
// CHECK-NEXT:[Swift](swift.org)
// CHECK-EMPTY:
// CHECK-NEXT:bold italics
// CHECK-NEXT:--------------
// CHECK-NEXT:Header 1
// CHECK-NEXT:Header 3
// NO-COLOR:{{.*}}error: non-nominal type 'Crap' (aka '() -> ()') cannot be extended
// NO-COLOR-NEXT:extension Crap {}
// NO-COLOR-NEXT:^ ~~~~
// NO-COLOR-NEXT:Nominal Types
// NO-COLOR-NEXT:--------------
// NO-COLOR-EMPTY:
// NO-COLOR-NEXT:Nominal types documentation content. This is a paragraph
// NO-COLOR-EMPTY:
// NO-COLOR-NEXT: blockquote
// NO-COLOR-NEXT: {{$}}
// NO-COLOR-NEXT: - item 1
// NO-COLOR-NEXT: - item 2
// NO-COLOR-NEXT: - item 3
// NO-COLOR-NEXT: {{$}}
// NO-COLOR-NEXT: let x = 42
// NO-COLOR-NEXT: if x > 0 {
// NO-COLOR-NEXT: print("positive")
// NO-COLOR-NEXT: }
// NO-COLOR-NEXT: {{$}}
// NO-COLOR-NEXT:Type 'MyClass'
// NO-COLOR-EMPTY:
// NO-COLOR-NEXT:[Swift](swift.org)
// NO-COLOR-EMPTY:
// NO-COLOR-NEXT:bold italics
// NO-COLOR-NEXT:--------------
// NO-COLOR-NEXT:Header 1
// NO-COLOR-NEXT:Header 3
// CHECK-DESCRIPTIVE: educational-notes.swift
// CHECK-DESCRIPTIVE-NEXT: | // A diagnostic with an educational note
// CHECK-DESCRIPTIVE-NEXT: | extension Crap {}
// CHECK-DESCRIPTIVE-NEXT: | ^ error: expected expression after operator
// CHECK-DESCRIPTIVE-NEXT: |
// CHECK-DESCRIPTIVE: educational-notes.swift
// CHECK-DESCRIPTIVE-NEXT: | // A diagnostic with an educational note
// CHECK-DESCRIPTIVE-NEXT: | extension Crap {}
// CHECK-DESCRIPTIVE-NEXT: | ~~~~
// CHECK-DESCRIPTIVE-NEXT: | ^ error: non-nominal type 'Crap' (aka '() -> ()') cannot be extended
// CHECK-DESCRIPTIVE-NEXT: |
// CHECK-DESCRIPTIVE-NEXT: Nominal Types
// CHECK-DESCRIPTIVE-NEXT: -------------