Using a MemoryBufferRef, If there is an error parsing, we can point the user to the location of the file.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D93024
if ((*Text)->getBuffer().empty())
continue;
llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
- ConfigHandler.second((*Text)->getBuffer());
+ ConfigHandler.second({(*Text)->getBuffer(), ConfigFile});
if (!ParsedOptions) {
if (ParsedOptions.getError())
llvm::errs() << "Error parsing " << ConfigFile << ": "
return Input.error();
}
-llvm::ErrorOr<ClangTidyOptions> parseConfiguration(StringRef Config) {
+llvm::ErrorOr<ClangTidyOptions>
+parseConfiguration(llvm::MemoryBufferRef Config) {
llvm::yaml::Input Input(Config);
ClangTidyOptions Options;
Input >> Options;
// A pair of configuration file base name and a function parsing
// configuration from text in the corresponding format.
typedef std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>(
- llvm::StringRef)>>
+ llvm::MemoryBufferRef)>>
ConfigFileHandler;
/// Configuration file handlers listed in the order of priority.
/// Parses configuration from JSON and returns \c ClangTidyOptions or an
/// error.
-llvm::ErrorOr<ClangTidyOptions> parseConfiguration(llvm::StringRef Config);
+llvm::ErrorOr<ClangTidyOptions>
+parseConfiguration(llvm::MemoryBufferRef Config);
/// Serializes configuration to a YAML-encoded string.
std::string configurationAsText(const ClangTidyOptions &Options);
if (UseColor.getNumOccurrences() > 0)
OverrideOptions.UseColor = UseColor;
- auto LoadConfig = [&](StringRef Configuration)
- -> std::unique_ptr<ClangTidyOptionsProvider> {
+ auto LoadConfig =
+ [&](StringRef Configuration,
+ StringRef Source) -> std::unique_ptr<ClangTidyOptionsProvider> {
llvm::ErrorOr<ClangTidyOptions> ParsedConfig =
- parseConfiguration(Configuration);
+ parseConfiguration(MemoryBufferRef(Configuration, Source));
if (ParsedConfig)
return std::make_unique<ConfigOptionsProvider>(
std::move(GlobalOptions),
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
- llvm::MemoryBuffer::getFile(ConfigFile.c_str());
+ llvm::MemoryBuffer::getFile(ConfigFile);
if (std::error_code EC = Text.getError()) {
llvm::errs() << "Error: can't read config-file '" << ConfigFile
<< "': " << EC.message() << "\n";
return nullptr;
}
- return LoadConfig((*Text)->getBuffer());
+ return LoadConfig((*Text)->getBuffer(), ConfigFile);
}
if (Config.getNumOccurrences() > 0)
- return LoadConfig(Config);
+ return LoadConfig(Config, "<command-line-config>");
return std::make_unique<FileOptionsProvider>(
std::move(GlobalOptions), std::move(DefaultOptions),
[this](llvm::Optional<llvm::StringRef> Data) {
Value.reset();
if (Data && !Data->empty()) {
- if (auto Parsed = tidy::parseConfiguration(*Data))
+ if (auto Parsed = tidy::parseConfiguration(
+ llvm::MemoryBufferRef(*Data, path())))
Value = std::make_shared<const tidy::ClangTidyOptions>(
std::move(*Parsed));
else
TEST(ParseConfiguration, ValidConfiguration) {
llvm::ErrorOr<ClangTidyOptions> Options =
- parseConfiguration("Checks: \"-*,misc-*\"\n"
- "HeaderFilterRegex: \".*\"\n"
- "AnalyzeTemporaryDtors: true\n"
- "User: some.user");
+ parseConfiguration(llvm::MemoryBufferRef("Checks: \"-*,misc-*\"\n"
+ "HeaderFilterRegex: \".*\"\n"
+ "AnalyzeTemporaryDtors: true\n"
+ "User: some.user",
+ "Options"));
EXPECT_TRUE(!!Options);
EXPECT_EQ("-*,misc-*", *Options->Checks);
EXPECT_EQ(".*", *Options->HeaderFilterRegex);
}
TEST(ParseConfiguration, MergeConfigurations) {
- llvm::ErrorOr<ClangTidyOptions> Options1 = parseConfiguration(R"(
+ llvm::ErrorOr<ClangTidyOptions> Options1 =
+ parseConfiguration(llvm::MemoryBufferRef(R"(
Checks: "check1,check2"
HeaderFilterRegex: "filter1"
AnalyzeTemporaryDtors: true
ExtraArgs: ['arg1', 'arg2']
ExtraArgsBefore: ['arg-before1', 'arg-before2']
UseColor: false
- )");
+ )",
+ "Options1"));
ASSERT_TRUE(!!Options1);
- llvm::ErrorOr<ClangTidyOptions> Options2 = parseConfiguration(R"(
+ llvm::ErrorOr<ClangTidyOptions> Options2 =
+ parseConfiguration(llvm::MemoryBufferRef(R"(
Checks: "check3,check4"
HeaderFilterRegex: "filter2"
AnalyzeTemporaryDtors: false
ExtraArgs: ['arg3', 'arg4']
ExtraArgsBefore: ['arg-before3', 'arg-before4']
UseColor: true
- )");
+ )",
+ "Options2"));
ASSERT_TRUE(!!Options2);
ClangTidyOptions Options = Options1->merge(*Options2, 0);
EXPECT_EQ("check1,check2,check3,check4", *Options.Checks);