From 40537d2f3f70197fc45cd518220099aa567fd865 Mon Sep 17 00:00:00 2001 From: Kunal Tyagi Date: Sun, 20 Oct 2024 16:59:07 +0900 Subject: [PATCH] Add example to showcase the use of fullName in a rule --- nsiqcppstyle_checker.py | 11 +- ...cope_in_fn_declarations_and_definitions.py | 111 ++++++++++++++++++ 2 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 rules/RULE_11_A_add_class_scope_in_fn_declarations_and_definitions.py diff --git a/nsiqcppstyle_checker.py b/nsiqcppstyle_checker.py index ab72566..124e467 100644 --- a/nsiqcppstyle_checker.py +++ b/nsiqcppstyle_checker.py @@ -1216,9 +1216,8 @@ def ConstructContextInfo(lexer): prevName = lexer.GetPrevTokenSkipWhiteSpaceAndCommentAndPreprocess() if prevName is not None: if prevName.type == "DOUBLECOLON": - fullName = ( - f"{lexer.GetPrevTokenSkipWhiteSpaceAndCommentAndPreprocess().value}::{fullName}" - ) + value_to_prepend = lexer.GetPrevTokenSkipWhiteSpaceAndCommentAndPreprocess().value + fullName = f"{value_to_prepend}::{fullName}" else: break else: @@ -1230,10 +1229,8 @@ def ConstructContextInfo(lexer): if prevName.type == "NOT": fullName = "~" + fullName elif prevName.type == "DOUBLECOLON": - fullName = "::" + fullName - fullName = ( - lexer.GetPrevTokenSkipWhiteSpaceAndCommentAndPreprocess().value + fullName - ) + value_to_prepend = lexer.GetPrevTokenSkipWhiteSpaceAndCommentAndPreprocess().value + fullName = f"{value_to_prepend}::{fullName}" else: break else: diff --git a/rules/RULE_11_A_add_class_scope_in_fn_declarations_and_definitions.py b/rules/RULE_11_A_add_class_scope_in_fn_declarations_and_definitions.py new file mode 100644 index 0000000..00fea33 --- /dev/null +++ b/rules/RULE_11_A_add_class_scope_in_fn_declarations_and_definitions.py @@ -0,0 +1,111 @@ +""" +Ensure that the functions declarations/definitions in the class/struct scope are scoped + +== Violation == + + class A + { + bool GetSth(); <== Violation. Should be A::GetSth. + }; + +== Good == + + class A + { + bool ::GetSth(); <== OK. + public: + bool A::GetSthElse(); <== OK. + }; +""" + +from nsiqcppstyle_reporter import * +from nsiqcppstyle_rulehelper import * +from nsiqcppstyle_rulemanager import * +from nsiqunittest.nsiqcppstyle_unittestbase import * + + +def RunRule(lexer, fullName, decl, contextStack, context): + t = lexer.GetCurToken() + value = t.value + upperBlock = contextStack.SigPeek() + if upperBlock is None: + return + if upperBlock.type in ["CLASS_BLOCK", "STRUCT_BLOCK"] and value == fullName: + class_name = upperBlock.name.rsplit("::")[-1] + nsiqcppstyle_reporter.Error(t, __name__, f"Function name({fullName}) should include local scope({class_name})") + + +ruleManager.AddFunctionNameRule(RunRule) + +########################################################################## +# Unit Test +########################################################################## + + +class testRule(nct): + def setUpRule(self): + ruleManager.AddFunctionNameRule(RunRule) + global currentVisibility + currentVisibility = False + + def test1(self): + self.Analyze( + "test/thisFile.c", + """ +bool CanHave() { +}""", + ) + self.ExpectSuccess(__name__) + + def test2(self): + self.Analyze( + "test/thisFile.c", + """ +class TT::K { +bool CanHave() { +} +}""", + ) + self.ExpectError(__name__) + + def test3(self): + self.Analyze( + "test/thisFile.c", + """ +class TT::K { +bool K::CanHave() { +} +}""", + ) + self.ExpectSuccess(__name__) + + def test4(self): + self.Analyze( + "test/thisFile.c", + """ +class TT::K { +bool TT::K::CanHave() { +} +}""", + ) + self.ExpectSuccess(__name__) + + def test5(self): + self.Analyze( + "test/thisFile.c", + """ +class TT::K { +K& operator++(); +}""", + ) + self.ExpectError(__name__) + + def test6(self): + self.Analyze( + "test/thisFile.c", + """ +class TT::K { +K& K::operator++(); +}""", + ) + self.ExpectSuccess(__name__)