Hello,
This patch exposes the enum CX_CXXAccessSpecifier in the Python bindings as
a property of the Cursor. The naming and implementation mimics that of the
CursorKind enum. Since there is an INVALID value in the enum, the property
does not raise when getting the access specifier would not make sense on
the node pointed by the cursor. It simply returns the INVALID value.
This is my first patch to this project, please provide feedback.
Regards,
Tamás Szelei
Index: clang/cindex.py
===================================================================
--- clang/cindex.py (revision 198264)
+++ clang/cindex.py (working copy)
@@ -1093,6 +1093,49 @@
# A module import declaration.
CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
+### C++ access specifiers ###
+class AccessSpecifier(object):
+
+ _kinds = []
+ _name_map = None
+
+ def __init__(self, value):
+ if value >= len(AccessSpecifier._kinds):
+ AccessSpecifier._kinds += [None] * (value - len(AccessSpecifier._kinds) + 1)
+ if AccessSpecifier._kinds[value] is not None:
+ raise ValueError,'AccessSpecifier already loaded'
+ self.value = value
+ AccessSpecifier._kinds[value] = self
+ AccessSpecifier._name_map = None
+
+ def from_param(self):
+ return self.value
+
+ @property
+ def name(self):
+ """Get the enumeration name of this access specifier kind."""
+ if self._name_map is None:
+ self._name_map = {}
+ for key,value in AccessSpecifier.__dict__.items():
+ if isinstance(value,AccessSpecifier):
+ self._name_map[value] = key
+ return self._name_map[self]
+
+ @staticmethod
+ def from_id(id):
+ if id >= len(AccessSpecifier._kinds) or AccessSpecifier._kinds[id] is None:
+ raise ValueError,'Unknown access specifier %d' % id
+ return AccessSpecifier._kinds[id]
+
+ def __repr__(self):
+ return 'AccessSpecifier.%s' % (self.name,)
+
+AccessSpecifier.INVALID = AccessSpecifier(0)
+AccessSpecifier.PUBLIC = AccessSpecifier(1)
+AccessSpecifier.PROTECTED = AccessSpecifier(2)
+AccessSpecifier.PRIVATE = AccessSpecifier(3)
+
+
### Cursors ###
class Cursor(Structure):
@@ -1349,6 +1392,15 @@
"""Returns the raw comment text associated with that Cursor"""
return conf.lib.clang_Cursor_getRawCommentText(self)
+ @property
+ def access_specifier(self):
+ """Return the access specifier of the node.
+ """
+ if not hasattr(self, '_access_specifier'):
+ self._access_specifier = AccessSpecifier.from_id(
+ conf.lib.clang_getCXXAccessSpecifier(self))
+ return self._access_specifier
+
def get_arguments(self):
"""Return an iterator for accessing the arguments of this cursor."""
num_args = conf.lib.clang_Cursor_getNumArguments(self)
Index: tests/cindex/test_access_specifiers.py
===================================================================
--- tests/cindex/test_access_specifiers.py (revision 0)
+++ tests/cindex/test_access_specifiers.py (working copy)
@@ -0,0 +1,32 @@
+from clang.cindex import TranslationUnit
+from clang.cindex import Cursor
+from clang.cindex import AccessSpecifier
+from .util import get_cursor
+from .util import get_tu
+
+def test_access_specifiers():
+ """
+ Ensure that C++ access specifiers are available on cursors
+ that point to nodes where it is relevant.
+ """
+ tu = get_tu("""
+class test_class
+{
+public:
+ void public_member_function();
+protected:
+ void protected_member_function();
+private:
+ void private_member_function();
+};
+""", lang='cpp')
+
+ test_class = get_cursor(tu, "test_class")
+ public = get_cursor(tu.cursor, "public_member_function")
+ protected = get_cursor(tu, "protected_member_function")
+ private = get_cursor(tu, "private_member_function")
+
+ assert public.access_specifier == AccessSpecifier.PUBLIC
+ assert protected.access_specifier == AccessSpecifier.PROTECTED
+ assert private.access_specifier == AccessSpecifier.PRIVATE
+ assert test_class.access_specifier == AccessSpecifier.INVALID
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits