mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Frontend] Allow additional files for diagnostic verifier
This change adds a frontend flag, -verify-additional-file, which can be used to pass extra files directly to the diagnostic verifier. These files are not otherwise considered to be Swift source files; they are not compiled or even properly parsed. This feature can be used to verify diagnostics emitted in non-source files, such as in module interfaces or header files.
This commit is contained in:
committed by
Alexis Laferrière
parent
ba00258c66
commit
5036a55550
@@ -41,6 +41,10 @@ public:
|
||||
/// Indicates whether diagnostic passes should be skipped.
|
||||
bool SkipDiagnosticPasses = false;
|
||||
|
||||
/// Additional non-source files which will have diagnostics emitted in them,
|
||||
/// and which should be scanned for expectations by the diagnostic verifier.
|
||||
std::vector<std::string> AdditionalVerifierFiles;
|
||||
|
||||
/// Keep emitting subsequent diagnostics after a fatal error.
|
||||
bool ShowDiagnosticsAfterFatalError = false;
|
||||
|
||||
@@ -54,22 +58,23 @@ public:
|
||||
/// Treat all warnings as errors
|
||||
bool WarningsAsErrors = false;
|
||||
|
||||
// When printing diagnostics, include the diagnostic name at the end
|
||||
/// When printing diagnostics, include the diagnostic name (diag::whatever) at
|
||||
/// the end.
|
||||
bool PrintDiagnosticNames = false;
|
||||
|
||||
/// If set to true, include educational notes in printed output if available.
|
||||
/// Educational notes are documentation which supplement diagnostics.
|
||||
bool PrintEducationalNotes = false;
|
||||
|
||||
// If set to true, use the more descriptive experimental formatting style for
|
||||
// diagnostics.
|
||||
/// Whether to emit diagnostics in the terse LLVM style or in a more
|
||||
/// descriptive style that's specific to Swift (currently experimental).
|
||||
FormattingStyle PrintedFormattingStyle = FormattingStyle::LLVM;
|
||||
|
||||
std::string DiagnosticDocumentationPath = "";
|
||||
|
||||
std::string LocalizationCode = "";
|
||||
|
||||
// Diagnostic messages directory path.
|
||||
/// Path to a directory of diagnostic localization tables.
|
||||
std::string LocalizationPath = "";
|
||||
|
||||
/// Return a hash code of any components from these options that should
|
||||
|
||||
@@ -65,6 +65,7 @@ class DiagnosticVerifier : public DiagnosticConsumer {
|
||||
SourceManager &SM;
|
||||
std::vector<CapturedDiagnosticInfo> CapturedDiagnostics;
|
||||
ArrayRef<unsigned> BufferIDs;
|
||||
SmallVector<unsigned, 4> AdditionalBufferIDs;
|
||||
bool AutoApplyFixes;
|
||||
bool IgnoreUnknown;
|
||||
|
||||
@@ -74,6 +75,10 @@ public:
|
||||
: SM(SM), BufferIDs(BufferIDs), AutoApplyFixes(AutoApplyFixes),
|
||||
IgnoreUnknown(IgnoreUnknown) {}
|
||||
|
||||
void appendAdditionalBufferID(unsigned bufferID) {
|
||||
AdditionalBufferIDs.push_back(bufferID);
|
||||
}
|
||||
|
||||
virtual void handleDiagnostic(SourceManager &SM,
|
||||
const DiagnosticInfo &Info) override;
|
||||
|
||||
|
||||
@@ -560,8 +560,11 @@ private:
|
||||
bool setUpInputs();
|
||||
bool setUpASTContextIfNeeded();
|
||||
void setupStatsReporter();
|
||||
void setupDiagnosticVerifierIfNeeded();
|
||||
void setupDependencyTrackerIfNeeded();
|
||||
|
||||
/// \return false if successsful, true on error.
|
||||
bool setupDiagnosticVerifierIfNeeded();
|
||||
|
||||
Optional<unsigned> setUpCodeCompletionBuffer();
|
||||
|
||||
/// Find a buffer for a given input file and ensure it is recorded in
|
||||
|
||||
@@ -114,6 +114,8 @@ def tbd_is_installapi: Flag<["-"], "tbd-is-installapi">,
|
||||
def verify : Flag<["-"], "verify">,
|
||||
HelpText<"Verify diagnostics against expected-{error|warning|note} "
|
||||
"annotations">;
|
||||
def verify_additional_file : Separate<["-"], "verify-additional-file">,
|
||||
HelpText<"Verify diagnostics in this file in addition to source files">;
|
||||
def verify_apply_fixes : Flag<["-"], "verify-apply-fixes">,
|
||||
HelpText<"Like -verify, but updates the original source file">;
|
||||
def verify_ignore_unknown: Flag<["-"], "verify-ignore-unknown">,
|
||||
|
||||
@@ -957,6 +957,9 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
||||
Opts.ShowDiagnosticsAfterFatalError |=
|
||||
Args.hasArg(OPT_show_diagnostics_after_fatal);
|
||||
|
||||
for (Arg *A : Args.filtered(OPT_verify_additional_file))
|
||||
Opts.AdditionalVerifierFiles.push_back(A->getValue());
|
||||
|
||||
Opts.UseColor |=
|
||||
Args.hasFlag(OPT_color_diagnostics,
|
||||
OPT_no_color_diagnostics,
|
||||
|
||||
@@ -978,7 +978,9 @@ void DiagnosticVerifier::handleDiagnostic(SourceManager &SM,
|
||||
bool DiagnosticVerifier::finishProcessing() {
|
||||
DiagnosticVerifier::Result Result = {false, false};
|
||||
|
||||
for (auto &BufferID : BufferIDs) {
|
||||
ArrayRef<unsigned> BufferIDLists[2] = { BufferIDs, AdditionalBufferIDs };
|
||||
for (ArrayRef<unsigned> BufferIDList : BufferIDLists)
|
||||
for (auto &BufferID : BufferIDList) {
|
||||
DiagnosticVerifier::Result FileResult = verifyFile(BufferID);
|
||||
Result.HadError |= FileResult.HadError;
|
||||
Result.HadUnexpectedDiag |= FileResult.HadUnexpectedDiag;
|
||||
|
||||
@@ -290,15 +290,31 @@ void CompilerInstance::setupStatsReporter() {
|
||||
Stats = std::move(Reporter);
|
||||
}
|
||||
|
||||
void CompilerInstance::setupDiagnosticVerifierIfNeeded() {
|
||||
bool CompilerInstance::setupDiagnosticVerifierIfNeeded() {
|
||||
auto &diagOpts = Invocation.getDiagnosticOptions();
|
||||
bool hadError = false;
|
||||
|
||||
if (diagOpts.VerifyMode != DiagnosticOptions::NoVerify) {
|
||||
DiagVerifier = std::make_unique<DiagnosticVerifier>(
|
||||
SourceMgr, InputSourceCodeBufferIDs,
|
||||
diagOpts.VerifyMode == DiagnosticOptions::VerifyAndApplyFixes,
|
||||
diagOpts.VerifyIgnoreUnknown);
|
||||
for (const auto &filename : diagOpts.AdditionalVerifierFiles) {
|
||||
auto result = getFileSystem().getBufferForFile(filename);
|
||||
if (!result) {
|
||||
Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file,
|
||||
filename, result.getError().message());
|
||||
hadError |= true;
|
||||
}
|
||||
|
||||
auto bufferID = SourceMgr.addNewSourceBuffer(std::move(result.get()));
|
||||
DiagVerifier->appendAdditionalBufferID(bufferID);
|
||||
}
|
||||
|
||||
addDiagnosticConsumer(DiagVerifier.get());
|
||||
}
|
||||
|
||||
return hadError;
|
||||
}
|
||||
|
||||
void CompilerInstance::setupDependencyTrackerIfNeeded() {
|
||||
@@ -347,7 +363,9 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
|
||||
return true;
|
||||
|
||||
setupStatsReporter();
|
||||
setupDiagnosticVerifierIfNeeded();
|
||||
|
||||
if (setupDiagnosticVerifierIfNeeded())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user