TextRange.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022-2023, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <LibSyntax/TextPosition.h>
  9. namespace Syntax {
  10. class TextRange {
  11. public:
  12. TextRange() = default;
  13. TextRange(TextPosition const& start, TextPosition const& end)
  14. : m_start(start)
  15. , m_end(end)
  16. {
  17. }
  18. bool is_valid() const { return m_start.is_valid() && m_end.is_valid() && m_start != m_end; }
  19. void clear()
  20. {
  21. m_start = {};
  22. m_end = {};
  23. }
  24. TextPosition& start() { return m_start; }
  25. TextPosition& end() { return m_end; }
  26. TextPosition const& start() const { return m_start; }
  27. TextPosition const& end() const { return m_end; }
  28. size_t line_count() const { return normalized_end().line() - normalized_start().line() + 1; }
  29. TextRange normalized() const { return TextRange(normalized_start(), normalized_end()); }
  30. void set_start(TextPosition const& position) { m_start = position; }
  31. void set_end(TextPosition const& position) { m_end = position; }
  32. void set(TextPosition const& start, TextPosition const& end)
  33. {
  34. m_start = start;
  35. m_end = end;
  36. }
  37. bool operator==(TextRange const& other) const
  38. {
  39. return m_start == other.m_start && m_end == other.m_end;
  40. }
  41. bool contains(TextPosition const& position) const
  42. {
  43. if (position.line() <= m_start.line() && (position.line() != m_start.line() || position.column() < m_start.column()))
  44. return false;
  45. if (position.line() >= m_end.line() && (position.line() != m_end.line() || position.column() > m_end.column()))
  46. return false;
  47. return true;
  48. }
  49. private:
  50. TextPosition normalized_start() const { return m_start < m_end ? m_start : m_end; }
  51. TextPosition normalized_end() const { return m_start < m_end ? m_end : m_start; }
  52. TextPosition m_start {};
  53. TextPosition m_end {};
  54. };
  55. }
  56. template<>
  57. struct AK::Formatter<Syntax::TextRange> : AK::Formatter<FormatString> {
  58. ErrorOr<void> format(FormatBuilder& builder, Syntax::TextRange const& value)
  59. {
  60. if (value.is_valid())
  61. return Formatter<FormatString>::format(builder, "{}-{}"sv, value.start(), value.end());
  62. return builder.put_string("TextRange(Invalid)"sv);
  63. }
  64. };