Skip to content

Commit 9afeded

Browse files
committed
feat: MrDocsSettings compilation database
Generate compile commands according to the glob patterns defined in the configuration file
1 parent 3bd94cf commit 9afeded

File tree

8 files changed

+412
-124
lines changed

8 files changed

+412
-124
lines changed

include/mrdocs/Support/Path.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class FileVisitor : public AnyFileVisitor
8787
@param recursive If true, files in subdirectories are
8888
also visited, recursively.
8989
@param visitor A callable object which is invoked
90-
for each file.
90+
for each file. This visitor might return
91+
`void` or `Expected<void>`.
9192
@return An error if any occurred.
9293
9394
*/

src/lib/AST/ASTVisitor.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,11 +3282,32 @@ buildFileInfo(std::string_view path)
32823282
file_info.full_path = path;
32833283

32843284
if (! files::isAbsolute(file_info.full_path))
3285-
file_info.full_path = files::makeAbsolute(
3286-
file_info.full_path, config_->sourceRoot);
3285+
{
3286+
bool found = false;
3287+
for (auto& includePath: config_->includes)
3288+
{
3289+
// append full path to this include path
3290+
// and check if the file exists
3291+
std::string fullPath = files::makeAbsolute(
3292+
file_info.full_path, includePath);
3293+
if (files::exists(fullPath))
3294+
{
3295+
file_info.full_path = fullPath;
3296+
found = true;
3297+
break;
3298+
}
3299+
}
3300+
if (!found)
3301+
{
3302+
file_info.full_path = files::makeAbsolute(
3303+
file_info.full_path, config_->sourceRoot);
3304+
}
3305+
}
32873306

3288-
if (! files::isPosixStyle(file_info.full_path))
3307+
if (!files::isPosixStyle(file_info.full_path))
3308+
{
32893309
file_info.full_path = files::makePosixStyle(file_info.full_path);
3310+
}
32903311

32913312
// Attempts to get a relative path for the prefix
32923313
auto tryGetRelativePosixPath = [&file_info](std::string_view const prefix)

src/lib/MrDocsCompilationDatabase.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ isCXXSrcFile(
4040
return driver::types::isCXX(extensionId);
4141
}
4242

43+
static
44+
bool
45+
isCXXHeaderFile(
46+
std::string_view filename)
47+
{
48+
StringRef ext = llvm::sys::path::extension(filename).drop_front();
49+
return ext == "hpp" || ext == "hh" || ext == "hxx" || ext == "h++";
50+
}
51+
4352
static
4453
bool
4554
isCSrcFile(
@@ -49,6 +58,15 @@ isCSrcFile(
4958
return ext == "c";
5059
}
5160

61+
static
62+
bool
63+
isCHeaderFile(
64+
std::string_view filename)
65+
{
66+
StringRef ext = llvm::sys::path::extension(filename).drop_front();
67+
return ext == "h";
68+
}
69+
5270
template<typename... Opts>
5371
static
5472
bool
@@ -413,7 +431,7 @@ adjustCommandLine(
413431
// These are additional defines specified in the config file
414432
for(auto const& def : (*config)->defines)
415433
{
416-
new_cmdline.emplace_back(std::format("-D{}", def));
434+
new_cmdline.emplace_back(std::format("-D{}", def));
417435
}
418436
new_cmdline.emplace_back("-D__MRDOCS__");
419437

@@ -554,7 +572,11 @@ MrDocsCompilationDatabase(
554572
cmd0.Filename);
555573
cmd.Directory = makeAbsoluteAndNative(workingDir, cmd0.Directory);
556574
cmd.Filename = makeAbsoluteAndNative(workingDir, cmd0.Filename);
557-
if (isCXXSrcFile(cmd.Filename) || isCSrcFile(cmd.Filename))
575+
if (
576+
isCXXSrcFile(cmd.Filename) ||
577+
isCSrcFile(cmd.Filename) ||
578+
isCXXHeaderFile(cmd.Filename) ||
579+
isCHeaderFile(cmd.Filename))
558580
{
559581
const bool emplaced = IndexByFile_.try_emplace(cmd.Filename, AllCommands_.size()).second;
560582
if (emplaced)

src/lib/MrDocsSettingsDB.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//
2+
// This is a derivative work. originally part of the LLVM Project.
3+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
8+
//
9+
// Official repository: https://github.com/cppalliance/mrdocs
10+
//
11+
12+
#include "MrDocsSettingsDB.hpp"
13+
#include <mrdocs/Support/Path.hpp>
14+
15+
namespace clang {
16+
namespace mrdocs {
17+
18+
MrDocsSettingsDB::MrDocsSettingsDB(ConfigImpl const& config)
19+
{
20+
std::vector<std::string> sourceFiles;
21+
auto& s = config.settings();
22+
for (auto const& curInput: s.input)
23+
{
24+
forEachFile(
25+
curInput,
26+
s.recursive,
27+
[&](std::string_view path) -> Expected<void> {
28+
if (files::isDirectory(path))
29+
{
30+
return {};
31+
}
32+
// Check file patterns that should match
33+
auto inputFilename = files::getFileName(path);
34+
if (std::ranges::none_of(
35+
s.filePatterns,
36+
[&](PathGlobPattern const& pattern) {
37+
return pattern.match(inputFilename);
38+
}))
39+
{
40+
return {};
41+
}
42+
// Check file or directories in path that should be skipped
43+
if (std::ranges::any_of(s.exclude, [&](std::string const& excludePath) {
44+
return files::startsWith(path, excludePath);
45+
}))
46+
{
47+
return {};
48+
}
49+
// Check if the relative path matches any of the s.excludePatterns
50+
if (std::ranges::any_of(
51+
s.excludePatterns,
52+
[&](PathGlobPattern const& pattern) {
53+
return pattern.match(path);
54+
}))
55+
{
56+
return {};
57+
}
58+
sourceFiles.emplace_back(path);
59+
return {};
60+
});
61+
}
62+
63+
for (auto const& pathName: sourceFiles)
64+
{
65+
// auto fileName = files::getFileName(pathName);
66+
auto parentDir = files::getParentDir(pathName);
67+
68+
std::vector<std::string> cmds;
69+
cmds.emplace_back("clang");
70+
cmds.emplace_back("-fsyntax-only");
71+
cmds.emplace_back("-std=c++23");
72+
cmds.emplace_back("-pedantic-errors");
73+
cmds.emplace_back("-Werror");
74+
cmds.emplace_back("-x");
75+
cmds.emplace_back("c++");
76+
cmds.emplace_back(pathName);
77+
cc_.emplace_back(parentDir, pathName, std::move(cmds), parentDir);
78+
cc_.back().Heuristic = "generated from mrdocs.yml";
79+
}
80+
}
81+
82+
std::vector<tooling::CompileCommand>
83+
MrDocsSettingsDB::getCompileCommands(llvm::StringRef FilePath) const
84+
{
85+
std::vector<tooling::CompileCommand> result;
86+
for (auto const& cmd: cc_)
87+
{
88+
if (cmd.Filename == FilePath)
89+
{
90+
result.push_back(cmd);
91+
}
92+
}
93+
return result;
94+
}
95+
96+
std::vector<std::string>
97+
MrDocsSettingsDB::getAllFiles() const
98+
{
99+
std::vector<std::string> result;
100+
result.reserve(cc_.size());
101+
for (auto const& cmd: cc_)
102+
{
103+
result.push_back(cmd.Filename);
104+
}
105+
return result;
106+
}
107+
108+
std::vector<tooling::CompileCommand>
109+
MrDocsSettingsDB::getAllCompileCommands() const
110+
{
111+
return cc_;
112+
}
113+
114+
} // namespace mrdocs
115+
} // namespace clang

src/lib/MrDocsSettingsDB.hpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// Licensed under the Apache License v2.0 with LLVM Exceptions.
3+
// See https://llvm.org/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
//
6+
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
7+
//
8+
// Official repository: https://github.com/cppalliance/mrdocs
9+
//
10+
11+
#ifndef MRDOCS_LIB_SINGLEFILEDB_HPP
12+
#define MRDOCS_LIB_SINGLEFILEDB_HPP
13+
14+
#include <mrdocs/Support/Path.hpp>
15+
#include <clang/Tooling/CompilationDatabase.h>
16+
#include "ConfigImpl.hpp"
17+
#include <string>
18+
#include <utility>
19+
#include <vector>
20+
21+
namespace clang {
22+
namespace mrdocs {
23+
24+
/** A compilation database generated from the mrdocs.yml options
25+
*/
26+
class MrDocsSettingsDB
27+
: public tooling::CompilationDatabase
28+
{
29+
std::vector<tooling::CompileCommand> cc_;
30+
31+
public:
32+
explicit
33+
MrDocsSettingsDB(
34+
ConfigImpl const& config);
35+
36+
std::vector<tooling::CompileCommand>
37+
getCompileCommands(
38+
llvm::StringRef FilePath) const override;
39+
40+
std::vector<std::string>
41+
getAllFiles() const override;
42+
43+
std::vector<tooling::CompileCommand>
44+
getAllCompileCommands() const override;
45+
};
46+
47+
} // mrdocs
48+
} // clang
49+
50+
#endif

0 commit comments

Comments
 (0)