mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
feat(tidy): Add new fairmq-tidy tool
This commit is contained in:
parent
f7d16b04c7
commit
0fcddd9d76
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
build
|
||||
|
||||
install
|
||||
.DS_Store
|
||||
|
||||
.vscode
|
||||
/compile_commands.json
|
||||
.cache
|
||||
|
|
|
@ -39,6 +39,8 @@ fairmq_build_option(BUILD_EXAMPLES "Build FairMQ examples."
|
|||
DEFAULT ON REQUIRES "BUILD_FAIRMQ")
|
||||
fairmq_build_option(BUILD_SDK "Build the FairMQ controller SDK."
|
||||
DEFAULT OFF REQUIRES "BUILD_DDS_PLUGIN;BUILD_SDK_COMMANDS")
|
||||
fairmq_build_option(BUILD_TIDY_TOOL "Build the fairmq-tidy tool."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(BUILD_DOCS "Build FairMQ documentation."
|
||||
DEFAULT OFF)
|
||||
fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended."
|
||||
|
@ -76,6 +78,10 @@ if(BUILD_DOCS)
|
|||
doxygen_add_docs(doxygen README.md fairmq)
|
||||
add_custom_target(docs ALL DEPENDS doxygen)
|
||||
endif()
|
||||
|
||||
if(BUILD_TIDY_TOOL)
|
||||
add_subdirectory(fairmq/tidy)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
||||
|
@ -107,6 +113,9 @@ endif()
|
|||
if(BUILD_SDK_COMMANDS)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS sdk_commands)
|
||||
endif()
|
||||
if(BUILD_TIDY_TOOL)
|
||||
list(APPEND PROJECT_PACKAGE_COMPONENTS tidy_tool)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ if(BUILD_PMIX_PLUGIN)
|
|||
find_package2(PRIVATE PMIx REQUIRED VERSION 2.1.4)
|
||||
endif()
|
||||
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK)
|
||||
if(BUILD_FAIRMQ OR BUILD_SDK OR BUILD_TIDY_TOOL)
|
||||
find_package2(PUBLIC FairLogger REQUIRED VERSION 1.6.0)
|
||||
find_package2(PUBLIC Boost REQUIRED VERSION 1.66
|
||||
COMPONENTS container program_options filesystem date_time regex
|
||||
|
@ -73,6 +73,13 @@ if(BUILD_DOCS)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_TIDY_TOOL)
|
||||
find_package2(PRIVATE LLVM REQUIRED)
|
||||
find_package2(PRIVATE Clang REQUIRED)
|
||||
set(Clang_VERSION ${LLVM_VERSION})
|
||||
find_package2(PRIVATE CLI11 REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package2_implicit_dependencies() # Always call last after latest find_package2
|
||||
|
||||
if(PROJECT_PACKAGE_DEPENDENCIES)
|
||||
|
|
|
@ -69,6 +69,12 @@ macro(fairmq_summary_components)
|
|||
set(sdk_commands_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_SDK_COMMANDS=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}sdk_commands${CR} ${sdk_commands_summary}")
|
||||
if(BUILD_TIDY_TOOL)
|
||||
set(sdk_tidy_summary "${BGreen}YES${CR} (disable with ${BMagenta}-DBUILD_TIDY_TOOL=OFF${CR})")
|
||||
else()
|
||||
set(sdk_tidy_summary "${BRed} NO${CR} (default, enable with ${BMagenta}-DBUILD_TIDY_TOOL=ON${CR})")
|
||||
endif()
|
||||
message(STATUS " ${BWhite}tidy_tool${CR} ${sdk_tidy_summary}")
|
||||
endmacro()
|
||||
|
||||
macro(fairmq_summary_static_analysis)
|
||||
|
|
24
fairmq/tidy/CMakeLists.txt
Normal file
24
fairmq/tidy/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
set(target fairmq-tidy)
|
||||
add_executable(${target}
|
||||
ModernizeNonNamespacedTypes.h
|
||||
Tool.h
|
||||
runTool.cpp
|
||||
)
|
||||
target_compile_features(${target} PRIVATE cxx_std_17)
|
||||
target_link_libraries(${target} PRIVATE clang-cpp LLVM)
|
||||
target_include_directories(${target} PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>
|
||||
)
|
||||
install(TARGETS ${target}
|
||||
EXPORT ${PROJECT_EXPORT_SET}
|
||||
RUNTIME DESTINATION ${PROJECT_INSTALL_BINDIR}
|
||||
)
|
81
fairmq/tidy/ModernizeNonNamespacedTypes.h
Normal file
81
fairmq/tidy/ModernizeNonNamespacedTypes.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_MQ_TIDY_MODERNIZENONNAMESPACEDTYPES
|
||||
#define FAIR_MQ_TIDY_MODERNIZENONNAMESPACEDTYPES
|
||||
|
||||
#include <clang/AST/AST.h>
|
||||
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
||||
#include <clang/ASTMatchers/ASTMatchers.h>
|
||||
#include <clang/Basic/Diagnostic.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace fair::mq::tidy {
|
||||
|
||||
struct ModernizeNonNamespacedTypes
|
||||
{
|
||||
ModernizeNonNamespacedTypes() = delete;
|
||||
ModernizeNonNamespacedTypes(clang::ast_matchers::MatchFinder& finder)
|
||||
{
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
// https://clang.llvm.org/docs/LibASTMatchersReference.html
|
||||
finder.addMatcher(
|
||||
typeLoc(loc(qualType(hasDeclaration(namedDecl(matchesName("FairMQ.*")).bind("decl")))))
|
||||
.bind("loc"),
|
||||
&fCallback);
|
||||
}
|
||||
|
||||
struct Callback : clang::ast_matchers::MatchFinder::MatchCallback
|
||||
{
|
||||
auto run(clang::ast_matchers::MatchFinder::MatchResult const& m) -> void final
|
||||
{
|
||||
using namespace clang;
|
||||
|
||||
auto const type_loc(m.Nodes.getNodeAs<TypeLoc>("loc"));
|
||||
auto const named_decl(m.Nodes.getNodeAs<NamedDecl>("decl"));
|
||||
|
||||
if (auto const type_alias_decl = m.Nodes.getNodeAs<TypeAliasDecl>("decl")) {
|
||||
auto const underlying_type(type_alias_decl->getUnderlyingType());
|
||||
|
||||
// auto ldecl_ctx(type_loc->getType()getLexicalDeclContext());
|
||||
// std::stringstream s;
|
||||
// while (ldecl_ctx) {
|
||||
// s << "." << ldecl_ctx->getDeclKindName();
|
||||
// if (ldecl_ctx->isNamespace()) {
|
||||
// s << dyn_cast<NamespaceDecl>(ldecl_ctx)->getNameAsString();
|
||||
// }
|
||||
// ldecl_ctx = ldecl_ctx->getLexicalParent();
|
||||
// }
|
||||
|
||||
if (underlying_type.getAsString().rfind("fair::mq::", 0) == 0) {
|
||||
auto& diag_engine(m.Context->getDiagnostics());
|
||||
auto builder(
|
||||
diag_engine.Report(type_loc->getBeginLoc(),
|
||||
diag_engine.getCustomDiagID(
|
||||
DiagnosticsEngine::Warning,
|
||||
"Modernize non-namespaced type %0 with %1. [%2]")));
|
||||
builder << named_decl;
|
||||
builder << underlying_type;
|
||||
builder << "fairmq-modernize-nonnamespaced-types";
|
||||
|
||||
builder.AddFixItHint(FixItHint::CreateReplacement(
|
||||
type_loc->getSourceRange(), underlying_type.getAsString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
Callback fCallback;
|
||||
};
|
||||
|
||||
} // namespace fair::mq::tidy
|
||||
|
||||
#endif /* FAIR_MQ_TIDY_MODERNIZENONNAMESPACEDTYPES */
|
76
fairmq/tidy/Tool.h
Normal file
76
fairmq/tidy/Tool.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_MQ_TIDY_TOOL
|
||||
#define FAIR_MQ_TIDY_TOOL
|
||||
|
||||
#include <clang/ASTMatchers/ASTMatchFinder.h>
|
||||
#include <clang/Basic/FileManager.h>
|
||||
#include <clang/Tooling/CompilationDatabase.h>
|
||||
#include <clang/Tooling/Tooling.h>
|
||||
#include <fairmq/tidy/ModernizeNonNamespacedTypes.h>
|
||||
#include <string>
|
||||
|
||||
namespace fair::mq::tidy {
|
||||
|
||||
// Getting up to speed, read this:
|
||||
// https://clang.llvm.org/docs/LibTooling.html
|
||||
// https://clang.llvm.org/docs/IntroductionToTheClangAST.html
|
||||
// Watch https://www.youtube.com/watch?v=VqCkCDFLSsc !!!
|
||||
//
|
||||
// optional, but helpful:
|
||||
// https://static.linaro.org/connect/yvr18/presentations/yvr18-223.pdf
|
||||
// https://steveire.wordpress.com/2018/11/20/composing-ast-matchers-in-clang-tidy/
|
||||
// https://www.goldsborough.me/c++/clang/llvm/tools/2017/02/24/00-00-06-emitting_diagnostics_and_fixithints_in_clang_tools/
|
||||
// https://steveire.com/CodeDive2018Presentation.pdf
|
||||
//
|
||||
// reference (no built-in search, however google will find things):
|
||||
// https://clang.llvm.org/doxygen/
|
||||
//
|
||||
// Note: Implementing a standalone tool will impose double PP and parsing cost if one also
|
||||
// runs clang-tidy. At the moment, one cannot extend clang-tidy with new checks without
|
||||
// recompiling clang-tidy. In principle llvm-project/clang-extra-tools/clang-tidy
|
||||
// has install rules, but Fedora is not packaging them which is likely due to their
|
||||
// unstable state (lots of comments aka todo, fixme, refactor etc). Also, it seems
|
||||
// focus has shifted towards implementing the
|
||||
// https://microsoft.github.io/language-server-protocol/
|
||||
// via https://clangd.llvm.org/ which includes clang-tidy, but also does not have
|
||||
// an extension/plugin interface for third-party checks yet AFAICS.
|
||||
|
||||
struct Tool
|
||||
{
|
||||
static auto run(clang::tooling::CompilationDatabase const &compilations,
|
||||
clang::ArrayRef<std::string> sources) -> int
|
||||
{
|
||||
using namespace clang;
|
||||
|
||||
// compose all checks in a single match finder
|
||||
ast_matchers::MatchFinder finder;
|
||||
ModernizeNonNamespacedTypes check1(finder);
|
||||
|
||||
// configure the clang tool
|
||||
tooling::ClangTool tool(compilations, sources);
|
||||
tool.appendArgumentsAdjuster(
|
||||
[](tooling::CommandLineArguments const &_args, StringRef /*file*/) {
|
||||
tooling::CommandLineArguments args(_args);
|
||||
// TODO add only if cdb was generated with GCC
|
||||
args.emplace(args.begin() + 1, "-I/usr/lib64/clang/12.0.0/include");
|
||||
// TODO add only if missing
|
||||
args.emplace(args.begin() + 1, "-std=c++17");
|
||||
args.emplace_back("-Wno-everything");
|
||||
return args;
|
||||
});
|
||||
|
||||
// run checks on given files
|
||||
return tool.run(clang::tooling::newFrontendActionFactory(&finder).get());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fair::mq::tidy
|
||||
|
||||
#endif /* FAIR_MQ_TIDY_TOOL */
|
29
fairmq/tidy/runTool.cpp
Normal file
29
fairmq/tidy/runTool.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <clang/Tooling/CommonOptionsParser.h>
|
||||
#include <clang/Tooling/Tooling.h>
|
||||
#include <fairmq/tidy/Tool.h>
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
|
||||
static llvm::cl::OptionCategory ToolCategory("fairmq-tidy options");
|
||||
static llvm::cl::extrahelp CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// TODO Replace command line parser with CLI11
|
||||
auto parser(clang::tooling::CommonOptionsParser::create(
|
||||
argc, argv, ToolCategory, llvm::cl::NumOccurrencesFlag::Optional, ""));
|
||||
if (!parser) {
|
||||
llvm::errs() << parser.takeError();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return fair::mq::tidy::Tool::run(parser->getCompilations(), parser->getSourcePathList());
|
||||
}
|
Loading…
Reference in New Issue
Block a user