Rename DiagnosticLocationTranslator -> DiagnosticConverter (#3804)

Since the addition of TranslateArg, I don't think this type is going to
go away (cutting a TODO). Refactoring names slightly to fit the current
role, and adding const to ConvertLocation.
This commit is contained in:
Jon Ross-Perkins
2024-03-21 23:35:04 +00:00
committed by GitHub
parent 033c68c45b
commit 0bd45f0d6b
22 changed files with 204 additions and 211 deletions
+2 -2
View File
@@ -82,7 +82,7 @@ cc_library(
"//toolchain/lex:tokenized_buffer",
"//toolchain/parse:node_kind",
"//toolchain/parse:tree",
"//toolchain/parse:tree_node_location_translator",
"//toolchain/parse:tree_node_diagnostic_converter",
"//toolchain/sem_ir:builtin_kind",
"//toolchain/sem_ir:file",
"//toolchain/sem_ir:ids",
@@ -119,7 +119,7 @@ cc_library(
"//toolchain/lex:tokenized_buffer",
"//toolchain/parse:node_kind",
"//toolchain/parse:tree",
"//toolchain/parse:tree_node_location_translator",
"//toolchain/parse:tree_node_diagnostic_converter",
"//toolchain/sem_ir:entry_point",
"//toolchain/sem_ir:file",
"//toolchain/sem_ir:ids",
+35 -38
View File
@@ -12,7 +12,7 @@
#include "toolchain/lex/token_kind.h"
#include "toolchain/parse/node_ids.h"
#include "toolchain/parse/tree.h"
#include "toolchain/parse/tree_node_location_translator.h"
#include "toolchain/parse/tree_node_diagnostic_converter.h"
#include "toolchain/sem_ir/file.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/typed_insts.h"
@@ -25,19 +25,18 @@ namespace Carbon::Check {
#include "toolchain/parse/node_kind.def"
// Handles the transformation of a SemIRLocation to a DiagnosticLocation.
class SemIRLocationTranslator
: public DiagnosticLocationTranslator<SemIRLocation> {
class SemIRDiagnosticConverter : public DiagnosticConverter<SemIRLocation> {
public:
explicit SemIRLocationTranslator(
const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
node_translators,
explicit SemIRDiagnosticConverter(
const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
node_converters,
const SemIR::File* sem_ir)
: node_translators_(node_translators), sem_ir_(sem_ir) {}
: node_converters_(node_converters), sem_ir_(sem_ir) {}
auto GetLocation(SemIRLocation loc) -> DiagnosticLocation override {
auto ConvertLocation(SemIRLocation loc) const -> DiagnosticLocation override {
// Parse nodes always refer to the current IR.
if (!loc.is_inst_id) {
return GetLocationInFile(sem_ir_, loc.node_location);
return ConvertLocationInFile(sem_ir_, loc.node_location);
}
const auto* cursor_ir = sem_ir_;
@@ -46,7 +45,7 @@ class SemIRLocationTranslator
// If the parse node is valid, use it for the location.
if (auto node_id = cursor_ir->insts().GetNodeId(cursor_inst_id);
node_id.is_valid()) {
return GetLocationInFile(cursor_ir, node_id);
return ConvertLocationInFile(cursor_ir, node_id);
}
// If the parse node was invalid, recurse through import references when
@@ -69,38 +68,37 @@ class SemIRLocationTranslator
}
// Invalid parse node but not an import; just nothing to point at.
return GetLocationInFile(cursor_ir, Parse::NodeId::Invalid);
return ConvertLocationInFile(cursor_ir, Parse::NodeId::Invalid);
}
}
auto TranslateArg(DiagnosticTypeTranslation translation, llvm::Any arg) const
auto ConvertArg(DiagnosticTypeConversion conversion, llvm::Any arg) const
-> llvm::Any override {
switch (translation) {
case DiagnosticTypeTranslation::NameId: {
switch (conversion) {
case DiagnosticTypeConversion::NameId: {
auto name_id = llvm::any_cast<SemIR::NameId>(arg);
return sem_ir_->names().GetFormatted(name_id).str();
}
case DiagnosticTypeTranslation::TypeId: {
case DiagnosticTypeConversion::TypeId: {
auto type_id = llvm::any_cast<SemIR::TypeId>(arg);
return sem_ir_->StringifyType(type_id);
}
default:
return DiagnosticLocationTranslator<SemIRLocation>::TranslateArg(
translation, arg);
return DiagnosticConverter<SemIRLocation>::ConvertArg(conversion, arg);
}
}
private:
auto GetLocationInFile(const SemIR::File* sem_ir,
Parse::NodeLocation node_location) const
auto ConvertLocationInFile(const SemIR::File* sem_ir,
Parse::NodeLocation node_location) const
-> DiagnosticLocation {
auto it = node_translators_->find(sem_ir);
CARBON_CHECK(it != node_translators_->end());
return it->second->GetLocation(node_location);
auto it = node_converters_->find(sem_ir);
CARBON_CHECK(it != node_converters_->end());
return it->second->ConvertLocation(node_location);
}
const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
node_translators_;
const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
node_converters_;
const SemIR::File* sem_ir_;
};
@@ -129,15 +127,15 @@ struct UnitInfo {
explicit UnitInfo(Unit& unit)
: unit(&unit),
translator(unit.tokens, unit.tokens->source().filename(),
unit.parse_tree),
converter(unit.tokens, unit.tokens->source().filename(),
unit.parse_tree),
err_tracker(*unit.consumer),
emitter(translator, err_tracker) {}
emitter(converter, err_tracker) {}
Unit* unit;
// Emitter information.
Parse::NodeLocationTranslator translator;
Parse::NodeLocationConverter converter;
ErrorTrackingDiagnosticConsumer err_tracker;
DiagnosticEmitter<Parse::NodeLocation> emitter;
@@ -255,8 +253,8 @@ static auto ProcessNodeIds(Context& context,
// Produces and checks the IR for the provided Parse::Tree.
static auto CheckParseTree(
llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
node_translators,
llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
node_converters,
const SemIR::File& builtin_ir, UnitInfo& unit_info,
llvm::raw_ostream* vlog_stream) -> void {
unit_info.unit->sem_ir->emplace(
@@ -265,11 +263,10 @@ static auto CheckParseTree(
// For ease-of-access.
SemIR::File& sem_ir = **unit_info.unit->sem_ir;
CARBON_CHECK(
node_translators->insert({&sem_ir, &unit_info.translator}).second);
CARBON_CHECK(node_converters->insert({&sem_ir, &unit_info.converter}).second);
SemIRLocationTranslator translator(node_translators, &sem_ir);
Context::DiagnosticEmitter emitter(translator, unit_info.err_tracker);
SemIRDiagnosticConverter converter(node_converters, &sem_ir);
Context::DiagnosticEmitter emitter(converter, unit_info.err_tracker);
Context context(*unit_info.unit->tokens, emitter, *unit_info.unit->parse_tree,
sem_ir, vlog_stream);
PrettyStackTraceFunction context_dumper(
@@ -582,15 +579,15 @@ auto CheckParseTrees(const SemIR::File& builtin_ir,
}
}
llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>
node_translators;
llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>
node_converters;
// Check everything with no dependencies. Earlier entries with dependencies
// will be checked as soon as all their dependencies have been checked.
for (int check_index = 0;
check_index < static_cast<int>(ready_to_check.size()); ++check_index) {
auto* unit_info = ready_to_check[check_index];
CheckParseTree(&node_translators, builtin_ir, *unit_info, vlog_stream);
CheckParseTree(&node_converters, builtin_ir, *unit_info, vlog_stream);
for (auto* incoming_import : unit_info->incoming_imports) {
--incoming_import->imports_remaining;
if (incoming_import->imports_remaining == 0) {
@@ -635,7 +632,7 @@ auto CheckParseTrees(const SemIR::File& builtin_ir,
// incomplete imports.
for (auto& unit_info : unit_infos) {
if (unit_info.imports_remaining > 0) {
CheckParseTree(&node_translators, builtin_ir, unit_info, vlog_stream);
CheckParseTree(&node_converters, builtin_ir, unit_info, vlog_stream);
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@
#include "toolchain/check/scope_stack.h"
#include "toolchain/parse/node_ids.h"
#include "toolchain/parse/tree.h"
#include "toolchain/parse/tree_node_location_translator.h"
#include "toolchain/parse/tree_node_diagnostic_converter.h"
#include "toolchain/sem_ir/file.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/inst.h"
+1 -1
View File
@@ -9,7 +9,7 @@
#include "toolchain/check/function.h"
#include "toolchain/check/interface.h"
#include "toolchain/check/modifiers.h"
#include "toolchain/parse/tree_node_location_translator.h"
#include "toolchain/parse/tree_node_diagnostic_converter.h"
#include "toolchain/sem_ir/entry_point.h"
#include "toolchain/sem_ir/function.h"
#include "toolchain/sem_ir/ids.h"
+1 -1
View File
@@ -17,8 +17,8 @@ cc_library(
hdrs = [
"diagnostic.h",
"diagnostic_consumer.h",
"diagnostic_converter.h",
"diagnostic_emitter.h",
"diagnostic_translator.h",
],
deps = [
":diagnostic_kind",
@@ -0,0 +1,79 @@
// 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 CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_
#define CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_
#include <cstdint>
#include "common/check.h"
#include "llvm/ADT/Any.h"
#include "toolchain/diagnostics/diagnostic.h"
namespace Carbon {
// Known diagnostic type conversions. These are enumerated because `llvm::Any`
// doesn't expose the contained type; instead, we infer it from a given
// diagnostic.
enum class DiagnosticTypeConversion : int8_t {
None,
NameId,
TypeId,
};
// An interface that can convert some representation of a location into a
// diagnostic location.
template <typename LocationT>
class DiagnosticConverter {
public:
virtual ~DiagnosticConverter() = default;
virtual auto ConvertLocation(LocationT loc) const -> DiagnosticLocation = 0;
// Converts arg types as needed. Not all uses support conversion, so the
// default simply errors.
virtual auto ConvertArg(DiagnosticTypeConversion conversion,
llvm::Any /*arg*/) const -> llvm::Any {
CARBON_FATAL() << "Unexpected call to ConvertArg: "
<< static_cast<int8_t>(conversion);
}
};
// Used by types to indicate a DiagnosticTypeConversion that results in the
// provided StorageType. For example, to convert NameId to a std::string, we
// write:
//
// struct NameId {
// using DiagnosticType =
// DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::NameId>;
// };
template <typename StorageTypeT, DiagnosticTypeConversion ConversionV>
struct DiagnosticTypeInfo {
using StorageType = StorageTypeT;
static constexpr DiagnosticTypeConversion Conversion = ConversionV;
};
namespace Internal {
// Determines whether there's a DiagnosticType member on Arg.
// Used by DiagnosticEmitter.
template <typename Arg>
concept HasDiagnosticType =
requires { std::type_identity<typename Arg::DiagnosticType>(); };
// The default implementation with no conversion.
template <typename Arg, typename /*Unused*/ = void>
struct DiagnosticTypeForArg
: public DiagnosticTypeInfo<Arg, DiagnosticTypeConversion::None> {};
// Exposes a custom conversion for an argument type.
template <typename Arg>
requires HasDiagnosticType<Arg>
struct DiagnosticTypeForArg<Arg> : public Arg::DiagnosticType {};
} // namespace Internal
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_
+12 -13
View File
@@ -16,8 +16,8 @@
#include "llvm/Support/FormatVariadic.h"
#include "toolchain/diagnostics/diagnostic.h"
#include "toolchain/diagnostics/diagnostic_consumer.h"
#include "toolchain/diagnostics/diagnostic_converter.h"
#include "toolchain/diagnostics/diagnostic_kind.h"
#include "toolchain/diagnostics/diagnostic_translator.h"
namespace Carbon {
@@ -103,7 +103,7 @@ class DiagnosticEmitter {
const Internal::DiagnosticBase<Args...>& diagnostic_base,
llvm::SmallVector<llvm::Any> args) -> DiagnosticMessage {
return DiagnosticMessage(
diagnostic_base.Kind, emitter->translator_->GetLocation(location),
diagnostic_base.Kind, emitter->converter_->ConvertLocation(location),
diagnostic_base.Format, std::move(args),
[](const DiagnosticMessage& message) -> std::string {
return FormatFn<Args...>(
@@ -131,12 +131,11 @@ class DiagnosticEmitter {
Diagnostic diagnostic_;
};
// The `translator` and `consumer` are required to outlive the diagnostic
// The `converter` and `consumer` are required to outlive the diagnostic
// emitter.
explicit DiagnosticEmitter(
DiagnosticLocationTranslator<LocationT>& translator,
DiagnosticConsumer& consumer)
: translator_(&translator), consumer_(&consumer) {}
explicit DiagnosticEmitter(DiagnosticConverter<LocationT>& converter,
DiagnosticConsumer& consumer)
: converter_(&converter), consumer_(&consumer) {}
~DiagnosticEmitter() = default;
// Emits an error.
@@ -167,22 +166,22 @@ class DiagnosticEmitter {
private:
// Converts an argument to llvm::Any for storage, handling input to storage
// type translation when needed.
// type conversion when needed.
template <typename Arg>
auto MakeAny(Arg arg) -> llvm::Any {
if constexpr (Internal::DiagnosticTypeForArg<Arg>::Translation ==
DiagnosticTypeTranslation::None) {
if constexpr (Internal::DiagnosticTypeForArg<Arg>::Conversion ==
DiagnosticTypeConversion::None) {
return arg;
} else {
return translator_->TranslateArg(
Internal::DiagnosticTypeForArg<Arg>::Translation, arg);
return converter_->ConvertArg(
Internal::DiagnosticTypeForArg<Arg>::Conversion, arg);
}
}
template <typename LocT, typename AnnotateFn>
friend class DiagnosticAnnotationScope;
DiagnosticLocationTranslator<LocationT>* translator_;
DiagnosticConverter<LocationT>* converter_;
DiagnosticConsumer* consumer_;
llvm::SmallVector<llvm::function_ref<auto(DiagnosticBuilder& builder)->void>>
annotate_fns_;
@@ -15,17 +15,17 @@ namespace {
using ::Carbon::Testing::IsDiagnostic;
struct FakeDiagnosticLocationTranslator : DiagnosticLocationTranslator<int> {
auto GetLocation(int n) -> DiagnosticLocation override {
struct FakeDiagnosticConverter : DiagnosticConverter<int> {
auto ConvertLocation(int n) const -> DiagnosticLocation override {
return {.line_number = 1, .column_number = n};
}
};
class DiagnosticEmitterTest : public ::testing::Test {
protected:
DiagnosticEmitterTest() : emitter_(translator_, consumer_) {}
DiagnosticEmitterTest() : emitter_(converter_, consumer_) {}
FakeDiagnosticLocationTranslator translator_;
FakeDiagnosticConverter converter_;
Testing::MockDiagnosticConsumer consumer_;
DiagnosticEmitter<int> emitter_;
};
@@ -1,82 +0,0 @@
// 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 CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_
#define CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_
#include <cstdint>
#include "common/check.h"
#include "llvm/ADT/Any.h"
#include "toolchain/diagnostics/diagnostic.h"
namespace Carbon {
// Known diagnostic type translations. These are enumerated because `llvm::Any`
// doesn't expose the contained type; instead, we infer it from a given
// diagnostic.
enum class DiagnosticTypeTranslation : int8_t {
None,
NameId,
TypeId,
};
// An interface that can translate some representation of a location into a
// diagnostic location.
//
// TODO: Revisit this once the diagnostics machinery is more complete and see
// if we can turn it into a `std::function`.
template <typename LocationT>
class DiagnosticLocationTranslator {
public:
virtual ~DiagnosticLocationTranslator() = default;
virtual auto GetLocation(LocationT loc) -> DiagnosticLocation = 0;
// Translates arg types as needed. Not all uses support translation, so the
// default simply errors.
virtual auto TranslateArg(DiagnosticTypeTranslation translation,
llvm::Any /*arg*/) const -> llvm::Any {
CARBON_FATAL() << "Unexpected call to TranslateArg: "
<< static_cast<int8_t>(translation);
}
};
// Used by types to indicate a DiagnosticTypeTranslation that results in the
// provided StorageType. For example, to translate NameId to a std::string, we
// write:
//
// struct NameId {
// using DiagnosticType =
// DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::NameId>;
// };
template <typename StorageTypeT, DiagnosticTypeTranslation TranslationV>
struct DiagnosticTypeInfo {
using StorageType = StorageTypeT;
static constexpr DiagnosticTypeTranslation Translation = TranslationV;
};
namespace Internal {
// Determines whether there's a DiagnosticType member on Arg.
// Used by DiagnosticEmitter.
template <typename Arg>
concept HasDiagnosticType =
requires { std::type_identity<typename Arg::DiagnosticType>(); };
// The default implementation with no translation.
template <typename Arg, typename /*Unused*/ = void>
struct DiagnosticTypeForArg
: public DiagnosticTypeInfo<Arg, DiagnosticTypeTranslation::None> {};
// Exposes a custom translation for an argument type.
template <typename Arg>
requires HasDiagnosticType<Arg>
struct DiagnosticTypeForArg<Arg> : public Arg::DiagnosticType {};
} // namespace Internal
} // namespace Carbon
#endif // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_
+7 -7
View File
@@ -10,15 +10,15 @@
namespace Carbon {
template <typename LocationT>
inline auto NullDiagnosticLocationTranslator()
-> DiagnosticLocationTranslator<LocationT>& {
struct Translator : DiagnosticLocationTranslator<LocationT> {
auto GetLocation(LocationT /*loc*/) -> DiagnosticLocation override {
inline auto NullDiagnosticConverter() -> DiagnosticConverter<LocationT>& {
struct Converter : DiagnosticConverter<LocationT> {
auto ConvertLocation(LocationT /*loc*/) const
-> DiagnosticLocation override {
return {};
}
};
static auto* translator = new Translator;
return *translator;
static auto* converter = new Converter;
return *converter;
}
inline auto NullDiagnosticConsumer() -> DiagnosticConsumer& {
@@ -32,7 +32,7 @@ inline auto NullDiagnosticConsumer() -> DiagnosticConsumer& {
template <typename LocationT>
inline auto NullDiagnosticEmitter() -> DiagnosticEmitter<LocationT>& {
static auto* emitter = new DiagnosticEmitter<LocationT>(
NullDiagnosticLocationTranslator<LocationT>(), NullDiagnosticConsumer());
NullDiagnosticConverter<LocationT>(), NullDiagnosticConsumer());
return *emitter;
}
@@ -19,18 +19,18 @@ using ::testing::InSequence;
CARBON_DIAGNOSTIC(TestDiagnostic, Error, "{0}", llvm::StringLiteral);
struct FakeDiagnosticLocationTranslator
: DiagnosticLocationTranslator<DiagnosticLocation> {
auto GetLocation(DiagnosticLocation loc) -> DiagnosticLocation override {
struct FakeDiagnosticConverter : DiagnosticConverter<DiagnosticLocation> {
auto ConvertLocation(DiagnosticLocation loc) const
-> DiagnosticLocation override {
return loc;
}
};
TEST(SortedDiagnosticEmitterTest, SortErrors) {
FakeDiagnosticLocationTranslator translator;
FakeDiagnosticConverter converter;
Testing::MockDiagnosticConsumer consumer;
SortingDiagnosticConsumer sorting_consumer(consumer);
DiagnosticEmitter<DiagnosticLocation> emitter(translator, sorting_consumer);
DiagnosticEmitter<DiagnosticLocation> emitter(converter, sorting_consumer);
emitter.Emit({"f", "line", 2, 1}, TestDiagnostic, "M1");
emitter.Emit({"f", "line", 1, 1}, TestDiagnostic, "M2");
+6 -6
View File
@@ -77,10 +77,10 @@ class [[clang::internal_linkage]] Lexer {
DiagnosticConsumer& consumer)
: buffer_(value_stores, source),
consumer_(consumer),
translator_(&buffer_),
emitter_(translator_, consumer_),
token_translator_(&buffer_),
token_emitter_(token_translator_, consumer_) {}
converter_(&buffer_),
emitter_(converter_, consumer_),
token_converter_(&buffer_),
token_emitter_(token_converter_, consumer_) {}
// Find all line endings and create the line data structures.
//
@@ -170,10 +170,10 @@ class [[clang::internal_linkage]] Lexer {
ErrorTrackingDiagnosticConsumer consumer_;
TokenizedBuffer::SourceBufferLocationTranslator translator_;
TokenizedBuffer::SourceBufferDiagnosticConverter converter_;
LexerDiagnosticEmitter emitter_;
TokenLocationTranslator token_translator_;
TokenDiagnosticConverter token_converter_;
TokenDiagnosticEmitter token_emitter_;
};
+2 -2
View File
@@ -33,8 +33,8 @@ class NumericLiteralTest : public ::testing::Test {
}
auto Parse(llvm::StringRef text) -> NumericLiteral::Value {
Testing::SingleTokenDiagnosticTranslator translator(text);
DiagnosticEmitter<const char*> emitter(translator, error_tracker);
Testing::SingleTokenDiagnosticConverter converter(text);
DiagnosticEmitter<const char*> emitter(converter, error_tracker);
return Lex(text).ComputeValue(emitter);
}
+2 -2
View File
@@ -27,8 +27,8 @@ class StringLiteralTest : public ::testing::Test {
auto Parse(llvm::StringRef text) -> llvm::StringRef {
StringLiteral token = Lex(text);
Testing::SingleTokenDiagnosticTranslator translator(text);
DiagnosticEmitter<const char*> emitter(translator, error_tracker);
Testing::SingleTokenDiagnosticConverter converter(text);
DiagnosticEmitter<const char*> emitter(converter, error_tracker);
return token.ComputeValue(allocator, emitter);
}
+5 -6
View File
@@ -15,17 +15,16 @@
namespace Carbon::Testing {
// A diagnostic translator for tests that lex a single token. Produces
// A diagnostic converter 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*> {
class SingleTokenDiagnosticConverter : public DiagnosticConverter<const char*> {
public:
// Form a translator for a given token. The string provided here must refer
// Form a converter 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)
explicit SingleTokenDiagnosticConverter(llvm::StringRef token)
: token_(token) {}
auto GetLocation(const char* pos) -> DiagnosticLocation override {
auto ConvertLocation(const char* pos) const -> DiagnosticLocation override {
CARBON_CHECK(StringRefContainsPointer(token_, pos))
<< "invalid diagnostic location";
llvm::StringRef prefix = token_.take_front(pos - token_.begin());
+4 -4
View File
@@ -345,8 +345,8 @@ auto TokenIterator::Print(llvm::raw_ostream& output) const -> void {
output << token_.index;
}
auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
const char* loc) -> DiagnosticLocation {
auto TokenizedBuffer::SourceBufferDiagnosticConverter::ConvertLocation(
const char* loc) const -> DiagnosticLocation {
CARBON_CHECK(StringRefContainsPointer(buffer_->source_->text(), loc))
<< "location not within buffer";
int64_t offset = loc - buffer_->source_->text().begin();
@@ -390,7 +390,7 @@ auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
.column_number = column_number + 1};
}
auto TokenLocationTranslator::GetLocation(TokenIndex token)
auto TokenDiagnosticConverter::ConvertLocation(TokenIndex token) const
-> DiagnosticLocation {
// Map the token location into a position within the source buffer.
const auto& token_info = buffer_->GetTokenInfo(token);
@@ -402,7 +402,7 @@ auto TokenLocationTranslator::GetLocation(TokenIndex token)
// TODO: Should we somehow indicate in the diagnostic location if this token
// is a recovery token that doesn't correspond to the original source?
DiagnosticLocation loc =
TokenizedBuffer::SourceBufferLocationTranslator(buffer_).GetLocation(
TokenizedBuffer::SourceBufferDiagnosticConverter(buffer_).ConvertLocation(
token_start);
loc.length = buffer_->GetTokenText(token).size();
return loc;
+10 -11
View File
@@ -111,16 +111,15 @@ class TokenIterator
TokenIndex token_;
};
// A diagnostic location translator that maps token locations into source
// A diagnostic location converter that maps token locations into source
// buffer locations.
class TokenLocationTranslator
: public DiagnosticLocationTranslator<TokenIndex> {
class TokenDiagnosticConverter : public DiagnosticConverter<TokenIndex> {
public:
explicit TokenLocationTranslator(const TokenizedBuffer* buffer)
explicit TokenDiagnosticConverter(const TokenizedBuffer* buffer)
: buffer_(buffer) {}
// Map the given token into a diagnostic location.
auto GetLocation(TokenIndex token) -> DiagnosticLocation override;
auto ConvertLocation(TokenIndex token) const -> DiagnosticLocation override;
private:
const TokenizedBuffer* buffer_;
@@ -244,19 +243,19 @@ class TokenizedBuffer : public Printable<TokenizedBuffer> {
private:
friend class Lexer;
friend class TokenLocationTranslator;
friend class TokenDiagnosticConverter;
// A diagnostic location translator that maps token locations into source
// A diagnostic location converter that maps token locations into source
// buffer locations.
class SourceBufferLocationTranslator
: public DiagnosticLocationTranslator<const char*> {
class SourceBufferDiagnosticConverter
: public DiagnosticConverter<const char*> {
public:
explicit SourceBufferLocationTranslator(const TokenizedBuffer* buffer)
explicit SourceBufferDiagnosticConverter(const TokenizedBuffer* buffer)
: buffer_(buffer) {}
// Map the given position within the source buffer into a diagnostic
// location.
auto GetLocation(const char* loc) -> DiagnosticLocation override;
auto ConvertLocation(const char* loc) const -> DiagnosticLocation override;
private:
const TokenizedBuffer* buffer_;
+2 -2
View File
@@ -154,8 +154,8 @@ cc_fuzz_test(
)
cc_library(
name = "tree_node_location_translator",
hdrs = ["tree_node_location_translator.h"],
name = "tree_node_diagnostic_converter",
hdrs = ["tree_node_diagnostic_converter.h"],
deps = [
":tree",
"//toolchain/diagnostics:diagnostic_emitter",
+2 -2
View File
@@ -20,8 +20,8 @@ auto HandleInvalid(Context& context) -> void {
auto Parse(Lex::TokenizedBuffer& tokens, DiagnosticConsumer& consumer,
llvm::raw_ostream* vlog_stream) -> Tree {
Lex::TokenLocationTranslator translator(&tokens);
Lex::TokenDiagnosticEmitter emitter(translator, consumer);
Lex::TokenDiagnosticConverter converter(&tokens);
Lex::TokenDiagnosticEmitter emitter(converter, consumer);
// Delegate to the parser.
Tree tree(tokens);
@@ -2,8 +2,8 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
#define CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
#ifndef CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_
#define CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_
#include "toolchain/diagnostics/diagnostic_emitter.h"
#include "toolchain/lex/tokenized_buffer.h"
@@ -34,18 +34,18 @@ inline auto TokenOnly(NodeId node_id) -> NodeLocation {
return NodeLocation(node_id, true);
}
class NodeLocationTranslator
: public DiagnosticLocationTranslator<NodeLocation> {
class NodeLocationConverter : public DiagnosticConverter<NodeLocation> {
public:
explicit NodeLocationTranslator(const Lex::TokenizedBuffer* tokens,
llvm::StringRef filename,
const Tree* parse_tree)
: token_translator_(tokens),
explicit NodeLocationConverter(const Lex::TokenizedBuffer* tokens,
llvm::StringRef filename,
const Tree* parse_tree)
: token_converter_(tokens),
filename_(filename),
parse_tree_(parse_tree) {}
// Map the given token into a diagnostic location.
auto GetLocation(NodeLocation node_location) -> DiagnosticLocation override {
auto ConvertLocation(NodeLocation node_location) const
-> DiagnosticLocation override {
// Support the invalid token as a way to emit only the filename, when there
// is no line association.
if (!node_location.node_id().is_valid()) {
@@ -53,7 +53,7 @@ class NodeLocationTranslator
}
if (node_location.token_only()) {
return token_translator_.GetLocation(
return token_converter_.ConvertLocation(
parse_tree_->node_token(node_location.node_id()));
}
@@ -73,11 +73,12 @@ class NodeLocationTranslator
end_token = desc_token;
}
}
DiagnosticLocation start_loc = token_translator_.GetLocation(start_token);
DiagnosticLocation start_loc =
token_converter_.ConvertLocation(start_token);
if (start_token == end_token) {
return start_loc;
}
DiagnosticLocation end_loc = token_translator_.GetLocation(end_token);
DiagnosticLocation end_loc = token_converter_.ConvertLocation(end_token);
// For multiline locations we simply return the rest of the line for now
// since true multiline locations are not yet supported.
if (start_loc.line_number != end_loc.line_number) {
@@ -92,11 +93,11 @@ class NodeLocationTranslator
}
private:
Lex::TokenLocationTranslator token_translator_;
Lex::TokenDiagnosticConverter token_converter_;
llvm::StringRef filename_;
const Tree* parse_tree_;
};
} // namespace Carbon::Parse
#endif // CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
#endif // CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_
+2 -2
View File
@@ -285,7 +285,7 @@ constexpr BoolValue BoolValue::True = BoolValue(1);
struct NameId : public IdBase, public Printable<NameId> {
// names().GetFormatted() is used for diagnostics.
using DiagnosticType =
DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::NameId>;
DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::NameId>;
// An explicitly invalid ID.
static const NameId Invalid;
@@ -423,7 +423,7 @@ struct TypeId : public IdBase, public Printable<TypeId> {
using ValueType = TypeInfo;
// StringifyType() is used for diagnostics.
using DiagnosticType =
DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::TypeId>;
DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::TypeId>;
// The builtin TypeType.
static const TypeId TypeType;
+7 -6
View File
@@ -11,8 +11,9 @@
namespace Carbon {
namespace {
struct FilenameTranslator : DiagnosticLocationTranslator<llvm::StringRef> {
auto GetLocation(llvm::StringRef filename) -> DiagnosticLocation override {
struct FilenameConverter : DiagnosticConverter<llvm::StringRef> {
auto ConvertLocation(llvm::StringRef filename) const
-> DiagnosticLocation override {
return {.filename = filename};
}
};
@@ -28,8 +29,8 @@ auto SourceBuffer::MakeFromFile(llvm::vfs::FileSystem& fs,
llvm::StringRef filename,
DiagnosticConsumer& consumer)
-> std::optional<SourceBuffer> {
FilenameTranslator translator;
DiagnosticEmitter<llvm::StringRef> emitter(translator, consumer);
FilenameConverter converter;
DiagnosticEmitter<llvm::StringRef> emitter(converter, consumer);
llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> file =
fs.openFileForRead(filename);
@@ -63,8 +64,8 @@ auto SourceBuffer::MakeFromMemoryBuffer(
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer,
llvm::StringRef filename, bool is_regular_file,
DiagnosticConsumer& consumer) -> std::optional<SourceBuffer> {
FilenameTranslator translator;
DiagnosticEmitter<llvm::StringRef> emitter(translator, consumer);
FilenameConverter converter;
DiagnosticEmitter<llvm::StringRef> emitter(converter, consumer);
if (buffer.getError()) {
CARBON_DIAGNOSTIC(ErrorReadingFile, Error, "Error reading file: {0}",