Skip to content

Commit 5a164c5

Browse files
committed
[Frontend] Switch from YAML to .strings based localization
1 parent 799fff6 commit 5a164c5

14 files changed

+127
-117
lines changed

lib/Frontend/CompilerInvocation.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
14501450
// for the specified locale code.
14511451
llvm::SmallString<128> localizationPath(A->getValue());
14521452
llvm::sys::path::append(localizationPath, Opts.LocalizationCode);
1453-
llvm::sys::path::replace_extension(localizationPath, ".yaml");
1453+
llvm::sys::path::replace_extension(localizationPath, ".strings");
14541454
if (!llvm::sys::fs::exists(localizationPath)) {
14551455
Diags.diagnose(SourceLoc(), diag::warning_cannot_find_locale_file,
14561456
Opts.LocalizationCode, localizationPath);

localization/CMakeLists.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ add_custom_command(
66
COMMAND
77
${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/diagnostics/ ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
88
COMMAND
9-
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swift-def-to-yaml-converter"
9+
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swift-def-to-strings-converter"
1010
--output-directory ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
1111
COMMAND
1212
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swift-serialize-diagnostics"
13-
--input-file-path ${CMAKE_BINARY_DIR}/share/swift/diagnostics/en.yaml
13+
--input-file-path ${CMAKE_BINARY_DIR}/share/swift/diagnostics/en.strings
1414
--output-directory ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
1515
COMMAND
1616
${CMAKE_COMMAND} -E touch ${diagnostic_witness}
1717
DEPENDS
18-
swift-def-to-yaml-converter
18+
swift-def-to-strings-converter
1919
swift-serialize-diagnostics
2020
# Add files in diagnostics subdirectory when they're created
2121
)
@@ -31,4 +31,5 @@ swift_install_in_component(
3131
FILES_MATCHING
3232
PATTERN "*.db"
3333
PATTERN "*.yaml"
34+
PATTERN "*.strings"
3435
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
*--- en.strings - Localized diagnostic messages for English --------------===*
3+
*
4+
* This source file is part of the Swift.org open source project
5+
*
6+
* Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
7+
* Licensed under Apache License v2.0 with Runtime Library Exception
8+
*
9+
* See https://swift.org/LICENSE.txt for license information
10+
* See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11+
*
12+
*===----------------------------------------------------------------------===*
13+
*
14+
* This file defines the diagnostic messages for the English language.
15+
* Each diagnostic is described in the following format:
16+
* "<diagnostic-id>" = "<diagnostic-message>";
17+
*
18+
*===----------------------------------------------------------------------===*
19+
*
20+
*/
21+
"lex_unterminated_string" = "unterminated string literal";
22+
"var_init_self_referential" = "variable used within its own initial value";
23+
/* Tests different number of spaces between id and diagnostic message */
24+
"cannot_find_in_scope"= "cannot %select{find|find operator}1 %0 in scope";
25+
"warning_invalid_locale_code" = "unsupported locale code; supported locale codes are '%0'";

test/diagnostics/Localization/Inputs/en.yaml

-30
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
*===--- fr.strings - Localized diagnostic messages for French ------------===*
3+
*
4+
* This source file is part of the Swift.org open source project
5+
*
6+
* Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
7+
* Licensed under Apache License v2.0 with Runtime Library Exception
8+
*
9+
* See https://swift.org/LICENSE.txt for license information
10+
* See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11+
*
12+
*===----------------------------------------------------------------------===*
13+
*
14+
* This file defines the diagnostic messages for the French language.
15+
* Each diagnostic is described in the following format:
16+
* "<diagnostic-id>" = "<diagnostic-message>";
17+
*
18+
*/
19+
20+
/* Different order from `en.strings` */
21+
"var_init_self_referential" = "variable utilisée dans sa propre valeur initiale";
22+
23+
"lex_unterminated_string" = "chaîne non terminée littérale";
24+
25+
"cannot_find_in_scope" = "impossible %select{de trouver|de trouver opérateur}1 %0 portée";
26+
27+
"warning_invalid_locale_code" = "code de paramètres régionaux non pris en charge; les codes pris en charge sont '%0'";

test/diagnostics/Localization/Inputs/fr.yaml

-30
This file was deleted.

test/diagnostics/Localization/fr_debug_diagnostic_name.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// 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+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/fr.strings --output-directory=%t/
3+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/en.strings --output-directory=%t/
44
// RUN: not %target-swift-frontend -debug-diagnostic-names -localization-path %S/Inputs -locale fr -typecheck %s 2>&1 | %FileCheck %s --check-prefix=CHECK_NAMES
55

66
_ = "HI!

test/diagnostics/Localization/fr_localization.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// 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+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/fr.strings --output-directory=%t/
3+
// RUN: swift-serialize-diagnostics --input-file-path=%S/Inputs/en.strings --output-directory=%t/
44
// RUN: %target-typecheck-verify-swift -localization-path %t -locale fr
55

66
_ = "HI!

test/diagnostics/Localization/no_localization_files_and_wrong_path.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-typecheck-verify-swift -localization-path /Nonexistent_path -locale en
22

3-
// <unknown>:0: warning: cannot find translations for 'en' at '/Nonexistent_path/en.yaml': no such file
3+
// <unknown>:0: warning: cannot find translations for 'en' at '/Nonexistent_path/en.strings': no such file
44
// <unknown>:0: warning: specified localization directory '/Nonexistent_path' does not exist, translation is disabled
55

66
_ = "HI!

tools/swift-serialize-diagnostics/swift-serialize-diagnostics.cpp

+30-18
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static llvm::cl::OptionCategory Category("swift-serialize-diagnostics Options");
4242

4343
static llvm::cl::opt<std::string>
4444
InputFilePath("input-file-path",
45-
llvm::cl::desc("Path to the YAML input file"),
45+
llvm::cl::desc("Path to the YAML or `.strings` input file"),
4646
llvm::cl::cat(Category));
4747

4848
static llvm::cl::opt<std::string>
@@ -60,38 +60,50 @@ int main(int argc, char *argv[]) {
6060
"Swift Serialize Diagnostics Tool\n");
6161

6262
if (!llvm::sys::fs::exists(options::InputFilePath)) {
63-
llvm::errs() << "YAML file not found\n";
63+
llvm::errs() << "diagnostics file not found\n";
6464
return EXIT_FAILURE;
6565
}
6666

67-
YAMLLocalizationProducer yaml(options::InputFilePath);
68-
6967
auto localeCode = llvm::sys::path::filename(options::InputFilePath);
7068
llvm::SmallString<128> SerializedFilePath(options::OutputDirectory);
7169
llvm::sys::path::append(SerializedFilePath, localeCode);
7270
llvm::sys::path::replace_extension(SerializedFilePath, ".db");
7371

7472
SerializedLocalizationWriter Serializer;
75-
yaml.forEachAvailable(
76-
[&Serializer](swift::DiagID id, llvm::StringRef translation) {
77-
Serializer.insert(id, translation);
78-
});
73+
74+
if (llvm::sys::path::extension(options::InputFilePath) == ".yaml") {
75+
YAMLLocalizationProducer yaml(options::InputFilePath);
76+
77+
yaml.forEachAvailable(
78+
[&Serializer](swift::DiagID id, llvm::StringRef translation) {
79+
Serializer.insert(id, translation);
80+
});
81+
82+
// Print out the diagnostics IDs that are available in YAML but not
83+
// available in `.def`
84+
if (!yaml.unknownIDs.empty()) {
85+
llvm::errs() << "These diagnostic IDs are no longer available: '";
86+
llvm::interleave(
87+
yaml.unknownIDs, [&](std::string id) { llvm::errs() << id; },
88+
[&] { llvm::errs() << ", "; });
89+
llvm::errs() << "'\n";
90+
}
91+
} else {
92+
assert(llvm::sys::path::extension(options::InputFilePath) == ".strings");
93+
94+
StringsLocalizationProducer strings(options::InputFilePath);
95+
96+
strings.forEachAvailable(
97+
[&Serializer](swift::DiagID id, llvm::StringRef translation) {
98+
Serializer.insert(id, translation);
99+
});
100+
}
79101

80102
if (Serializer.emit(SerializedFilePath.str())) {
81103
llvm::errs() << "Cannot serialize diagnostic file "
82104
<< options::InputFilePath << '\n';
83105
return EXIT_FAILURE;
84106
}
85107

86-
// Print out the diagnostics IDs that are available in YAML but not available
87-
// in `.def`
88-
if (!yaml.unknownIDs.empty()) {
89-
llvm::errs() << "These diagnostic IDs are no longer available: '";
90-
llvm::interleave(
91-
yaml.unknownIDs, [&](std::string id) { llvm::errs() << id; },
92-
[&] { llvm::errs() << ", "; });
93-
llvm::errs() << "'\n";
94-
}
95-
96108
return EXIT_SUCCESS;
97109
}

unittests/Localization/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
add_swift_unittest(swiftLocalizationTests
2-
DefToYAMLConverterTests.cpp
2+
DefToStringsConverterTests.cpp
33
SerializationTests.cpp)
44

55
target_link_libraries(swiftLocalizationTests

unittests/Localization/DefToYAMLConverterTests.cpp unittests/Localization/DefToStringsConverterTests.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//===--- DefToYAMLConverterTests.cpp -------------------------------------===//
1+
//===--- DefToStringsConverterTests.cpp -----------------------------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -49,22 +49,22 @@ TEST_F(LocalizationTest, MissingLocalizationFiles) {
4949
ASSERT_TRUE(llvm::sys::fs::exists(getDefaultLocalizationPath()));
5050
llvm::SmallString<128> EnglishLocalization(getDefaultLocalizationPath());
5151
llvm::sys::path::append(EnglishLocalization, "en");
52-
llvm::sys::path::replace_extension(EnglishLocalization, ".yaml");
52+
llvm::sys::path::replace_extension(EnglishLocalization, ".strings");
5353
ASSERT_TRUE(llvm::sys::fs::exists(EnglishLocalization));
5454
llvm::sys::path::replace_extension(EnglishLocalization, ".db");
5555
ASSERT_TRUE(llvm::sys::fs::exists(EnglishLocalization));
5656
}
5757

5858
TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesSequentially) {
59-
YAMLLocalizationProducer yaml(YAMLPath);
60-
yaml.forEachAvailable([](swift::DiagID id, llvm::StringRef translation) {
59+
StringsLocalizationProducer strings(DiagsPath);
60+
strings.forEachAvailable([](swift::DiagID id, llvm::StringRef translation) {
6161
llvm::StringRef msg = diagnosticMessages[static_cast<uint32_t>(id)];
6262
ASSERT_EQ(msg, translation);
6363
});
6464
}
6565

6666
TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesRandomly) {
67-
YAMLLocalizationProducer yaml(YAMLPath);
67+
StringsLocalizationProducer strings(DiagsPath);
6868

6969
std::random_device rd;
7070
std::mt19937 gen(rd());
@@ -74,7 +74,7 @@ TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesRandomly) {
7474
unsigned randomNum = RandNumber(LocalDiagID::NumDiags);
7575
DiagID randomId = static_cast<DiagID>(randomNum);
7676
llvm::StringRef msg = diagnosticMessages[randomNum];
77-
llvm::StringRef translation = yaml.getMessageOr(randomId, "");
77+
llvm::StringRef translation = strings.getMessageOr(randomId, "");
7878
ASSERT_EQ(msg, translation);
7979
}
8080
}

unittests/Localization/LocalizationTest.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ struct LocalizationTest : public ::testing::Test {
5353
llvm::SmallVector<std::string, 4> TempFiles;
5454

5555
public:
56-
std::string YAMLPath;
56+
std::string DiagsPath;
5757

5858
LocalizationTest() {
59-
YAMLPath = std::string(createTemporaryFile("en", "yaml"));
59+
DiagsPath = std::string(createTemporaryFile("en", "strings"));
6060
}
6161

6262
void SetUp() override {
63-
bool failed = convertDefIntoYAML(YAMLPath);
64-
assert(!failed && "failed to generate a YAML file");
63+
bool failed = convertDefIntoStrings(DiagsPath);
64+
assert(!failed && "failed to generate a `.strings` file");
6565
}
6666

6767
void TearDown() override {
@@ -85,7 +85,7 @@ struct LocalizationTest : public ::testing::Test {
8585
unsigned RandNumber(unsigned n) { return unsigned(rand()) % n; }
8686

8787
protected:
88-
static bool convertDefIntoYAML(std::string outputPath) {
88+
static bool convertDefIntoStrings(std::string outputPath) {
8989
std::error_code error;
9090
llvm::raw_fd_ostream OS(outputPath, error, llvm::sys::fs::OF_None);
9191
if (OS.has_error() || error)
@@ -95,7 +95,7 @@ struct LocalizationTest : public ::testing::Test {
9595
llvm::ArrayRef<const char *> messages(diagnosticMessages,
9696
LocalDiagID::NumDiags);
9797

98-
DefToYAMLConverter converter(ids, messages);
98+
DefToStringsConverter converter(ids, messages);
9999
converter.convert(OS);
100100

101101
OS.flush();

0 commit comments

Comments
 (0)