@@ -301,17 +301,15 @@ def test_line(self, line: str) -> bool:
301301 # Ignore matches inside strings.
302302 for match in matches :
303303 n_quotes_before = line .count ('"' , 0 , match [0 ]) # Count quotation marks before the match.
304- if n_quotes_before % 2 : # If odd, we are inside a string and we should ignore this match.
305- continue
306- # We are not inside a string and this match is valid.
307- return False
304+ if not n_quotes_before % 2 : # If even, we are not inside a string and this match is valid.
305+ return False
308306 return True
309307
310308
311- class TestROOT (TestSpec ):
309+ class TestRootEntity (TestSpec ):
312310 """Detect unnecessary use of ROOT entities."""
313311
314- name = "root- entity"
312+ name = "root/ entity"
315313 message = "Replace ROOT entities with equivalents from standard C++ or from O2."
316314 suffixes = [".h" , ".cxx" ]
317315
@@ -329,6 +327,23 @@ def test_line(self, line: str) -> bool:
329327 return re .search (pattern , line ) is None
330328
331329
330+ class TestRootLorentzVector (TestSpec ):
331+ """Detect use of TLorentzVector."""
332+
333+ name = "root/lorentz-vector"
334+ message = (
335+ "Do not use the TLorentzVector legacy class. "
336+ "Use std::array with RecoDecay methods or ROOT::Math::LorentzVector instead."
337+ )
338+ suffixes = [".h" , ".cxx" ]
339+
340+ def test_line (self , line : str ) -> bool :
341+ if is_comment_cpp (line ):
342+ return True
343+ line = remove_comment_cpp (line )
344+ return "TLorentzVector" not in line
345+
346+
332347class TestPi (TestSpec ):
333348 """Detect use of external pi."""
334349
@@ -404,7 +419,7 @@ def test_line(self, line: str) -> bool:
404419 return "TDatabasePDG" not in line
405420
406421
407- class TestPdgCode (TestSpec ):
422+ class TestPdgExplicitCode (TestSpec ):
408423 """Detect use of hard-coded PDG codes."""
409424
410425 name = "pdg/explicit-code"
@@ -425,7 +440,7 @@ def test_line(self, line: str) -> bool:
425440 return True
426441
427442
428- class TestPdgMass (TestSpec ):
443+ class TestPdgKnownMass (TestSpec ):
429444 """Detect unnecessary call of Mass() for a known PDG code."""
430445
431446 name = "pdg/known-mass"
@@ -444,6 +459,49 @@ def test_line(self, line: str) -> bool:
444459 return True
445460
446461
462+ class TestPdgExplicitMass (TestSpec ):
463+ """Detect hard-coded particle masses."""
464+
465+ name = "pdg/explicit-mass"
466+ message = "Avoid hard-coded particle masses. Use o2::constants::physics::Mass... instead."
467+ suffixes = [".h" , ".cxx" ]
468+ masses : "list[str]" = [] # list of mass values to detect
469+
470+ def __init__ (self ) -> None :
471+ super ().__init__ ()
472+
473+ # List of masses of commonly used particles
474+ self .masses .append (r"0\.000511" ) # e
475+ self .masses .append (r"0\.105" ) # μ
476+ self .masses .append (r"0\.139" ) # π+
477+ self .masses .append (r"0\.493" ) # K+
478+ self .masses .append (r"0\.497" ) # K0
479+ self .masses .append (r"0\.938" ) # p
480+ self .masses .append (r"0\.939" ) # n
481+ self .masses .append (r"1\.115" ) # Λ
482+ self .masses .append (r"1\.864" ) # D0
483+ self .masses .append (r"2\.286" ) # Λc
484+ self .masses .append (r"3\.096" ) # J/ψ
485+
486+ def test_line (self , line : str ) -> bool :
487+ if is_comment_cpp (line ):
488+ return True
489+ line = remove_comment_cpp (line )
490+ iterators = re .finditer (rf"(^|\D)({ '|' .join (self .masses )} )" , line )
491+ matches = [(it .start (), it .group (2 )) for it in iterators ]
492+ if not matches :
493+ return True
494+ if '"' not in line : # Found a match which cannot be inside a string.
495+ return False
496+ # Ignore matches inside strings.
497+ for match in matches :
498+ n_quotes_before = line .count ('"' , 0 , match [0 ]) # Count quotation marks before the match.
499+ if not n_quotes_before % 2 : # If even, we are not inside a string and this match is valid.
500+ print (match [1 ])
501+ return False
502+ return True
503+
504+
447505class TestLogging (TestSpec ):
448506 """Detect non-O2 logging."""
449507
@@ -598,16 +656,30 @@ class TestMagicNumber(TestSpec):
598656 name = "magic-number"
599657 message = "Avoid magic numbers in expressions. Assign the value to a clearly named variable or constant."
600658 suffixes = [".h" , ".cxx" , ".C" ]
659+ pattern_compare = r"([<>]=?|[!=]=)"
660+ pattern_number = r"[\+-]?([\d\.]+)f?"
601661
602662 def test_line (self , line : str ) -> bool :
603663 if is_comment_cpp (line ):
604664 return True
605665 line = remove_comment_cpp (line )
606- if not (match := re .search (r" ([<>]=?|[!=]=) [\+-]?([\d\.]+)" , line )):
666+ iterators = re .finditer (
667+ rf" { self .pattern_compare } { self .pattern_number } |\W{ self .pattern_number } { self .pattern_compare } " , line
668+ )
669+ matches = [(it .start (), it .group (2 ), it .group (3 )) for it in iterators ]
670+ if not matches :
607671 return True
608- number = match .group (2 )
609- # Accept only 0 or 1 (int or float).
610- return re .match (r"[01](\.0?)?$" , number ) is not None
672+ # Ignore matches inside strings.
673+ for match in matches :
674+ n_quotes_before = line .count ('"' , 0 , match [0 ]) # Count quotation marks before the match.
675+ if n_quotes_before % 2 : # If odd, we are inside a string and we should ignore this match.
676+ continue
677+ # We are not inside a string and this match is valid.
678+ for match_n in (match [1 ], match [2 ]):
679+ # Accept only 0 or 1 (int or float).
680+ if (match_n is not None ) and (re .match (r"[01](\.0?)?$" , match_n ) is None ):
681+ return False
682+ return True
611683
612684
613685# Documentation
@@ -1442,13 +1514,15 @@ def main():
14421514 tests .append (TestUsingStd ())
14431515 tests .append (TestUsingDirectives ())
14441516 tests .append (TestStdPrefix ())
1445- tests .append (TestROOT ())
1517+ tests .append (TestRootEntity ())
1518+ tests .append (TestRootLorentzVector ())
14461519 tests .append (TestPi ())
14471520 tests .append (TestTwoPiAddSubtract ())
14481521 tests .append (TestPiMultipleFraction ())
14491522 tests .append (TestPdgDatabase ())
1450- tests .append (TestPdgCode ())
1451- tests .append (TestPdgMass ())
1523+ tests .append (TestPdgExplicitCode ())
1524+ tests .append (TestPdgKnownMass ())
1525+ tests .append (TestPdgExplicitMass ())
14521526 tests .append (TestLogging ())
14531527 tests .append (TestConstRefInForLoop ())
14541528 tests .append (TestConstRefInSubscription ())
0 commit comments