Skip to content

A2-7-3: Exclude Doxygen comment groups from results #640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions change_notes/2024-07-12-support-doxygen-comment-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `A2-7-3` - `UndocumentedUserDefinedType.ql`:
- Fixes #391. Declarations for which a Doxygen comment group provides documentation will no longer produce results.
42 changes: 40 additions & 2 deletions cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ private predicate isInFunctionScope(Declaration d) {
isInFunctionScope(d.getDeclaringType())
}

private string doxygenCommentGroupStrings(boolean opening) {
opening = true and result = ["///@{", "/**@{*/"]
or
opening = false and result = ["///@}", "/**@}*/"]
}

pragma[inline]
private predicate isBetweenDoxygenCommentGroup(
Location loc, Comment opening, Comment body, Comment closing
) {
// All in the same file
loc.getFile() = opening.getLocation().getFile() and
loc.getFile() = closing.getLocation().getFile() and
loc.getFile() = body.getLocation().getFile() and
// The comments are doxygen comments
opening.getContents().matches(doxygenCommentGroupStrings(true)) and
closing.getContents().matches(doxygenCommentGroupStrings(false)) and
// The closing comment is after the opening comment
opening.getLocation().getStartLine() < closing.getLocation().getStartLine() and
// The `body` comment directly precedes the opening comment
body.getLocation().getEndLine() = opening.getLocation().getStartLine() - 1 and
// There are no other opening/closing comment pairs between the opening and closing comments
not exists(Comment c |
c.getContents().matches(doxygenCommentGroupStrings(_)) and
c.getLocation().getStartLine() > opening.getLocation().getStartLine() and
c.getLocation().getStartLine() < closing.getLocation().getStartLine()
) and
// `loc` is between the opening and closing comments and after the body comment
loc.getStartLine() > opening.getLocation().getStartLine() and
loc.getStartLine() < closing.getLocation().getStartLine() and
loc.getStartLine() > body.getLocation().getEndLine()
}

/**
* A declaration which is required to be preceded by documentation by AUTOSAR A2-7-3.
*/
Expand Down Expand Up @@ -80,11 +113,13 @@ class DocumentableDeclaration extends Declaration {
}

/**
* A `DeclarationEntry` is considered documented if it has an associated `Comment`, and the `Comment`
* precedes the `DeclarationEntry`.
* A `DeclarationEntry` is considered documented if it has an associated `Comment`, the `Comment`
* precedes the `DeclarationEntry`, and the `Comment` is not a doxygen comment group prefix.
*/
cached
predicate isDocumented(DeclarationEntry de) {
exists(Comment c | c.getCommentedElement() = de |
not c.getContents() = doxygenCommentGroupStrings(true) and
exists(Location commentLoc, Location deLoc |
commentLoc = c.getLocation() and deLoc = de.getLocation()
|
Expand All @@ -96,6 +131,9 @@ predicate isDocumented(DeclarationEntry de) {
commentLoc.getStartColumn() < deLoc.getStartColumn()
)
)
or
// The declaration entry is between a doxygen comment group
isBetweenDoxygenCommentGroup(de.getLocation(), _, _, _)
}

from DocumentableDeclaration d, DeclarationEntry de
Expand Down
20 changes: 11 additions & 9 deletions cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
| test.cpp:70:7:70:12 | definition of ClassD | Declaration entry for user-defined type ClassD is missing documentation. |
| test.cpp:72:7:72:7 | definition of a | Declaration entry for member variable a is missing documentation. |
| test.cpp:73:14:73:14 | declaration of b | Declaration entry for member variable b is missing documentation. |
| test.cpp:74:8:74:8 | declaration of f | Declaration entry for function f is missing documentation. |
| test.cpp:76:7:76:7 | definition of c | Declaration entry for member variable c is missing documentation. |
| test.cpp:78:6:78:6 | declaration of d | Declaration entry for function d is missing documentation. |
| test.cpp:81:6:81:6 | definition of e | Declaration entry for function e is missing documentation. |
| test.cpp:88:1:88:30 | definition of message_to_string_undocumented | Declaration entry for function message_to_string_undocumented is missing documentation. |
| test.cpp:160:21:160:24 | definition of kBar | Declaration entry for member variable kBar is missing documentation. |
| test.cpp:74:8:74:8 | declaration of j | Declaration entry for function j is missing documentation. |
| test.cpp:75:8:75:8 | declaration of k | Declaration entry for function k is missing documentation. |
| test.cpp:90:7:90:12 | definition of ClassD | Declaration entry for user-defined type ClassD is missing documentation. |
| test.cpp:92:7:92:7 | definition of a | Declaration entry for member variable a is missing documentation. |
| test.cpp:93:14:93:14 | declaration of b | Declaration entry for member variable b is missing documentation. |
| test.cpp:94:8:94:8 | declaration of f | Declaration entry for function f is missing documentation. |
| test.cpp:96:7:96:7 | definition of c | Declaration entry for member variable c is missing documentation. |
| test.cpp:98:6:98:6 | declaration of d | Declaration entry for function d is missing documentation. |
| test.cpp:101:6:101:6 | definition of e | Declaration entry for function e is missing documentation. |
| test.cpp:108:1:108:30 | definition of message_to_string_undocumented | Declaration entry for function message_to_string_undocumented is missing documentation. |
| test.cpp:180:21:180:24 | definition of kBar | Declaration entry for member variable kBar is missing documentation. |
20 changes: 20 additions & 0 deletions cpp/autosar/test/rules/A2-7-3/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,30 @@ class ClassC { // COMPLIANT
/// @param i an integer.
/// @throw std::runtime_error
void f(int i); // COMPLIANT

/** Same documentation for all members
* This is a multiline comment.
*/
///@{
void g(); // COMPLIANT
void h(); // COMPLIANT
void i(); // COMPLIANT
///@}

///@{
void j(); // NON_COMPLIANT
void k(); // NON_COMPLIANT
/** Member-specific documentation */
void l(); // COMPLIANT
///@}

private:
/// @brief A Doxygen comment.
int c; // COMPLIANT
};
void ClassC::i() { // not flagged, as we will only flag the non-definition
// declaration
}
/// A Doxygen comment.
void c(); // COMPLIANT

Expand Down
Loading