Skip to content

Commit

Permalink
feat: input filters
Browse files Browse the repository at this point in the history
  • Loading branch information
alandefreitas committed Feb 14, 2024
1 parent 67fa963 commit 5f2e60e
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 32 deletions.
103 changes: 93 additions & 10 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ParseJavadoc.hpp"
#include "lib/Support/Path.hpp"
#include "lib/Support/Debug.hpp"
#include "lib/Support/Glob.hpp"
#include "lib/Lib/Diagnostics.hpp"
#include "lib/Lib/Filters.hpp"
#include "lib/Lib/Info.hpp"
Expand Down Expand Up @@ -1243,7 +1244,7 @@ class ASTVisitor
const Decl* D,
AccessSpecifier access)
{
if(config_->inaccessibleMembers !=
if (config_->inaccessibleMembers !=
ConfigImpl::SettingsImpl::ExtractPolicy::Always)
{
// KRYSTIAN FIXME: this doesn't handle direct
Expand All @@ -1253,6 +1254,44 @@ class ASTVisitor
return false;
}

if (!config_->input.include.empty())
{
// Get filename
FileInfo* file = getFileInfo(D->getBeginLoc());
if (!file)
return false;
std::string filename = file->full_path;
bool matchPrefix = std::ranges::any_of(
config_->input.include,
[&filename](const std::string& prefix)
{
return filename.starts_with(prefix);
});
if (!matchPrefix)
{
return false;
}
}

if (!config_->input.filePatterns.empty())
{
// Get filename
FileInfo* file = getFileInfo(D->getBeginLoc());
if (!file)
return false;
std::string filename = file->full_path;
bool matchPattern = std::ranges::any_of(
config_->input.filePatterns,
[&filename](const std::string& pattern)
{
return globMatch(pattern, filename);
});
if (!matchPattern)
{
return false;
}
}

#if 0
bool extract = inExtractedFile(D);
// if we're extracting a declaration as a dependency,
Expand Down Expand Up @@ -3433,19 +3472,20 @@ class ASTVisitorConsumer
// so errors prior to traversal are reported
Diagnostics diags;

// loads and caches source files into memory
SourceManager& source = Context.getSourceManager();
// get the name of the translation unit.
// will be std::nullopt_t if it isn't a file
std::optional<llvm::SmallString<128>> file_name =
source.getNonBuiltinFilenameForID(source.getMainFileID());
// KRYSTIAN NOTE: should we report anything here?
if(! file_name)
if (!file_name)
{
return;
}

// skip the translation unit if configured to do so
if(! config_.shouldVisitTU(
convert_to_slash(*file_name)))
return;
convert_to_slash(*file_name);

ASTVisitor visitor(
config_,
Expand All @@ -3454,7 +3494,7 @@ class ASTVisitorConsumer
Context,
*sema_);

// traverse the translation unit
// Traverse the translation unit
visitor.build();

// VFALCO If we returned from the function early
Expand Down Expand Up @@ -3537,6 +3577,14 @@ class ASTVisitorConsumer
//
//------------------------------------------------

/** A frontend action for visiting the AST
This is used by the tooling infrastructure to create
an ASTAction for each translation unit.
The ASTAction is responsible for creating the ASTConsumer
which will be used to traverse the AST.
*/
struct ASTAction
: public clang::ASTFrontendAction
{
Expand All @@ -3548,27 +3596,57 @@ struct ASTAction
{
}

/** Execute the action
This is called by the tooling infrastructure to execute
the action for each translation unit.
The action will parse the AST with the consumer
that should have been previously created with
CreateASTConsumer.
This consumer then creates a ASTVisitor that
will convert the AST into a set of MrDocs Info
objects.
*/
void
ExecuteAction() override
{
CompilerInstance& CI = getCompilerInstance();
if(! CI.hasPreprocessor())
if (!CI.hasPreprocessor())
{
return;
}

// ensure comments in system headers are retained.
// we may want them if e.g. a declaration was extracted
// Ensure comments in system headers are retained.
// We may want them if, e.g., a declaration was extracted
// as a dependency
CI.getLangOpts().RetainCommentsFromSystemHeaders = true;

if(! CI.hasSema())
if (!CI.hasSema())
{
CI.createSema(getTranslationUnitKind(), nullptr);
}

ParseAST(
CI.getSema(),
false, // ShowStats
true); // SkipFunctionBodies
}

/** Create the object that will traverse the AST
This is called by the tooling infrastructure to create
an ASTConsumer for each translation unit.
This consumer creates a ASTVisitor that will convert
the AST into a set of our objects.
The main function of the ASTVisitorConsumer is
the HandleTranslationUnit function, which is called
to traverse the AST.
*/
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(
clang::CompilerInstance& Compiler,
Expand All @@ -3585,6 +3663,11 @@ struct ASTAction

//------------------------------------------------

/** A frontend action factory for ASTAction
This is used by the tooling infrastructure to create
an ASTAction for each translation unit.
*/
struct ASTActionFactory :
tooling::FrontendActionFactory
{
Expand Down
43 changes: 33 additions & 10 deletions src/lib/Lib/ConfigImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "lib/Support/Error.hpp"
#include "lib/Support/Path.hpp"
#include "lib/Support/Yaml.hpp"
#include "lib/Support/Glob.hpp"
#include <mrdocs/Support/Path.hpp>
#include <clang/Tooling/AllTUsExecution.h>
#include <llvm/Support/FileSystem.h>
Expand All @@ -40,6 +41,7 @@ struct llvm::yaml::MappingTraits<
SettingsImpl::FileFilter& f)
{
io.mapOptional("include", f.include);
io.mapOptional("file-patterns", f.filePatterns);
}
};

Expand Down Expand Up @@ -87,20 +89,21 @@ struct llvm::yaml::MappingTraits<SettingsImpl>
static void mapping(IO& io,
SettingsImpl& cfg)
{
io.mapOptional("include", cfg.ignoreFailures);
io.mapOptional("defines", cfg.defines);
io.mapOptional("ignore-failures", cfg.ignoreFailures);


// io.mapOptional("extract", cfg.extract);
io.mapOptional("referenced-declarations", cfg.referencedDeclarations);
io.mapOptional("anonymous-namespaces", cfg.anonymousNamespaces);
io.mapOptional("inaccessible-members", cfg.inaccessibleMembers);
io.mapOptional("inaccessible-bases", cfg.inaccessibleBases);

io.mapOptional("anonymous-namespaces", cfg.anonymousNamespaces);
io.mapOptional("inaccessible-members", cfg.inaccessibleMembers);
io.mapOptional("inaccessible-bases", cfg.inaccessibleBases);

io.mapOptional("generate", cfg.generate);
io.mapOptional("multipage", cfg.multiPage);
io.mapOptional("source-root", cfg.sourceRoot);
io.mapOptional("base-url", cfg.baseURL);
io.mapOptional("base-url", cfg.baseURL);

io.mapOptional("input", cfg.input);

Expand Down Expand Up @@ -209,7 +212,7 @@ ConfigImpl(
}

// Adjust input files
for(auto& name : inputFileIncludes_)
for (auto& name : settings_.input.include)
{
name = files::makePosixStyle(
files::makeAbsolute(name, settings_.workingDir));
Expand All @@ -231,14 +234,34 @@ ConfigImpl(

bool
ConfigImpl::
shouldVisitTU(
shouldVisitSymbol(
llvm::StringRef filePath) const noexcept
{
if(inputFileIncludes_.empty())
if (settings_.input.include.empty())
{
return true;
for(auto const& s : inputFileIncludes_)
if(filePath == s)
}
for (auto& p: settings_.input.include)
{
// Exact match
if (filePath == p)
{
return true;
}
// Prefix match
if (filePath.startswith(p))
{
bool validPattern = std::ranges::any_of(
settings_.input.filePatterns,
[&](auto const &pattern) {
return globMatch(pattern, filePath);
});
if (validPattern)
{
return true;
}
}
}
return false;
}

Expand Down
6 changes: 4 additions & 2 deletions src/lib/Lib/ConfigImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ class ConfigImpl
{
/// Directories to include
std::vector<std::string> include;

/// File patterns
std::vector<std::string> filePatterns;
};

/// @copydoc FileFilter
Expand Down Expand Up @@ -158,7 +161,6 @@ class ConfigImpl
SettingsImpl settings_;
ThreadPool& threadPool_;
llvm::SmallString<0> outputPath_;
std::vector<std::string> inputFileIncludes_;
dom::Object configObj_;

friend class Config;
Expand Down Expand Up @@ -194,7 +196,7 @@ class ConfigImpl
to the file being processed.
*/
bool
shouldVisitTU(
shouldVisitSymbol(
llvm::StringRef filePath) const noexcept;

/** Returns true if the file should be visited.
Expand Down
22 changes: 12 additions & 10 deletions src/lib/Lib/CorpusImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ build(
#else
InfoExecutionContext context(*config);
#endif
// Create an `ASTActionFactory` to create multiple
// `ASTAction`s that extract the AST for each translation unit.
std::unique_ptr<tooling::FrontendActionFactory> action =
makeFrontendActionFactory(context, *config);
MRDOCS_ASSERT(action);
Expand All @@ -147,11 +149,13 @@ build(
tooling::ClangTool Tool(compilations, { path },
std::make_shared<PCHContainerOperations>(), FS);

// suppress error messages from the tool
// Suppress error messages from the tool
Tool.setPrintErrorMessage(false);

if(Tool.run(action.get()))
if (Tool.run(action.get()))
{
formatError("Failed to run action on {}", path).Throw();
}
};

// ------------------------------------------
Expand Down Expand Up @@ -182,8 +186,8 @@ build(
else
{
TaskGroup taskGroup(config->threadPool());
for(std::size_t index = 0;
std::string& file : files)
std::size_t index = 0;
for (std::string& file : files)
{
taskGroup.async(
[&, idx = ++index, path = std::move(file)]()
Expand All @@ -205,8 +209,10 @@ build(
if (!errors.empty())
{
Error err(errors);
if(! (*config)->ignoreFailures)
if (!(*config)->ignoreFailures)
{
return Unexpected(err);
}
report::warn(
"Warning: mapping failed because ", err);
}
Expand All @@ -222,11 +228,7 @@ build(
report::format(reportLevel,
"Reducing declarations");

auto results = context.results();
if(! results)
return Unexpected(results.error());
corpus->info_ = std::move(results.value());

MRDOCS_TRY(corpus->info_, context.results());
report::format(reportLevel,
"Reduced {} symbols in {}",
corpus->info_.size(),
Expand Down
Loading

0 comments on commit 5f2e60e

Please sign in to comment.