1 #include "TestFilenameCheck.h"
2
3 #include <ClangTidyDiagnosticConsumer.h>
4 #include <clang/Basic/IdentifierTable.h>
5 #include <clang/Basic/SourceLocation.h>
6 #include <clang/Basic/SourceManager.h>
7 #include <clang/Lex/PPCallbacks.h>
8 #include <clang/Lex/Preprocessor.h>
9 #include <clang/Lex/Token.h>
10 #include <llvm/ADT/STLExtras.h>
11
12 #include "clang/Frontend/CompilerInstance.h"
13
14 namespace clang
15 {
16 class MacroArgs;
17 class MacroDefinition;
18 } // namespace clang
19
20 using namespace clang::ast_matchers;
21
22 namespace clang
23 {
24 namespace tidy
25 {
26 namespace cata
27 {
28
29 class TestFilenameCallbacks : public PPCallbacks
30 {
31 public:
TestFilenameCallbacks(TestFilenameCheck * Check,CompilerInstance * Compiler)32 TestFilenameCallbacks( TestFilenameCheck *Check, CompilerInstance *Compiler ) :
33 Check( Check ), Compiler( Compiler ) {}
34
MacroExpands(const Token & MacroNameTok,const MacroDefinition &,SourceRange Range,const MacroArgs *)35 void MacroExpands( const Token &MacroNameTok,
36 const MacroDefinition &,
37 SourceRange Range,
38 const MacroArgs * ) override {
39 StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName();
40
41 if( MacroName == "TEST_CASE" ) {
42 SourceManager &SM = Compiler->getSourceManager();
43 StringRef Filename = SM.getBufferName( Range.getBegin() );
44 bool IsTestFilename = Filename.endswith( "_test.cpp" );
45
46 if( !IsTestFilename ) {
47 Check->diag( Range.getBegin(),
48 "Files containing a test definition should have a filename "
49 "ending in '_test.cpp'." );
50 }
51 }
52 }
53 private:
54 TestFilenameCheck *Check;
55 CompilerInstance *Compiler;
56 };
57
registerPPCallbacks(CompilerInstance & Compiler)58 void TestFilenameCheck::registerPPCallbacks( CompilerInstance &Compiler )
59 {
60 Compiler.getPreprocessor().addPPCallbacks(
61 llvm::make_unique<TestFilenameCallbacks>( this, &Compiler ) );
62 }
63
64 } // namespace cata
65 } // namespace tidy
66 } // namespace clang
67