mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Handle access note I/O and parse errors
This commit is contained in:
@@ -405,5 +405,10 @@ WARNING(module_incompatible_with_skip_function_bodies,none,
|
|||||||
"-experimental-skip-*-function-bodies* flags; they have "
|
"-experimental-skip-*-function-bodies* flags; they have "
|
||||||
"been automatically disabled", (StringRef))
|
"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
|
#define UNDEFINE_DIAGNOSTIC_MACROS
|
||||||
#include "DefineDiagnosticMacros.h"
|
#include "DefineDiagnosticMacros.h"
|
||||||
|
|||||||
@@ -215,15 +215,30 @@ template <> struct llvm::yaml::MappingTraits<swift::AccessNote> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace swift {
|
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>
|
llvm::Expected<AccessNotes>
|
||||||
AccessNotes::load(ASTContext &ctx, llvm::MemoryBuffer *buffer) {
|
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;
|
AccessNotes notes;
|
||||||
yamlIn >> notes;
|
yamlIn >> notes;
|
||||||
|
|
||||||
if (yamlIn.error())
|
if (yamlIn.error())
|
||||||
return llvm::errorCodeToError(yamlIn.error());
|
return llvm::Expected<AccessNotes>(std::move(errors));
|
||||||
|
|
||||||
return notes;
|
return notes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -902,6 +902,16 @@ bool CompilerInstance::createFilesForMainModule(
|
|||||||
return false;
|
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 {
|
ModuleDecl *CompilerInstance::getMainModule() const {
|
||||||
if (!MainModule) {
|
if (!MainModule) {
|
||||||
Identifier ID = Context->getIdentifier(Invocation.getModuleName());
|
Identifier ID = Context->getIdentifier(Invocation.getModuleName());
|
||||||
@@ -935,18 +945,26 @@ ModuleDecl *CompilerInstance::getMainModule() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Invocation.getFrontendOptions().AccessNotesPath.empty()) {
|
if (!Invocation.getFrontendOptions().AccessNotesPath.empty()) {
|
||||||
auto bufferOrError =
|
auto accessNotesPath = Invocation.getFrontendOptions().AccessNotesPath;
|
||||||
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 expectedAccessNotes = AccessNotes::load(*Context, buffer.get());
|
auto expectedBuffer = llvm::errorOrToExpected(
|
||||||
// FIXME: Diagnose properly
|
swift::vfs::getFileOrSTDIN(getFileSystem(), accessNotesPath));
|
||||||
MainModule->getAccessNotes() = cantFail(std::move(expectedAccessNotes),
|
|
||||||
"invalid access notes:");
|
|
||||||
|
|
||||||
|
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;
|
return MainModule;
|
||||||
|
|||||||
1
test/Sema/Inputs/bad.accessnotes
Normal file
1
test/Sema/Inputs/bad.accessnotes
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Colourless green ideas sleep furiously.
|
||||||
5
test/Sema/access-notes-invalid.swift
Normal file
5
test/Sema/access-notes-invalid.swift
Normal 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{{$}}
|
||||||
Reference in New Issue
Block a user