bindings: expose C++ access specifiers
Expose the enum CX_CXXAccessSpecifier in the python bindings as a property of the cursor. If access specifier is not applicable to the node, return the INVALID specifier rather than raising an exception. Patch by Tamás Szeli! llvm-svn: 207173
This commit is contained in:
parent
b59d7c73b0
commit
05f9613610
|
@ -1204,6 +1204,17 @@ class Cursor(Structure):
|
|||
|
||||
return self._extent
|
||||
|
||||
@property
|
||||
def access_specifier(self):
|
||||
"""
|
||||
Retrieves the access specifier (if any) of the entity pointed at by the
|
||||
cursor.
|
||||
"""
|
||||
if not hasattr(self, '_access_specifier'):
|
||||
self._access_specifier = conf.lib.clang_getCXXAccessSpecifier(self)
|
||||
|
||||
return AccessSpecifier.from_id(self._access_specifier)
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
|
@ -1426,6 +1437,54 @@ class Cursor(Structure):
|
|||
res._tu = args[0]._tu
|
||||
return res
|
||||
|
||||
### C++ access specifiers ###
|
||||
|
||||
class AccessSpecifier(object):
|
||||
"""
|
||||
Describes the access of a C++ class member
|
||||
"""
|
||||
|
||||
# The unique kind objects, index by id.
|
||||
_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."""
|
||||
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 not AccessSpecifier._kinds[id]:
|
||||
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)
|
||||
AccessSpecifier.NONE = AccessSpecifier(4)
|
||||
|
||||
### Type Kinds ###
|
||||
|
||||
class TypeKind(object):
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
from clang.cindex import AccessSpecifier
|
||||
from clang.cindex import Cursor
|
||||
from clang.cindex import TranslationUnit
|
||||
|
||||
from .util import get_cursor
|
||||
from .util import get_tu
|
||||
|
||||
def test_access_specifiers():
|
||||
"""Ensure that C++ access specifiers are available on cursors"""
|
||||
|
||||
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")
|
||||
assert test_class.access_specifier == AccessSpecifier.INVALID;
|
||||
|
||||
public = get_cursor(tu.cursor, "public_member_function")
|
||||
assert public.access_specifier == AccessSpecifier.PUBLIC
|
||||
|
||||
protected = get_cursor(tu.cursor, "protected_member_function")
|
||||
assert protected.access_specifier == AccessSpecifier.PROTECTED
|
||||
|
||||
private = get_cursor(tu.cursor, "private_member_function")
|
||||
assert private.access_specifier == AccessSpecifier.PRIVATE
|
||||
|
Loading…
Reference in New Issue