diff --git a/CppHeaderParser/CppHeaderParser.py b/CppHeaderParser/CppHeaderParser.py index 007d78a..a369308 100644 --- a/CppHeaderParser/CppHeaderParser.py +++ b/CppHeaderParser/CppHeaderParser.py @@ -280,6 +280,10 @@ def _split_namespace(namestack): :rtype: Tuple[str, list] """ # TODO: this should be using tokens instead of nhack + typename = None + if namestack and namestack[0] == "typename": + typename = namestack[0] + namestack = namestack[1:] last_colon = None for i, n in enumerate(namestack): @@ -296,6 +300,9 @@ def _split_namespace(namestack): else: ns = "" + if typename: + namestack = [typename] + namestack + return ns, namestack @@ -1269,7 +1276,11 @@ def __init__(self, nameStack, doxygen, location, **kwargs): # backwards compat; deprecate camelCase in dicts self["defaultValue"] = default - elif is_fundamental(nameStack[-1]) or nameStack[-1] in [">", "<", ":", "."]: + elif ( + is_fundamental(nameStack[-1]) + or nameStack[-1] in [">", "<", ":", "."] + or (len(nameStack) > 2 and nameStack[-2] == "::") + ): # Un named parameter self["type"] = " ".join(nameStack) self["name"] = "" @@ -3348,7 +3359,10 @@ def _evaluate_stack(self, token=None): else: atype["namespace"] = ns - atype["raw_type"] = ns + atype["type"] + if atype["type"].startswith("typename "): + atype["raw_type"] = "typename " + ns + atype["type"][9:] + else: + atype["raw_type"] = ns + atype["type"] if self.curClass: klass = self.classes[self.curClass] diff --git a/test/test_CppHeaderParser.py b/test/test_CppHeaderParser.py index 9656437..fedacc0 100644 --- a/test/test_CppHeaderParser.py +++ b/test/test_CppHeaderParser.py @@ -4010,5 +4010,33 @@ def test_fn(self): self.assertEqual(False, c["methods"]["public"][1]["template"]) +class UsingTypename(unittest.TestCase): + def setUp(self): + self.cppHeader = CppHeaderParser.CppHeader( + """ +template class P { +public: + using State = typename f::TP::S; + P(State st); +}; +""", + "string", + ) + + def test_fn(self): + c = self.cppHeader.classes["P"] + self.assertEqual("P", c["name"]) + state = c["using"]["State"] + self.assertEqual(state["raw_type"], "typename f::TP::S") + self.assertEqual(state["type"], "typename TP::S") + + m = c["methods"]["public"][0] + self.assertEqual(m["name"], "P") + self.assertEqual(m["parameters"][0]["namespace"], "f::") + self.assertEqual(m["parameters"][0]["name"], "st") + self.assertEqual(m["parameters"][0]["raw_type"], "typename f::TP::S") + self.assertEqual(m["parameters"][0]["type"], "typename TP::S") + + if __name__ == "__main__": unittest.main()