forked from apple/swift
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master' into master-next
- Loading branch information
Showing
8 changed files
with
263 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
swift_install_in_component(DIRECTORY diagnostics | ||
DESTINATION "share/swift/" | ||
COMPONENT compiler) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
//===--- LocalizationFormat.h - YAML format for Diagnostic Messages ---*- | ||
// C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines the format for localized diagnostic messages. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_LOCALIZATIONFORMAT_H | ||
#define SWIFT_LOCALIZATIONFORMAT_H | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/Support/YAMLParser.h" | ||
#include "llvm/Support/YAMLTraits.h" | ||
#include <string> | ||
#include <type_traits> | ||
|
||
namespace swift { | ||
enum class DiagID : uint32_t; | ||
|
||
namespace diag { | ||
class LocalizationProducer { | ||
public: | ||
/// If the message isn't available/localized in the current `yaml` file, | ||
/// return the fallback default message. | ||
virtual llvm::StringRef getMessageOr(swift::DiagID id, | ||
llvm::StringRef defaultMessage) const { | ||
return defaultMessage; | ||
} | ||
|
||
virtual ~LocalizationProducer() {} | ||
}; | ||
|
||
class YAMLLocalizationProducer final : public LocalizationProducer { | ||
public: | ||
std::vector<std::string> diagnostics; | ||
explicit YAMLLocalizationProducer(std::string locale, std::string path); | ||
llvm::StringRef getMessageOr(swift::DiagID id, | ||
llvm::StringRef defaultMessage) const override; | ||
}; | ||
|
||
class LocalizationInput : public llvm::yaml::Input { | ||
using Input::Input; | ||
|
||
/// Read diagnostics in the YAML file iteratively | ||
template <typename T, typename Context> | ||
friend typename std::enable_if<llvm::yaml::has_SequenceTraits<T>::value, | ||
void>::type | ||
readYAML(llvm::yaml::IO &io, T &Seq, bool, Context &Ctx); | ||
|
||
template <typename T> | ||
friend typename std::enable_if<llvm::yaml::has_SequenceTraits<T>::value, | ||
LocalizationInput &>::type | ||
operator>>(LocalizationInput &yin, T &diagnostics); | ||
}; | ||
|
||
} // namespace diag | ||
} // namespace swift | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#===--- en.yaml - Localized diagnostic messages for English ---*- YAML -*-===# | ||
# | ||
# This source file is part of the Swift.org open source project | ||
# | ||
# Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
# Licensed under Apache License v2.0 with Runtime Library Exception | ||
# | ||
# See https://swift.org/LICENSE.txt for license information | ||
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
# | ||
#===----------------------------------------------------------------------===# | ||
# | ||
# This file defines the diagnostic messages for the English language. | ||
# Each diagnostic is described in the following format: | ||
# - id: "<diagnostic-id>" | ||
# msg: "<diagnostic-message>" | ||
# | ||
#===----------------------------------------------------------------------===# | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#===--- fr.yaml - Localized diagnostic messages for French ---*- YAML -*-===# | ||
# | ||
# This source file is part of the Swift.org open source project | ||
# | ||
# Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
# Licensed under Apache License v2.0 with Runtime Library Exception | ||
# | ||
# See https://swift.org/LICENSE.txt for license information | ||
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
# | ||
#===----------------------------------------------------------------------===# | ||
# | ||
# This file defines the diagnostic messages for the French language. | ||
# Each diagnostic is described in the following format: | ||
# - id: "<diagnostic-id>" | ||
# msg: "<diagnostic-message>" | ||
# | ||
#===----------------------------------------------------------------------===# | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
//===--- LocalizationFormat.cpp - YAML format for Diagnostic Messages ---*- | ||
// C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file implements the format for localized diagnostic messages. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "swift/AST/LocalizationFormat.h" | ||
#include "llvm/ADT/SmallString.h" | ||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/Support/CommandLine.h" | ||
#include "llvm/Support/MemoryBuffer.h" | ||
#include "llvm/Support/YAMLParser.h" | ||
#include "llvm/Support/YAMLTraits.h" | ||
#include <string> | ||
#include <type_traits> | ||
|
||
namespace { | ||
enum LocalDiagID : uint32_t { | ||
#define DIAG(KIND, ID, Options, Text, Signature) ID, | ||
#include "swift/AST/DiagnosticsAll.def" | ||
NumDiags | ||
}; | ||
|
||
struct DiagnosticNode { | ||
uint32_t id; | ||
std::string msg; | ||
}; | ||
} // namespace | ||
|
||
namespace llvm { | ||
namespace yaml { | ||
|
||
template <> struct ScalarEnumerationTraits<LocalDiagID> { | ||
static void enumeration(IO &io, LocalDiagID &value) { | ||
#define DIAG(KIND, ID, Options, Text, Signature) \ | ||
io.enumCase(value, #ID, LocalDiagID::ID); | ||
#include "swift/AST/DiagnosticsAll.def" | ||
} | ||
}; | ||
|
||
template <> struct MappingTraits<DiagnosticNode> { | ||
static void mapping(IO &io, DiagnosticNode &node) { | ||
LocalDiagID diagID; | ||
io.mapRequired("id", diagID); | ||
io.mapRequired("msg", node.msg); | ||
node.id = static_cast<uint32_t>(diagID); | ||
} | ||
}; | ||
|
||
} // namespace yaml | ||
} // namespace llvm | ||
|
||
namespace swift { | ||
namespace diag { | ||
|
||
YAMLLocalizationProducer::YAMLLocalizationProducer(std::string locale, | ||
std::string path) { | ||
llvm::SmallString<128> DiagnosticsFilePath(path); | ||
llvm::sys::path::append(DiagnosticsFilePath, locale); | ||
llvm::sys::path::replace_extension(DiagnosticsFilePath, ".yaml"); | ||
auto FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(DiagnosticsFilePath); | ||
// Absence of localizations shouldn't crash the compiler. | ||
if (!FileBufOrErr) | ||
return; | ||
llvm::MemoryBuffer *document = FileBufOrErr->get(); | ||
diag::LocalizationInput yin(document->getBuffer()); | ||
yin >> diagnostics; | ||
} | ||
|
||
llvm::StringRef | ||
YAMLLocalizationProducer::getMessageOr(swift::DiagID id, | ||
llvm::StringRef defaultMessage) const { | ||
if (diagnostics.empty()) | ||
return defaultMessage; | ||
const std::string &diagnosticMessage = diagnostics[(unsigned)id]; | ||
if (diagnosticMessage.empty()) | ||
return defaultMessage; | ||
return diagnosticMessage; | ||
} | ||
|
||
template <typename T, typename Context> | ||
typename std::enable_if<llvm::yaml::has_SequenceTraits<T>::value, void>::type | ||
readYAML(llvm::yaml::IO &io, T &Seq, bool, Context &Ctx) { | ||
unsigned count = io.beginSequence(); | ||
if (count) | ||
Seq.resize(LocalDiagID::NumDiags); | ||
for (unsigned i = 0; i < count; ++i) { | ||
void *SaveInfo; | ||
if (io.preflightElement(i, SaveInfo)) { | ||
DiagnosticNode current; | ||
yamlize(io, current, true, Ctx); | ||
io.postflightElement(SaveInfo); | ||
// YAML file isn't guaranteed to have diagnostics in order of their | ||
// declaration in `.def` files, to accommodate that we need to leave | ||
// holes in diagnostic array for diagnostics which haven't yet been | ||
// localized and for the ones that have `DiagnosticNode::id` | ||
// indicates their position. | ||
Seq[static_cast<unsigned>(current.id)] = std::move(current.msg); | ||
} | ||
} | ||
io.endSequence(); | ||
} | ||
|
||
template <typename T> | ||
typename std::enable_if<llvm::yaml::has_SequenceTraits<T>::value, | ||
LocalizationInput &>::type | ||
operator>>(LocalizationInput &yin, T &diagnostics) { | ||
llvm::yaml::EmptyContext Ctx; | ||
if (yin.setCurrentDocument()) { | ||
// If YAML file's format doesn't match the current format in | ||
// DiagnosticMessageFormat, will throw an error. | ||
readYAML(yin, diagnostics, true, Ctx); | ||
} | ||
return yin; | ||
} | ||
|
||
} // namespace diag | ||
} // namespace swift |