Parser bugfix: vtable namespace (#910)

This commit is contained in:
MS 2024-05-11 18:40:31 -04:00 committed by GitHub
parent f88f7b115e
commit 119ff93461
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 15 deletions

View file

@ -69,32 +69,39 @@ def is_blank_or_comment(line: str) -> bool:
)
template_class_decl_regex = re.compile(
r"\s*(?:\/\/)?\s*(?:class|struct) (\w+)<([\w]+)\s*(\*+)?\s*>"
template_regex = re.compile(r"<(?P<type>[\w]+)\s*(?P<asterisks>\*+)?\s*>")
class_decl_regex = re.compile(
r"\s*(?:\/\/)?\s*(?:class|struct) ((?:\w+(?:<.+>)?(?:::)?)+)"
)
class_decl_regex = re.compile(r"\s*(?:\/\/)?\s*(?:class|struct) (\w+)")
def template_replace(match: re.Match) -> str:
(type_name, asterisks) = match.groups()
if asterisks is None:
return f"<{type_name}>"
return f"<{type_name} {asterisks}>"
def fix_template_type(class_name: str) -> str:
"""For template classes, we should reformat the class name so it matches
the output from cvdump: one space between the template type and any asterisks
if it is a pointer type."""
if "<" not in class_name:
return class_name
return template_regex.sub(template_replace, class_name)
def get_class_name(line: str) -> Optional[str]:
"""For VTABLE markers, extract the class name from the code line or comment
where it appears."""
match = template_class_decl_regex.match(line)
if match is not None:
# For template classes, we should reformat the class name so it matches
# the output from cvdump: one space between the template type and any asterisks
# if it is a pointer type.
(class_name, template_type, asterisks) = match.groups()
if asterisks is not None:
return f"{class_name}<{template_type} {asterisks}>"
return f"{class_name}<{template_type}>"
match = class_decl_regex.match(line)
if match is not None:
return match.group(1)
return fix_template_type(match.group(1))
return None

View file

@ -756,3 +756,18 @@ def test_virtual_inheritance(parser):
assert parser.vtables[1].base_class == "Greetings"
assert parser.vtables[2].base_class == "Howdy"
assert all(v.name == "HiThere" for v in parser.vtables)
def test_namespace_in_comment(parser):
parser.read_lines(
[
"// VTABLE: HELLO 0x1234",
"// class Tgl::Object",
"// VTABLE: HELLO 0x5555",
"// class TglImpl::RendererImpl<D3DRMImpl::D3DRM>",
]
)
assert len(parser.vtables) == 2
assert parser.vtables[0].name == "Tgl::Object"
assert parser.vtables[1].name == "TglImpl::RendererImpl<D3DRMImpl::D3DRM>"

View file

@ -126,6 +126,7 @@ def test_marker_dict_type_replace():
("// class MxList<LegoPathController* >", "MxList<LegoPathController *>"),
# I don't know if this would ever come up, but sure, why not?
("// class MxList<LegoPathController**>", "MxList<LegoPathController **>"),
("// class Many::Name::Spaces", "Many::Name::Spaces"),
]