Files
carbon-lang/toolchain/lexer/test_helpers.h
T
Chandler Carruth a857b7ea1a Cleanup or suppress numerous clang-tidy issues. (#577)
This gets us to a nearly clean state across the toolchain. A couple of
these are checks that I don't think we want to try to rigidly use and
I've disabled them completely. Others I've added relevant `NOLINT` style
suppressions or applied the automatic fix suggested by `clang-tidy`.

The implicit conversions that are allowed here with `NOLINT` are
probably worth at least a tiny bit of scrutiny to see if we could
replace the construct with something more direct without undue effort
and no longer need the implicit conversion. But until then, it seemed
fine to suppress.
2021-06-14 19:46:49 -07:00

60 lines
2.2 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef TOOLCHAIN_LEXER_TEST_HELPERS_H_
#define TOOLCHAIN_LEXER_TEST_HELPERS_H_
#include <array>
#include <string>
#include "gmock/gmock.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "toolchain/diagnostics/diagnostic_emitter.h"
namespace Carbon::Testing {
// A diagnostic translator for tests that lex a single token. Produces
// locations such as "`12.5`:1:3" to refer to the third character in the token.
class SingleTokenDiagnosticTranslator
: public DiagnosticLocationTranslator<const char*> {
public:
// Form a translator for a given token. The string provided here must refer
// to the same character array that we are going to lex.
explicit SingleTokenDiagnosticTranslator(llvm::StringRef token)
: token(token) {}
auto GetLocation(const char* pos) -> Diagnostic::Location override {
assert(llvm::is_sorted(std::array{token.begin(), pos, token.end()}) &&
"invalid diagnostic location");
llvm::StringRef prefix = token.take_front(pos - token.begin());
auto [before_last_newline, this_line] = prefix.rsplit('\n');
if (before_last_newline.size() == prefix.size()) {
// On first line.
return {.file_name = SynthesizeFilename(),
.line_number = 1,
.column_number = static_cast<int32_t>(pos - token.begin() + 1)};
} else {
// On second or subsequent lines. Note that the line number here is 2
// more than the number of newlines because `rsplit` removed one newline
// and `line_number` is 1-based.
return {.file_name = SynthesizeFilename(),
.line_number =
static_cast<int32_t>(before_last_newline.count('\n') + 2),
.column_number = static_cast<int32_t>(this_line.size() + 1)};
}
}
private:
[[nodiscard]] auto SynthesizeFilename() const -> std::string {
return llvm::formatv("`{0}`", token);
}
llvm::StringRef token;
};
} // namespace Carbon::Testing
#endif // TOOLCHAIN_LEXER_TOKENIZED_BUFFER_TEST_HELPERS_H_