diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-25 02:58:03 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-04-25 02:58:03 +0000 |
commit | 4f2e3bb97d2b431dfc302ebbd43976c24739b15e (patch) | |
tree | 7c5e96f71af67b43e94fee1a4d013bf3f675c936 /bindings | |
parent | 02091f0c8ec941a8f7f21cbfde8706ada91c504c (diff) |
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!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207173 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/clang/cindex.py | 59 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_access_specifiers.py | 34 |
2 files changed, 93 insertions, 0 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index eea7d331ae..516f961ad0 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -1205,6 +1205,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): """ Retrieve the Type (if any) of the entity pointed at by the cursor. @@ -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): diff --git a/bindings/python/tests/cindex/test_access_specifiers.py b/bindings/python/tests/cindex/test_access_specifiers.py new file mode 100644 index 0000000000..cfa04dc865 --- /dev/null +++ b/bindings/python/tests/cindex/test_access_specifiers.py @@ -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 + |