Skip to content

[Diagnostics] Updated diagnostic printing style #30027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Mar 3, 2020

Conversation

owenv
Copy link
Contributor

@owenv owenv commented Feb 24, 2020

This PR adds a new diag printing style behind the -enable-experimental-diagnostic-formatting frontend flag. A few notes:

  • This style supports -no-color-diagnostics, but mostly just for testing purposes. When this is supported in the driver, I think it would be better just to fallback to the LLVM style if color is unsupported or disabled.
  • This relies on a lot of expensive line-breaking SourceManager operations. Perf seems ok so far, but I intend to investigate alternatives before this becomes an officially supported feature.
  • Until [DiagnosticVerifier] Make DiagnosticVerifier a DiagnosticConsumer #28313 lands, enabling this feature will break the verifier.
  • I assume vim/emacs can't parse this format out of the box, but I haven't tested it yet.
  • I'm not a designer so some of the color/layout decisions here are probably terrible :)

The code/tests aren't the easiest to parse, so here's an example of a program:

func foo(a: Int, b: Int) {
  a + b
}

foo(b: 1, a: 2)


func baz() {
  bar(a: "hello, world!")
}

struct Foo: Codable {
  var x: Int
  var x: Int
}

func bar(a: Int) {}
func bar(a: Float) {}


func bazz() throws {

}
bazz()

struct A {}
extension A {
  let x: Int = { 42 }
}

let abc = "👍

Which produces diags that look like this:


Owens-MacBook-Pro-3swift-macosx-x86_64 owenvoorhees$ binswift -Xfrontend -enable-experimental-diagnostic-formatting ~Desktop
UsersowenvoorheesDesktophello swift241

@owenv
Copy link
Contributor Author

owenv commented Feb 24, 2020

I've only tested this on macOS so far, let's get some preliminary results on other platforms.

@swift-ci please test

}

// Describe a fix-it out-of-line.
static void describeFixIt(SourceManager &SM, DiagnosticInfo::FixIt fixIt,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice!

@owenv
Copy link
Contributor Author

owenv commented Feb 24, 2020

@swift-ci please test Windows platform

1 similar comment
@owenv
Copy link
Contributor Author

owenv commented Feb 24, 2020

@swift-ci please test Windows platform

@owenv
Copy link
Contributor Author

owenv commented Feb 24, 2020

This is a big change, so here's a rough overview of how everything fits together.

  • The PrintingDiagnosticConsumer entry point remains handleDiagnostic Depending on whether experimental formatting is enabled, it either uses the existing LLVM-style formatting, or creates an AnnotatedSourceSnippet which groups a diagnostic and any notes which follow it.

  • AnnotatedSourceSnippet manages a group of AnnotatedFileExcerpts. Often this will only be one unless the diagnostic and notes span multiple files/compiled modules. It also tracks any parts of the diagnostic with unknown source locations.

  • Each AnnotatedFileExcerpt has one or more AnnotatedLines, which collect the messages, highlights, and inline fix-its for a single line in the source file.

Printing each message is a two stage process. First, as the consumer receives diags and associated notes, it builds up an AnnotatedSourceSnippet using the appropriate add* methods. Then, once the snippet is complete, render is called to perform the actual printing to an output stream.

@owenv owenv requested review from hborla and xedin February 24, 2020 15:53
@xedin
Copy link
Contributor

xedin commented Feb 24, 2020

Thank you, @owenv! I'll try to take a look asap

if (shouldDelete != Deleted) {
Out.resetColor();
if (shouldDelete) {
Out.changeColor(ColoredStream::Colors::RED);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For accessibility reasons, proposed insertions and deletions shouldn't be distinguished (at least solely) by the colors red and green. This is because red-green colorblindness is the most common form of the condition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing this up. I've started to address this by adding a textual description of the fix-it to the end of all messages with fix-its, instead of just notes (e.g. error: argument 'a' must precede argument 'b' [remove ', a: 2' and insert 'a: 2, ']).

I think there's more that can and should be done here, but I haven't come up with a design I'm happy with yet, so I'll leave this unresolved for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now modified the formatting to put a + below inserted characters and a - below deleted characters. The message now looks like this:

Screen Shot 2020-02-27 at 3 33 17 PM

Combined with the change above, I think this is more accessible than the first attempt and mostly addresses your second comment as well.

/*background*/ false);
++i;
} else {
Out << fixIt.Text[i];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be helpful to have some other way of indicating that a certain span of text is a proposed fix-it insertion. At present, my first glance impression was that there was some syntax coloring going on, which doesn't immediately make it clear that the text isn't already in the source code.

@owenv owenv force-pushed the pretty_print_errors branch from c52c41b to 3382965 Compare February 27, 2020 17:09
@owenv
Copy link
Contributor Author

owenv commented Feb 27, 2020

Kicking off another round of tests to verify the recent changes

@swift-ci please smoke test

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you, @owenv! You can also split some of the changes, e.g. renaming of the language option for educational notes, into a separate PR so it could be merged sooner.

@owenv
Copy link
Contributor Author

owenv commented Mar 2, 2020

@xedin Thanks for looking over this! In that case, should I wait to merge this PR? Since this is frontend-only right now, I was planning on improving it on master until I'm ready to add driver support or make it public.

@xedin
Copy link
Contributor

xedin commented Mar 2, 2020

Since this is under a flag and doesn't affect anything else I think you can go ahead and merge it.

@owenv
Copy link
Contributor Author

owenv commented Mar 2, 2020

@xedin sounds good, I'll just make sure this is still passing tests on all three platforms then.

@owenv
Copy link
Contributor Author

owenv commented Mar 2, 2020

@swift-ci please test

@owenv
Copy link
Contributor Author

owenv commented Mar 2, 2020

@swift-ci please test Windows platform

@owenv owenv merged commit 69b513a into swiftlang:master Mar 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants