mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -377,9 +377,6 @@ void DiagnosticHelper::Implementation::beginMessage() {
|
||||
if (invocation.getDiagnosticOptions().UseColor)
|
||||
PDC.forceColors();
|
||||
|
||||
PDC.setPrintEducationalNotes(
|
||||
invocation.getDiagnosticOptions().PrintEducationalNotes);
|
||||
|
||||
PDC.setFormattingStyle(
|
||||
invocation.getDiagnosticOptions().PrintedFormattingStyle);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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:{{.*}}[0m[0;1;31merror: [0m[1mexpected 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:{{.*}}[0m[0;1;31merror: [0m[1mnon-nominal type 'Crap' (aka '() -> ()') cannot be extended
|
||||
// CHECK-NEXT:[0mextension Crap {}
|
||||
// CHECK-NEXT:[0;1;32m^ ~~~~
|
||||
// CHECK-NEXT:[0m[0m[1mNominal Types[0m
|
||||
// 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:[0m[1mbold[0m italics
|
||||
// CHECK-NEXT:--------------
|
||||
// CHECK-NEXT:[0m[1mHeader 1[0m
|
||||
// CHECK-NEXT:[0m[1mHeader 3[0m
|
||||
|
||||
// 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: -------------
|
||||
Reference in New Issue
Block a user