1212#include " clang/ASTMatchers/ASTMatchFinder.h"
1313#include < iostream>
1414#include < regex>
15+ #include < string>
1516
1617using namespace clang ::ast_matchers;
1718
@@ -22,7 +23,15 @@ namespace aliceO2 {
2223void MemberNamesCheck::registerMatchers (MatchFinder *Finder) {
2324 // Our policy says that only class members need to start with m, not
2425 // struct members
25- Finder->addMatcher ((fieldDecl (hasParent (recordDecl (isClass ())))).bind (" field_decl1" ), this );
26+ auto o2PatchableMember = matchesName (" ::[a-z][A-Z][^:]*$" );
27+ auto o2InvalidMember = matchesName (" ::[^m][A-Z][^:]*$" );
28+ auto namingRules = allOf (o2PatchableMember,o2InvalidMember);
29+ auto isAClass = hasParent (recordDecl (isClass ()));
30+ auto field = fieldDecl (allOf (isAClass, namingRules));
31+ auto initialisers = forEachConstructorInitializer (cxxCtorInitializer (forField (field)).bind (" member_initialiser1" ));
32+ Finder->addMatcher (field.bind (" field_decl1" ), this );
33+ Finder->addMatcher (memberExpr (hasDeclaration (field)).bind (" member_decl1" ), this );
34+ Finder->addMatcher (cxxConstructorDecl (forEachConstructorInitializer (allOf (cxxCtorInitializer (isMemberInitializer ()).bind (" member_initialiser1" ), forField (field)))), this );
2635}
2736
2837void MemberNamesCheck::check (const MatchFinder::MatchResult &Result) {
@@ -35,14 +44,53 @@ void MemberNamesCheck::check(const MatchFinder::MatchResult &Result) {
3544 && (MatchedDecl->getQualifiedNameAsString ().find (" o2::" ) != 0 ))
3645 return ;
3746
38- if (std::regex_match (MatchedDecl->getNameAsString (), Regex)) {
39- return ;
40- }
41-
47+ std::string newName (MatchedDecl->getNameAsString ());
48+ newName[0 ] = ' m' ;
4249 diag (MatchedDecl->getLocation (),
4350 " field declaration %0 does not match naming rule" ,
4451 DiagnosticIDs::Error)
45- << MatchedDecl;
52+ << MatchedDecl
53+ << FixItHint::CreateReplacement (MatchedDecl->getLocation (), newName);
54+ }
55+ const auto *MatchedValue = Result.Nodes .getNodeAs <MemberExpr>(" member_decl1" );
56+ if (MatchedValue) {
57+ const auto *MatchedValueDecl = MatchedValue->getMemberDecl ();
58+ // check that we are inside the AliceO2 namespace to exlude system stuff
59+ // FIXME: needs to be configurable
60+ // NOTE: AliceO2:: is the old one. We agreed to use o2::
61+
62+ if ((MatchedValueDecl->getQualifiedNameAsString ().find (" AliceO2::" ) != 0 )
63+ && (MatchedValueDecl->getQualifiedNameAsString ().find (" o2::" ) != 0 ))
64+ return ;
65+
66+ std::string newName (MatchedValueDecl->getNameAsString ());
67+ newName[0 ] = ' m' ;
68+ diag (MatchedValue->getMemberLoc (),
69+ " field reference %0 does not match naming rule" ,
70+ DiagnosticIDs::Error)
71+ << MatchedValueDecl
72+ << FixItHint::CreateReplacement (MatchedValue->getMemberLoc (), newName);
73+ }
74+ const auto *MatchedInitializer = Result.Nodes .getNodeAs <CXXCtorInitializer>(" member_initialiser1" );
75+ if (MatchedInitializer) {
76+ if (!MatchedInitializer->isWritten ())
77+ return ;
78+ const auto *MatchedValueDecl = MatchedInitializer->getMember ();
79+ // check that we are inside the AliceO2 namespace to exlude system stuff
80+ // FIXME: needs to be configurable
81+ // NOTE: AliceO2:: is the old one. We agreed to use o2::
82+
83+ if ((MatchedValueDecl->getQualifiedNameAsString ().find (" AliceO2::" ) != 0 )
84+ && (MatchedValueDecl->getQualifiedNameAsString ().find (" o2::" ) != 0 ))
85+ return ;
86+
87+ std::string newName (MatchedValueDecl->getNameAsString ());
88+ newName[0 ] = ' m' ;
89+ diag (MatchedInitializer->getMemberLocation (),
90+ " initialiser %0 does not match naming rule" ,
91+ DiagnosticIDs::Error)
92+ << MatchedValueDecl
93+ << FixItHint::CreateReplacement (MatchedInitializer->getMemberLocation (), newName);
4694 }
4795}
4896
0 commit comments