Handle access note I/O and parse errors

This commit is contained in:
Becca Royal-Gordon
2021-02-04 15:59:47 -08:00
parent d347ffae0e
commit e42294737f
5 changed files with 56 additions and 12 deletions

View File

@@ -405,5 +405,10 @@ WARNING(module_incompatible_with_skip_function_bodies,none,
"-experimental-skip-*-function-bodies* flags; they have "
"been automatically disabled", (StringRef))
WARNING(invalid_access_notes_file,none,
"access notes at '%0' will be ignored due to an error while loading "
"them: %1",
(StringRef, StringRef))
#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"

View File

@@ -215,15 +215,30 @@ template <> struct llvm::yaml::MappingTraits<swift::AccessNote> {
};
namespace swift {
static void
convertToErrorAndJoin(const llvm::SMDiagnostic &diag, void *Context) {
auto newError = llvm::createStringError(std::errc::invalid_argument,
"%s at line %d, column %d",
diag.getMessage().bytes_begin(),
diag.getLineNo(), diag.getColumnNo());
auto &errors = *(llvm::Error*)Context;
errors = llvm::joinErrors(std::move(errors), std::move(newError));
}
llvm::Expected<AccessNotes>
AccessNotes::load(ASTContext &ctx, llvm::MemoryBuffer *buffer) {
llvm::yaml::Input yamlIn(buffer->getBuffer(), (void *)&ctx);
llvm::Error errors = llvm::Error::success();
llvm::yaml::Input yamlIn(buffer->getBuffer(), (void *)&ctx,
convertToErrorAndJoin, &errors);
AccessNotes notes;
yamlIn >> notes;
if (yamlIn.error())
return llvm::errorCodeToError(yamlIn.error());
return llvm::Expected<AccessNotes>(std::move(errors));
return notes;
}

View File

@@ -902,6 +902,16 @@ bool CompilerInstance::createFilesForMainModule(
return false;
}
template<typename ExpectedOut, typename ExpectedIn>
static llvm::Expected<ExpectedOut>
flatMap(llvm::Expected<ExpectedIn> &&in,
llvm::function_ref<llvm::Expected<ExpectedOut>(ExpectedIn &&)> transform) {
if (!in)
return llvm::Expected<ExpectedOut>(in.takeError());
return transform(std::move(in.get()));
}
ModuleDecl *CompilerInstance::getMainModule() const {
if (!MainModule) {
Identifier ID = Context->getIdentifier(Invocation.getModuleName());
@@ -935,18 +945,26 @@ ModuleDecl *CompilerInstance::getMainModule() const {
}
if (!Invocation.getFrontendOptions().AccessNotesPath.empty()) {
auto bufferOrError =
swift::vfs::getFileOrSTDIN(getFileSystem(),
Invocation.getFrontendOptions().AccessNotesPath);
// FIXME: Diagnose properly
auto buffer = cantFail(llvm::errorOrToExpected(std::move(bufferOrError)),
"can't open access notes file");
auto accessNotesPath = Invocation.getFrontendOptions().AccessNotesPath;
auto expectedAccessNotes = AccessNotes::load(*Context, buffer.get());
// FIXME: Diagnose properly
MainModule->getAccessNotes() = cantFail(std::move(expectedAccessNotes),
"invalid access notes:");
auto expectedBuffer = llvm::errorOrToExpected(
swift::vfs::getFileOrSTDIN(getFileSystem(), accessNotesPath));
auto expectedAccessNotes =
flatMap<AccessNotes, std::unique_ptr<llvm::MemoryBuffer>>(
std::move(expectedBuffer),
[&](auto &&buffer) -> auto {
return AccessNotes::load(*Context, buffer.get());
});
if (expectedAccessNotes)
MainModule->getAccessNotes() = std::move(expectedAccessNotes).get();
else
llvm::handleAllErrors(expectedAccessNotes.takeError(),
[&](const llvm::ErrorInfoBase &error) {
Context->Diags.diagnose(SourceLoc(), diag::invalid_access_notes_file,
accessNotesPath, error.message());
});
}
}
return MainModule;

View File

@@ -0,0 +1 @@
Colourless green ideas sleep furiously.

View File

@@ -0,0 +1,5 @@
// RUN: %target-swift-frontend -typecheck -primary-file %s -access-notes-path %S/Inputs/missing.accessnotes 2>&1 | %FileCheck --check-prefix=CHECK-MISSING %s
// CHECK-MISSING: <unknown>:0: warning: access notes at 'SOURCE_DIR/test/Sema/Inputs/missing.accessnotes' will be ignored due to an error while loading them: No such file or directory{{$}}
// RUN: %target-swift-frontend -typecheck -primary-file %s -access-notes-path %S/Inputs/bad.accessnotes 2>&1 | %FileCheck --check-prefix=CHECK-BAD %s
// CHECK-BAD: <unknown>:0: warning: access notes at 'SOURCE_DIR/test/Sema/Inputs/bad.accessnotes' will be ignored due to an error while loading them: not a mapping at line 1, column 0{{$}}