Skip to content

Add support for class templates #1

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
13 changes: 11 additions & 2 deletions py_cppmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,22 @@ def __repr__(self) -> str:
return "<py_cppmodel.Class {}>".format(self.name)


class ClassTemplate(Class):
def __init__(self, cursor: Cursor, namespaces: List[str]):
Class.__init__(self, cursor, namespaces)
# TODO: replace the count with the actual template args once count works.
self.template_parameter_count = cursor.get_num_template_arguments()


class Model(object):
def __init__(self, translation_unit: TranslationUnit):
"""Create a model from a translation unit."""
self.filename: str = translation_unit.spelling
self.functions: List[Function] = []
self.classes: List[Class] = []
self.classes: List[Class|ClassTemplate] = []
self.unmodelled_nodes: List[Unmodelled] = []
# Keep a reference to the translation unit to prevent it from being garbage collected.
self.translation_unit: TranslationUnit = translation_unit
self.translation_unit: TranslationUnit = translation_unit

def is_error_in_current_file(diagnostic: Diagnostic) -> bool:
if str(diagnostic.location.file) != str(translation_unit.spelling):
Expand Down Expand Up @@ -251,6 +258,8 @@ def _add_child_nodes(self, cursor: Any, namespaces: List[str] = []):
for c in cursor.get_children():
if c.kind == CursorKind.CLASS_DECL or c.kind == CursorKind.STRUCT_DECL:
self.classes.append(Class(c, namespaces))
elif c.kind == CursorKind.CLASS_TEMPLATE:
self.classes.append(ClassTemplate(c, namespaces))
elif (
c.kind == CursorKind.FUNCTION_DECL
and c.type.kind == TypeKind.FUNCTIONPROTO
Expand Down
1 change: 0 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ set -x

python -m pytype .
python -m unittest discover .

16 changes: 10 additions & 6 deletions test_py_cppmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import py_cppmodel
import unittest

# This is a workaround for the current inability to portably find libclang.
clang.cindex.Config.set_library_path("/Library/Developer/CommandLineTools/usr/lib/")


Expand All @@ -25,7 +26,7 @@ def test_functions(self):
)

def test_classes(self):
self.assertEqual(len(self.model.classes), 1)
self.assertEqual(len(self.model.classes), 2)
self.assertEqual(str(self.model.classes[0]), "<py_cppmodel.Class A>")

self.assertEqual(len(self.model.classes[0].members), 3)
Expand All @@ -47,15 +48,18 @@ def test_classes(self):
str(self.model.classes[0].methods[0]), "<py_cppmodel.Method int foo(int)>"
)

self.assertEqual(len(self.model.unmodelled_nodes), 2)
self.assertEqual(str(self.model.classes[1]), "<py_cppmodel.Class B>")
self.assertIsInstance(self.model.classes[1], py_cppmodel.ClassTemplate)
if isinstance(self.model.classes[1], py_cppmodel.ClassTemplate):
self.assertEqual(self.model.classes[1].template_parameter_count, 1)


def test_unmodelled_nodes(self):
self.assertEqual(len(self.model.unmodelled_nodes), 1)
self.assertEqual(
str(self.model.unmodelled_nodes[0]),
"<py_cppmodel.Unmodelled z <SourceLocation file 'sample.cc', line 1, column 5>>",
)
self.assertEqual(
str(self.model.unmodelled_nodes[1]),
"<py_cppmodel.Unmodelled B<T> <SourceLocation file 'sample.cc', line 12, column 7>>",
)


if __name__ == "__main__":
Expand Down