diff --git a/change_notes/2023-11-24-a2-7-3-remove-function-scope.md b/change_notes/2023-11-24-a2-7-3-remove-function-scope.md new file mode 100644 index 0000000000..cfd50f8ab8 --- /dev/null +++ b/change_notes/2023-11-24-a2-7-3-remove-function-scope.md @@ -0,0 +1,3 @@ + * `A2-7-3` - `UndocumentedUserDefinedType.ql`: + - Excluding declarations in function scope. The rationale is that these declarations are not exposed outside the scope of the function. + \ No newline at end of file diff --git a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql index 247f3ef2a1..a8bfe3b361 100644 --- a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql +++ b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql @@ -17,6 +17,14 @@ import cpp import codingstandards.cpp.autosar +private predicate isInFunctionScope(Declaration d) { + // Type declared in function + exists(d.(UserType).getEnclosingFunction()) + or + // Member declared in type which is in function scope + isInFunctionScope(d.getDeclaringType()) +} + /** * A declaration which is required to be preceded by documentation by AUTOSAR A2-7-3. */ @@ -42,10 +50,8 @@ class DocumentableDeclaration extends Declaration { declarationType = "member variable" and // Exclude memeber variables in instantiated templates, which cannot reasonably be documented. not this.(MemberVariable).isFromTemplateInstantiation(_) and - // Exclude anonymous lambda functions. - // TODO: replace with the following when support is added. - // not this.(MemberVariable).isCompilerGenerated() - not exists(LambdaExpression lc | lc.getACapture().getField() = this) + // Exclude compiler generated variables, such as those for anonymous lambda functions + not this.(MemberVariable).isCompilerGenerated() } /** Gets a `DeclarationEntry` for this declaration that should be documented. */ @@ -96,6 +102,7 @@ from DocumentableDeclaration d, DeclarationEntry de where not isExcluded(de, CommentsPackage::undocumentedUserDefinedTypeQuery()) and not isExcluded(d, CommentsPackage::undocumentedUserDefinedTypeQuery()) and + not isInFunctionScope(d) and d.getAnUndocumentedDeclarationEntry() = de select de, "Declaration entry for " + d.getDeclarationType() + " " + d.getName() + diff --git a/cpp/autosar/test/rules/A2-7-3/test.cpp b/cpp/autosar/test/rules/A2-7-3/test.cpp index bc174d918d..8e9e180458 100644 --- a/cpp/autosar/test/rules/A2-7-3/test.cpp +++ b/cpp/autosar/test/rules/A2-7-3/test.cpp @@ -160,4 +160,19 @@ template class A2_7_3 final { const std::string kBar{"bar"}; // NON_COMPLIANT }; /// @brief This is the instantiateA2_7_3 documentation -void instantiateA2_7_3() { A2_7_3 instance; } \ No newline at end of file +void instantiateA2_7_3() { A2_7_3 instance; } + +/// Test documentation +void testFunctionScope() { + using my_float = float; + class ClassF { // COMPLIANT - in function scope + public: + int m_x; // COMPLIANT - in function scope + void fTest(); // COMPLIANT - in function scope + class ClassFNested { + public: + int m_nested_x; // COMPLIANT - in function scope + void fNestedTest(); // COMPLIANT - in function scope + }; + }; +} \ No newline at end of file diff --git a/rule_packages/cpp/Comments.json b/rule_packages/cpp/Comments.json index d6364f01d6..7af32f62c1 100644 --- a/rule_packages/cpp/Comments.json +++ b/rule_packages/cpp/Comments.json @@ -70,7 +70,10 @@ "tags": [ "maintainability", "readability" - ] + ], + "implementation_scope": { + "description": "Function scope declarations are excluded from this rule as they are restricted in scope to only a single function." + } } ], "title": "All declarations of 'user-defined' types, static and non-static data members, functions and methods shall be preceded by documentation."