Skip to content

Commit 2eb57d2

Browse files
authored
Merge pull request #34319 from HassanElDesouky/localization-debug-diagnostics
[Diag] Print the diagnostic ID name from localization
2 parents fe10f31 + 09b794d commit 2eb57d2

File tree

6 files changed

+84
-19
lines changed

6 files changed

+84
-19
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,15 @@ namespace swift {
814814
if (llvm::sys::fs::exists(filePath)) {
815815
if (auto file = llvm::MemoryBuffer::getFile(filePath)) {
816816
localization = std::make_unique<diag::SerializedLocalizationProducer>(
817-
std::move(file.get()));
817+
std::move(file.get()), getPrintDiagnosticNames());
818818
}
819819
} else {
820820
llvm::sys::path::replace_extension(filePath, ".yaml");
821821
// In case of missing localization files, we should fallback to messages
822822
// from `.def` files.
823823
if (llvm::sys::fs::exists(filePath)) {
824-
localization =
825-
std::make_unique<diag::YAMLLocalizationProducer>(filePath.str());
824+
localization = std::make_unique<diag::YAMLLocalizationProducer>(
825+
filePath.str(), getPrintDiagnosticNames());
826826
}
827827
}
828828
}
@@ -1049,7 +1049,7 @@ namespace swift {
10491049

10501050
public:
10511051
llvm::StringRef diagnosticStringFor(const DiagID id,
1052-
bool printDiagnosticName);
1052+
bool printDiagnosticNames);
10531053

10541054
/// If there is no clear .dia file for a diagnostic, put it in the one
10551055
/// corresponding to the SourceLoc given here.

include/swift/Localization/LocalizationFormat.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Support/EndianStream.h"
2727
#include "llvm/Support/MemoryBuffer.h"
2828
#include "llvm/Support/OnDiskHashTable.h"
29+
#include "llvm/Support/StringSaver.h"
2930
#include "llvm/Support/YAMLParser.h"
3031
#include "llvm/Support/YAMLTraits.h"
3132
#include "llvm/Support/raw_ostream.h"
@@ -154,14 +155,23 @@ class SerializedLocalizationWriter {
154155
};
155156

156157
class LocalizationProducer {
158+
/// This allocator will retain localized diagnostic strings containing the
159+
/// diagnostic's message and identifier as `message [id]` for the duration of
160+
/// compiler invocation. This will be used when the frontend flag
161+
/// `-debug-diagnostic-names` is used.
162+
llvm::BumpPtrAllocator localizationAllocator;
163+
llvm::StringSaver localizationSaver;
164+
bool printDiagnosticNames;
165+
157166
public:
167+
LocalizationProducer(bool printDiagnosticNames = false)
168+
: localizationSaver(localizationAllocator),
169+
printDiagnosticNames(printDiagnosticNames) {}
170+
158171
/// If the message isn't available/localized in current context
159172
/// return the fallback default message.
160173
virtual llvm::StringRef getMessageOr(swift::DiagID id,
161-
llvm::StringRef defaultMessage) const {
162-
auto message = getMessage(id);
163-
return message.empty() ? defaultMessage : message;
164-
}
174+
llvm::StringRef defaultMessage);
165175

166176
virtual ~LocalizationProducer() {}
167177

@@ -177,7 +187,8 @@ class YAMLLocalizationProducer final : public LocalizationProducer {
177187
public:
178188
/// The diagnostics IDs that are no longer available in `.def`
179189
std::vector<std::string> unknownIDs;
180-
explicit YAMLLocalizationProducer(llvm::StringRef filePath);
190+
explicit YAMLLocalizationProducer(llvm::StringRef filePath,
191+
bool printDiagnosticNames = false);
181192

182193
/// Iterate over all of the available (non-empty) translations
183194
/// maintained by this producer, callback gets each translation
@@ -198,7 +209,8 @@ class SerializedLocalizationProducer final : public LocalizationProducer {
198209

199210
public:
200211
explicit SerializedLocalizationProducer(
201-
std::unique_ptr<llvm::MemoryBuffer> buffer);
212+
std::unique_ptr<llvm::MemoryBuffer> buffer,
213+
bool printDiagnosticNames = false);
202214

203215
protected:
204216
llvm::StringRef getMessage(swift::DiagID id) const override;

lib/AST/DiagnosticEngine.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,12 +1115,10 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
11151115

11161116
llvm::StringRef
11171117
DiagnosticEngine::diagnosticStringFor(const DiagID id,
1118-
bool printDiagnosticName) {
1119-
// TODO: Print diagnostic names from `localization`.
1120-
if (printDiagnosticName) {
1121-
return debugDiagnosticStrings[(unsigned)id];
1122-
}
1123-
auto defaultMessage = diagnosticStrings[(unsigned)id];
1118+
bool printDiagnosticNames) {
1119+
auto defaultMessage = printDiagnosticNames
1120+
? debugDiagnosticStrings[(unsigned)id]
1121+
: diagnosticStrings[(unsigned)id];
11241122
if (localization) {
11251123
auto localizedMessage =
11261124
localization.get()->getMessageOr(id, defaultMessage);

lib/Localization/LocalizationFormat.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ enum LocalDiagID : uint32_t {
3737
NumDiags
3838
};
3939

40+
static constexpr const char *const diagnosticNameStrings[] = {
41+
#define DIAG(KIND, ID, Options, Text, Signature) " [" #ID "]",
42+
#include "swift/AST/DiagnosticsAll.def"
43+
"<not a diagnostic>",
44+
};
45+
4046
} // namespace
4147

4248
namespace llvm {
@@ -85,9 +91,24 @@ bool SerializedLocalizationWriter::emit(llvm::StringRef filePath) {
8591
return OS.has_error();
8692
}
8793

94+
llvm::StringRef
95+
LocalizationProducer::getMessageOr(swift::DiagID id,
96+
llvm::StringRef defaultMessage) {
97+
auto localizedMessage = getMessage(id);
98+
if (localizedMessage.empty())
99+
return defaultMessage;
100+
if (printDiagnosticNames) {
101+
llvm::StringRef diagnosticName(diagnosticNameStrings[(unsigned)id]);
102+
auto localizedDebugDiagnosticMessage =
103+
localizationSaver.save(localizedMessage.str() + diagnosticName.str());
104+
return localizedDebugDiagnosticMessage;
105+
}
106+
return localizedMessage;
107+
}
108+
88109
SerializedLocalizationProducer::SerializedLocalizationProducer(
89-
std::unique_ptr<llvm::MemoryBuffer> buffer)
90-
: Buffer(std::move(buffer)) {
110+
std::unique_ptr<llvm::MemoryBuffer> buffer, bool printDiagnosticNames)
111+
: LocalizationProducer(printDiagnosticNames), Buffer(std::move(buffer)) {
91112
auto base =
92113
reinterpret_cast<const unsigned char *>(Buffer.get()->getBufferStart());
93114
auto tableOffset = endian::read<offset_type>(base, little);
@@ -103,7 +124,9 @@ SerializedLocalizationProducer::getMessage(swift::DiagID id) const {
103124
return {(const char *)value.getDataPtr(), value.getDataLen()};
104125
}
105126

106-
YAMLLocalizationProducer::YAMLLocalizationProducer(llvm::StringRef filePath) {
127+
YAMLLocalizationProducer::YAMLLocalizationProducer(llvm::StringRef filePath,
128+
bool printDiagnosticNames)
129+
: LocalizationProducer(printDiagnosticNames) {
107130
auto FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(filePath);
108131
llvm::MemoryBuffer *document = FileBufOrErr->get();
109132
diag::LocalizationInput yin(document->getBuffer());
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: not %target-swift-frontend -debug-diagnostic-names -localization-path %S/Inputs -locale en -typecheck %s 2>&1 | %FileCheck %s --check-prefix=CHECK_NAMES
2+
3+
_ = "HI!
4+
// CHECK_NAMES: error: unterminated string literal [lex_unterminated_string]{{$}}
5+
6+
var self1 = self1
7+
// CHECK_NAMES: error: circular reference [circular_reference]{{$}}
8+
// CHECK_NAMES: note: through reference here [circular_reference_through]{{$}}
9+
10+
struct Broken {
11+
var b : Bool = True
12+
}
13+
// CHECK_NAMES: error: cannot find 'True' in scope [cannot_find_in_scope]{{$}}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/fr.yaml --output-directory=%t/
3+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/en.yaml --output-directory=%t/ 2>&1 | %FileCheck %s
4+
// RUN: not %target-swift-frontend -debug-diagnostic-names -localization-path %S/Inputs -locale fr -typecheck %s 2>&1 | %FileCheck %s --check-prefix=CHECK_NAMES
5+
6+
// CHECK: These diagnostic IDs are no longer availiable: 'not_available_in_def, not_available_in_def_2, not_available_in_def_3, not_available_in_def_4, not_available_in_def_5'
7+
_ = "HI!
8+
// CHECK_NAMES: error: chaîne non terminée littérale [lex_unterminated_string]{{$}}
9+
10+
// FIXME: This used to produce a localized diagnostic.
11+
12+
var self1 = self1
13+
// CHECK_NAMES: error: circular reference [circular_reference]{{$}}
14+
// CHECK_NAMES: note: through reference here [circular_reference_through]{{$}}
15+
16+
struct Broken {
17+
var b : Bool = True
18+
}
19+
// CHECK_NAMES: error: impossible de trouver 'True' portée [cannot_find_in_scope]{{$}}

0 commit comments

Comments
 (0)