[clangd] makeStringError,make_error<StringError> -> error()

This commit is contained in:
Sam McCall 2020-09-14 11:33:12 +02:00
parent 4232bccfb4
commit 687e1d7121
23 changed files with 110 additions and 230 deletions

View File

@ -43,12 +43,9 @@ struct ScoredSymbolGreater {
llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc, llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc,
llvm::StringRef TUPath) { llvm::StringRef TUPath) {
auto Path = URI::resolve(Loc.FileURI, TUPath); auto Path = URI::resolve(Loc.FileURI, TUPath);
if (!Path) { if (!Path)
return llvm::make_error<llvm::StringError>( return error("Could not resolve path for file '{0}': {1}", Loc.FileURI,
llvm::formatv("Could not resolve path for file '{0}': {1}", Loc.FileURI, Path.takeError());
llvm::toString(Path.takeError())),
llvm::inconvertibleErrorCode());
}
Location L; Location L;
L.uri = URIForFile::canonicalize(*Path, TUPath); L.uri = URIForFile::canonicalize(*Path, TUPath);
Position Start, End; Position Start, End;

View File

@ -153,8 +153,7 @@ std::vector<Fix> IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const {
return ResolvedInserted.takeError(); return ResolvedInserted.takeError();
auto Spelled = Inserter->calculateIncludePath(*ResolvedInserted, File); auto Spelled = Inserter->calculateIncludePath(*ResolvedInserted, File);
if (!Spelled) if (!Spelled)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Header not on include path");
"Header not on include path");
return std::make_pair( return std::make_pair(
std::move(*Spelled), std::move(*Spelled),
Inserter->shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted)); Inserter->shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));

View File

@ -12,6 +12,7 @@
#include "support/Shutdown.h" #include "support/Shutdown.h"
#include "llvm/Support/Errno.h" #include "llvm/Support/Errno.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include <system_error>
namespace clang { namespace clang {
namespace clangd { namespace clangd {
@ -100,9 +101,8 @@ public:
llvm::Error loop(MessageHandler &Handler) override { llvm::Error loop(MessageHandler &Handler) override {
while (!feof(In)) { while (!feof(In)) {
if (shutdownRequested()) if (shutdownRequested())
return llvm::createStringError( return error(std::make_error_code(std::errc::operation_canceled),
std::make_error_code(std::errc::operation_canceled), "Got signal, shutting down");
"Got signal, shutting down");
if (ferror(In)) if (ferror(In))
return llvm::errorCodeToError( return llvm::errorCodeToError(
std::error_code(errno, std::system_category())); std::error_code(errno, std::system_category()));

View File

@ -243,8 +243,7 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
IgnoringDiagConsumer IgnoreDiags; IgnoringDiagConsumer IgnoreDiags;
auto CI = buildCompilerInvocation(PI, IgnoreDiags); auto CI = buildCompilerInvocation(PI, IgnoreDiags);
if (!CI) if (!CI)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("failed to create compiler invocation");
"failed to create compiler invocation");
CI->getDiagnosticOpts().IgnoreWarnings = true; CI->getDiagnosticOpts().IgnoreWarnings = true;
auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents); auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents);
// This means we're scanning (though not preprocessing) the preamble section // This means we're scanning (though not preprocessing) the preamble section
@ -260,14 +259,12 @@ scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
// also implies missing resolved paths for includes. // also implies missing resolved paths for includes.
FS.view(llvm::None), IgnoreDiags); FS.view(llvm::None), IgnoreDiags);
if (Clang->getFrontendOpts().Inputs.empty()) if (Clang->getFrontendOpts().Inputs.empty())
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("compiler instance had no inputs");
"compiler instance had no inputs");
// We are only interested in main file includes. // We are only interested in main file includes.
Clang->getPreprocessorOpts().SingleFileParseMode = true; Clang->getPreprocessorOpts().SingleFileParseMode = true;
PreprocessOnlyAction Action; PreprocessOnlyAction Action;
if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("failed BeginSourceFile");
"failed BeginSourceFile");
const auto &SM = Clang->getSourceManager(); const auto &SM = Clang->getSourceManager();
Preprocessor &PP = Clang->getPreprocessor(); Preprocessor &PP = Clang->getPreprocessor();
IncludeStructure Includes; IncludeStructure Includes;

View File

@ -175,20 +175,17 @@ size_t lspLength(llvm::StringRef Code) {
llvm::Expected<size_t> positionToOffset(llvm::StringRef Code, Position P, llvm::Expected<size_t> positionToOffset(llvm::StringRef Code, Position P,
bool AllowColumnsBeyondLineLength) { bool AllowColumnsBeyondLineLength) {
if (P.line < 0) if (P.line < 0)
return llvm::make_error<llvm::StringError>( return error(llvm::errc::invalid_argument,
llvm::formatv("Line value can't be negative ({0})", P.line), "Line value can't be negative ({0})", P.line);
llvm::errc::invalid_argument);
if (P.character < 0) if (P.character < 0)
return llvm::make_error<llvm::StringError>( return error(llvm::errc::invalid_argument,
llvm::formatv("Character value can't be negative ({0})", P.character), "Character value can't be negative ({0})", P.character);
llvm::errc::invalid_argument);
size_t StartOfLine = 0; size_t StartOfLine = 0;
for (int I = 0; I != P.line; ++I) { for (int I = 0; I != P.line; ++I) {
size_t NextNL = Code.find('\n', StartOfLine); size_t NextNL = Code.find('\n', StartOfLine);
if (NextNL == llvm::StringRef::npos) if (NextNL == llvm::StringRef::npos)
return llvm::make_error<llvm::StringError>( return error(llvm::errc::invalid_argument,
llvm::formatv("Line value is out of range ({0})", P.line), "Line value is out of range ({0})", P.line);
llvm::errc::invalid_argument);
StartOfLine = NextNL + 1; StartOfLine = NextNL + 1;
} }
StringRef Line = StringRef Line =
@ -198,10 +195,9 @@ llvm::Expected<size_t> positionToOffset(llvm::StringRef Code, Position P,
bool Valid; bool Valid;
size_t ByteInLine = measureUnits(Line, P.character, lspEncoding(), Valid); size_t ByteInLine = measureUnits(Line, P.character, lspEncoding(), Valid);
if (!Valid && !AllowColumnsBeyondLineLength) if (!Valid && !AllowColumnsBeyondLineLength)
return llvm::make_error<llvm::StringError>( return error(llvm::errc::invalid_argument,
llvm::formatv("{0} offset {1} is invalid for line {2}", lspEncoding(), "{0} offset {1} is invalid for line {2}", lspEncoding(),
P.character, P.line), P.character, P.line);
llvm::errc::invalid_argument);
return StartOfLine + ByteInLine; return StartOfLine + ByteInLine;
} }

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "URI.h" #include "URI.h"
#include "support/Logger.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h" #include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
@ -21,11 +22,6 @@ namespace clang {
namespace clangd { namespace clangd {
namespace { namespace {
inline llvm::Error make_string_error(const llvm::Twine &Message) {
return llvm::make_error<llvm::StringError>(Message,
llvm::inconvertibleErrorCode());
}
bool isWindowsPath(llvm::StringRef Path) { bool isWindowsPath(llvm::StringRef Path) {
return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':'; return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
} }
@ -45,9 +41,9 @@ public:
getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body, getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body,
llvm::StringRef /*HintPath*/) const override { llvm::StringRef /*HintPath*/) const override {
if (!Body.startswith("/")) if (!Body.startswith("/"))
return make_string_error("File scheme: expect body to be an absolute " return error("File scheme: expect body to be an absolute path starting "
"path starting with '/': " + "with '/': {0}",
Body); Body);
llvm::SmallString<128> Path; llvm::SmallString<128> Path;
if (!Authority.empty()) { if (!Authority.empty()) {
// Windows UNC paths e.g. file://server/share => \\server\share // Windows UNC paths e.g. file://server/share => \\server\share
@ -89,7 +85,7 @@ findSchemeByName(llvm::StringRef Scheme) {
continue; continue;
return URIScheme.instantiate(); return URIScheme.instantiate();
} }
return make_string_error("Can't find scheme: " + Scheme); return error("Can't find scheme: {0}", Scheme);
} }
bool shouldEscape(unsigned char C) { bool shouldEscape(unsigned char C) {
@ -187,12 +183,11 @@ llvm::Expected<URI> URI::parse(llvm::StringRef OrigUri) {
auto Pos = Uri.find(':'); auto Pos = Uri.find(':');
if (Pos == llvm::StringRef::npos) if (Pos == llvm::StringRef::npos)
return make_string_error("Scheme must be provided in URI: " + OrigUri); return error("Scheme must be provided in URI: {0}", OrigUri);
auto SchemeStr = Uri.substr(0, Pos); auto SchemeStr = Uri.substr(0, Pos);
U.Scheme = percentDecode(SchemeStr); U.Scheme = percentDecode(SchemeStr);
if (!isValidScheme(U.Scheme)) if (!isValidScheme(U.Scheme))
return make_string_error(llvm::formatv("Invalid scheme: {0} (decoded: {1})", return error("Invalid scheme: {0} (decoded: {1})", SchemeStr, U.Scheme);
SchemeStr, U.Scheme));
Uri = Uri.substr(Pos + 1); Uri = Uri.substr(Pos + 1);
if (Uri.consume_front("//")) { if (Uri.consume_front("//")) {
Pos = Uri.find('/'); Pos = Uri.find('/');
@ -217,7 +212,7 @@ llvm::Expected<std::string> URI::resolve(llvm::StringRef FileURI,
llvm::Expected<URI> URI::create(llvm::StringRef AbsolutePath, llvm::Expected<URI> URI::create(llvm::StringRef AbsolutePath,
llvm::StringRef Scheme) { llvm::StringRef Scheme) {
if (!llvm::sys::path::is_absolute(AbsolutePath)) if (!llvm::sys::path::is_absolute(AbsolutePath))
return make_string_error("Not a valid absolute path: " + AbsolutePath); return error("Not a valid absolute path: {0}", AbsolutePath);
auto S = findSchemeByName(Scheme); auto S = findSchemeByName(Scheme);
if (!S) if (!S)
return S.takeError(); return S.takeError();

View File

@ -272,15 +272,13 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
IgnoreDiagnostics IgnoreDiags; IgnoreDiagnostics IgnoreDiags;
auto CI = buildCompilerInvocation(Inputs, IgnoreDiags); auto CI = buildCompilerInvocation(Inputs, IgnoreDiags);
if (!CI) if (!CI)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Couldn't build compiler invocation");
"Couldn't build compiler invocation");
auto Clang = auto Clang =
prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr, prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr,
std::move(*Buf), std::move(FS), IgnoreDiags); std::move(*Buf), std::move(FS), IgnoreDiags);
if (!Clang) if (!Clang)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Couldn't build compiler instance");
"Couldn't build compiler instance");
SymbolCollector::Options IndexOpts; SymbolCollector::Options IndexOpts;
// Creates a filter to not collect index results from files with unchanged // Creates a filter to not collect index results from files with unchanged
@ -318,8 +316,7 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front(); const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front();
if (!Action->BeginSourceFile(*Clang, Input)) if (!Action->BeginSourceFile(*Clang, Input))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("BeginSourceFile() failed");
"BeginSourceFile() failed");
if (llvm::Error Err = Action->Execute()) if (llvm::Error Err = Action->Execute())
return Err; return Err;

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "SymbolID.h" #include "SymbolID.h"
#include "support/Logger.h"
#include "llvm/Support/SHA1.h" #include "llvm/Support/SHA1.h"
namespace clang { namespace clang {
@ -34,12 +35,10 @@ std::string SymbolID::str() const { return llvm::toHex(raw()); }
llvm::Expected<SymbolID> SymbolID::fromStr(llvm::StringRef Str) { llvm::Expected<SymbolID> SymbolID::fromStr(llvm::StringRef Str) {
if (Str.size() != RawSize * 2) if (Str.size() != RawSize * 2)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Bad ID length");
"Bad ID length");
for (char C : Str) for (char C : Str)
if (!llvm::isHexDigit(C)) if (!llvm::isHexDigit(C))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Bad hex ID");
"Bad hex ID");
return fromRaw(llvm::fromHex(Str)); return fromRaw(llvm::fromHex(Str));
} }

View File

@ -18,6 +18,7 @@
#include "SymbolLocation.h" #include "SymbolLocation.h"
#include "SymbolOrigin.h" #include "SymbolOrigin.h"
#include "dex/Dex.h" #include "dex/Dex.h"
#include "support/Logger.h"
#include "support/Trace.h" #include "support/Trace.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
@ -533,9 +534,7 @@ symbolFromYAML(StringRef YAML, llvm::UniqueStringSaver *Strings) {
clangd::Symbol Deserialized; clangd::Symbol Deserialized;
llvm::yaml::Input YAMLInput(YAML, Strings); llvm::yaml::Input YAMLInput(YAML, Strings);
if (YAMLInput.error()) if (YAMLInput.error())
return llvm::make_error<llvm::StringError>( return error("Unable to deserialize Symbol from YAML: {0}", YAML);
llvm::formatv("Unable to deserialize Symbol from YAML: {0}", YAML),
llvm::inconvertibleErrorCode());
YAMLInput >> Deserialized; YAMLInput >> Deserialized;
return Deserialized; return Deserialized;
} }
@ -545,9 +544,7 @@ llvm::Expected<clangd::Ref> refFromYAML(StringRef YAML,
clangd::Ref Deserialized; clangd::Ref Deserialized;
llvm::yaml::Input YAMLInput(YAML, Strings); llvm::yaml::Input YAMLInput(YAML, Strings);
if (YAMLInput.error()) if (YAMLInput.error())
return llvm::make_error<llvm::StringError>( return error("Unable to deserialize Symbol from YAML: {0}", YAML);
llvm::formatv("Unable to deserialize Symbol from YAML: {0}", YAML),
llvm::inconvertibleErrorCode());
YAMLInput >> Deserialized; YAMLInput >> Deserialized;
return Deserialized; return Deserialized;
} }

View File

@ -45,11 +45,6 @@ llvm::Expected<llvm::DenseSet<SymbolID>> getIDs(IDRange IDs) {
return Result; return Result;
} }
llvm::Error makeStringError(llvm::StringRef Message) {
return llvm::make_error<llvm::StringError>(Message,
llvm::inconvertibleErrorCode());
}
} // namespace } // namespace
Marshaller::Marshaller(llvm::StringRef RemoteIndexRoot, Marshaller::Marshaller(llvm::StringRef RemoteIndexRoot,
@ -132,7 +127,7 @@ Marshaller::fromProtobuf(const RelationsRequest *Message) {
llvm::Expected<clangd::Symbol> Marshaller::fromProtobuf(const Symbol &Message) { llvm::Expected<clangd::Symbol> Marshaller::fromProtobuf(const Symbol &Message) {
if (!Message.has_info() || !Message.has_canonical_declaration()) if (!Message.has_info() || !Message.has_canonical_declaration())
return makeStringError("Missing info or declaration."); return error("Missing info or declaration.");
clangd::Symbol Result; clangd::Symbol Result;
auto ID = SymbolID::fromStr(Message.id()); auto ID = SymbolID::fromStr(Message.id());
if (!ID) if (!ID)
@ -170,7 +165,7 @@ llvm::Expected<clangd::Symbol> Marshaller::fromProtobuf(const Symbol &Message) {
llvm::Expected<clangd::Ref> Marshaller::fromProtobuf(const Ref &Message) { llvm::Expected<clangd::Ref> Marshaller::fromProtobuf(const Ref &Message) {
if (!Message.has_location()) if (!Message.has_location())
return makeStringError("Missing location."); return error("Missing location.");
clangd::Ref Result; clangd::Ref Result;
auto Location = fromProtobuf(Message.location()); auto Location = fromProtobuf(Message.location());
if (!Location) if (!Location)
@ -186,7 +181,7 @@ Marshaller::fromProtobuf(const Relation &Message) {
if (!SubjectID) if (!SubjectID)
return SubjectID.takeError(); return SubjectID.takeError();
if (!Message.has_object()) if (!Message.has_object())
return makeStringError("Missing Object."); return error("Missing Object.");
auto Object = fromProtobuf(Message.object()); auto Object = fromProtobuf(Message.object());
if (!Object) if (!Object)
return Object.takeError(); return Object.takeError();
@ -304,10 +299,9 @@ Marshaller::relativePathToURI(llvm::StringRef RelativePath) {
assert(RelativePath == llvm::sys::path::convert_to_slash( assert(RelativePath == llvm::sys::path::convert_to_slash(
RelativePath, llvm::sys::path::Style::posix)); RelativePath, llvm::sys::path::Style::posix));
if (RelativePath.empty()) if (RelativePath.empty())
return makeStringError("Empty relative path."); return error("Empty relative path.");
if (llvm::sys::path::is_absolute(RelativePath)) if (llvm::sys::path::is_absolute(RelativePath))
return makeStringError( return error("RelativePath '{0}' is absolute.", RelativePath);
llvm::formatv("RelativePath '{0}' is absolute.", RelativePath).str());
llvm::SmallString<256> FullPath = llvm::StringRef(*LocalIndexRoot); llvm::SmallString<256> FullPath = llvm::StringRef(*LocalIndexRoot);
llvm::sys::path::append(FullPath, RelativePath); llvm::sys::path::append(FullPath, RelativePath);
auto Result = URI::createFile(FullPath); auto Result = URI::createFile(FullPath);
@ -320,16 +314,11 @@ llvm::Expected<std::string> Marshaller::uriToRelativePath(llvm::StringRef URI) {
if (!ParsedURI) if (!ParsedURI)
return ParsedURI.takeError(); return ParsedURI.takeError();
if (ParsedURI->scheme() != "file") if (ParsedURI->scheme() != "file")
return makeStringError( return error("Can not use URI schemes other than file, given: '{0}'.", URI);
llvm::formatv("Can not use URI schemes other than file, given: '{0}'.",
URI)
.str());
llvm::SmallString<256> Result = ParsedURI->body(); llvm::SmallString<256> Result = ParsedURI->body();
if (!llvm::sys::path::replace_path_prefix(Result, *RemoteIndexRoot, "")) if (!llvm::sys::path::replace_path_prefix(Result, *RemoteIndexRoot, ""))
return makeStringError( return error("File path '{0}' doesn't start with '{1}'.", Result.str(),
llvm::formatv("File path '{0}' doesn't start with '{1}'.", Result.str(), *RemoteIndexRoot);
*RemoteIndexRoot)
.str());
// Make sure the result has UNIX slashes. // Make sure the result has UNIX slashes.
return llvm::sys::path::convert_to_slash(Result, return llvm::sys::path::convert_to_slash(Result,
llvm::sys::path::Style::posix); llvm::sys::path::Style::posix);

View File

@ -213,9 +213,7 @@ llvm::Error makeError(ReasonToReject Reason) {
} }
llvm_unreachable("unhandled reason kind"); llvm_unreachable("unhandled reason kind");
}; };
return llvm::make_error<llvm::StringError>( return error("Cannot rename symbol: {0}", Message(Reason));
llvm::formatv("Cannot rename symbol: {0}", Message(Reason)),
llvm::inconvertibleErrorCode());
} }
// Return all rename occurrences in the main file. // Return all rename occurrences in the main file.
@ -319,16 +317,11 @@ findOccurrencesOutsideFile(const NamedDecl &RenameDecl,
}); });
if (AffectedFiles.size() >= MaxLimitFiles) if (AffectedFiles.size() >= MaxLimitFiles)
return llvm::make_error<llvm::StringError>( return error("The number of affected files exceeds the max limit {0}",
llvm::formatv("The number of affected files exceeds the max limit {0}", MaxLimitFiles);
MaxLimitFiles), if (HasMore)
llvm::inconvertibleErrorCode()); return error("The symbol {0} has too many occurrences",
if (HasMore) { RenameDecl.getQualifiedNameAsString());
return llvm::make_error<llvm::StringError>(
llvm::formatv("The symbol {0} has too many occurrences",
RenameDecl.getQualifiedNameAsString()),
llvm::inconvertibleErrorCode());
}
// Sort and deduplicate the results, in case that index returns duplications. // Sort and deduplicate the results, in case that index returns duplications.
for (auto &FileAndOccurrences : AffectedFiles) { for (auto &FileAndOccurrences : AffectedFiles) {
auto &Ranges = FileAndOccurrences.getValue(); auto &Ranges = FileAndOccurrences.getValue();
@ -379,20 +372,15 @@ llvm::Expected<FileEdits> renameOutsideFile(
// Our heuristics fails to adjust rename ranges to the current state of // Our heuristics fails to adjust rename ranges to the current state of
// the file, it is most likely the index is stale, so we give up the // the file, it is most likely the index is stale, so we give up the
// entire rename. // entire rename.
return llvm::make_error<llvm::StringError>( return error("Index results don't match the content of file {0} "
llvm::formatv("Index results don't match the content of file {0} " "(the index may be stale)",
"(the index may be stale)", FilePath);
FilePath),
llvm::inconvertibleErrorCode());
} }
auto RenameEdit = auto RenameEdit =
buildRenameEdit(FilePath, *AffectedFileCode, *RenameRanges, NewName); buildRenameEdit(FilePath, *AffectedFileCode, *RenameRanges, NewName);
if (!RenameEdit) { if (!RenameEdit)
return llvm::make_error<llvm::StringError>( return error("failed to rename in file {0}: {1}", FilePath,
llvm::formatv("fail to build rename edit for file {0}: {1}", FilePath, RenameEdit.takeError());
llvm::toString(RenameEdit.takeError())),
llvm::inconvertibleErrorCode());
}
if (!RenameEdit->Replacements.empty()) if (!RenameEdit->Replacements.empty())
Results.insert({FilePath, std::move(*RenameEdit)}); Results.insert({FilePath, std::move(*RenameEdit)});
} }
@ -455,14 +443,10 @@ llvm::Expected<FileEdits> rename(const RenameInputs &RInputs) {
auto Content = auto Content =
SM.getFileManager().getVirtualFileSystem().getBufferForFile(AbsPath); SM.getFileManager().getVirtualFileSystem().getBufferForFile(AbsPath);
if (!Content) if (!Content)
return llvm::createStringError( return error("Fail to open file {0}: {1}", AbsPath,
llvm::inconvertibleErrorCode(), Content.getError().message());
llvm::formatv("Fail to open file {0}: {1}", AbsPath,
Content.getError().message()));
if (!*Content) if (!*Content)
return llvm::createStringError( return error("Got no buffer for file {0}", AbsPath);
llvm::inconvertibleErrorCode(),
llvm::formatv("Got no buffer for file {0}", AbsPath));
return (*Content)->getBuffer().str(); return (*Content)->getBuffer().str();
}; };
@ -559,10 +543,8 @@ llvm::Expected<Edit> buildRenameEdit(llvm::StringRef AbsFilePath,
auto ShiftedOffset = auto ShiftedOffset =
positionToOffset(InitialCode.substr(LastOffset), Shifted); positionToOffset(InitialCode.substr(LastOffset), Shifted);
if (!ShiftedOffset) if (!ShiftedOffset)
return llvm::make_error<llvm::StringError>( return error("fail to convert the position {0} to offset ({1})", P,
llvm::formatv("fail to convert the position {0} to offset ({1})", P, ShiftedOffset.takeError());
llvm::toString(ShiftedOffset.takeError())),
llvm::inconvertibleErrorCode());
LastPos = P; LastPos = P;
LastOffset += *ShiftedOffset; LastOffset += *ShiftedOffset;
return LastOffset; return LastOffset;

View File

@ -80,12 +80,10 @@ llvm::Expected<std::unique_ptr<Tweak>> prepareTweak(StringRef ID,
TweakRegistry::entries(), TweakRegistry::entries(),
[ID](const TweakRegistry::entry &E) { return E.getName() == ID; }); [ID](const TweakRegistry::entry &E) { return E.getName() == ID; });
if (It == TweakRegistry::end()) if (It == TweakRegistry::end())
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("tweak ID {0} is invalid", ID);
"id of the tweak is invalid");
std::unique_ptr<Tweak> T = It->instantiate(); std::unique_ptr<Tweak> T = It->instantiate();
if (!T->prepare(S)) if (!T->prepare(S))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("failed to prepare() tweak {0}", ID);
"failed to prepare() a check");
return std::move(T); return std::move(T);
} }
@ -95,10 +93,8 @@ Tweak::Effect::fileEdit(const SourceManager &SM, FileID FID,
Edit Ed(SM.getBufferData(FID), std::move(Replacements)); Edit Ed(SM.getBufferData(FID), std::move(Replacements));
if (auto FilePath = getCanonicalPath(SM.getFileEntryForID(FID), SM)) if (auto FilePath = getCanonicalPath(SM.getFileEntryForID(FID), SM))
return std::make_pair(*FilePath, std::move(Ed)); return std::make_pair(*FilePath, std::move(Ed));
return llvm::createStringError( return error("Failed to get absolute path for edited file: {0}",
llvm::inconvertibleErrorCode(), SM.getFileEntryForID(FID)->getName());
"Failed to get absolute path for edited file: " +
SM.getFileEntryForID(FID)->getName());
} }
llvm::Expected<Tweak::Effect> llvm::Expected<Tweak::Effect>

View File

@ -169,8 +169,7 @@ findInsertionPoint(const Tweak::Selection &Inputs,
return Tok.kind() == tok::l_brace; return Tok.kind() == tok::l_brace;
}); });
if (Tok == Toks.end() || Tok->endLocation().isInvalid()) { if (Tok == Toks.end() || Tok->endLocation().isInvalid()) {
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Namespace with no {");
"Namespace with no {");
} }
if (!Tok->endLocation().isMacroID()) { if (!Tok->endLocation().isMacroID()) {
InsertionPointData Out; InsertionPointData Out;
@ -183,8 +182,7 @@ findInsertionPoint(const Tweak::Selection &Inputs,
// top level decl. // top level decl.
auto TLDs = Inputs.AST->getLocalTopLevelDecls(); auto TLDs = Inputs.AST->getLocalTopLevelDecls();
if (TLDs.empty()) { if (TLDs.empty()) {
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Cannot find place to insert \"using\"");
"Cannot find place to insert \"using\"");
} }
InsertionPointData Out; InsertionPointData Out;
Out.Loc = SM.getExpansionLoc(TLDs[0]->getBeginLoc()); Out.Loc = SM.getExpansionLoc(TLDs[0]->getBeginLoc());
@ -272,9 +270,7 @@ Expected<Tweak::Effect> AddUsing::apply(const Selection &Inputs) {
auto SpelledTokens = TB.spelledForExpanded( auto SpelledTokens = TB.spelledForExpanded(
TB.expandedTokens(QualifierToRemove.getSourceRange())); TB.expandedTokens(QualifierToRemove.getSourceRange()));
if (!SpelledTokens) { if (!SpelledTokens) {
return llvm::createStringError( return error("Could not determine length of the qualifier");
llvm::inconvertibleErrorCode(),
"Could not determine length of the qualifier");
} }
unsigned Length = unsigned Length =
syntax::Token::range(SM, SpelledTokens->front(), SpelledTokens->back()) syntax::Token::range(SM, SpelledTokens->front(), SpelledTokens->back())

View File

@ -205,18 +205,15 @@ llvm::Expected<std::string> qualifyAllDecls(const FunctionDecl *FD,
} }
}); });
if (HadErrors) { if (HadErrors)
return llvm::createStringError( return error(
llvm::inconvertibleErrorCode(), "define inline: Failed to compute qualifiers. See logs for details.");
"define inline: Failed to compute qualifiers see logs for details.");
}
// Get new begin and end positions for the qualified body. // Get new begin and end positions for the qualified body.
auto OrigBodyRange = toHalfOpenFileRange( auto OrigBodyRange = toHalfOpenFileRange(
SM, FD->getASTContext().getLangOpts(), FD->getBody()->getSourceRange()); SM, FD->getASTContext().getLangOpts(), FD->getBody()->getSourceRange());
if (!OrigBodyRange) if (!OrigBodyRange)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Couldn't get range func body.");
"Couldn't get range func body.");
unsigned BodyBegin = SM.getFileOffset(OrigBodyRange->getBegin()); unsigned BodyBegin = SM.getFileOffset(OrigBodyRange->getBegin());
unsigned BodyEnd = Replacements.getShiftedCodePosition( unsigned BodyEnd = Replacements.getShiftedCodePosition(
@ -311,9 +308,7 @@ renameParameters(const FunctionDecl *Dest, const FunctionDecl *Source) {
ReplaceRange = Lexer::makeFileCharRange(ReplaceRange, SM, LangOpts); ReplaceRange = Lexer::makeFileCharRange(ReplaceRange, SM, LangOpts);
// Bail out if we need to replace macro bodies. // Bail out if we need to replace macro bodies.
if (ReplaceRange.isInvalid()) { if (ReplaceRange.isInvalid()) {
auto Err = llvm::createStringError( auto Err = error("Cant rename parameter inside macro body.");
llvm::inconvertibleErrorCode(),
"Cant rename parameter inside macro body.");
elog("define inline: {0}", Err); elog("define inline: {0}", Err);
return std::move(Err); return std::move(Err);
} }
@ -450,11 +445,8 @@ public:
const auto &SM = AST.getSourceManager(); const auto &SM = AST.getSourceManager();
auto Semicolon = getSemicolonForDecl(Target); auto Semicolon = getSemicolonForDecl(Target);
if (!Semicolon) { if (!Semicolon)
return llvm::createStringError( return error("Couldn't find semicolon for target declaration.");
llvm::inconvertibleErrorCode(),
"Couldn't find semicolon for target declaration.");
}
auto AddInlineIfNecessary = addInlineIfInHeader(Target); auto AddInlineIfNecessary = addInlineIfInHeader(Target);
auto ParamReplacements = renameParameters(Target, Source); auto ParamReplacements = renameParameters(Target, Source);
@ -479,10 +471,8 @@ public:
SM.getExpansionRange(CharSourceRange::getCharRange(getBeginLoc(Source), SM.getExpansionRange(CharSourceRange::getCharRange(getBeginLoc(Source),
Source->getEndLoc())) Source->getEndLoc()))
.getAsRange()); .getAsRange());
if (!DefRange) { if (!DefRange)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Couldn't get range for the source.");
"Couldn't get range for the source.");
}
unsigned int SourceLen = SM.getFileOffset(DefRange->getEnd()) - unsigned int SourceLen = SM.getFileOffset(DefRange->getEnd()) -
SM.getFileOffset(DefRange->getBegin()); SM.getFileOffset(DefRange->getBegin());
const tooling::Replacement DeleteFuncBody(SM, DefRange->getBegin(), const tooling::Replacement DeleteFuncBody(SM, DefRange->getBegin(),

View File

@ -120,8 +120,7 @@ getFunctionSourceAfterReplacements(const FunctionDecl *FD,
auto OrigFuncRange = toHalfOpenFileRange( auto OrigFuncRange = toHalfOpenFileRange(
SM, FD->getASTContext().getLangOpts(), FD->getSourceRange()); SM, FD->getASTContext().getLangOpts(), FD->getSourceRange());
if (!OrigFuncRange) if (!OrigFuncRange)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Couldn't get range for function.");
"Couldn't get range for function.");
assert(!FD->getDescribedFunctionTemplate() && assert(!FD->getDescribedFunctionTemplate() &&
"Define out-of-line doesn't apply to function templates."); "Define out-of-line doesn't apply to function templates.");
@ -151,9 +150,7 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
auto &SM = AST.getSourceManager(); auto &SM = AST.getSourceManager();
auto TargetContext = findContextForNS(TargetNamespace, FD->getDeclContext()); auto TargetContext = findContextForNS(TargetNamespace, FD->getDeclContext());
if (!TargetContext) if (!TargetContext)
return llvm::createStringError( return error("define outline: couldn't find a context for target");
llvm::inconvertibleErrorCode(),
"define outline: couldn't find a context for target");
llvm::Error Errors = llvm::Error::success(); llvm::Error Errors = llvm::Error::success();
tooling::Replacements DeclarationCleanups; tooling::Replacements DeclarationCleanups;
@ -219,12 +216,9 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
assert(A->getLocation().isValid()); assert(A->getLocation().isValid());
if (!AttrTokens || AttrTokens->empty()) { if (!AttrTokens || AttrTokens->empty()) {
Errors = llvm::joinErrors( Errors = llvm::joinErrors(
std::move(Errors), std::move(Errors), error("define outline: Can't move out of line as "
llvm::createStringError( "function has a macro `{0}` specifier.",
llvm::inconvertibleErrorCode(), A->getSpelling()));
llvm::StringRef("define outline: Can't move out of line as "
"function has a macro `") +
A->getSpelling() + "` specifier."));
return; return;
} }
CharSourceRange DelRange = CharSourceRange DelRange =
@ -248,10 +242,8 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
if (!Spelling) { if (!Spelling) {
Errors = llvm::joinErrors( Errors = llvm::joinErrors(
std::move(Errors), std::move(Errors),
llvm::createStringError( error("define outline: couldn't remove `{0}` keyword.",
llvm::inconvertibleErrorCode(), tok::getKeywordSpelling(Kind)));
llvm::formatv("define outline: couldn't remove `{0}` keyword.",
tok::getKeywordSpelling(Kind))));
break; break;
} }
CharSourceRange DelRange = CharSourceRange DelRange =
@ -264,11 +256,8 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
if (!FoundAny) { if (!FoundAny) {
Errors = llvm::joinErrors( Errors = llvm::joinErrors(
std::move(Errors), std::move(Errors),
llvm::createStringError( error("define outline: couldn't find `{0}` keyword to remove.",
llvm::inconvertibleErrorCode(), tok::getKeywordSpelling(Kind)));
llvm::formatv(
"define outline: couldn't find `{0}` keyword to remove.",
tok::getKeywordSpelling(Kind))));
} }
}; };
@ -411,15 +400,11 @@ public:
auto MainFileName = auto MainFileName =
getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
if (!MainFileName) if (!MainFileName)
return llvm::createStringError( return error("Couldn't get absolute path for main file.");
llvm::inconvertibleErrorCode(),
"Couldn't get absolute path for mainfile.");
auto CCFile = getSourceFile(*MainFileName, Sel); auto CCFile = getSourceFile(*MainFileName, Sel);
if (!CCFile) if (!CCFile)
return llvm::createStringError( return error("Couldn't find a suitable implementation file.");
llvm::inconvertibleErrorCode(),
"Couldn't find a suitable implementation file.");
auto &FS = auto &FS =
Sel.AST->getSourceManager().getFileManager().getVirtualFileSystem(); Sel.AST->getSourceManager().getFileManager().getVirtualFileSystem();
@ -427,8 +412,7 @@ public:
// FIXME: Maybe we should consider creating the implementation file if it // FIXME: Maybe we should consider creating the implementation file if it
// doesn't exist? // doesn't exist?
if (!Buffer) if (!Buffer)
return llvm::createStringError(Buffer.getError(), return llvm::errorCodeToError(Buffer.getError());
Buffer.getError().message());
auto Contents = Buffer->get()->getBuffer(); auto Contents = Buffer->get()->getBuffer();
auto InsertionPoint = getInsertionPoint( auto InsertionPoint = getInsertionPoint(
Contents, Source->getQualifiedNameAsString(), Sel.AST->getLangOpts()); Contents, Source->getQualifiedNameAsString(), Sel.AST->getLangOpts());

View File

@ -45,11 +45,6 @@ public:
private: private:
/// Cache the AutoTypeLoc, so that we do not need to search twice. /// Cache the AutoTypeLoc, so that we do not need to search twice.
llvm::Optional<clang::AutoTypeLoc> CachedLocation; llvm::Optional<clang::AutoTypeLoc> CachedLocation;
/// Create an error message with filename and line number in it
llvm::Error createErrorMessage(const std::string& Message,
const Selection &Inputs);
}; };
REGISTER_TWEAK(ExpandAutoType) REGISTER_TWEAK(ExpandAutoType)
@ -78,21 +73,19 @@ Expected<Tweak::Effect> ExpandAutoType::apply(const Selection& Inputs) {
// if we can't resolve the type, return an error message // if we can't resolve the type, return an error message
if (DeducedType == llvm::None) if (DeducedType == llvm::None)
return createErrorMessage("Could not deduce type for 'auto' type", Inputs); return error("Could not deduce type for 'auto' type");
// if it's a lambda expression, return an error message // if it's a lambda expression, return an error message
if (isa<RecordType>(*DeducedType) && if (isa<RecordType>(*DeducedType) &&
dyn_cast<RecordType>(*DeducedType)->getDecl()->isLambda()) { dyn_cast<RecordType>(*DeducedType)->getDecl()->isLambda()) {
return createErrorMessage("Could not expand type of lambda expression", return error("Could not expand type of lambda expression");
Inputs);
} }
// if it's a function expression, return an error message // if it's a function expression, return an error message
// naively replacing 'auto' with the type will break declarations. // naively replacing 'auto' with the type will break declarations.
// FIXME: there are other types that have similar problems // FIXME: there are other types that have similar problems
if (DeducedType->getTypePtr()->isFunctionPointerType()) { if (DeducedType->getTypePtr()->isFunctionPointerType()) {
return createErrorMessage("Could not expand type of function pointer", return error("Could not expand type of function pointer");
Inputs);
} }
std::string PrettyTypeName = printType(*DeducedType, std::string PrettyTypeName = printType(*DeducedType,
@ -105,18 +98,6 @@ Expected<Tweak::Effect> ExpandAutoType::apply(const Selection& Inputs) {
return Effect::mainFileEdit(SrcMgr, tooling::Replacements(Expansion)); return Effect::mainFileEdit(SrcMgr, tooling::Replacements(Expansion));
} }
llvm::Error ExpandAutoType::createErrorMessage(const std::string& Message,
const Selection& Inputs) {
auto &SrcMgr = Inputs.AST->getSourceManager();
std::string ErrorMessage =
Message + ": " +
SrcMgr.getFilename(Inputs.Cursor).str() + " Line " +
std::to_string(SrcMgr.getExpansionLineNumber(Inputs.Cursor));
return llvm::createStringError(llvm::inconvertibleErrorCode(),
ErrorMessage.c_str());
}
} // namespace } // namespace
} // namespace clangd } // namespace clangd
} // namespace clang } // namespace clang

View File

@ -625,9 +625,8 @@ llvm::Expected<NewFunction> getExtractedFunction(ExtractionZone &ExtZone,
CapturedZoneInfo CapturedInfo = captureZoneInfo(ExtZone); CapturedZoneInfo CapturedInfo = captureZoneInfo(ExtZone);
// Bail out if any break of continue exists // Bail out if any break of continue exists
if (CapturedInfo.BrokenControlFlow) if (CapturedInfo.BrokenControlFlow)
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Cannot extract break/continue without corresponding "
+"Cannot extract break/continue without " "loop/switch statement.");
"corresponding loop/switch statement.");
NewFunction ExtractedFunc(getSemicolonPolicy(ExtZone, SM, LangOpts)); NewFunction ExtractedFunc(getSemicolonPolicy(ExtZone, SM, LangOpts));
ExtractedFunc.BodyRange = ExtZone.ZoneRange; ExtractedFunc.BodyRange = ExtZone.ZoneRange;
ExtractedFunc.InsertionPoint = ExtZone.getInsertionPoint(); ExtractedFunc.InsertionPoint = ExtZone.getInsertionPoint();
@ -637,8 +636,7 @@ llvm::Expected<NewFunction> getExtractedFunction(ExtractionZone &ExtZone,
if (!createParameters(ExtractedFunc, CapturedInfo) || if (!createParameters(ExtractedFunc, CapturedInfo) ||
!generateReturnProperties(ExtractedFunc, *ExtZone.EnclosingFunction, !generateReturnProperties(ExtractedFunc, *ExtZone.EnclosingFunction,
CapturedInfo)) CapturedInfo))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Too complex to extract.");
+"Too complex to extract.");
return ExtractedFunc; return ExtractedFunc;
} }

View File

@ -68,8 +68,7 @@ ObjCLocalizeStringLiteral::apply(const Selection &Inputs) {
const auto &TB = AST->getTokens(); const auto &TB = AST->getTokens();
auto Toks = TB.spelledForExpanded(TB.expandedTokens(Str->getSourceRange())); auto Toks = TB.spelledForExpanded(TB.expandedTokens(Str->getSourceRange()));
if (!Toks || Toks->empty()) if (!Toks || Toks->empty())
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("Failed to find tokens to replace.");
"Failed to find tokens to replace.");
// Insert `NSLocalizedString(` before the literal. // Insert `NSLocalizedString(` before the literal.
auto Reps = tooling::Replacements(tooling::Replacement( auto Reps = tooling::Replacements(tooling::Replacement(
SM, Toks->front().location(), 0, "NSLocalizedString(")); SM, Toks->front().location(), 0, "NSLocalizedString("));

View File

@ -10,6 +10,7 @@
#include "Selection.h" #include "Selection.h"
#include "SourceCode.h" #include "SourceCode.h"
#include "refactor/Tweak.h" #include "refactor/Tweak.h"
#include "support/Logger.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h" #include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclCXX.h"
@ -73,8 +74,7 @@ removeUsingDirective(ASTContext &Ctx, const UsingDirectiveDecl *D) {
llvm::Optional<Token> NextTok = llvm::Optional<Token> NextTok =
Lexer::findNextToken(D->getEndLoc(), SM, Ctx.getLangOpts()); Lexer::findNextToken(D->getEndLoc(), SM, Ctx.getLangOpts());
if (!NextTok || NextTok->isNot(tok::semi)) if (!NextTok || NextTok->isNot(tok::semi))
return llvm::createStringError(llvm::inconvertibleErrorCode(), return error("no semicolon after using-directive");
"no semicolon after using-directive");
// FIXME: removing the semicolon may be invalid in some obscure cases, e.g. // FIXME: removing the semicolon may be invalid in some obscure cases, e.g.
// if (x) using namespace std; else using namespace bar; // if (x) using namespace std; else using namespace bar;
return tooling::Replacement( return tooling::Replacement(

View File

@ -69,15 +69,11 @@ Expected<Tweak::Effect> SwapIfBranches::apply(const Selection &Inputs) {
auto ThenRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(), auto ThenRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
If->getThen()->getSourceRange()); If->getThen()->getSourceRange());
if (!ThenRng) if (!ThenRng)
return llvm::createStringError( return error("Could not obtain range of the 'then' branch. Macros?");
llvm::inconvertibleErrorCode(),
"Could not obtain range of the 'then' branch. Macros?");
auto ElseRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(), auto ElseRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
If->getElse()->getSourceRange()); If->getElse()->getSourceRange());
if (!ElseRng) if (!ElseRng)
return llvm::createStringError( return error("Could not obtain range of the 'else' branch. Macros?");
llvm::inconvertibleErrorCode(),
"Could not obtain range of the 'else' branch. Macros?");
auto ThenCode = toSourceCode(SrcMgr, *ThenRng); auto ThenCode = toSourceCode(SrcMgr, *ThenRng);
auto ElseCode = toSourceCode(SrcMgr, *ElseRng); auto ElseCode = toSourceCode(SrcMgr, *ElseRng);

View File

@ -484,9 +484,9 @@ public:
// Still require "/" in body to mimic file scheme, as we want lengths of an // Still require "/" in body to mimic file scheme, as we want lengths of an
// equivalent URI in both schemes to be the same. // equivalent URI in both schemes to be the same.
if (!Body.startswith("/")) if (!Body.startswith("/"))
return llvm::make_error<llvm::StringError>( return error(
"Expect URI body to be an absolute path starting with '/': " + Body, "Expect URI body to be an absolute path starting with '/': {0}",
llvm::inconvertibleErrorCode()); Body);
Body = Body.ltrim('/'); Body = Body.ltrim('/');
llvm::SmallVector<char, 16> Path(Body.begin(), Body.end()); llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
path::native(Path); path::native(Path);
@ -497,11 +497,9 @@ public:
llvm::Expected<URI> llvm::Expected<URI>
uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override { uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
llvm::StringRef Body = AbsolutePath; llvm::StringRef Body = AbsolutePath;
if (!Body.consume_front(TestScheme::TestDir)) { if (!Body.consume_front(TestScheme::TestDir))
return llvm::make_error<llvm::StringError>( return error("Path {0} doesn't start with root {1}", AbsolutePath,
"Path " + AbsolutePath + " doesn't start with root " + TestDir, TestDir);
llvm::inconvertibleErrorCode());
}
return URI("test", /*Authority=*/"", return URI("test", /*Authority=*/"",
llvm::sys::path::convert_to_slash(Body)); llvm::sys::path::convert_to_slash(Body));

View File

@ -100,13 +100,9 @@ public:
getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body, getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
llvm::StringRef HintPath) const override { llvm::StringRef HintPath) const override {
if (!HintPath.startswith(testRoot())) if (!HintPath.startswith(testRoot()))
return llvm::make_error<llvm::StringError>( return error("Hint path doesn't start with test root: {0}", HintPath);
"Hint path doesn't start with test root: " + HintPath,
llvm::inconvertibleErrorCode());
if (!Body.consume_front("/")) if (!Body.consume_front("/"))
return llvm::make_error<llvm::StringError>( return error("Body of an unittest: URI must start with '/'");
"Body of an unittest: URI must start with '/'",
llvm::inconvertibleErrorCode());
llvm::SmallString<16> Path(Body.begin(), Body.end()); llvm::SmallString<16> Path(Body.begin(), Body.end());
llvm::sys::path::native(Path); llvm::sys::path::native(Path);
return testPath(Path); return testPath(Path);
@ -116,9 +112,7 @@ public:
uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override { uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
llvm::StringRef Body = AbsolutePath; llvm::StringRef Body = AbsolutePath;
if (!Body.consume_front(testRoot())) if (!Body.consume_front(testRoot()))
return llvm::make_error<llvm::StringError>( return error("{0} does not start with {1}", AbsolutePath, testRoot());
AbsolutePath + "does not start with " + testRoot(),
llvm::inconvertibleErrorCode());
return URI(Scheme, /*Authority=*/"", return URI(Scheme, /*Authority=*/"",
llvm::sys::path::convert_to_slash(Body)); llvm::sys::path::convert_to_slash(Body));

View File

@ -41,7 +41,7 @@ Error decodeError(const json::Object &O) {
std::string(O.getString("message").getValueOr("Unspecified error")); std::string(O.getString("message").getValueOr("Unspecified error"));
if (auto Code = O.getInteger("code")) if (auto Code = O.getInteger("code"))
return make_error<LSPError>(std::move(Msg), ErrorCode(*Code)); return make_error<LSPError>(std::move(Msg), ErrorCode(*Code));
return make_error<StringError>(std::move(Msg), inconvertibleErrorCode()); return error("{0}", Msg);
} }
// C "closure" for XPCTransport::loop() method // C "closure" for XPCTransport::loop() method