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