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( template_regex = re.compile(r"<(?P<type>[\w]+)\s*(?P<asterisks>\*+)?\s*>")
r"\s*(?:\/\/)?\s*(?:class|struct) (\w+)<([\w]+)\s*(\*+)?\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]: def get_class_name(line: str) -> Optional[str]:
"""For VTABLE markers, extract the class name from the code line or comment """For VTABLE markers, extract the class name from the code line or comment
where it appears.""" 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) match = class_decl_regex.match(line)
if match is not None: if match is not None:
return match.group(1) return fix_template_type(match.group(1))
return None return None

View file

@ -756,3 +756,18 @@ def test_virtual_inheritance(parser):
assert parser.vtables[1].base_class == "Greetings" assert parser.vtables[1].base_class == "Greetings"
assert parser.vtables[2].base_class == "Howdy" assert parser.vtables[2].base_class == "Howdy"
assert all(v.name == "HiThere" for v in parser.vtables) 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 *>"), ("// class MxList<LegoPathController* >", "MxList<LegoPathController *>"),
# I don't know if this would ever come up, but sure, why not? # I don't know if this would ever come up, but sure, why not?
("// class MxList<LegoPathController**>", "MxList<LegoPathController **>"), ("// class MxList<LegoPathController**>", "MxList<LegoPathController **>"),
("// class Many::Name::Spaces", "Many::Name::Spaces"),
] ]