DiagnosticEngine.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "DiagnosticEngine.h"
  7. namespace JSSpecCompiler {
  8. bool DiagnosticEngine::has_fatal_errors() const
  9. {
  10. return m_has_fatal_errors;
  11. }
  12. void DiagnosticEngine::print_diagnostics()
  13. {
  14. auto use_color = isatty(STDERR_FILENO) ? UseColor::Yes : UseColor::No;
  15. StringBuilder builder;
  16. for (auto const& diagnostic : m_diagnostics)
  17. diagnostic.format_into(builder, use_color);
  18. out(stderr, "{}", builder.string_view());
  19. }
  20. void DiagnosticEngine::Diagnostic::format_into(StringBuilder& builder, UseColor use_color) const
  21. {
  22. if (!location.filename.is_empty())
  23. builder.appendff("{}:{}:{}: ", location.filename, location.line + 1, location.column + 1);
  24. static constexpr Array<StringView, 4> colored_diagnostic_levels = { {
  25. "\e[1mnote\e[0m"sv,
  26. "\e[1;33mwarning\e[0m"sv,
  27. "\e[1;31merror\e[0m"sv,
  28. "\e[1;31mfatal error\e[0m"sv,
  29. } };
  30. static constexpr Array<StringView, 4> diagnostic_levels = { {
  31. "note"sv,
  32. "warning"sv,
  33. "error"sv,
  34. "fatal error"sv,
  35. } };
  36. auto diagnostic_level_text = (use_color == UseColor::Yes ? colored_diagnostic_levels : diagnostic_levels);
  37. builder.appendff("{}: ", diagnostic_level_text[to_underlying(level)]);
  38. if (auto logical_location = location.logical_location) {
  39. if (!logical_location->section.is_empty()) {
  40. builder.appendff("in {}", logical_location->section);
  41. if (!logical_location->step.is_empty())
  42. builder.appendff(" step {}", logical_location->step);
  43. builder.appendff(": ");
  44. }
  45. }
  46. builder.append(message);
  47. builder.append('\n');
  48. for (auto const& note : notes)
  49. note.format_into(builder, use_color);
  50. }
  51. void DiagnosticEngine::add_diagnostic(Diagnostic&& diagnostic)
  52. {
  53. if (diagnostic.level == DiagnosticLevel::FatalError)
  54. m_has_fatal_errors = true;
  55. if (diagnostic.level != DiagnosticLevel::Note)
  56. m_diagnostics.append(move(diagnostic));
  57. else
  58. m_diagnostics.last().notes.append(move(diagnostic));
  59. }
  60. }