Skip to content

Commit 76cf073

Browse files
committed
refactor file filtering
1 parent 770ed6c commit 76cf073

File tree

8 files changed

+88
-64
lines changed

8 files changed

+88
-64
lines changed

include/mrdox/Config.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct Config
4848
// Directory where processed files are stored. Links
4949
// to definition locations will only be generated if
5050
// the file is in this dir.
51-
std::string SourceRoot;
51+
std::vector<llvm::SmallString<0>> includePaths;
5252

5353
// URL of repository that hosts code used
5454
// for links to definition locations.
@@ -61,7 +61,16 @@ struct Config
6161
Config(Config&&) = delete;
6262
Config& operator=(Config&&) = delete;
6363

64-
bool shouldSkipFile(llvm::StringRef filePath) const noexcept;
64+
/** Returns true if the file should be skipped.
65+
66+
If the file is not skipped, then prefixPath
67+
is set to the portion of the file path which
68+
should be be removed for matching files.
69+
*/
70+
bool
71+
filterFile(
72+
llvm::StringRef filePath,
73+
llvm::SmallVectorImpl<char>& prefixPath) const noexcept;
6574

6675
public:
6776
struct filter { std::vector<std::string> include, exclude; };

include/mrdox/Visitor.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <clang/AST/ASTConsumer.h>
2727
#include <clang/AST/RecursiveASTVisitor.h>
2828
#include <utility>
29+
#include <unordered_map>
2930

3031
namespace clang {
3132
namespace mrdox {
@@ -38,9 +39,18 @@ class Visitor
3839
: public RecursiveASTVisitor<Visitor>
3940
, public ASTConsumer
4041
{
42+
struct FileFilter
43+
{
44+
llvm::SmallString<0> prefix;
45+
bool exclude = true;
46+
};
47+
4148
bool handleTranslationUnit_ = false;
4249
tooling::ExecutionContext& exc_;
4350
Config const& config_;
51+
std::unordered_map<
52+
clang::SourceLocation::UIntTy,
53+
FileFilter> fileFilter_;
4454

4555
public:
4656
Visitor(

source/lib/Config.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,6 @@ namespace mrdox {
4949
Config::
5050
Config()
5151
{
52-
if (auto p = ::getenv("MRDOX_SOURCE_ROOT"))
53-
SourceRoot = p;
54-
else
55-
{
56-
llvm::SmallString<128> SourceRootDir;
57-
llvm::sys::fs::current_path(SourceRootDir);
58-
SourceRoot = SourceRootDir.c_str();
59-
}
60-
6152
if (auto p = ::getenv("MRDOX_REPOSITORY_URL"))
6253
RepositoryUrl.emplace(p);
6354
else if (auto q = ::getenv("DRONE_REMOTE_URL"))
@@ -66,10 +57,27 @@ Config()
6657

6758
bool
6859
Config::
69-
shouldSkipFile(
70-
llvm::StringRef filePath) const noexcept
60+
filterFile(
61+
llvm::StringRef filePath,
62+
llvm::SmallVectorImpl<char>& prefixPath) const noexcept
7163
{
72-
return false;
64+
namespace path = llvm::sys::path;
65+
66+
for(auto const s : includePaths)
67+
{
68+
if(filePath.starts_with(s))
69+
{
70+
prefixPath = s;
71+
if(! path::is_separator(prefixPath.back()))
72+
{
73+
auto const sep = path::get_separator();
74+
prefixPath.insert(prefixPath.end(),
75+
sep.begin(), sep.end());
76+
}
77+
return false;
78+
}
79+
}
80+
return true;
7381
}
7482

7583
std::error_code
@@ -78,6 +86,7 @@ load(
7886
const std::string & name,
7987
const std::source_location & loc)
8088
{
89+
#if 0
8190
auto ct = llvm::MemoryBuffer::getFile(SourceRoot + "/" + name);
8291
if (!ct)
8392
return ct.getError();
@@ -87,7 +96,7 @@ load(
8796
yin >> *this;
8897
if ( yin.error() )
8998
return yin.error();
90-
99+
#endif
91100
return {};
92101
}
93102

source/lib/Visitor.cpp

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <clang/Index/USRGeneration.h>
2323
#include <llvm/ADT/StringExtras.h>
2424
#include <llvm/Support/Error.h>
25+
#include <llvm/Support/Path.h>
2526

2627
namespace clang {
2728
namespace mrdox {
@@ -41,26 +42,48 @@ bool
4142
Visitor::
4243
mapDecl(T const* D)
4344
{
45+
namespace path = llvm::sys::path;
46+
4447
clang::SourceManager const& sm =
4548
D->getASTContext().getSourceManager();
46-
clang::SourceLocation const loc = D->getLocation();
4749

48-
if(sm.isInSystemHeader(loc))
50+
if(sm.isInSystemHeader(D->getLocation()))
4951
{
5052
// skip system header
5153
return true;
5254
}
5355

54-
if (D->getParentFunctionOrMethod())
56+
if(D->getParentFunctionOrMethod())
5557
{
5658
// skip function-local declarations
5759
return true;
5860
}
5961

60-
llvm::SmallString<128> filePath;
61-
filePath = sm.getPresumedLoc(D->getBeginLoc()).getFilename();
62-
if(config_.shouldSkipFile(filePath))
63-
return true;
62+
llvm::SmallString<512> filePath;
63+
clang::PresumedLoc const loc =
64+
sm.getPresumedLoc(D->getBeginLoc());
65+
auto result = fileFilter_.emplace(
66+
loc.getIncludeLoc().getRawEncoding(),
67+
FileFilter());
68+
if(result.second)
69+
{
70+
// new element
71+
filePath = loc.getFilename();
72+
FileFilter& ff = result.first->second;
73+
ff.exclude = config_.filterFile(filePath, ff.prefix);
74+
if(ff.exclude)
75+
return true;
76+
path::replace_path_prefix(filePath, ff.prefix, "");
77+
}
78+
else
79+
{
80+
// existing element
81+
FileFilter const& ff = result.first->second;
82+
if(ff.exclude)
83+
return true;
84+
filePath = loc.getFilename();
85+
path::replace_path_prefix(filePath, ff.prefix, "");
86+
}
6487

6588
// If there is an error generating a USR for the decl, skip this decl.
6689
{
@@ -72,14 +95,13 @@ mapDecl(T const* D)
7295
}
7396
}
7497

75-
bool IsFileInRootDir;
76-
llvm::SmallString<128> File =
77-
getFile(D, D->getASTContext(), config_.SourceRoot, IsFileInRootDir);
98+
// VFALCO is this right?
99+
bool const IsFileInRootDir = true;
78100
auto I = emitInfo(
79101
D,
80102
getComment(D, D->getASTContext()),
81103
getLine(D, D->getASTContext()),
82-
File,
104+
filePath,
83105
IsFileInRootDir,
84106
config_.PublicOnly);
85107

@@ -178,31 +200,5 @@ getLine(
178200
D->getBeginLoc()).getLine();
179201
}
180202

181-
llvm::SmallString<128>
182-
Visitor::
183-
getFile(NamedDecl const* D,
184-
ASTContext const& Context,
185-
llvm::StringRef RootDir,
186-
bool& IsFileInRootDir) const
187-
{
188-
llvm::SmallString<128> File(
189-
Context.getSourceManager()
190-
.getPresumedLoc(D->getBeginLoc())
191-
.getFilename());
192-
IsFileInRootDir = false;
193-
if (RootDir.empty() || !File.startswith(RootDir))
194-
return File;
195-
IsFileInRootDir = true;
196-
llvm::SmallString<128> Prefix(RootDir);
197-
// replace_path_prefix removes the exact prefix provided. The result of
198-
// calling that function on ("A/B/C.c", "A/B", "") would be "/C.c", which
199-
// starts with a / that is not needed. This is why we fix Prefix so it always
200-
// ends with a / and the result has the desired format.
201-
if (!llvm::sys::path::is_separator(Prefix.back()))
202-
Prefix += llvm::sys::path::get_separator();
203-
llvm::sys::path::replace_path_prefix(File, Prefix, "");
204-
return File;
205-
}
206-
207203
} // mrdox
208204
} // clang

source/lib/XML.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,11 @@ writeInfo(
352352
Info const& I)
353353
{
354354
writeTagLine("extract-name", I.extractName());
355+
#if 0
355356
auto relPath = I.getRelativeFilePath(config_.SourceRoot);
356357
if(! relPath.empty())
357358
writeTagLine("rel-path", relPath);
359+
#endif
358360
writeTagLine("base-name", I.getFileBaseName());
359361
}
360362

source/tests/TestMain.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,19 @@ testResult(
191191
int
192192
testMain(int argc, const char** argv)
193193
{
194+
namespace path = llvm::sys::path;
195+
194196
Config config;
195197
Reporter R;
196-
auto const gen = makeXMLGenerator();
198+
199+
for(int i = 1; i < argc; ++i)
200+
{
201+
llvm::SmallString<0> s(argv[i]);
202+
path::remove_dots(s, true);
203+
config.includePaths.emplace_back(std::move(s));
204+
}
197205

206+
auto const gen = makeXMLGenerator();
198207
llvm::ThreadPool Pool(llvm::hardware_concurrency(
199208
tooling::ExecutorConcurrency));
200209
for(int i = 1; i < argc; ++i)

source/tool/ToolMain.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,6 @@ OutDirectory(
6969
llvm::cl::init("."),
7070
llvm::cl::cat(ToolCategory));
7171

72-
static
73-
llvm::cl::opt<std::string>
74-
SourceRoot(
75-
"source-root", llvm::cl::desc(R"(
76-
Directory where processed files are stored.
77-
Links to definition locations will only be
78-
generated if the file is in this dir.)"),
79-
llvm::cl::cat(ToolCategory));
80-
8172
static
8273
llvm::cl::opt<std::string>
8374
ConfigPath(

testfiles/2.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
</all>
55
<namespace name="">
66
<extract-name>GlobalNamespace</extract-name>
7-
<rel-path>GlobalNamespace</rel-path>
87
<base-name>index</base-name>
98
<namespace name="N" usr="rjlMNXAaWNMkQYMTJzRA1DR0DiE=">
109
<extract-name>N</extract-name>
11-
<rel-path>N</rel-path>
1210
<base-name>index</base-name>
1311
</namespace>
1412
</namespace>

0 commit comments

Comments
 (0)