test_helpers.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef TOOLCHAIN_LEXER_TEST_HELPERS_H_
  5. #define TOOLCHAIN_LEXER_TEST_HELPERS_H_
  6. #include <array>
  7. #include <string>
  8. #include "gmock/gmock.h"
  9. #include "llvm/ADT/STLExtras.h"
  10. #include "llvm/Support/FormatVariadic.h"
  11. #include "toolchain/diagnostics/diagnostic_emitter.h"
  12. namespace Carbon::Testing {
  13. // A diagnostic translator for tests that lex a single token. Produces
  14. // locations such as "`12.5`:1:3" to refer to the third character in the token.
  15. class SingleTokenDiagnosticTranslator
  16. : public DiagnosticLocationTranslator<const char*> {
  17. public:
  18. // Form a translator for a given token. The string provided here must refer
  19. // to the same character array that we are going to lex.
  20. explicit SingleTokenDiagnosticTranslator(llvm::StringRef token)
  21. : token(token) {}
  22. auto GetLocation(const char* pos) -> Diagnostic::Location override {
  23. assert(llvm::is_sorted(std::array{token.begin(), pos, token.end()}) &&
  24. "invalid diagnostic location");
  25. llvm::StringRef prefix = token.take_front(pos - token.begin());
  26. auto [before_last_newline, this_line] = prefix.rsplit('\n');
  27. if (before_last_newline.size() == prefix.size()) {
  28. // On first line.
  29. return {.file_name = SynthesizeFilename(),
  30. .line_number = 1,
  31. .column_number = static_cast<int32_t>(pos - token.begin() + 1)};
  32. } else {
  33. // On second or subsequent lines. Note that the line number here is 2
  34. // more than the number of newlines because `rsplit` removed one newline
  35. // and `line_number` is 1-based.
  36. return {.file_name = SynthesizeFilename(),
  37. .line_number =
  38. static_cast<int32_t>(before_last_newline.count('\n') + 2),
  39. .column_number = static_cast<int32_t>(this_line.size() + 1)};
  40. }
  41. }
  42. private:
  43. [[nodiscard]] auto SynthesizeFilename() const -> std::string {
  44. return llvm::formatv("`{0}`", token);
  45. }
  46. llvm::StringRef token;
  47. };
  48. } // namespace Carbon::Testing
  49. #endif // TOOLCHAIN_LEXER_TOKENIZED_BUFFER_TEST_HELPERS_H_