From: Manuel Klimek Date: Mon, 7 May 2012 05:56:03 +0000 (+0000) Subject: - Adding lexical_parent and semantic_parent properties to clang.cindex.Cursor X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=667fd80de4c3b7b143ba98a3b73e9b9b200f6af0;p=clang - Adding lexical_parent and semantic_parent properties to clang.cindex.Cursor - Two new tests (one for each property), require libclang built from r155858 or later to pass - New test utility function (get_cursors) that gets all the nodes with a specific spelling. Patch by Evan Pipho. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156286 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index d988e7685a..a88c12b88d 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -1047,6 +1047,22 @@ class Cursor(Structure): return self._hash + @property + def semantic_parent(self): + """Return the semantic parent for this cursor.""" + if not hasattr(self, '_semantic_parent'): + self._semantic_parent = Cursor_semantic_parent(self) + + return self._semantic_parent + + @property + def lexical_parent(self): + """Return the lexical parent for this cursor.""" + if not hasattr(self, '_lexical_parent'): + self._lexical_parent = Cursor_lexical_parent(self) + + return self._lexical_parent + def get_children(self): """Return an iterator for accessing the children of this cursor.""" @@ -1974,6 +1990,16 @@ Cursor_objc_type_encoding.argtypes = [Cursor] Cursor_objc_type_encoding.restype = _CXString Cursor_objc_type_encoding.errcheck = _CXString.from_result +Cursor_semantic_parent = lib.clang_getCursorSemanticParent +Cursor_semantic_parent.argtypes = [Cursor] +Cursor_semantic_parent.restype = Cursor +Cursor_semantic_parent.errcheck = Cursor.from_result + +Cursor_lexical_parent = lib.clang_getCursorLexicalParent +Cursor_lexical_parent.argtypes = [Cursor] +Cursor_lexical_parent.restype = Cursor +Cursor_lexical_parent.errcheck = Cursor.from_result + Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) Cursor_visit = lib.clang_visitChildren Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object] diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index 0582d2af63..8b12f8d94e 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -1,6 +1,7 @@ from clang.cindex import CursorKind from clang.cindex import TypeKind from .util import get_cursor +from .util import get_cursors from .util import get_tu kInput = """\ @@ -75,6 +76,30 @@ def test_underlying_type(): underlying = typedef.underlying_typedef_type assert underlying.kind == TypeKind.INT +kParentTest = """\ + class C { + void f(); + } + + void C::f() { } + """ +def test_semantic_parent(): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + assert(len(curs) == 2) + assert(curs[0].semantic_parent == curs[1].semantic_parent) + assert(curs[0].semantic_parent == decl) + +def test_lexical_parent(): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + assert(len(curs) == 2) + assert(curs[0].lexical_parent != curs[1].lexical_parent) + assert(curs[0].lexical_parent == decl) + assert(curs[1].lexical_parent == tu.cursor) + def test_enum_type(): tu = get_tu('enum TEST { FOO=1, BAR=2 };') enum = get_cursor(tu, 'TEST') diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py index f924094b21..e945aeacf7 100644 --- a/bindings/python/tests/cindex/util.py +++ b/bindings/python/tests/cindex/util.py @@ -58,9 +58,38 @@ def get_cursor(source, spelling): return result return None + +def get_cursors(source, spelling): + """Obtain all cursors from a source object with a specific spelling. + This provides a convenient search mechanism to find all cursors with specific + spelling within a source. The first argument can be either a + TranslationUnit or Cursor instance. + + If no cursors are found, an empty list is returned. + """ + cursors = [] + children = [] + if isinstance(source, Cursor): + children = source.get_children() + else: + # Assume TU + children = source.cursor.get_children() + + for cursor in children: + if cursor.spelling == spelling: + cursors.append(cursor) + + # Recurse into children. + cursors.extend(get_cursors(cursor, spelling)) + + return cursors + + + __all__ = [ 'get_cursor', + 'get_cursors', 'get_tu', ]