(diag *Diagnostic)
| 44 | } |
| 45 | |
| 46 | func (w *diagnosticTextWriter) WriteDiagnostic(diag *Diagnostic) error { |
| 47 | if diag == nil { |
| 48 | return errors.New("nil diagnostic") |
| 49 | } |
| 50 | |
| 51 | var colorCode, highlightCode, resetCode string |
| 52 | if w.color { |
| 53 | switch diag.Severity { |
| 54 | case DiagError: |
| 55 | colorCode = "\x1b[31m" |
| 56 | case DiagWarning: |
| 57 | colorCode = "\x1b[33m" |
| 58 | } |
| 59 | resetCode = "\x1b[0m" |
| 60 | highlightCode = "\x1b[1;4m" |
| 61 | } |
| 62 | |
| 63 | var severityStr string |
| 64 | switch diag.Severity { |
| 65 | case DiagError: |
| 66 | severityStr = "Error" |
| 67 | case DiagWarning: |
| 68 | severityStr = "Warning" |
| 69 | default: |
| 70 | // should never happen |
| 71 | severityStr = "???????" |
| 72 | } |
| 73 | |
| 74 | _, err := fmt.Fprintf(w.wr, "%s%s%s: %s\n\n", colorCode, severityStr, resetCode, diag.Summary) |
| 75 | if err != nil { |
| 76 | return fmt.Errorf("write failed: %w", err) |
| 77 | } |
| 78 | |
| 79 | if diag.Subject != nil { |
| 80 | snipRange := *diag.Subject |
| 81 | highlightRange := snipRange |
| 82 | if diag.Context != nil { |
| 83 | // Show enough of the source code to include both the subject |
| 84 | // and context ranges, which overlap in all reasonable |
| 85 | // situations. |
| 86 | snipRange = RangeOver(snipRange, *diag.Context) |
| 87 | } |
| 88 | // We can't illustrate an empty range, so we'll turn such ranges into |
| 89 | // single-character ranges, which might not be totally valid (may point |
| 90 | // off the end of a line, or off the end of the file) but are good |
| 91 | // enough for the bounds checks we do below. |
| 92 | if snipRange.Empty() { |
| 93 | snipRange.End.Byte++ |
| 94 | snipRange.End.Column++ |
| 95 | } |
| 96 | if highlightRange.Empty() { |
| 97 | highlightRange.End.Byte++ |
| 98 | highlightRange.End.Column++ |
| 99 | } |
| 100 | |
| 101 | file := w.files[diag.Subject.Filename] |
| 102 | if file == nil || file.Bytes == nil { |
| 103 | _, err = fmt.Fprintf(w.wr, " on %s line %d:\n (source code not available)\n\n", diag.Subject.Filename, diag.Subject.Start.Line) |
no test coverage detected