Tools: fixes/improvements for 'check_struct_comments' check

- Fix using forward declarations when extracting struct information as
  it causing this check to be ignored.
- Fix extracting comments which sometimes included code fragments.
- Fix extracting the outer comment for struct declarations on a single
  line.
- Skip source files in the build directory.
This commit is contained in:
Campbell Barton 2023-07-26 15:23:21 +10:00
parent 673fc326db
commit 6f85a1ae9f
1 changed files with 39 additions and 10 deletions

View File

@ -164,16 +164,18 @@ class clang_checkers:
# IPython.embed()
if node.kind == CursorKind.STRUCT_DECL:
struct_type = node.spelling.strip()
if not struct_type:
# The parent may be a `typedef [..] TypeID` where `[..]` is `struct { a; b; c; }`.
# Inspect the parent.
if node_parent is not None and (node_parent.kind == CursorKind.TYPEDEF_DECL):
tokens = list(node_parent.get_tokens())
if tokens[0].spelling == "typedef":
struct_type = tokens[-1].spelling
# Ignore forward declarations.
if next(node.get_children(), None) is not None:
struct_type = node.spelling.strip()
if not struct_type:
# The parent may be a `typedef [..] TypeID` where `[..]` is `struct { a; b; c; }`.
# Inspect the parent.
if node_parent is not None and (node_parent.kind == CursorKind.TYPEDEF_DECL):
tokens = list(node_parent.get_tokens())
if tokens[0].spelling == "typedef":
struct_type = tokens[-1].spelling
struct_decl_map[struct_type] = node
struct_decl_map[struct_type] = node
# Ignore declarations for anything defined outside this file.
if str(node.location.file) == filepath:
@ -238,8 +240,31 @@ class clang_checkers:
break
beg = end - 1
while beg != 0 and bytes((file_data[beg],)) != b"\n":
while beg != 0 and bytes((file_data[beg],)) not in {
b"\n",
# Needed so declarations on a single line don't detect a comment
# from an outer comment, e.g.
# SomeStruct x = {
# /*list*/ {nullptr, nullptr},
# };
# Would start inside the first `nullptr` and walk backwards to find `/*list*/`.
b"{"
}:
beg -= 1
# Seek back until the comment end (in some cases this includes code).
# This occurs when the body of the declaration includes code, e.g.
# rcti x = {
# /*xmin*/ foo->bar.baz,
# ... snip ...
# };
# Where `"xmin*/ foo->bar."` would be extracted were it not for this check.
# There might be a more elegant way to handle this, for how snipping off the last
# comment characters is sufficient.
end_test = file_data.rfind(b"*/", end + 1, beg)
if end_test != -1:
end = end_test
text = file_data[beg:end]
if text.lstrip().startswith(b"/*"):
if not has_newline:
@ -422,6 +447,10 @@ def source_info_filter(
has_match = True
if not has_match:
continue
else:
# Skip files not in source (generated files from the build directory),
# these could be check but it's not all that useful (preview blend ... etc).
continue
source_info_result.append(item)