forked from OSchip/llvm-project
90 lines
3.2 KiB
C++
90 lines
3.2 KiB
C++
|
//===--- AvoidUnderscoreInGoogletestNameCheck.cpp - clang-tidy --*- C++ -*-===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
#include "AvoidUnderscoreInGoogletestNameCheck.h"
|
||
|
#include "clang/AST/ASTContext.h"
|
||
|
#include "clang/ASTMatchers/ASTMatchers.h"
|
||
|
#include "clang/Frontend/CompilerInstance.h"
|
||
|
#include "clang/Lex/MacroArgs.h"
|
||
|
|
||
|
namespace clang {
|
||
|
namespace tidy {
|
||
|
namespace google {
|
||
|
namespace readability {
|
||
|
|
||
|
constexpr llvm::StringLiteral kDisabledTestPrefix = "DISABLED_";
|
||
|
|
||
|
// Determines whether the macro is a Googletest test macro.
|
||
|
static bool isGoogletestTestMacro(StringRef MacroName) {
|
||
|
static const llvm::StringSet<> MacroNames = {"TEST", "TEST_F", "TEST_P",
|
||
|
"TYPED_TEST", "TYPED_TEST_P"};
|
||
|
return MacroNames.find(MacroName) != MacroNames.end();
|
||
|
}
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
class AvoidUnderscoreInGoogletestNameCallback : public PPCallbacks {
|
||
|
public:
|
||
|
AvoidUnderscoreInGoogletestNameCallback(
|
||
|
Preprocessor *PP, AvoidUnderscoreInGoogletestNameCheck *Check)
|
||
|
: PP(PP), Check(Check) {}
|
||
|
|
||
|
// Detects expansions of the TEST, TEST_F, TEST_P, TYPED_TEST, TYPED_TEST_P
|
||
|
// macros and checks that their arguments do not have any underscores.
|
||
|
void MacroExpands(const Token &MacroNameToken,
|
||
|
const MacroDefinition &MacroDefinition, SourceRange Range,
|
||
|
const MacroArgs *Args) override {
|
||
|
IdentifierInfo *NameIdentifierInfo = MacroNameToken.getIdentifierInfo();
|
||
|
if (!NameIdentifierInfo)
|
||
|
return;
|
||
|
StringRef MacroName = NameIdentifierInfo->getName();
|
||
|
if (!isGoogletestTestMacro(MacroName) || !Args ||
|
||
|
Args->getNumMacroArguments() < 2)
|
||
|
return;
|
||
|
const Token *TestCaseNameToken = Args->getUnexpArgument(0);
|
||
|
const Token *TestNameToken = Args->getUnexpArgument(1);
|
||
|
if (!TestCaseNameToken || !TestNameToken)
|
||
|
return;
|
||
|
std::string TestCaseName = PP->getSpelling(*TestCaseNameToken);
|
||
|
if (TestCaseName.find('_') != std::string::npos)
|
||
|
Check->diag(TestCaseNameToken->getLocation(),
|
||
|
"avoid using \"_\" in test case name \"%0\" according to "
|
||
|
"Googletest FAQ")
|
||
|
<< TestCaseName;
|
||
|
|
||
|
std::string TestNameMaybeDisabled = PP->getSpelling(*TestNameToken);
|
||
|
StringRef TestName = TestNameMaybeDisabled;
|
||
|
TestName.consume_front(kDisabledTestPrefix);
|
||
|
if (TestName.contains('_'))
|
||
|
Check->diag(TestNameToken->getLocation(),
|
||
|
"avoid using \"_\" in test name \"%0\" according to "
|
||
|
"Googletest FAQ")
|
||
|
<< TestName;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
Preprocessor *PP;
|
||
|
AvoidUnderscoreInGoogletestNameCheck *Check;
|
||
|
};
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
void AvoidUnderscoreInGoogletestNameCheck::registerPPCallbacks(
|
||
|
CompilerInstance &Compiler) {
|
||
|
Compiler.getPreprocessor().addPPCallbacks(
|
||
|
llvm::make_unique<AvoidUnderscoreInGoogletestNameCallback>(
|
||
|
&Compiler.getPreprocessor(), this));
|
||
|
}
|
||
|
|
||
|
} // namespace readability
|
||
|
} // namespace google
|
||
|
} // namespace tidy
|
||
|
} // namespace clang
|